From ff3b45352d1f7bd8c82fd927ceb84e59ecb7302e Mon Sep 17 00:00:00 2001 From: me Date: Tue, 16 Dec 2025 17:42:48 +0200 Subject: [PATCH] blocks --- readme.md | 8 ++-- src/parser/parser.rs | 45 ++++++++++++++++++- .../ayin__parser__parser__tests__fn_def.snap | 14 ++++-- ...__parser__parser__tests__paren_fncall.snap | 14 ++++-- 4 files changed, 67 insertions(+), 14 deletions(-) diff --git a/readme.md b/readme.md index 0281dc2..d42cde8 100644 --- a/readme.md +++ b/readme.md @@ -17,19 +17,19 @@ let init = fn() { return { player: { position: { x: 10, y: 20 }, }, } -} +}; let update = fn(state, events) { return state'; -} +}; let draw = fn(frame, state) { frame.clear(0,0,0); -} +}; let migrate = fn(state) { return { player: { pos: state.player.position } }, -} +}; ``` - dynamic software updating could occur every frame diff --git a/src/parser/parser.rs b/src/parser/parser.rs index 5f4b090..306d40f 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -101,8 +101,13 @@ fn parse_simple_expr(tokens: &mut Tokens) -> ParseResult { fn parse_fn(tokens: &mut Tokens) -> ParseResult { if let Some(_) = tokens.next_if(&Token::Fn) { if let Some(args) = parse_args(tokens)? { - if let Some(body) = tokens.between(&Token::OpenCurly, &Token::CloseCurly, parse_expr)? { - Ok(Some(ast::Expr::Func(Box::new(ast::Fn { args, body })))) + if let Some(body) = + tokens.between(&Token::OpenCurly, &Token::CloseCurly, parse_block)? + { + Ok(Some(ast::Expr::Func(Box::new(ast::Fn { + args, + body: ast::Expr::Block(body), + })))) } else { Err(Error::UnexpectedTokenForParser( "fn_body".into(), @@ -120,6 +125,17 @@ fn parse_fn(tokens: &mut Tokens) -> ParseResult { } } +fn parse_block(tokens: &mut Tokens) -> ParseResult> { + tokens.many(parse_statement) +} + +fn parse_statement(tokens: &mut Tokens) -> ParseResult { + tokens.one_of(vec![ + |tokens| Ok(parse_expr(tokens)?.map(ast::Statement::Expr)), + |tokens| Ok(parse_definition(tokens)?.map(ast::Statement::Let)), + ]) +} + fn parse_args(tokens: &mut Tokens) -> ParseResult> { tokens.between(&Token::OpenParen, &Token::CloseParen, |ts| { ts.many_sep_by(&Token::Comma, parse_identifier_arg) @@ -312,4 +328,29 @@ mod tests { let result = parse(&mut scan(program), parse_definition); insta::assert_debug_snapshot!(result); } + #[test] + fn full_program() { + let program = " +let init = fn() { + return { + player: { position: { x: 10, y: 20 }, }, + } +}; + +let update = fn(state, events) { + return state'; +}; + +let draw = fn(frame, state) { + frame.clear(0,0,0); +}; + +let migrate = fn(state) { + return { player: { pos: state.player.position } }, +}; +" + .to_string(); + let result = parse(&mut scan(program), parse_definitions); + insta::assert_debug_snapshot!(result); + } } diff --git a/src/parser/snapshots/ayin__parser__parser__tests__fn_def.snap b/src/parser/snapshots/ayin__parser__parser__tests__fn_def.snap index cd567c3..94a2c1c 100644 --- a/src/parser/snapshots/ayin__parser__parser__tests__fn_def.snap +++ b/src/parser/snapshots/ayin__parser__parser__tests__fn_def.snap @@ -22,10 +22,16 @@ Ok( ), }, ], - body: Value( - Int( - 108, - ), + body: Block( + [ + Expr( + Value( + Int( + 108, + ), + ), + ), + ], ), }, ), diff --git a/src/parser/snapshots/ayin__parser__parser__tests__paren_fncall.snap b/src/parser/snapshots/ayin__parser__parser__tests__paren_fncall.snap index ad5534c..3090d22 100644 --- a/src/parser/snapshots/ayin__parser__parser__tests__paren_fncall.snap +++ b/src/parser/snapshots/ayin__parser__parser__tests__paren_fncall.snap @@ -23,10 +23,16 @@ Ok( ), }, ], - body: Value( - Int( - 108, - ), + body: Block( + [ + Expr( + Value( + Int( + 108, + ), + ), + ), + ], ), }, ),