fix and tests for half assignments... whew.

This commit is contained in:
Jeremy Ashkenas 2010-03-21 23:24:24 -04:00
parent 895cd88761
commit cbfe7f5822
3 changed files with 64 additions and 13 deletions

View File

@ -139,8 +139,13 @@
tag = 'LEADING_WHEN'; tag = 'LEADING_WHEN';
} }
this.i += id.length; this.i += id.length;
if (!accessed && include(COFFEE_ALIASES, id)) { if (!accessed) {
tag = (id = CONVERSIONS[id]); if (include(COFFEE_ALIASES, id)) {
tag = (id = CONVERSIONS[id]);
}
if (this.prev() && this.prev()[0] === 'ASSIGN' && include(HALF_ASSIGNMENTS, tag)) {
return this.tag_half_assignment(tag);
}
} }
this.token(tag, id); this.token(tag, id);
return true; return true;
@ -339,7 +344,7 @@
// here. `;` and newlines are both treated as a `TERMINATOR`, we distinguish // here. `;` and newlines are both treated as a `TERMINATOR`, we distinguish
// parentheses that indicate a method call from regular parentheses, and so on. // parentheses that indicate a method call from regular parentheses, and so on.
Lexer.prototype.literal_token = function literal_token() { Lexer.prototype.literal_token = function literal_token() {
var last, match, prev_spaced, space, tag, value; var match, prev_spaced, space, tag, value;
match = this.chunk.match(OPERATOR); match = this.chunk.match(OPERATOR);
value = match && match[1]; value = match && match[1];
space = match && match[2]; space = match && match[2];
@ -373,11 +378,9 @@
} }
this.i += value.length; this.i += value.length;
if (space && prev_spaced && this.prev()[0] === 'ASSIGN' && include(HALF_ASSIGNMENTS, tag)) { if (space && prev_spaced && this.prev()[0] === 'ASSIGN' && include(HALF_ASSIGNMENTS, tag)) {
last = this.tokens.pop(); return this.tag_half_assignment(tag);
this.tokens.push(['' + tag + "=", '' + tag + "=", last[2]]);
} else {
this.token(tag, value);
} }
this.token(tag, value);
return true; return true;
}; };
// Token Manipulators // Token Manipulators
@ -404,6 +407,13 @@
indent = (doc.match(HEREDOC_INDENT) || ['']).sort()[0]; indent = (doc.match(HEREDOC_INDENT) || ['']).sort()[0];
return doc.replace(new RegExp("^" + indent, 'gm'), '').replace(MULTILINER, "\\n").replace(new RegExp(quote, 'g'), '\\"'); return doc.replace(new RegExp("^" + indent, 'gm'), '').replace(MULTILINER, "\\n").replace(new RegExp(quote, 'g'), '\\"');
}; };
// Tag a half assignment.
Lexer.prototype.tag_half_assignment = function tag_half_assignment(tag) {
var last;
last = this.tokens.pop();
this.tokens.push(['' + tag + "=", '' + tag + "=", last[2]]);
return true;
};
// A source of ambiguity in our grammar used to be parameter lists in function // A source of ambiguity in our grammar used to be parameter lists in function
// definitions versus argument lists in function calls. Walk backwards, tagging // definitions versus argument lists in function calls. Walk backwards, tagging
// parameters specially in order to make things easier for the parser. // parameters specially in order to make things easier for the parser.

View File

@ -100,7 +100,9 @@ exports.Lexer: class Lexer
@identifier_error id if include RESERVED, id @identifier_error id if include RESERVED, id
tag: 'LEADING_WHEN' if tag is 'WHEN' and include LINE_BREAK, @tag() tag: 'LEADING_WHEN' if tag is 'WHEN' and include LINE_BREAK, @tag()
@i += id.length @i += id.length
tag: id: CONVERSIONS[id] if not accessed and include(COFFEE_ALIASES, id) if not accessed
tag: id: CONVERSIONS[id] if include COFFEE_ALIASES, id
return @tag_half_assignment(tag) if @prev() and @prev()[0] is 'ASSIGN' and include HALF_ASSIGNMENTS, tag
@token(tag, id) @token(tag, id)
true true
@ -270,11 +272,8 @@ exports.Lexer: class Lexer
tag: 'CALL_START' if value is '(' tag: 'CALL_START' if value is '('
tag: 'INDEX_START' if value is '[' tag: 'INDEX_START' if value is '['
@i += value.length @i += value.length
if space and prev_spaced and @prev()[0] is 'ASSIGN' and include HALF_ASSIGNMENTS, tag return @tag_half_assignment(tag) if space and prev_spaced and @prev()[0] is 'ASSIGN' and include HALF_ASSIGNMENTS, tag
last: @tokens.pop() @token tag, value
@tokens.push ["$tag=", "$tag=", last[2]]
else
@token tag, value
true true
# Token Manipulators # Token Manipulators
@ -299,6 +298,12 @@ exports.Lexer: class Lexer
.replace(MULTILINER, "\\n") .replace(MULTILINER, "\\n")
.replace(new RegExp(quote, 'g'), '\\"') .replace(new RegExp(quote, 'g'), '\\"')
# Tag a half assignment.
tag_half_assignment: (tag) ->
last: @tokens.pop()
@tokens.push ["$tag=", "$tag=", last[2]]
true
# A source of ambiguity in our grammar used to be parameter lists in function # A source of ambiguity in our grammar used to be parameter lists in function
# definitions versus argument lists in function calls. Walk backwards, tagging # definitions versus argument lists in function calls. Walk backwards, tagging
# parameters specially in order to make things easier for the parser. # parameters specially in order to make things easier for the parser.

View File

@ -0,0 +1,36 @@
num: 10
num: - 5
ok num is 5
num: -3
ok num is -3
num: +3
ok num is 3
num: * 10
ok num is 30
num: / 10
ok num is 3
val: false
val: or 'value'
ok val is 'value'
val: and 'other'
ok val is 'other'
val: null
val: ? 'value'
ok val is 'value'