diff --git a/src/front/glsl_new/ast.rs b/src/front/glsl_new/ast.rs index 7980b0ae7c..3819ceb4fb 100644 --- a/src/front/glsl_new/ast.rs +++ b/src/front/glsl_new/ast.rs @@ -34,6 +34,7 @@ impl Program { context: Context { expressions: Arena::::new(), local_variables: Arena::::new(), + lookup_local_variables: FastHashMap::default(), }, } } @@ -48,6 +49,7 @@ pub enum Profile { pub struct Context { pub expressions: Arena, pub local_variables: Arena, + pub lookup_local_variables: FastHashMap>, } #[derive(Debug)] diff --git a/src/front/glsl_new/lex.rs b/src/front/glsl_new/lex.rs index 898236723b..27c6e1ca81 100644 --- a/src/front/glsl_new/lex.rs +++ b/src/front/glsl_new/lex.rs @@ -115,6 +115,7 @@ pub fn consume_token(mut input: &str) -> (Option, &str) { "out" => (Some(Token::Out(meta)), rest), // types "void" => (Some(Token::Void(meta)), rest), + "float" => (Some(Token::Float(meta)), rest), "vec2" => (Some(Token::Vec2(meta)), rest), "vec3" => (Some(Token::Vec3(meta)), rest), "vec4" => (Some(Token::Vec4(meta)), rest), diff --git a/src/front/glsl_new/parser.rs b/src/front/glsl_new/parser.rs index 79b489bc35..6e4e592c8e 100644 --- a/src/front/glsl_new/parser.rs +++ b/src/front/glsl_new/parser.rs @@ -86,6 +86,8 @@ pomelo! { %type expression ExpressionRule; %type constant_expression Handle; + %type initializer ExpressionRule; + // decalartions %type declaration VarDeclaration; %type init_declarator_list VarDeclaration; @@ -153,12 +155,17 @@ pomelo! { statements: vec![], } } else { - // try global vars + // try global and local vars if let Some(global_var) = extra.lookup_global_variables.get(&v.1) { ExpressionRule{ expression: extra.context.expressions.append(Expression::GlobalVariable(*global_var)), statements: vec![], } + } else if let Some(local_var) = extra.context.lookup_local_variables.get(&v.1) { + ExpressionRule{ + expression: extra.context.expressions.append(Expression::LocalVariable(*local_var)), + statements: vec![], + } } else { return Err(ErrorKind::UnknownVariable(v.0, v.1)) } @@ -442,7 +449,10 @@ pomelo! { } // init_declarator_list ::= init_declarator_list Comma Identifier array_specifier; // init_declarator_list ::= init_declarator_list Comma Identifier array_specifier Equal initializer; - // init_declarator_list ::= init_declarator_list Comma Identifier Equal initializer; + init_declarator_list ::= init_declarator_list(mut idl) Comma Identifier(i) Equal initializer(init) { + idl.ids_initializers.push((i.1, Some(init))); + idl + } single_declaration ::= fully_specified_type(t) { let ty = t.1.ok_or(ErrorKind::SemanticError("Empty type for declaration"))?; @@ -462,6 +472,17 @@ pomelo! { ty, } } + // single_declaration ::= fully_specified_type Identifier array_specifier; + // single_declaration ::= fully_specified_type Identifier array_specifier Equal initializer; + single_declaration ::= fully_specified_type(t) Identifier(i) Equal initializer(init) { + let ty = t.1.ok_or(ErrorKind::SemanticError("Empty type for declaration"))?; + + VarDeclaration{ + type_qualifiers: t.0, + ids_initializers: vec![(i.1, Some(init))], + ty, + } + } fully_specified_type ::= type_specifier(t) {(vec![], t)} fully_specified_type ::= type_qualifier(q) type_specifier(t) {(q,t)} @@ -513,11 +534,33 @@ pomelo! { storage_qualifier ::= Out {StorageClass::Output} //TODO: other storage qualifiers + initializer ::= assignment_expression; + // initializer ::= LeftBrace initializer_list RightBrace; + // initializer ::= LeftBrace initializer_list Comma RightBrace; - declaration_statement ::= declaration { - //TODO: Should declarations be able to genereate expression/statements? - //TODO: local vars - Statement::Empty + // initializer_list ::= initializer; + // initializer_list ::= initializer_list Comma initializer; + + declaration_statement ::= declaration(d) { + let mut statements = Vec::::new(); + // local variables + for (id, initializer) in d.ids_initializers { + let h = extra.context.local_variables.append( + LocalVariable { + name: Some(id.clone()), + ty: d.ty, + init: initializer.map(|i| { + statements.extend(i.statements); + i.expression + }), + } + ); + extra.context.lookup_local_variables.insert(id, h); + } + match statements.len() { + 1 => statements.remove(0), + _ => Statement::Block(statements), + } } // statement @@ -580,6 +623,15 @@ pomelo! { } type_specifier_nonarray ::= Void { None } + type_specifier_nonarray ::= Float { + Some(Type { + name: None, + inner: TypeInner::Scalar { + kind: ScalarKind::Float, + width: 4, + } + }) + } type_specifier_nonarray ::= Vec2 { Some(Type { name: None, diff --git a/test-data/simple.vert b/test-data/simple.vert index 761b17ed05..3aa56b2e95 100644 --- a/test-data/simple.vert +++ b/test-data/simple.vert @@ -3,5 +3,6 @@ layout(location = 0) in vec2 position; void main() { - gl_Position = vec4(position, 0.0, 1.0); + float w = 1.0; + gl_Position = vec4(position, 0.0, w); }