mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Make power operator have higher precedence than unary operators: +, -, ~, !
This commit is contained in:
parent
fbc019171c
commit
08b59aef8a
8 changed files with 56 additions and 37 deletions
|
@ -535,14 +535,16 @@
|
|||
Operation: [
|
||||
o('UNARY Expression', function() {
|
||||
return new Op($1, $2);
|
||||
}), o('UNARY_MATH Expression', function() {
|
||||
return new Op($1, $2);
|
||||
}), o('- Expression', (function() {
|
||||
return new Op('-', $2);
|
||||
}), {
|
||||
prec: 'UNARY'
|
||||
prec: 'UNARY_MATH'
|
||||
}), o('+ Expression', (function() {
|
||||
return new Op('+', $2);
|
||||
}), {
|
||||
prec: 'UNARY'
|
||||
prec: 'UNARY_MATH'
|
||||
}), o('-- SimpleAssignable', function() {
|
||||
return new Op('--', $2);
|
||||
}), o('++ SimpleAssignable', function() {
|
||||
|
@ -588,7 +590,7 @@
|
|||
]
|
||||
};
|
||||
|
||||
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['right', '**'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
|
||||
operators = [['left', '.', '?.', '::', '?::'], ['left', 'CALL_START', 'CALL_END'], ['nonassoc', '++', '--'], ['left', '?'], ['right', 'UNARY'], ['right', '**'], ['right', 'UNARY_MATH'], ['left', 'MATH'], ['left', '+', '-'], ['left', 'SHIFT'], ['left', 'RELATION'], ['left', 'COMPARE'], ['left', 'LOGIC'], ['nonassoc', 'INDENT', 'OUTDENT'], ['right', '=', ':', 'COMPOUND_ASSIGN', 'RETURN', 'THROW', 'EXTENDS'], ['right', 'FORIN', 'FOROF', 'BY', 'WHEN'], ['right', 'IF', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS'], ['right', 'POST_IF']];
|
||||
|
||||
tokens = [];
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// Generated by CoffeeScript 1.6.2
|
||||
(function() {
|
||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, starts, throwSyntaxError, _ref, _ref1,
|
||||
var BOM, BOOL, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_ALIAS_MAP, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, HEREDOC, HEREDOC_ILLEGAL, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, INDEXABLE, INVERSES, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LINE_BREAK, LINE_CONTINUER, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NOT_REGEX, NOT_SPACED_REGEX, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, STRICT_PROSCRIBED, TRAILING_SPACES, UNARY, UNARY_MATH, WHITESPACE, compact, count, invertLiterate, key, last, locationDataToString, starts, throwSyntaxError, _ref, _ref1,
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
_ref = require('./rewriter'), Rewriter = _ref.Rewriter, INVERSES = _ref.INVERSES;
|
||||
|
@ -457,6 +457,8 @@
|
|||
tag = 'COMPOUND_ASSIGN';
|
||||
} else if (__indexOf.call(UNARY, value) >= 0) {
|
||||
tag = 'UNARY';
|
||||
} else if (__indexOf.call(UNARY_MATH, value) >= 0) {
|
||||
tag = 'UNARY_MATH';
|
||||
} else if (__indexOf.call(SHIFT, value) >= 0) {
|
||||
tag = 'SHIFT';
|
||||
} else if (__indexOf.call(LOGIC, value) >= 0 || value === '?' && (prev != null ? prev.spaced : void 0)) {
|
||||
|
@ -752,7 +754,7 @@
|
|||
|
||||
Lexer.prototype.unfinished = function() {
|
||||
var _ref2;
|
||||
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
||||
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
||||
};
|
||||
|
||||
Lexer.prototype.escapeLines = function(str, heredoc) {
|
||||
|
@ -862,7 +864,9 @@
|
|||
|
||||
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|='];
|
||||
|
||||
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO'];
|
||||
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO'];
|
||||
|
||||
UNARY_MATH = ['!', '~'];
|
||||
|
||||
LOGIC = ['&&', '||', '&', '|', '^'];
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -465,7 +465,7 @@
|
|||
|
||||
IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@', 'THIS'];
|
||||
|
||||
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
||||
IMPLICIT_CALL = ['IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS', 'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'];
|
||||
|
||||
IMPLICIT_UNSPACED_CALL = ['+', '-'];
|
||||
|
||||
|
|
|
@ -531,8 +531,9 @@ grammar =
|
|||
# rules are necessary.
|
||||
Operation: [
|
||||
o 'UNARY Expression', -> new Op $1 , $2
|
||||
o '- Expression', (-> new Op '-', $2), prec: 'UNARY'
|
||||
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY'
|
||||
o 'UNARY_MATH Expression', -> new Op $1 , $2
|
||||
o '- Expression', (-> new Op '-', $2), prec: 'UNARY_MATH'
|
||||
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY_MATH'
|
||||
|
||||
o '-- SimpleAssignable', -> new Op '--', $2
|
||||
o '++ SimpleAssignable', -> new Op '++', $2
|
||||
|
@ -584,6 +585,7 @@ operators = [
|
|||
['left', '?']
|
||||
['right', 'UNARY']
|
||||
['right', '**']
|
||||
['right', 'UNARY_MATH']
|
||||
['left', 'MATH']
|
||||
['left', '+', '-']
|
||||
['left', 'SHIFT']
|
||||
|
|
|
@ -406,6 +406,7 @@ exports.Lexer = class Lexer
|
|||
else if value in COMPARE then tag = 'COMPARE'
|
||||
else if value in COMPOUND_ASSIGN then tag = 'COMPOUND_ASSIGN'
|
||||
else if value in UNARY then tag = 'UNARY'
|
||||
else if value in UNARY_MATH then tag = 'UNARY_MATH'
|
||||
else if value in SHIFT then tag = 'SHIFT'
|
||||
else if value in LOGIC or value is '?' and prev?.spaced then tag = 'LOGIC'
|
||||
else if prev and not prev.spaced
|
||||
|
@ -675,8 +676,8 @@ exports.Lexer = class Lexer
|
|||
# Are we in the midst of an unfinished expression?
|
||||
unfinished: ->
|
||||
LINE_CONTINUER.test(@chunk) or
|
||||
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', '+', '-', 'SHIFT', 'RELATION'
|
||||
'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
|
||||
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
|
||||
'SHIFT', 'RELATION', 'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
|
||||
|
||||
# Converts newlines for string literals.
|
||||
escapeLines: (str, heredoc) ->
|
||||
|
@ -821,19 +822,21 @@ COMPOUND_ASSIGN = [
|
|||
]
|
||||
|
||||
# Unary tokens.
|
||||
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']
|
||||
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO']
|
||||
|
||||
UNARY_MATH = ['!', '~']
|
||||
|
||||
# Logical tokens.
|
||||
LOGIC = ['&&', '||', '&', '|', '^']
|
||||
LOGIC = ['&&', '||', '&', '|', '^']
|
||||
|
||||
# Bit-shifting tokens.
|
||||
SHIFT = ['<<', '>>', '>>>']
|
||||
SHIFT = ['<<', '>>', '>>>']
|
||||
|
||||
# Comparison tokens.
|
||||
COMPARE = ['==', '!=', '<', '>', '<=', '>=']
|
||||
|
||||
# Mathematical tokens.
|
||||
MATH = ['*', '/', '%']
|
||||
MATH = ['*', '/', '%']
|
||||
|
||||
# Relational tokens that are negatable with `not` prefix.
|
||||
RELATION = ['IN', 'OF', 'INSTANCEOF']
|
||||
|
|
|
@ -458,8 +458,8 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@
|
|||
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
|
||||
IMPLICIT_CALL = [
|
||||
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
|
||||
'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY', 'SUPER'
|
||||
'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'
|
||||
'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY',
|
||||
'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'
|
||||
]
|
||||
|
||||
IMPLICIT_UNSPACED_CALL = ['+', '-']
|
||||
|
|
|
@ -302,6 +302,12 @@ test "power operator", ->
|
|||
|
||||
test "power operator has higher precedence than other maths operators", ->
|
||||
eq 55, 1 + 3 ** 3 * 2
|
||||
eq -4, -2 ** 2
|
||||
eq false, !2 ** 2
|
||||
eq 0, (!2) ** 2
|
||||
eq -2, ~1 ** 5
|
||||
|
||||
#test "power operator has lower precedence than"
|
||||
|
||||
test "power operator is right associative", ->
|
||||
eq 2, 2 ** 1 ** 3
|
Loading…
Add table
Reference in a new issue