mirror of
https://github.com/jashkenas/coffeescript.git
synced 2026-04-11 03:00:13 -04:00
Merge branch 'master' into newline-splat
Conflicts: lib/lexer.js lib/parser.js src/lexer.coffee
This commit is contained in:
68
lib/lexer.js
68
lib/lexer.js
@@ -1,10 +1,11 @@
|
||||
(function() {
|
||||
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, NEXT_ELLIPSIS, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX, RELATION, RESERVED, Rewriter, SHIFT, SIMPLESTR, TRAILING_SPACES, UNARY, WHITESPACE, _ref, compact, count, include, last, op, starts;
|
||||
var ASSIGNED, BOOL, 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, NEXT_ELLIPSIS, 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() {
|
||||
Lexer = (function() {
|
||||
return function Lexer() {};
|
||||
function Lexer() {};
|
||||
return Lexer;
|
||||
})();
|
||||
Lexer.prototype.tokenize = function(code, options) {
|
||||
var o;
|
||||
@@ -19,7 +20,7 @@
|
||||
this.seenFor = false;
|
||||
this.indents = [];
|
||||
this.tokens = [];
|
||||
while ((this.chunk = code.slice(this.i))) {
|
||||
while (this.chunk = code.slice(this.i)) {
|
||||
this.identifierToken() || this.commentToken() || this.whitespaceToken() || this.lineToken() || this.heredocToken() || this.stringToken() || this.numberToken() || this.regexToken() || this.jsToken() || this.literalToken();
|
||||
}
|
||||
this.closeIndentation();
|
||||
@@ -29,17 +30,17 @@
|
||||
return (new Rewriter).rewrite(this.tokens);
|
||||
};
|
||||
Lexer.prototype.identifierToken = function() {
|
||||
var forcedIdentifier, id, match, tag;
|
||||
var _ref2, colon, forcedIdentifier, id, input, match, tag;
|
||||
if (!(match = IDENTIFIER.exec(this.chunk))) {
|
||||
return false;
|
||||
}
|
||||
id = match[0];
|
||||
this.i += id.length;
|
||||
_ref2 = match, input = _ref2[0], id = _ref2[1], colon = _ref2[2];
|
||||
this.i += input.length;
|
||||
if (id === 'all' && this.tag() === 'FOR') {
|
||||
this.token('ALL', id);
|
||||
return true;
|
||||
}
|
||||
forcedIdentifier = this.tagAccessor() || ASSIGNED.test(this.chunk);
|
||||
forcedIdentifier = colon || this.tagAccessor();
|
||||
tag = 'IDENTIFIER';
|
||||
if (include(JS_KEYWORDS, id) || !forcedIdentifier && include(COFFEE_KEYWORDS, id)) {
|
||||
tag = id.toUpperCase();
|
||||
@@ -79,9 +80,15 @@
|
||||
tag = 'UNARY';
|
||||
} else if (include(LOGIC, id)) {
|
||||
tag = 'LOGIC';
|
||||
} else if (include(BOOL, tag)) {
|
||||
id = tag.toLowerCase();
|
||||
tag = 'BOOL';
|
||||
}
|
||||
}
|
||||
this.token(tag, id);
|
||||
if (colon) {
|
||||
this.token(':', ':');
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Lexer.prototype.numberToken = function() {
|
||||
@@ -330,9 +337,9 @@
|
||||
if (!prev[1].reserved && include(JS_FORBIDDEN, prev[1])) {
|
||||
this.assignmentError();
|
||||
}
|
||||
if (('or' === (_ref2 = prev[1]) || 'and' === _ref2)) {
|
||||
if (('||' === (_ref2 = prev[1]) || '&&' === _ref2)) {
|
||||
prev[0] = 'COMPOUND_ASSIGN';
|
||||
prev[1] = COFFEE_ALIASES[prev[1]] + '=';
|
||||
prev[1] += '=';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -374,25 +381,23 @@
|
||||
return true;
|
||||
};
|
||||
Lexer.prototype.tagAccessor = function() {
|
||||
var accessor, prev;
|
||||
var prev;
|
||||
if (!(prev = last(this.tokens)) || prev.spaced) {
|
||||
return false;
|
||||
}
|
||||
accessor = (function() {
|
||||
if (prev[1] === '::') {
|
||||
return this.tag(0, 'PROTOTYPE_ACCESS');
|
||||
} else if (prev[1] === '.' && this.value(1) !== '.') {
|
||||
if (this.tag(1) === '?') {
|
||||
this.tag(0, 'SOAK_ACCESS');
|
||||
return this.tokens.splice(-2, 1);
|
||||
} else {
|
||||
return this.tag(0, 'PROPERTY_ACCESS');
|
||||
}
|
||||
if (prev[1] === '::') {
|
||||
this.tag(0, 'PROTOTYPE_ACCESS');
|
||||
} else if (prev[1] === '.' && this.value(1) !== '.') {
|
||||
if (this.tag(1) === '?') {
|
||||
this.tag(0, 'SOAK_ACCESS');
|
||||
this.tokens.splice(-2, 1);
|
||||
} else {
|
||||
return prev[0] === '@';
|
||||
this.tag(0, 'PROPERTY_ACCESS');
|
||||
}
|
||||
}).call(this);
|
||||
return accessor ? 'accessor' : false;
|
||||
} else {
|
||||
return prev[0] === '@';
|
||||
}
|
||||
return true;
|
||||
};
|
||||
Lexer.prototype.sanitizeHeredoc = function(doc, options) {
|
||||
var _ref2, _ref3, attempt, herecomment, indent, match;
|
||||
@@ -422,10 +427,7 @@
|
||||
return;
|
||||
}
|
||||
i = this.tokens.length;
|
||||
while (true) {
|
||||
if (!(tok = this.tokens[--i])) {
|
||||
return;
|
||||
}
|
||||
while (tok = this.tokens[--i]) {
|
||||
switch (tok[0]) {
|
||||
case 'IDENTIFIER':
|
||||
tok[0] = 'PARAM';
|
||||
@@ -435,7 +437,8 @@
|
||||
break;
|
||||
case '(':
|
||||
case 'CALL_START':
|
||||
return (tok[0] = 'PARAM_START');
|
||||
tok[0] = 'PARAM_START';
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@@ -444,10 +447,10 @@
|
||||
return this.outdentToken(this.indent);
|
||||
};
|
||||
Lexer.prototype.identifierError = function(word) {
|
||||
throw new Error("SyntaxError: Reserved word \"" + word + "\" on line " + (this.line + 1));
|
||||
throw SyntaxError("Reserved word \"" + word + "\" on line " + (this.line + 1));
|
||||
};
|
||||
Lexer.prototype.assignmentError = function() {
|
||||
throw new Error("SyntaxError: Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
||||
throw SyntaxError("Reserved word \"" + (this.value()) + "\" on line " + (this.line + 1) + " can't be assigned");
|
||||
};
|
||||
Lexer.prototype.balancedString = function(str, delimited, options) {
|
||||
var _i, _len, _ref2, close, i, levels, open, pair, slen;
|
||||
@@ -596,7 +599,7 @@
|
||||
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$]*/;
|
||||
IDENTIFIER = /^([$A-Za-z_][$\w]*)([^\n\S]*:(?!:))?/;
|
||||
NUMBER = /^0x[\da-f]+|^(?:\d+(\.\d+)?|\.\d+)(?:e[+-]?\d+)?/i;
|
||||
HEREDOC = /^("""|''')([\s\S]*?)(?:\n[ \t]*)?\1/;
|
||||
OPERATOR = /^(?:-[-=>]?|\+[+=]?|\.\.\.?|[*&|\/%=<>^:!?]+)/;
|
||||
@@ -624,7 +627,8 @@
|
||||
COMPARE = ['<=', '<', '>', '>='];
|
||||
MATH = ['*', '/', '%'];
|
||||
RELATION = ['IN', 'OF', 'INSTANCEOF'];
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', '++', '--', 'FALSE', 'NULL', 'TRUE', ']'];
|
||||
BOOL = ['TRUE', 'FALSE', 'NULL'];
|
||||
NOT_REGEX = ['NUMBER', 'REGEX', 'BOOL', '++', '--', ']'];
|
||||
CALLABLE = ['IDENTIFIER', 'SUPER', ')', ']', '}', 'STRING', '@', 'THIS', '?', '::'];
|
||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||||
}).call(this);
|
||||
|
||||
Reference in New Issue
Block a user