Fixing for loop

This commit is contained in:
2026-04-14 06:13:55 +02:00
parent b4faebd34e
commit 43ce27c12e
4 changed files with 48 additions and 37 deletions
+6 -11
View File
@@ -70,6 +70,11 @@ pub enum Statement {
init: Option<Expression>, init: Option<Expression>,
}, },
VarAssign {
target: Expression,
value: Expression,
},
// if (...) stmt else stmt // if (...) stmt else stmt
If { If {
condition: Expression, condition: Expression,
@@ -85,7 +90,7 @@ pub enum Statement {
// for (...) stmt // for (...) stmt
For { For {
init: Option<ForInit>, init: (VarKind, String, Option<Expression>),
condition: Option<Expression>, condition: Option<Expression>,
update: Option<Expression>, update: Option<Expression>,
body: Box<Statement>, body: Box<Statement>,
@@ -118,13 +123,3 @@ pub enum VarKind {
Const, Const,
Var, Var,
} }
#[derive(Debug, Clone, Serialize)]
pub enum ForInit {
VarDecl {
kind: VarKind,
name: String,
init: Option<Expression>,
},
Expr(Expression),
}
+8 -4
View File
@@ -39,6 +39,7 @@ statement_list = { statement* }
statement = _{ statement = _{
expr_stmt expr_stmt
| var_decl | var_decl
| var_assign
| if_stmt | if_stmt
| while_stmt | while_stmt
| for_stmt | for_stmt
@@ -66,6 +67,10 @@ var_decl = {
var_decl_kind ~ identifier ~ ("=" ~ expr)? ~ ";" var_decl_kind ~ identifier ~ ("=" ~ expr)? ~ ";"
} }
var_assign = {
expr ~ "=" ~ expr ~ ";"
}
// --- control flow --- // --- control flow ---
if_stmt = { if_stmt = {
@@ -77,12 +82,11 @@ while_stmt = {
} }
for_stmt = { for_stmt = {
"for" ~ "(" ~ (var_decl_no_semicolon | expr_stmt | ";") ~ expr? ~ ";" ~ expr? ~ ")" ~ statement "for" ~ "(" ~ var_decl ~ expr ~ ";" ~ var_assign_no_semicolon ~ ")" ~ statement
} }
// helper (same as var_decl but no trailing ;) var_assign_no_semicolon = {
var_decl_no_semicolon = { expr ~ "=" ~ expr
var_decl_kind ~ identifier ~ ("=" ~ expr)?
} }
// ================= EXPRESSIONS ================= // ================= EXPRESSIONS =================
+32 -22
View File
@@ -229,30 +229,32 @@ impl Statement {
Rule::for_stmt => { Rule::for_stmt => {
let mut inner = pair.into_inner(); let mut inner = pair.into_inner();
let init = inner.next().map(|p| match p.as_rule() { let init = inner
Rule::var_decl_no_semicolon => { .next()
let mut it = p.into_inner(); .map(|p| match p.as_rule() {
Rule::var_decl => {
let mut it = p.into_inner();
let kind = match it.next().unwrap().as_str() { let kind = match it.next().unwrap().as_str() {
"let" => VarKind::Let, "let" => VarKind::Let,
"const" => VarKind::Const, "const" => VarKind::Const,
"var" => VarKind::Var, "var" => VarKind::Var,
_ => unreachable!(), _ => unreachable!(),
}; };
let name = it.next().unwrap().as_str().to_string(); let name = it.next().unwrap().as_str().to_string();
let init_expr = it let init_expr = it
.next() .next()
.map(|e| Expression::from_pair(e.into_inner().next().unwrap())); .map(|e| Expression::from_pair(e.into_inner().next().unwrap()));
ForInit::VarDecl { (kind, name, init_expr)
kind,
name,
init: init_expr,
} }
} _ => unimplemented!(
_ => ForInit::Expr(Expression::from_pair(p)), "For loop init parsing not implemented yet: {:?}",
}); p.as_rule()
),
})
.unwrap();
let condition = inner.next().map(Expression::from_pair); let condition = inner.next().map(Expression::from_pair);
let update = inner.next().map(Expression::from_pair); let update = inner.next().map(Expression::from_pair);
@@ -260,12 +262,20 @@ impl Statement {
Statement::For { Statement::For {
init, init,
condition, condition: None,
update, update: None,
body: Box::new(body), body: Box::new(body),
} }
} }
Rule::var_assign => {
let mut inner = pair.into_inner();
let target = Expression::from_pair(inner.next().unwrap());
let value = Expression::from_pair(inner.next().unwrap());
Statement::VarAssign { target, value }
}
_ => unimplemented!( _ => unimplemented!(
"Statement parsing not implemented yet: {:?}", "Statement parsing not implemented yet: {:?}",
pair.as_rule() pair.as_rule()
+2
View File
@@ -1,11 +1,13 @@
function add(a: int, b: int): int { function add(a: int, b: int): int {
let sum = 0; let sum = 0;
for (let i = 0; i < 10; i = i + 1) {
if (i == 5) { if (i == 5) {
continue; continue;
} }
sum = sum + i; sum = sum + i;
}
if (sum > 20) { if (sum > 20) {
return sum; return sum;