diff --git a/src/grammar.coffee b/src/grammar.coffee index 91ab43c5ce..7ad4fdd602 100644 --- a/src/grammar.coffee +++ b/src/grammar.coffee @@ -526,6 +526,7 @@ grammar = o 'Expression - Expression', -> new Op '-' , $1, $3 o 'Expression MATH Expression', -> new Op $2, $1, $3 + o 'Expression ** Expression', -> new Op $2, $1, $3 o 'Expression SHIFT Expression', -> new Op $2, $1, $3 o 'Expression COMPARE Expression', -> new Op $2, $1, $3 o 'Expression LOGIC Expression', -> new Op $2, $1, $3 @@ -560,6 +561,7 @@ operators = [ ['nonassoc', '++', '--'] ['left', '?'] ['right', 'UNARY'] + ['right', '**'] ['left', 'MATH'] ['left', '+', '-'] ['left', 'SHIFT'] diff --git a/src/lexer.coffee b/src/lexer.coffee index 050b3ce1f8..670edaee80 100644 --- a/src/lexer.coffee +++ b/src/lexer.coffee @@ -599,6 +599,7 @@ OPERATOR = /// ^ ( | ([&|<>])\2=? # logic / shift | \?\. # soak access | \.{2,3} # range or splat + | \*\* # power ) /// WHITESPACE = /^[^\n\S]+/ diff --git a/src/nodes.coffee b/src/nodes.coffee index 414f9130fa..0d3b23a5a9 100644 --- a/src/nodes.coffee +++ b/src/nodes.coffee @@ -1406,6 +1406,7 @@ exports.Op = class Op extends Base return @compileUnary o if @isUnary() return @compileChain o if isChain return @compileExistence o if @operator is '?' + return @compilePower o if @operator is '**' code = @first.compile(o, LEVEL_OP) + ' ' + @operator + ' ' + @second.compile(o, LEVEL_OP) if o.level <= LEVEL_OP then code else "(#{code})" @@ -1441,6 +1442,11 @@ exports.Op = class Op extends Base parts.push @first.compile o, LEVEL_OP parts.reverse() if @flip parts.join '' + + compilePower: (o) -> + left = @first.compile o, LEVEL_OP + right = @second.compile o, LEVEL_OP + "Math.pow(#{left}, #{right})" toString: (idt) -> super idt, @constructor.name + ' ' + @operator diff --git a/test/operators.coffee b/test/operators.coffee index 2ae0c6a90f..716b104a64 100644 --- a/test/operators.coffee +++ b/test/operators.coffee @@ -269,3 +269,12 @@ test "Regression with implicit calls against an indented assignment", -> 1 eq a, 1 + +test "power operator", -> + eq 27, 3 ** 3 + +test "power operator has higher precedence than other maths operators", -> + eq 55, 1 + 3 ** 3 * 2 + +test "power operator is right associative", -> + eq 2, 2 ** 1 ** 3 \ No newline at end of file