almost there with half-assignments
This commit is contained in:
parent
f2ea18b0ba
commit
895cd88761
22
lib/lexer.js
22
lib/lexer.js
|
@ -1,5 +1,5 @@
|
|||
(function(){
|
||||
var ACCESSORS, ASSIGNMENT, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMMENT_CLEANER, CONVERSIONS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, INTERPOLATION, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, Lexer, MULTILINER, MULTI_DENT, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_ESCAPE, REGEX_FLAGS, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, STRING_NEWLINES, WHITESPACE, balanced_string, compact, count, helpers, include, starts;
|
||||
var ACCESSORS, ASSIGNMENT, CALLABLE, CODE, COFFEE_ALIASES, COFFEE_KEYWORDS, COMMENT, COMMENT_CLEANER, CONVERSIONS, HALF_ASSIGNMENTS, HEREDOC, HEREDOC_INDENT, IDENTIFIER, INTERPOLATION, JS_CLEANER, JS_FORBIDDEN, JS_KEYWORDS, KEYWORDS, LAST_DENT, LAST_DENTS, LINE_BREAK, Lexer, MULTILINER, MULTI_DENT, NOT_REGEX, NO_NEWLINE, NUMBER, OPERATOR, REGEX_ESCAPE, REGEX_FLAGS, REGEX_INTERPOLATION, REGEX_START, RESERVED, Rewriter, STRING_NEWLINES, WHITESPACE, balanced_string, compact, count, helpers, include, starts;
|
||||
// The CoffeeScript Lexer. Uses a series of token-matching regexes to attempt
|
||||
// matches against the beginning of the source code. When a match is found,
|
||||
// a token is produced, we consume the match, and start again. Tokens are in the
|
||||
|
@ -339,14 +339,15 @@
|
|||
// here. `;` and newlines are both treated as a `TERMINATOR`, we distinguish
|
||||
// parentheses that indicate a method call from regular parentheses, and so on.
|
||||
Lexer.prototype.literal_token = function literal_token() {
|
||||
var match, not_spaced, tag, value;
|
||||
var last, match, prev_spaced, space, tag, value;
|
||||
match = this.chunk.match(OPERATOR);
|
||||
value = match && match[1];
|
||||
space = match && match[2];
|
||||
if (value && value.match(CODE)) {
|
||||
this.tag_parameters();
|
||||
}
|
||||
value = value || this.chunk.substr(0, 1);
|
||||
not_spaced = !this.prev() || !this.prev().spaced;
|
||||
prev_spaced = this.prev() && this.prev().spaced;
|
||||
tag = value;
|
||||
if (value.match(ASSIGNMENT)) {
|
||||
tag = 'ASSIGN';
|
||||
|
@ -355,14 +356,14 @@
|
|||
}
|
||||
} else if (value === ';') {
|
||||
tag = 'TERMINATOR';
|
||||
} else if (value === '[' && this.tag() === '?' && not_spaced) {
|
||||
} else if (value === '[' && this.tag() === '?' && !prev_spaced) {
|
||||
tag = 'SOAKED_INDEX_START';
|
||||
this.soaked_index = true;
|
||||
this.tokens.pop();
|
||||
} else if (value === ']' && this.soaked_index) {
|
||||
tag = 'SOAKED_INDEX_END';
|
||||
this.soaked_index = false;
|
||||
} else if (include(CALLABLE, this.tag()) && not_spaced) {
|
||||
} else if (include(CALLABLE, this.tag()) && !prev_spaced) {
|
||||
if (value === '(') {
|
||||
tag = 'CALL_START';
|
||||
}
|
||||
|
@ -370,8 +371,13 @@
|
|||
tag = 'INDEX_START';
|
||||
}
|
||||
}
|
||||
this.token(tag, value);
|
||||
this.i += value.length;
|
||||
if (space && prev_spaced && this.prev()[0] === 'ASSIGN' && include(HALF_ASSIGNMENTS, tag)) {
|
||||
last = this.tokens.pop();
|
||||
this.tokens.push(['' + tag + "=", '' + tag + "=", last[2]]);
|
||||
} else {
|
||||
this.token(tag, value);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
// Token Manipulators
|
||||
|
@ -597,7 +603,7 @@
|
|||
NUMBER = /^(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i;
|
||||
HEREDOC = /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/;
|
||||
INTERPOLATION = /^\$([a-zA-Z_@]\w*(\.\w+)*)/;
|
||||
OPERATOR = /^([+\*&|\/\-%=<>:!?]+)/;
|
||||
OPERATOR = /^([+\*&|\/\-%=<>:!?]+)([ \t]*)/;
|
||||
WHITESPACE = /^([ \t]+)/;
|
||||
COMMENT = /^(((\n?[ \t]*)?#[^\n]*)+)/;
|
||||
CODE = /^((-|=)>)/;
|
||||
|
@ -633,6 +639,8 @@
|
|||
// occurs at the start of a line. We disambiguate these from trailing whens to
|
||||
// avoid an ambiguity in the grammar.
|
||||
LINE_BREAK = ['INDENT', 'OUTDENT', 'TERMINATOR'];
|
||||
// Half-assignments...
|
||||
HALF_ASSIGNMENTS = ['-', '+', '/', '*', '%', '||', '&&', '?'];
|
||||
// Conversions from CoffeeScript operators into JavaScript ones.
|
||||
CONVERSIONS = {
|
||||
'and': '&&',
|
||||
|
|
|
@ -249,27 +249,32 @@ exports.Lexer: class Lexer
|
|||
literal_token: ->
|
||||
match: @chunk.match(OPERATOR)
|
||||
value: match and match[1]
|
||||
space: match and match[2]
|
||||
@tag_parameters() if value and value.match(CODE)
|
||||
value ||= @chunk.substr(0, 1)
|
||||
not_spaced: not @prev() or not @prev().spaced
|
||||
prev_spaced: @prev() and @prev().spaced
|
||||
tag: value
|
||||
if value.match(ASSIGNMENT)
|
||||
tag: 'ASSIGN'
|
||||
@assignment_error() if include JS_FORBIDDEN, @value
|
||||
else if value is ';'
|
||||
tag: 'TERMINATOR'
|
||||
else if value is '[' and @tag() is '?' and not_spaced
|
||||
else if value is '[' and @tag() is '?' and not prev_spaced
|
||||
tag: 'SOAKED_INDEX_START'
|
||||
@soaked_index: true
|
||||
@tokens.pop()
|
||||
else if value is ']' and @soaked_index
|
||||
tag: 'SOAKED_INDEX_END'
|
||||
@soaked_index: false
|
||||
else if include(CALLABLE, @tag()) and not_spaced
|
||||
else if include(CALLABLE, @tag()) and not prev_spaced
|
||||
tag: 'CALL_START' if value is '('
|
||||
tag: 'INDEX_START' if value is '['
|
||||
@token tag, value
|
||||
@i += value.length
|
||||
if space and prev_spaced and @prev()[0] is 'ASSIGN' and include HALF_ASSIGNMENTS, tag
|
||||
last: @tokens.pop()
|
||||
@tokens.push ["$tag=", "$tag=", last[2]]
|
||||
else
|
||||
@token tag, value
|
||||
true
|
||||
|
||||
# Token Manipulators
|
||||
|
@ -462,7 +467,7 @@ IDENTIFIER : /^([a-zA-Z\$_](\w|\$)*)/
|
|||
NUMBER : /^(\b((0(x|X)[0-9a-fA-F]+)|([0-9]+(\.[0-9]+)?(e[+\-]?[0-9]+)?)))\b/i
|
||||
HEREDOC : /^("{6}|'{6}|"{3}\n?([\s\S]*?)\n?([ \t]*)"{3}|'{3}\n?([\s\S]*?)\n?([ \t]*)'{3})/
|
||||
INTERPOLATION : /^\$([a-zA-Z_@]\w*(\.\w+)*)/
|
||||
OPERATOR : /^([+\*&|\/\-%=<>:!?]+)/
|
||||
OPERATOR : /^([+\*&|\/\-%=<>:!?]+)([ \t]*)/
|
||||
WHITESPACE : /^([ \t]+)/
|
||||
COMMENT : /^(((\n?[ \t]*)?#[^\n]*)+)/
|
||||
CODE : /^((-|=)>)/
|
||||
|
@ -509,6 +514,9 @@ ACCESSORS: ['PROPERTY_ACCESS', 'PROTOTYPE_ACCESS', 'SOAK_ACCESS', '@']
|
|||
# avoid an ambiguity in the grammar.
|
||||
LINE_BREAK: ['INDENT', 'OUTDENT', 'TERMINATOR']
|
||||
|
||||
# Half-assignments...
|
||||
HALF_ASSIGNMENTS: ['-', '+', '/', '*', '%', '||', '&&', '?']
|
||||
|
||||
# Conversions from CoffeeScript operators into JavaScript ones.
|
||||
CONVERSIONS: {
|
||||
'and': '&&'
|
||||
|
|
Loading…
Reference in New Issue