Skip to content
This repository has been archived by the owner on Jan 29, 2025. It is now read-only.

Commit

Permalink
[glsl-in] Fix void function calls
Browse files Browse the repository at this point in the history
  • Loading branch information
JCapucho authored and kvark committed May 21, 2021
1 parent c526c85 commit 4e95c46
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 44 deletions.
53 changes: 39 additions & 14 deletions src/front/glsl/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub struct FunctionDeclaration {
pub handle: Handle<Function>,
/// Wheter this function was already defined or is just a prototype
pub defined: bool,
/// Wheter or not this function returns void (nothing)
pub void: bool,
}

#[derive(Debug)]
Expand Down Expand Up @@ -321,33 +323,55 @@ impl<'function> Context<'function> {
self.scopes.pop();
}

pub fn lower(
pub fn lower_expect(
&mut self,
program: &mut Program,
expr: Handle<HirExpr>,
lhs: bool,
body: &mut Block,
) -> Result<(Handle<Expression>, SourceMetadata), ErrorKind> {
let (maybe_expr, meta) = self.lower(program, expr, lhs, body)?;

let expr = match maybe_expr {
Some(e) => e,
None => {
return Err(ErrorKind::SemanticError(
meta,
"Expression returns void".into(),
))
}
};

Ok((expr, meta))
}

pub fn lower(
&mut self,
program: &mut Program,
expr: Handle<HirExpr>,
lhs: bool,
body: &mut Block,
) -> Result<(Option<Handle<Expression>>, SourceMetadata), ErrorKind> {
let HirExpr { kind, meta } = self.hir_exprs[expr].clone();

let handle = match kind {
HirExprKind::Access { base, index } => {
let base = self.lower(program, base, lhs, body)?.0;
let index = self.lower(program, index, false, body)?.0;
let base = self.lower_expect(program, base, lhs, body)?.0;
let index = self.lower_expect(program, index, false, body)?.0;

self.add_expression(Expression::Access { base, index }, body)
}
HirExprKind::Select { base, field } => {
let base = self.lower(program, base, lhs, body)?.0;
let base = self.lower_expect(program, base, lhs, body)?.0;

program.field_selection(self, body, base, &field, meta)?
}
HirExprKind::Constant(constant) if !lhs => {
self.add_expression(Expression::Constant(constant), body)
}
HirExprKind::Binary { left, op, right } if !lhs => {
let (left, left_meta) = self.lower(program, left, false, body)?;
let (right, right_meta) = self.lower(program, right, false, body)?;
let (left, left_meta) = self.lower_expect(program, left, false, body)?;
let (right, right_meta) = self.lower_expect(program, right, false, body)?;

if let BinaryOperator::Equal | BinaryOperator::NotEqual = op {
let equals = op == BinaryOperator::Equal;
Expand Down Expand Up @@ -386,7 +410,7 @@ impl<'function> Context<'function> {
}
}
HirExprKind::Unary { op, expr } if !lhs => {
let expr = self.lower(program, expr, false, body)?.0;
let expr = self.lower_expect(program, expr, false, body)?.0;

self.add_expression(Expression::Unary { op, expr }, body)
}
Expand All @@ -405,16 +429,17 @@ impl<'function> Context<'function> {
}
}
HirExprKind::Call(call) if !lhs => {
program.function_call(self, body, call.kind, &call.args, meta)?
let maybe_expr = program.function_call(self, body, call.kind, &call.args, meta)?;
return Ok((maybe_expr, meta));
}
HirExprKind::Conditional {
condition,
accept,
reject,
} if !lhs => {
let condition = self.lower(program, condition, false, body)?.0;
let accept = self.lower(program, accept, false, body)?.0;
let reject = self.lower(program, reject, false, body)?.0;
let condition = self.lower_expect(program, condition, false, body)?.0;
let accept = self.lower_expect(program, accept, false, body)?.0;
let reject = self.lower_expect(program, reject, false, body)?.0;

self.add_expression(
Expression::Select {
Expand All @@ -426,8 +451,8 @@ impl<'function> Context<'function> {
)
}
HirExprKind::Assign { tgt, value } if !lhs => {
let pointer = self.lower(program, tgt, true, body)?.0;
let value = self.lower(program, value, false, body)?.0;
let pointer = self.lower_expect(program, tgt, true, body)?.0;
let value = self.lower_expect(program, value, false, body)?.0;

self.emit_flush(body);
self.emit_start();
Expand All @@ -444,7 +469,7 @@ impl<'function> Context<'function> {
}
};

Ok((handle, meta))
Ok((Some(handle), meta))
}
}

Expand Down
54 changes: 33 additions & 21 deletions src/front/glsl/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ impl Program<'_> {
fc: FunctionCallKind,
raw_args: &[Handle<HirExpr>],
meta: SourceMetadata,
) -> Result<Handle<Expression>, ErrorKind> {
) -> Result<Option<Handle<Expression>>, ErrorKind> {
let args: Vec<_> = raw_args
.iter()
.map(|e| ctx.lower(self, *e, false, body))
.map(|e| ctx.lower_expect(self, *e, false, body))
.collect::<Result<_, _>>()?;

match fc {
Expand Down Expand Up @@ -89,7 +89,7 @@ impl Program<'_> {
)
};

Ok(h)
Ok(Some(h))
}
FunctionCallKind::Function(name) => {
match name.as_str() {
Expand All @@ -98,14 +98,14 @@ impl Program<'_> {
return Err(ErrorKind::wrong_function_args(name, 2, args.len(), meta));
}
ctx.samplers.insert(args[0].0, args[1].0);
Ok(args[0].0)
Ok(Some(args[0].0))
}
"texture" => {
if args.len() != 2 {
return Err(ErrorKind::wrong_function_args(name, 2, args.len(), meta));
}
if let Some(sampler) = ctx.samplers.get(&args[0].0).copied() {
Ok(ctx.add_expression(
Ok(Some(ctx.add_expression(
Expression::ImageSample {
image: args[0].0,
sampler,
Expand All @@ -116,7 +116,7 @@ impl Program<'_> {
depth_ref: None,
},
body,
))
)))
} else {
Err(ErrorKind::SemanticError(meta, "Bad call to texture".into()))
}
Expand All @@ -126,7 +126,7 @@ impl Program<'_> {
return Err(ErrorKind::wrong_function_args(name, 3, args.len(), meta));
}
if let Some(sampler) = ctx.samplers.get(&args[0].0).copied() {
Ok(ctx.add_expression(
Ok(Some(ctx.add_expression(
Expression::ImageSample {
image: args[0].0,
sampler,
Expand All @@ -137,7 +137,7 @@ impl Program<'_> {
depth_ref: None,
},
body,
))
)))
} else {
Err(ErrorKind::SemanticError(
meta,
Expand All @@ -151,7 +151,7 @@ impl Program<'_> {
if args.len() != 1 {
return Err(ErrorKind::wrong_function_args(name, 1, args.len(), meta));
}
Ok(ctx.add_expression(
Ok(Some(ctx.add_expression(
Expression::Math {
fun: match name.as_str() {
"ceil" => MathFunction::Ceil,
Expand All @@ -176,13 +176,13 @@ impl Program<'_> {
arg2: None,
},
body,
))
)))
}
"pow" | "dot" | "max" => {
if args.len() != 2 {
return Err(ErrorKind::wrong_function_args(name, 2, args.len(), meta));
}
Ok(ctx.add_expression(
Ok(Some(ctx.add_expression(
Expression::Math {
fun: match name.as_str() {
"pow" => MathFunction::Pow,
Expand All @@ -195,13 +195,13 @@ impl Program<'_> {
arg2: None,
},
body,
))
)))
}
"mix" | "clamp" => {
if args.len() != 3 {
return Err(ErrorKind::wrong_function_args(name, 3, args.len(), meta));
}
Ok(ctx.add_expression(
Ok(Some(ctx.add_expression(
Expression::Math {
fun: match name.as_str() {
"mix" => MathFunction::Mix,
Expand All @@ -213,14 +213,14 @@ impl Program<'_> {
arg2: Some(args[2].0),
},
body,
))
)))
}
"lessThan" | "greaterThan" | "lessThanEqual" | "greaterThanEqual" | "equal"
| "notEqual" => {
if args.len() != 2 {
return Err(ErrorKind::wrong_function_args(name, 2, args.len(), meta));
}
Ok(ctx.add_expression(
Ok(Some(ctx.add_expression(
Expression::Binary {
op: match name.as_str() {
"lessThan" => BinaryOperator::Less,
Expand All @@ -235,7 +235,7 @@ impl Program<'_> {
right: args[1].0,
},
body,
))
)))
}
"isinf" | "isnan" | "all" | "any" => {
let fun = match name.as_str() {
Expand All @@ -246,7 +246,9 @@ impl Program<'_> {
_ => unreachable!(),
};

self.parse_relational_fun(ctx, body, name, &args, fun, meta)
Ok(Some(
self.parse_relational_fun(ctx, body, name, &args, fun, meta)?,
))
}
_ => {
let mut parameters = Vec::new();
Expand All @@ -273,22 +275,27 @@ impl Program<'_> {

let mut arguments = Vec::with_capacity(raw_args.len());
for (qualifier, expr) in fun.parameters.iter().zip(raw_args.iter()) {
let handle = ctx.lower(self, *expr, qualifier.is_lhs(), body)?.0;
let handle = ctx.lower_expect(self, *expr, qualifier.is_lhs(), body)?.0;
arguments.push(handle)
}

ctx.emit_flush(body);

let expression = ctx.add_expression(Expression::Call(fun.handle), body);
let result = if !fun.void {
Some(ctx.add_expression(Expression::Call(fun.handle), body))
} else {
None
};

body.push(crate::Statement::Call {
function: fun.handle,
arguments,
result: Some(expression),
result,
});

ctx.emit_start();

Ok(expression)
Ok(result)
}
}
}
Expand Down Expand Up @@ -351,6 +358,8 @@ impl Program<'_> {
}
}

let void = function.result.is_none();

if let Some(decl) = self.lookup_function.get_mut(&sig) {
if decl.defined {
return Err(ErrorKind::SemanticError(
Expand All @@ -369,6 +378,7 @@ impl Program<'_> {
parameters,
handle,
defined: true,
void,
},
);
}
Expand All @@ -391,6 +401,7 @@ impl Program<'_> {
name,
parameters: function.arguments.iter().map(|p| p.ty).collect(),
};
let void = function.result.is_none();

for (arg, qualifier) in function.arguments.iter_mut().zip(parameters.iter()) {
if qualifier.is_lhs() {
Expand All @@ -412,6 +423,7 @@ impl Program<'_> {
parameters,
handle,
defined: false,
void,
},
);

Expand Down
Loading

0 comments on commit 4e95c46

Please sign in to comment.