From 993521965db00c427b339d27d75b92964cf5ce69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Capucho?= Date: Sat, 6 Feb 2021 22:15:25 +0000 Subject: [PATCH] Add support for unary ops to glsl --- src/front/glsl/ast.rs | 9 ++++++++- src/front/glsl/parser.rs | 28 ++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/src/front/glsl/ast.rs b/src/front/glsl/ast.rs index 157e72c0b9..4ece1ce9ed 100644 --- a/src/front/glsl/ast.rs +++ b/src/front/glsl/ast.rs @@ -3,7 +3,7 @@ use crate::{ proc::{ResolveContext, Typifier}, Arena, BinaryOperator, Binding, Constant, Expression, FastHashMap, Function, FunctionArgument, GlobalVariable, Handle, Interpolation, LocalVariable, Module, RelationalFunction, ShaderStage, - Statement, StorageClass, Type, + Statement, StorageClass, Type, UnaryOperator, }; #[derive(Debug)] @@ -57,6 +57,13 @@ impl Program { })) } + pub fn unary_expr(&mut self, op: UnaryOperator, tgt: &ExpressionRule) -> ExpressionRule { + ExpressionRule::from_expression(self.context.expressions.append(Expression::Unary { + op, + expr: tgt.expression, + })) + } + /// Helper function to insert equality expressions, this handles the special /// case of `vec1 == vec2` and `vec1 != vec2` since in the IR they are /// represented as `all(equal(vec1, vec2))` and `any(notEqual(vec1, vec2))` diff --git a/src/front/glsl/parser.rs b/src/front/glsl/parser.rs index dc48cea8be..474a288323 100644 --- a/src/front/glsl/parser.rs +++ b/src/front/glsl/parser.rs @@ -8,7 +8,7 @@ pomelo! { Arena, BinaryOperator, Binding, Block, Constant, ConstantInner, EntryPoint, Expression, Function, GlobalVariable, Handle, Interpolation, - LocalVariable, ScalarValue, + LocalVariable, ScalarValue, ScalarKind, Statement, StorageAccess, StorageClass, StructMember, SwitchCase, Type, TypeInner, UnaryOperator, FunctionArgument }; @@ -319,15 +319,27 @@ pomelo! { //TODO return Err(ErrorKind::NotImplemented("--pre")) } - unary_expression ::= unary_operator unary_expression { - //TODO - return Err(ErrorKind::NotImplemented("unary_op")) + unary_expression ::= Plus unary_expression(tgt) { + tgt + } + unary_expression ::= Dash unary_expression(tgt) { + extra.unary_expr(UnaryOperator::Negate, &tgt) + } + unary_expression ::= Bang unary_expression(tgt) { + if let TypeInner::Scalar { kind: ScalarKind::Bool, .. } = extra.resolve_type(tgt.expression)? { + extra.unary_expr(UnaryOperator::Not, &tgt) + } else { + return Err(ErrorKind::SemanticError("Cannot apply '!' to non bool type".into())) + } + } + unary_expression ::= Tilde unary_expression(tgt) { + if extra.resolve_type(tgt.expression)?.scalar_kind() != Some(ScalarKind::Bool) { + extra.unary_expr(UnaryOperator::Not, &tgt) + } else { + return Err(ErrorKind::SemanticError("Cannot apply '~' to type".into())) + } } - unary_operator ::= Plus; - unary_operator ::= Dash; - unary_operator ::= Bang; - unary_operator ::= Tilde; multiplicative_expression ::= unary_expression; multiplicative_expression ::= multiplicative_expression(left) Star unary_expression(right) { extra.binary_expr(BinaryOperator::Multiply, &left, &right)