From 55735b4eddf240ea44b30b3b0406a8458ba28236 Mon Sep 17 00:00:00 2001 From: tascord Date: Wed, 11 Mar 2026 17:24:05 +1100 Subject: [PATCH] i thought i fixed that --- examples/for_loops.lf | 14 +++++++------- src/parser/mod.rs | 33 +++++---------------------------- src/runtime/mod.rs | 25 +++++++++++++++++++++++++ tests/examples.rs | 10 ++++++++++ 4 files changed, 47 insertions(+), 35 deletions(-) diff --git a/examples/for_loops.lf b/examples/for_loops.lf index 81f1317..99b9694 100644 --- a/examples/for_loops.lf +++ b/examples/for_loops.lf @@ -4,16 +4,16 @@ fn main() { let numbers = [1, 2, 3, 4, 5]; - print("Iterating over numbers:"); + term.println("Iterating over numbers:"); for n in numbers { - print(n); + term.println(n); } let nested = [[1, 2], [3, 4], [5, 6]]; - print("Nested loops:"); + term.println("Nested loops:"); for pair in nested { for n in pair { - print(n); + term.println(n); } } @@ -28,9 +28,9 @@ fn main() { Person { name: "Bob", age: 25 } ]; - print("Iterating over people (testing field access):"); + term.println("Iterating over people (testing field access):"); for p in people { - print(p.name); - print(p.age); + term.println(p.name); + term.println(p.age); } } diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 16f1edb..9bf5415 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -1210,7 +1210,9 @@ impl<'a> Parser<'a> { }; self.expect_keyword("in")?; - let iterable = self.parse_expression()?; + + // Parse the iterable, preventing it from consuming the { as a struct literal + let iterable = self.parse_match_subject()?; let body = Box::new(self.parse_block_statement()?); @@ -1511,31 +1513,6 @@ impl<'a> Parser<'a> { Ok(left) } - fn parse_binary_expr_no_postfix(&mut self, min_prec: u8) -> Result { - let mut left = self.parse_primary_expr()?; - - while let Some(token) = self.peek()? { - if let Token::Op(op) = token { - let prec = self.get_precedence(&op); - if prec < min_prec { - break; - } - - self.next()?; // consume operator - let right = self.parse_binary_expr_no_postfix(prec + 1)?; - left = Expr::BinOp { - op, - left: Box::new(left), - right: Box::new(right), - }; - } else { - break; - } - } - - Ok(left) - } - fn parse_primary_expr(&mut self) -> Result { let token_opt = self.next()?; match token_opt { @@ -1606,8 +1583,8 @@ impl<'a> Parser<'a> { break; } - // Use parse_binary_expr_no_postfix to avoid consuming postfix ops - elements.push(self.parse_binary_expr_no_postfix(0)?); + // Use parse_expression to correctly handle postfix operations like struct literals + elements.push(self.parse_expression()?); if let Some(token) = self.peek()? { if self.is_punct(&token, ",") { diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index 3d493b6..a3770ec 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -724,6 +724,31 @@ impl Interpreter { for stmt in stmts { last_value = self.eval_stmt(stmt)?; } + + // After evaluating all statements, if a 'main' function exists, call it + if let Some(Value::Function { + params, + body, + is_async, + .. + }) = self.env.get("main").cloned() + { + if params.is_empty() { + // Call main function + self.env.push_scope(); + let result = self.eval_stmt(*body)?; + let result = self.returning.take().unwrap_or(result); + self.env.pop_scope(); + + // If async, wrap result in a Promise + if is_async { + return Ok(Value::Promise(Box::new(result))); + } else { + return Ok(result); + } + } + } + Ok(last_value) } diff --git a/tests/examples.rs b/tests/examples.rs index f236b57..5a54cf1 100644 --- a/tests/examples.rs +++ b/tests/examples.rs @@ -58,6 +58,16 @@ fn example_factorial() { run_example("examples/factorial.lf", None); } +#[test] +fn example_for_loop() { + run_example("examples/for_loop.lf", None); +} + +#[test] +fn example_for_loops() { + run_example("examples/for_loops.lf", None); +} + #[test] fn example_mutable_capture() { run_example("examples/mutable_capture.lf", None);