mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-02-19 03:44:23 -05:00
lexer now distinguishes between IN/OF and FORIN/FOROF to help grammar, fixing #737
This commit is contained in:
49
lib/lexer.js
49
lib/lexer.js
@@ -1,5 +1,5 @@
|
||||
(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, NEXT_CHARACTER, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, 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, 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, op, starts;
|
||||
Rewriter = require('./rewriter').Rewriter;
|
||||
_ref = require('./helpers'), include = _ref.include, count = _ref.count, starts = _ref.starts, compact = _ref.compact, last = _ref.last;
|
||||
exports.Lexer = (function() {
|
||||
@@ -16,6 +16,7 @@
|
||||
this.indent = 0;
|
||||
this.indebt = 0;
|
||||
this.outdebt = 0;
|
||||
this.seenFor = false;
|
||||
this.indents = [];
|
||||
this.tokens = [];
|
||||
while ((this.chunk = code.slice(this.i))) {
|
||||
@@ -28,7 +29,7 @@
|
||||
return (new Rewriter).rewrite(this.tokens);
|
||||
};
|
||||
Lexer.prototype.identifierToken = function() {
|
||||
var _ref2, closeIndex, forcedIdentifier, id, match, tag;
|
||||
var closeIndex, forcedIdentifier, id, match, tag;
|
||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||||
return false;
|
||||
}
|
||||
@@ -44,11 +45,21 @@
|
||||
tag = id.toUpperCase();
|
||||
if (tag === 'WHEN' && include(LINE_BREAK, this.tag())) {
|
||||
tag = 'LEADING_WHEN';
|
||||
} else if (tag === 'FOR') {
|
||||
this.seenFor = true;
|
||||
} else if (include(UNARY, tag)) {
|
||||
tag = 'UNARY';
|
||||
} else if (('not' === (_ref2 = include(RELATION, tag) && this.value()) || '!' === _ref2)) {
|
||||
this.tokens.pop();
|
||||
tag = 'NOT_RELATED';
|
||||
} else if (include(RELATION, tag)) {
|
||||
if (tag !== 'INSTANCEOF' && this.seenFor) {
|
||||
this.seenFor = false;
|
||||
tag = 'FOR' + tag;
|
||||
} else {
|
||||
tag = 'RELATION';
|
||||
if (this.value() === '!') {
|
||||
this.tokens.pop();
|
||||
id = '!' + id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (include(JS_FORBIDDEN, id)) {
|
||||
@@ -67,8 +78,8 @@
|
||||
}
|
||||
}
|
||||
if (!(forcedIdentifier)) {
|
||||
if (include(COFFEE_ALIASES, id)) {
|
||||
tag = (id = CONVERSIONS[id]);
|
||||
if (COFFEE_ALIASES.hasOwnProperty(id)) {
|
||||
tag = (id = COFFEE_ALIASES[id]);
|
||||
}
|
||||
if (id === '!') {
|
||||
tag = 'UNARY';
|
||||
@@ -330,7 +341,7 @@
|
||||
if (('or' === pval || 'and' === pval)) {
|
||||
prev = last(this.tokens);
|
||||
prev[0] = 'COMPOUND_ASSIGN';
|
||||
prev[1] = CONVERSIONS[pval] + '=';
|
||||
prev[1] = COFFEE_ALIASES[pval] + '=';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -575,8 +586,18 @@
|
||||
return Lexer;
|
||||
})();
|
||||
JS_KEYWORDS = ['if', 'else', 'true', 'false', 'new', 'return', 'try', 'catch', 'finally', 'throw', 'break', 'continue', 'for', 'in', 'while', 'delete', 'instanceof', 'typeof', 'switch', 'super', 'extends', 'class', 'this', 'null', 'debugger'];
|
||||
COFFEE_ALIASES = ['and', 'or', 'is', 'isnt', 'not'];
|
||||
COFFEE_KEYWORDS = COFFEE_ALIASES.concat(['then', 'unless', 'until', 'loop', 'yes', 'no', 'on', 'off', 'of', 'by', 'when']);
|
||||
COFFEE_KEYWORDS = ['then', 'unless', 'until', 'loop', 'yes', 'no', 'on', 'off', 'of', 'by', 'when'];
|
||||
COFFEE_ALIASES = {
|
||||
and: '&&',
|
||||
or: '||',
|
||||
is: '==',
|
||||
isnt: '!=',
|
||||
not: '!'
|
||||
};
|
||||
for (op in COFFEE_ALIASES) {
|
||||
COFFEE_KEYWORDS.push(op);
|
||||
}
|
||||
COFFEE_ALIASES['==='] = '==';
|
||||
RESERVED = ['case', 'default', 'do', 'function', 'var', 'void', 'with', 'const', 'let', 'enum', 'export', 'import', 'native', '__hasProp', '__extends', '__slice'];
|
||||
JS_FORBIDDEN = JS_KEYWORDS.concat(RESERVED);
|
||||
IDENTIFIER = /^[a-zA-Z_$][\w$]*/;
|
||||
@@ -609,12 +630,4 @@
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']'];
|
||||
CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::'];
|
||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||||
CONVERSIONS = {
|
||||
'and': '&&',
|
||||
'or': '||',
|
||||
'is': '==',
|
||||
'isnt': '!=',
|
||||
'not': '!',
|
||||
'===': '=='
|
||||
};
|
||||
}).call(this);
|
||||
|
||||
Reference in New Issue
Block a user