From 56455044d04779ea10664d6aa9d328d45274c057 Mon Sep 17 00:00:00 2001 From: Max Brunsfeld Date: Mon, 8 Sep 2014 00:35:08 -0700 Subject: [PATCH] Add math assignment operators, fix some precedences --- grammar.coffee | 60 +++++++++++++++++++++--------------- grammar_test/expressions.txt | 32 +++++++++++++++++++ 2 files changed, 68 insertions(+), 24 deletions(-) diff --git a/grammar.coffee b/grammar.coffee index c0c93c62d..bf11e0617 100644 --- a/grammar.coffee +++ b/grammar.coffee @@ -43,7 +43,7 @@ module.exports = compiler.grammar if_statement: -> seq( keyword("if"), - "(", err(@expression), ")", + @_paren_expression, @statement, optional(seq( keyword("else"), @@ -91,14 +91,14 @@ module.exports = compiler.grammar while_statement: -> seq( keyword("while"), - "(", err(@expression), ")", + @_paren_expression, @statement) do_statement: -> seq( keyword("do"), @statement_block, keyword("while"), - "(", err(@expression), ")") + @_paren_expression) return_statement: -> seq( keyword("return"), @@ -166,7 +166,11 @@ module.exports = compiler.grammar @rel_op, @type_op, @assignment, - seq("(", err(@expression), ")")) + @math_assignment, + @_paren_expression) + + _paren_expression: -> seq( + "(", err(@expression), ")") function_call: -> seq( @expression, @@ -198,6 +202,14 @@ module.exports = compiler.grammar "=", @expression)) + math_assignment: -> prec(-2, seq( + choice( + @identifier, + @member_access, + @subscript_access) + choice("+=", "-=", "*=", "/="), + @expression)) + object: -> seq( "{", commaSep(err(@pair)), "}") @@ -237,33 +249,33 @@ module.exports = compiler.grammar prec(1, seq(@expression, "||", @expression))) bitwise_op: -> choice( - prec(3, seq(@expression, ">>", @expression)), - prec(3, seq(@expression, "<<", @expression)), - prec(2, seq(@expression, "&", @expression)), - prec(1, seq(@expression, "|", @expression))) + prec(13, seq(@expression, ">>", @expression)), + prec(13, seq(@expression, "<<", @expression)), + prec(12, seq(@expression, "&", @expression)), + prec(11, seq(@expression, "|", @expression))) ternary: -> prec(-1, seq( @expression, "?", @expression, ":", @expression)) math_op: -> choice( - prec(4, seq("-", @expression)), - prec(4, seq("+", @expression)), - prec(4, seq(@expression, "++")), - prec(4, seq(@expression, "--")), - prec(1, seq(@expression, "+", @expression)), - prec(1, seq(@expression, "-", @expression)), - prec(2, seq(@expression, "*", @expression)), - prec(2, seq(@expression, "/", @expression))) + prec(14, seq("-", @expression)), + prec(14, seq("+", @expression)), + prec(14, seq(@expression, "++")), + prec(14, seq(@expression, "--")), + prec(11, seq(@expression, "+", @expression)), + prec(11, seq(@expression, "-", @expression)), + prec(12, seq(@expression, "*", @expression)), + prec(12, seq(@expression, "/", @expression))) rel_op: -> choice( - seq(@expression, "<", @expression), - seq(@expression, "<=", @expression), - seq(@expression, "==", @expression), - seq(@expression, "===", @expression), - seq(@expression, "!=", @expression), - seq(@expression, "!==", @expression), - seq(@expression, ">=", @expression), - seq(@expression, ">", @expression)) + prec(10, seq(@expression, "<", @expression)), + prec(10, seq(@expression, "<=", @expression)), + prec(10, seq(@expression, "==", @expression)), + prec(10, seq(@expression, "===", @expression)), + prec(10, seq(@expression, "!=", @expression)), + prec(10, seq(@expression, "!==", @expression)), + prec(10, seq(@expression, ">=", @expression)), + prec(10, seq(@expression, ">", @expression))) type_op: -> choice( prec(1, seq(keyword("typeof"), @expression)), diff --git a/grammar_test/expressions.txt b/grammar_test/expressions.txt index 89bff9d4a..4a5d8e036 100644 --- a/grammar_test/expressions.txt +++ b/grammar_test/expressions.txt @@ -321,3 +321,35 @@ x instanceof String; (program (expression_statement (type_op (identifier))) (expression_statement (type_op (identifier) (identifier)))) + +============================================== +Math assignment operators +============================================== + +x += 1; +y.z *= 3; + +--- + +(program + (expression_statement + (math_assignment (identifier) (number))) + (expression_statement + (math_assignment (member_access (identifier) (identifier)) (number)))) + +============================================== +Operator precedence +============================================== + +a <= b && c >= d; +a.b = c ? d : e; + +--- + +(program + (expression_statement (bool_op + (rel_op (identifier) (identifier)) + (rel_op (identifier) (identifier)))) + (expression_statement (assignment + (member_access (identifier) (identifier)) + (ternary (identifier) (identifier) (identifier)))))