@@ -151,7 +151,7 @@ primitive_type = { "i8" | "i16" | "i32" | "i64" | "u8" | "u16" | "u32" | "u64" |
151151
152152// ===== Statements =====
153153
154- statement = { if_stmt | while_stmt | return_stmt | local_const | local_var | assign_stmt | expr_stmt }
154+ statement = { if_stmt | while_stmt | for_stmt | return_stmt | local_const | local_var | assign_stmt | expr_stmt }
155155 -> TypedStatement {
156156 "get_child": { "index": 0 }
157157 }
@@ -192,6 +192,18 @@ while_stmt = { "while" ~ "(" ~ expr ~ ")" ~ block }
192192 ]
193193 }
194194
195+ // For loop: for (slice) |item| { ... }
196+ for_stmt = { "for" ~ "(" ~ expr ~ ")" ~ "|" ~ identifier ~ "|" ~ block }
197+ -> TypedStatement {
198+ "commands": [
199+ { "define": "for", "args": {
200+ "iterable": "$1",
201+ "binding": "$2",
202+ "body": "$3"
203+ }}
204+ ]
205+ }
206+
195207// Assignment statement: identifier = expr;
196208assign_stmt = { identifier ~ "=" ~ expr ~ ";" }
197209 -> TypedStatement {
@@ -281,12 +293,24 @@ block = { "{" ~ statement* ~ "}" }
281293
282294// ===== Expressions =====
283295
284- expr = { comparison }
296+ expr = { logical_or }
285297 -> TypedExpression {
286298 "get_child": { "index": 0 }
287299 }
288300
289- // Comparison operators (lowest precedence)
301+ // Logical OR (lowest precedence)
302+ logical_or = { logical_and ~ (or_op ~ logical_and)* }
303+ -> TypedExpression {
304+ "fold_binary": { "operand": "logical_and", "operator": "or_op" }
305+ }
306+
307+ // Logical AND
308+ logical_and = { comparison ~ (and_op ~ comparison)* }
309+ -> TypedExpression {
310+ "fold_binary": { "operand": "comparison", "operator": "and_op" }
311+ }
312+
313+ // Comparison operators
290314comparison = { addition ~ ((eq_op | neq_op | lte_op | gte_op | lt_op | gt_op) ~ addition)* }
291315 -> TypedExpression {
292316 "fold_binary": { "operand": "addition", "operator": "eq_op|neq_op|lte_op|gte_op|lt_op|gt_op" }
@@ -302,12 +326,19 @@ multiplication = { unary ~ ((mul_op | div_op) ~ unary)* }
302326 "fold_binary": { "operand": "unary", "operator": "mul_op|div_op" }
303327 }
304328
305- unary = { unary_op? ~ primary }
329+ unary = { unary_with_op | primary }
306330 -> TypedExpression {
307331 "get_child": { "index": 0 }
308332 }
309333
310- primary = { bool_literal | integer_literal | call_expr | identifier_expr | paren_expr }
334+ unary_with_op = { unary_op ~ primary }
335+ -> TypedExpression {
336+ "commands": [
337+ { "define": "unary", "args": { "op": "$1", "operand": "$2" } }
338+ ]
339+ }
340+
341+ primary = { bool_literal | string_literal | integer_literal | call_expr | identifier_expr | paren_expr }
311342 -> TypedExpression {
312343 "get_child": { "index": 0 }
313344 }
@@ -354,6 +385,17 @@ integer_literal = @{ "-"? ~ ASCII_DIGIT+ }
354385 "args": { "value": "$result" }
355386 }
356387
388+ string_literal = @{ "\"" ~ string_inner* ~ "\"" }
389+ -> TypedExpression {
390+ "get_text": true,
391+ "define": "string_literal",
392+ "args": { "value": "$result" }
393+ }
394+
395+ string_inner = { (!("\"" | "\\") ~ ANY) | escape_seq }
396+
397+ escape_seq = { "\\" ~ ("n" | "r" | "t" | "\\" | "\"" | "0") }
398+
357399// ===== Identifiers =====
358400
359401identifier = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
@@ -363,6 +405,13 @@ identifier = @{ (ASCII_ALPHA | "_") ~ (ASCII_ALPHANUMERIC | "_")* }
363405
364406// ===== Operators =====
365407
408+ // Logical operators
409+ and_op = { "and" }
410+ -> String { "get_text": true }
411+
412+ or_op = { "or" }
413+ -> String { "get_text": true }
414+
366415// Comparison operators (must check longer operators first)
367416eq_op = { "==" }
368417 -> String { "get_text": true }
0 commit comments