fixing issue #745 ... precedence of huh operator.

This commit is contained in:
Jeremy Ashkenas 2010-10-07 22:22:33 -04:00
parent 4f486bc444
commit b21057d166
6 changed files with 29 additions and 37 deletions

View File

@ -567,8 +567,6 @@
return new Op('--', $1, null, true);
}), o("Expression ++", function() {
return new Op('++', $1, null, true);
}), o("Expression ? Expression", function() {
return new Op('?', $1, $3);
}), o("Expression + Expression", function() {
return new Op('+', $1, $3);
}), o("Expression - Expression", function() {
@ -594,7 +592,7 @@
})
]
};
operators = [["right", '?'], ["left", 'CALL_START', 'CALL_END'], ["nonassoc", '++', '--'], ["right", 'UNARY'], ["left", 'MATH'], ["left", '+', '-'], ["left", 'SHIFT'], ["left", 'COMPARE'], ["left", 'RELATION'], ["left", '==', '!='], ["left", 'LOGIC'], ["right", 'COMPOUND_ASSIGN'], ["left", '.'], ["nonassoc", 'INDENT', 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'FORIN', 'FOROF', 'BY', 'THROW'], ["right", 'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS'], ["right", '=', ':', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS']];
operators = [["left", 'CALL_START', 'CALL_END'], ["nonassoc", '++', '--'], ["left", '?'], ["right", 'UNARY'], ["left", 'MATH'], ["left", '+', '-'], ["left", 'SHIFT'], ["left", 'COMPARE'], ["left", 'RELATION'], ["left", '==', '!='], ["left", 'LOGIC'], ["right", 'COMPOUND_ASSIGN'], ["left", '.'], ["nonassoc", 'INDENT', 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'FORIN', 'FOROF', 'BY', 'THROW'], ["right", 'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS'], ["right", '=', ':', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS']];
tokens = [];
for (name in grammar) {
if (!__hasProp.call(grammar, name)) continue;

View File

@ -313,7 +313,7 @@
return true;
};
Lexer.prototype.literalToken = function() {
var match, prev, ptag, pval, tag, value;
var _ref2, match, prev, tag, value;
if (match = OPERATOR.exec(this.chunk)) {
value = match[0];
if (CODE.test(value)) {
@ -324,15 +324,14 @@
}
this.i += value.length;
tag = value;
prev = last(this.tokens);
if (value === '=') {
pval = this.value();
if (!pval.reserved && include(JS_FORBIDDEN, pval)) {
if (!prev[1].reserved && include(JS_FORBIDDEN, prev[1])) {
this.assignmentError();
}
if (('or' === pval || 'and' === pval)) {
prev = last(this.tokens);
if (('or' === (_ref2 = prev[1]) || 'and' === _ref2)) {
prev[0] = 'COMPOUND_ASSIGN';
prev[1] = COFFEE_ALIASES[pval] + '=';
prev[1] = COFFEE_ALIASES[prev[1]] + '=';
return true;
}
}
@ -350,15 +349,17 @@
tag = 'UNARY';
} else if (include(SHIFT, value)) {
tag = 'SHIFT';
} else if ((prev = last(this.tokens)) && !prev.spaced && include(CALLABLE, ptag = prev[0])) {
} else if (value === '?' && prev.spaced) {
tag = 'LOGIC';
} else if (prev && !prev.spaced && include(CALLABLE, prev[0])) {
if (value === '(') {
if (ptag === '?') {
if (prev[0] === '?') {
prev[0] = 'FUNC_EXIST';
}
tag = 'CALL_START';
} else if (value === '[') {
tag = 'INDEX_START';
switch (ptag) {
switch (prev[0]) {
case '?':
prev[0] = 'INDEX_SOAK';
break;

File diff suppressed because one or more lines are too long

View File

@ -535,7 +535,6 @@ grammar =
o "Expression --", -> new Op '--', $1, null, true
o "Expression ++", -> new Op '++', $1, null, true
o "Expression ? Expression", -> new Op '?', $1, $3
o "Expression + Expression", -> new Op '+', $1, $3
o "Expression - Expression", -> new Op '-', $1, $3
o "Expression == Expression", -> new Op '==', $1, $3
@ -571,9 +570,9 @@ grammar =
#
# (2 + 3) * 4
operators = [
["right", '?']
["left", 'CALL_START', 'CALL_END']
["nonassoc", '++', '--']
["left", '?']
["right", 'UNARY']
["left", 'MATH']
["left", '+', '-']

View File

@ -307,13 +307,12 @@ exports.Lexer = class Lexer
value = @chunk.charAt 0
@i += value.length
tag = value
prev = last @tokens
if value is '='
pval = @value()
@assignmentError() if not pval.reserved and include JS_FORBIDDEN, pval
if pval in ['or', 'and']
prev = last @tokens
@assignmentError() if not prev[1].reserved and include JS_FORBIDDEN, prev[1]
if prev[1] in ['or', 'and']
prev[0] = 'COMPOUND_ASSIGN'
prev[1] = COFFEE_ALIASES[pval] + '='
prev[1] = COFFEE_ALIASES[prev[1]] + '='
return true
if ';' is value then tag = 'TERMINATOR'
else if include LOGIC , value then tag = 'LOGIC'
@ -322,14 +321,14 @@ exports.Lexer = class Lexer
else if include COMPOUND_ASSIGN, value then tag = 'COMPOUND_ASSIGN'
else if include UNARY , value then tag = 'UNARY'
else if include SHIFT , value then tag = 'SHIFT'
else if (prev = last @tokens) and not prev.spaced and
include(CALLABLE, ptag = prev[0])
else if value is '?' and prev.spaced then tag = 'LOGIC'
else if prev and not prev.spaced and include CALLABLE, prev[0]
if value is '('
prev[0] = 'FUNC_EXIST' if ptag is '?'
prev[0] = 'FUNC_EXIST' if prev[0] is '?'
tag = 'CALL_START'
else if value is '['
tag = 'INDEX_START'
switch ptag
switch prev[0]
when '?' then prev[0] = 'INDEX_SOAK'
when '::' then prev[0] = 'INDEX_PROTO'
@token tag, value

View File

@ -24,9 +24,6 @@ func = -> i += 1
result = func() ? 101
ok result is 10
ok (non ? existent ? variables ? 1) is 1
# Only evaluate once.
counter = 0
getNextNode = ->