diff --git a/readme.md b/readme.md index a3e4a2c..c630f22 100644 --- a/readme.md +++ b/readme.md @@ -20,6 +20,8 @@ let setup = fn() { }; let update = fn(state, events) { + let new = 100; + state.player.position.x = new; return state; }; diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 3c9ce2e..f71db34 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1,4 +1,8 @@ -pub mod types; -pub mod scanner; pub mod parser; -pub use parser::*; +pub mod scanner; +pub mod types; + +pub fn parse_file(code: String) -> Result { + let mut tokens = scanner::scan(code); + parser::parse(&mut tokens, parser::parse_program) +} diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 0f591f4..f022d06 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -25,14 +25,7 @@ fn parse_definitions(tokens: &mut Tokens) -> ParseResult> { fn parse_set(tokens: &mut Tokens) -> ParseResult { if let Some(_eq) = tokens.next_if(&Token::Equals) { if let Some(expr) = parse_expr(tokens)? { - if let Some(_) = tokens.next_if(&Token::Semicolon) { - Ok(Some(expr)) - } else { - Err(Error::UnexpectedToken { - expected: Token::Semicolon, - got: tokens.next(), - }) - } + Ok(Some(expr)) } else { Err(Error::UnexpectedTokenForParser( "expr".into(), @@ -65,11 +58,18 @@ fn parse_definition(tokens: &mut Tokens) -> ParseResult { }; if let Some(name) = parse_identifier_name(tokens)? { if let Some(expr) = parse_set(tokens)? { - Ok(Some(ast::Definition { - mutable, - name, - expr, - })) + if let Some(_) = tokens.next_if(&Token::Semicolon) { + Ok(Some(ast::Definition { + mutable, + name, + expr, + })) + } else { + Err(Error::UnexpectedToken { + expected: Token::Semicolon, + got: tokens.next(), + }) + } } else { Err(Error::UnexpectedToken { expected: Token::Equals, @@ -162,6 +162,7 @@ fn parse_statement(tokens: &mut Tokens) -> ParseResult { if let Some(_) = tokens.next_if(&Token::Semicolon) { Ok(Some(expr)) } else { + println!("parse statement expr"); Err(Error::UnexpectedToken { expected: Token::Semicolon, got: tokens.next(), @@ -358,7 +359,7 @@ mod tests { } #[test] fn assign() { - let program = "x = [2, { .hello: 7 }];".to_string(); + let program = "x = [2, { .hello: 7 }]".to_string(); let result = parse(&mut scan(program), parse_expr); insta::assert_debug_snapshot!(result); } @@ -402,6 +403,8 @@ let setup = fn() { }; let update = fn(state, events) { + let new = 100; + state.player.position.x = new; return state; }; diff --git a/src/parser/snapshots/ayin__parser__parser__tests__full_program.snap b/src/parser/snapshots/ayin__parser__parser__tests__full_program.snap index f1624ae..66ff9d4 100644 --- a/src/parser/snapshots/ayin__parser__parser__tests__full_program.snap +++ b/src/parser/snapshots/ayin__parser__parser__tests__full_program.snap @@ -74,6 +74,49 @@ Ok( ], body: Block( [ + Let( + Definition { + mutable: false, + name: Name( + "new", + ), + expr: Value( + Int( + 100, + ), + ), + }, + ), + Expr( + Op { + lhs: Access { + expr: Access { + expr: Access { + expr: Var( + Name( + "state", + ), + ), + field: Label( + "player", + ), + }, + field: Label( + "position", + ), + }, + field: Label( + "x", + ), + }, + op: Assign, + rhs: Var( + Name( + "new", + ), + ), + }, + ), Return( Some( Var(