mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-18 11:31:20 -05:00
nagated relational operators are now grouped into NOT_RELATED, fixing #720
This commit is contained in:
2
Cakefile
2
Cakefile
@@ -59,7 +59,7 @@ task 'build:parser', 'rebuild the Jison parser (run build first)', ->
|
|||||||
parser = require('./lib/grammar').parser
|
parser = require('./lib/grammar').parser
|
||||||
js = parser.generate()
|
js = parser.generate()
|
||||||
# TODO: Remove this when the Jison patch is released.
|
# TODO: Remove this when the Jison patch is released.
|
||||||
js = js.replace 'if (require.main === module)', 'if (typeof module !== "undefined" && require.main === module)'
|
js = js.replace 'if (require.main === module)', "if (typeof module !== 'undefined' && require.main === module)"
|
||||||
fs.writeFile 'lib/parser.js', js
|
fs.writeFile 'lib/parser.js', js
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -600,19 +600,15 @@
|
|||||||
}), o("Expression IN Expression", function() {
|
}), o("Expression IN Expression", function() {
|
||||||
return new InNode($1, $3);
|
return new InNode($1, $3);
|
||||||
}), o("Expression OF Expression", function() {
|
}), o("Expression OF Expression", function() {
|
||||||
return new OpNode('in', $1, $3);
|
return new OpNode($2, $1, $3);
|
||||||
}), o("Expression INSTANCEOF Expression", function() {
|
}), o("Expression INSTANCEOF Expression", function() {
|
||||||
return new OpNode('instanceof', $1, $3);
|
return new OpNode($2, $1, $3);
|
||||||
}), o("Expression UNARY IN Expression", function() {
|
}), o("Expression NOT_RELATED Expression", function() {
|
||||||
return new OpNode($2, new InNode($1, $4));
|
return $2 === 'in' ? new OpNode('!', new InNode($1, $3)) : new OpNode('!', new ParentheticalNode(new OpNode($2, $1, $3)));
|
||||||
}), o("Expression UNARY OF Expression", function() {
|
|
||||||
return new OpNode($2, new ParentheticalNode(new OpNode('in', $1, $4)));
|
|
||||||
}), o("Expression UNARY INSTANCEOF Expression", function() {
|
|
||||||
return new OpNode($2, new ParentheticalNode(new OpNode('instanceof', $1, $4)));
|
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
operators = [["right", '?'], ["left", 'CALL_START', 'CALL_END'], ["nonassoc", '++', '--'], ["right", 'UNARY'], ["left", 'MATH'], ["left", '+', '-'], ["left", 'SHIFT'], ["left", 'COMPARE'], ["left", 'INSTANCEOF'], ["left", '==', '!='], ["left", 'LOGIC'], ["right", 'COMPOUND_ASSIGN'], ["left", '.'], ["nonassoc", 'INDENT', 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY', 'THROW'], ["right", 'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS'], ["right", '=', ':', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS']];
|
operators = [["right", '?'], ["left", 'CALL_START', 'CALL_END'], ["nonassoc", '++', '--'], ["right", 'UNARY'], ["left", 'MATH'], ["left", '+', '-'], ["left", 'SHIFT'], ["left", 'COMPARE'], ["left", 'INSTANCEOF', 'NOT_RELATED'], ["left", '==', '!='], ["left", 'LOGIC'], ["right", 'COMPOUND_ASSIGN'], ["left", '.'], ["nonassoc", 'INDENT', 'OUTDENT'], ["right", 'WHEN', 'LEADING_WHEN', 'IN', 'OF', 'BY', 'THROW'], ["right", 'IF', 'UNLESS', 'ELSE', 'FOR', 'WHILE', 'UNTIL', 'LOOP', 'SUPER', 'CLASS', 'EXTENDS'], ["right", '=', ':', 'RETURN'], ["right", '->', '=>', 'UNLESS', 'POST_IF', 'POST_UNLESS']];
|
||||||
tokens = [];
|
tokens = [];
|
||||||
for (name in grammar) {
|
for (name in grammar) {
|
||||||
if (!__hasProp.call(grammar, name)) continue;
|
if (!__hasProp.call(grammar, name)) continue;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
(function() {
|
(function() {
|
||||||
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEGATABLE, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, starts;
|
var ASSIGNED, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMPARE, COMPOUND_ASSIGN, CONVERSIONS, HEREDOC, HEREDOC_INDENT, HEREGEX, HEREGEX_OMIT, IDENTIFIER, JSTOKEN, JS_FORBIDDEN, JS_KEYWORDS, LEADING_SPACES, LINE_BREAK, LOGIC, Lexer, MATH, MULTILINER, MULTI_DENT, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, starts;
|
||||||
Rewriter = require('./rewriter').Rewriter;
|
Rewriter = require('./rewriter').Rewriter;
|
||||||
_ref = require('./helpers'), include = _ref.include, count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
_ref = require('./helpers'), include = _ref.include, count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
||||||
exports.Lexer = (function() {
|
exports.Lexer = (function() {
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
return (new Rewriter).rewrite(this.tokens);
|
return (new Rewriter).rewrite(this.tokens);
|
||||||
};
|
};
|
||||||
Lexer.prototype.identifierToken = function() {
|
Lexer.prototype.identifierToken = function() {
|
||||||
var closeIndex, forcedIdentifier, id, match, tag;
|
var _ref2, closeIndex, forcedIdentifier, id, match, tag;
|
||||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -46,6 +46,9 @@
|
|||||||
tag = 'LEADING_WHEN';
|
tag = 'LEADING_WHEN';
|
||||||
} else if (include(UNARY, tag)) {
|
} else if (include(UNARY, tag)) {
|
||||||
tag = 'UNARY';
|
tag = 'UNARY';
|
||||||
|
} else if (('not' === (_ref2 = include(RELATION, tag) && this.value()) || '!' === _ref2)) {
|
||||||
|
this.tokens.pop();
|
||||||
|
tag = 'NOT_RELATED';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (include(JS_FORBIDDEN, id)) {
|
if (include(JS_FORBIDDEN, id)) {
|
||||||
@@ -602,9 +605,9 @@
|
|||||||
SHIFT = ['<<', '>>', '>>>'];
|
SHIFT = ['<<', '>>', '>>>'];
|
||||||
COMPARE = ['<=', '<', '>', '>='];
|
COMPARE = ['<=', '<', '>', '>='];
|
||||||
MATH = ['*', '/', '%'];
|
MATH = ['*', '/', '%'];
|
||||||
|
RELATION = ['IN', 'OF', 'INSTANCEOF'];
|
||||||
NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']'];
|
NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']'];
|
||||||
CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::'];
|
CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::'];
|
||||||
NEGATABLE = ['IN', 'OF', 'INSTANCEOF'];
|
|
||||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||||||
CONVERSIONS = {
|
CONVERSIONS = {
|
||||||
'and': '&&',
|
'and': '&&',
|
||||||
|
|||||||
@@ -1346,7 +1346,8 @@
|
|||||||
__extends(OpNode, BaseNode);
|
__extends(OpNode, BaseNode);
|
||||||
OpNode.prototype.CONVERSIONS = {
|
OpNode.prototype.CONVERSIONS = {
|
||||||
'==': '===',
|
'==': '===',
|
||||||
'!=': '!=='
|
'!=': '!==',
|
||||||
|
of: 'in'
|
||||||
};
|
};
|
||||||
OpNode.prototype.INVERSIONS = {
|
OpNode.prototype.INVERSIONS = {
|
||||||
'!==': '===',
|
'!==': '===',
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -553,11 +553,13 @@ grammar =
|
|||||||
o "Value COMPOUND_ASSIGN INDENT Expression OUTDENT", -> new OpNode $2, $1, $4
|
o "Value COMPOUND_ASSIGN INDENT Expression OUTDENT", -> new OpNode $2, $1, $4
|
||||||
|
|
||||||
o "Expression IN Expression", -> new InNode $1, $3
|
o "Expression IN Expression", -> new InNode $1, $3
|
||||||
o "Expression OF Expression", -> new OpNode 'in', $1, $3
|
o "Expression OF Expression", -> new OpNode $2, $1, $3
|
||||||
o "Expression INSTANCEOF Expression", -> new OpNode 'instanceof', $1, $3
|
o "Expression INSTANCEOF Expression", -> new OpNode $2, $1, $3
|
||||||
o "Expression UNARY IN Expression", -> new OpNode $2, new InNode $1, $4
|
o "Expression NOT_RELATED Expression", ->
|
||||||
o "Expression UNARY OF Expression", -> new OpNode $2, new ParentheticalNode new OpNode 'in', $1, $4
|
if $2 is 'in'
|
||||||
o "Expression UNARY INSTANCEOF Expression", -> new OpNode $2, new ParentheticalNode new OpNode 'instanceof', $1, $4
|
new OpNode '!', new InNode $1, $3
|
||||||
|
else
|
||||||
|
new OpNode '!', new ParentheticalNode new OpNode $2, $1, $3
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -581,7 +583,7 @@ operators = [
|
|||||||
["left", '+', '-']
|
["left", '+', '-']
|
||||||
["left", 'SHIFT']
|
["left", 'SHIFT']
|
||||||
["left", 'COMPARE']
|
["left", 'COMPARE']
|
||||||
["left", 'INSTANCEOF']
|
["left", 'INSTANCEOF', 'NOT_RELATED']
|
||||||
["left", '==', '!=']
|
["left", '==', '!=']
|
||||||
["left", 'LOGIC']
|
["left", 'LOGIC']
|
||||||
["right", 'COMPOUND_ASSIGN']
|
["right", 'COMPOUND_ASSIGN']
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ exports.Lexer = class Lexer
|
|||||||
tag = 'LEADING_WHEN'
|
tag = 'LEADING_WHEN'
|
||||||
else if include UNARY, tag
|
else if include UNARY, tag
|
||||||
tag = 'UNARY'
|
tag = 'UNARY'
|
||||||
|
else if include(RELATION, tag) and @value() in ['not', '!']
|
||||||
|
@tokens.pop()
|
||||||
|
tag = 'NOT_RELATED'
|
||||||
if include JS_FORBIDDEN, id
|
if include JS_FORBIDDEN, id
|
||||||
if forcedIdentifier
|
if forcedIdentifier
|
||||||
tag = 'STRING'
|
tag = 'STRING'
|
||||||
@@ -588,6 +591,9 @@ COMPARE = ['<=', '<', '>', '>=']
|
|||||||
# Mathmatical tokens.
|
# Mathmatical tokens.
|
||||||
MATH = ['*', '/', '%']
|
MATH = ['*', '/', '%']
|
||||||
|
|
||||||
|
# Relational tokens that are negatable with `not` prefix.
|
||||||
|
RELATION = ['IN', 'OF', 'INSTANCEOF']
|
||||||
|
|
||||||
# Tokens which a regular expression will never immediately follow, but which
|
# Tokens which a regular expression will never immediately follow, but which
|
||||||
# a division operator might.
|
# a division operator might.
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -1130,6 +1130,7 @@ exports.OpNode = class OpNode extends BaseNode
|
|||||||
CONVERSIONS:
|
CONVERSIONS:
|
||||||
'==': '==='
|
'==': '==='
|
||||||
'!=': '!=='
|
'!=': '!=='
|
||||||
|
of: 'in'
|
||||||
|
|
||||||
# The map of invertible operators.
|
# The map of invertible operators.
|
||||||
INVERSIONS:
|
INVERSIONS:
|
||||||
|
|||||||
@@ -139,6 +139,5 @@ ok c is 3
|
|||||||
|
|
||||||
|
|
||||||
# Instanceof.
|
# Instanceof.
|
||||||
# FIXME: These parentheses are workaround of #720
|
ok new String instanceof String
|
||||||
ok (new String) instanceof String
|
ok new Number not instanceof String
|
||||||
ok (new Number) not instanceof String
|
|
||||||
|
|||||||
Reference in New Issue
Block a user