Add math assignment operators, fix some precedences

pull/70/head
Max Brunsfeld 2014-09-08 00:35:08 +07:00
parent 1fb4a27ac0
commit 56455044d0
2 changed files with 68 additions and 24 deletions

@ -43,7 +43,7 @@ module.exports = compiler.grammar
if_statement: -> seq( if_statement: -> seq(
keyword("if"), keyword("if"),
"(", err(@expression), ")", @_paren_expression,
@statement, @statement,
optional(seq( optional(seq(
keyword("else"), keyword("else"),
@ -91,14 +91,14 @@ module.exports = compiler.grammar
while_statement: -> seq( while_statement: -> seq(
keyword("while"), keyword("while"),
"(", err(@expression), ")", @_paren_expression,
@statement) @statement)
do_statement: -> seq( do_statement: -> seq(
keyword("do"), keyword("do"),
@statement_block, @statement_block,
keyword("while"), keyword("while"),
"(", err(@expression), ")") @_paren_expression)
return_statement: -> seq( return_statement: -> seq(
keyword("return"), keyword("return"),
@ -166,7 +166,11 @@ module.exports = compiler.grammar
@rel_op, @rel_op,
@type_op, @type_op,
@assignment, @assignment,
seq("(", err(@expression), ")")) @math_assignment,
@_paren_expression)
_paren_expression: -> seq(
"(", err(@expression), ")")
function_call: -> seq( function_call: -> seq(
@expression, @expression,
@ -198,6 +202,14 @@ module.exports = compiler.grammar
"=", "=",
@expression)) @expression))
math_assignment: -> prec(-2, seq(
choice(
@identifier,
@member_access,
@subscript_access)
choice("+=", "-=", "*=", "/="),
@expression))
object: -> seq( object: -> seq(
"{", commaSep(err(@pair)), "}") "{", commaSep(err(@pair)), "}")
@ -237,33 +249,33 @@ module.exports = compiler.grammar
prec(1, seq(@expression, "||", @expression))) prec(1, seq(@expression, "||", @expression)))
bitwise_op: -> choice( bitwise_op: -> choice(
prec(3, seq(@expression, ">>", @expression)), prec(13, seq(@expression, ">>", @expression)),
prec(3, seq(@expression, "<<", @expression)), prec(13, seq(@expression, "<<", @expression)),
prec(2, seq(@expression, "&", @expression)), prec(12, seq(@expression, "&", @expression)),
prec(1, seq(@expression, "|", @expression))) prec(11, seq(@expression, "|", @expression)))
ternary: -> prec(-1, seq( ternary: -> prec(-1, seq(
@expression, "?", @expression, ":", @expression)) @expression, "?", @expression, ":", @expression))
math_op: -> choice( math_op: -> choice(
prec(4, seq("-", @expression)), prec(14, seq("-", @expression)),
prec(4, seq("+", @expression)), prec(14, seq("+", @expression)),
prec(4, seq(@expression, "++")), prec(14, seq(@expression, "++")),
prec(4, seq(@expression, "--")), prec(14, seq(@expression, "--")),
prec(1, seq(@expression, "+", @expression)), prec(11, seq(@expression, "+", @expression)),
prec(1, seq(@expression, "-", @expression)), prec(11, seq(@expression, "-", @expression)),
prec(2, seq(@expression, "*", @expression)), prec(12, seq(@expression, "*", @expression)),
prec(2, seq(@expression, "/", @expression))) prec(12, seq(@expression, "/", @expression)))
rel_op: -> choice( rel_op: -> choice(
seq(@expression, "<", @expression), prec(10, seq(@expression, "<", @expression)),
seq(@expression, "<=", @expression), prec(10, seq(@expression, "<=", @expression)),
seq(@expression, "==", @expression), prec(10, seq(@expression, "==", @expression)),
seq(@expression, "===", @expression), prec(10, seq(@expression, "===", @expression)),
seq(@expression, "!=", @expression), prec(10, seq(@expression, "!=", @expression)),
seq(@expression, "!==", @expression), prec(10, seq(@expression, "!==", @expression)),
seq(@expression, ">=", @expression), prec(10, seq(@expression, ">=", @expression)),
seq(@expression, ">", @expression)) prec(10, seq(@expression, ">", @expression)))
type_op: -> choice( type_op: -> choice(
prec(1, seq(keyword("typeof"), @expression)), prec(1, seq(keyword("typeof"), @expression)),

@ -321,3 +321,35 @@ x instanceof String;
(program (program
(expression_statement (type_op (identifier))) (expression_statement (type_op (identifier)))
(expression_statement (type_op (identifier) (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)))))