diff --git a/grammar.coffee b/grammar.coffee index 09d0331..d84ffc0 100644 --- a/grammar.coffee +++ b/grammar.coffee @@ -71,6 +71,7 @@ module.exports = grammar @var_declaration, @return_statement, @if_statement, + @for_statement, @expression_statement, @statement_block), @@ -87,6 +88,17 @@ module.exports = grammar keyword("else"), @statement))) + for_statement: -> seq( + keyword("for"), + "(", + choice( + @var_declaration, + seq(optional(@expression), ";")), + optional(@expression), ";", + optional(@expression), + ")", + @statement) + type: -> seq( optional(keyword("const")), choice( @@ -159,6 +171,7 @@ module.exports = grammar @identifier, @bool_op, @math_op, + @rel_op, @assignment, @function_call, @field_access, @@ -176,6 +189,8 @@ module.exports = grammar @expression, "(", err(commaSep(@expression)), ")") math_op: -> choice( + prec(4, seq(@expression, "++")), + prec(4, seq(@expression, "++")), prec(3, seq("-", @expression)), prec(2, seq(@expression, "*", @expression)), prec(2, seq(@expression, "/", @expression)), @@ -187,6 +202,14 @@ module.exports = grammar prec(2, seq(@expression, "&&", @expression)), prec(1, seq(@expression, "||", @expression))) + rel_op: -> choice( + prec(1, seq(@expression, "<", @expression)), + prec(1, seq(@expression, "<=", @expression)), + prec(1, seq(@expression, "==", @expression)), + prec(1, seq(@expression, "!=", @expression)), + prec(1, seq(@expression, ">=", @expression)), + prec(1, seq(@expression, ">", @expression))) + assignment: -> seq( choice( @identifier, diff --git a/grammar_test/statements.txt b/grammar_test/statements.txt index c70567a..30c8ba6 100644 --- a/grammar_test/statements.txt +++ b/grammar_test/statements.txt @@ -44,3 +44,36 @@ int main() { (expression_statement (identifier))) (statement_block (expression_statement (identifier)))))) + +============================================ +For loops +============================================ + +int main() { + for (;;) + x; + + for (int i = 0; i < 5; i++) { + y; + } + + for (start(); check(); step()) + z; +} + +--- + +(function_declaration (identifier) (identifier) (formal_parameters) + (statement_block + (for_statement + (expression_statement (identifier))) + (for_statement + (var_declaration (identifier) (var_assignment (identifier) (number))) + (rel_op (identifier) (number)) + (math_op (identifier)) + (statement_block (expression_statement (identifier)))) + (for_statement + (function_call (identifier)) + (function_call (identifier)) + (function_call (identifier)) + (expression_statement (identifier)))))