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';
}
this.i += id.length;
if (!accessed && include(COFFEE_ALIASES, id)) {
tag = (id = CONVERSIONS[id]);
if (!accessed) {
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);
return true;
@ -339,7 +344,7 @@
// 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 last, match, prev_spaced, space, tag, value;
var match, prev_spaced, space, tag, value;
match = this.chunk.match(OPERATOR);
value = match && match[1];
space = match && match[2];
@ -373,11 +378,9 @@
}
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 this.tag_half_assignment(tag);
}
this.token(tag, value);
return true;
};
// Token Manipulators
@ -404,6 +407,13 @@
indent = (doc.match(HEREDOC_INDENT) || ['']).sort()[0];
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
// definitions versus argument lists in function calls. Walk backwards, tagging
// 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
tag: 'LEADING_WHEN' if tag is 'WHEN' and include LINE_BREAK, @tag()
@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)
true
@ -270,11 +272,8 @@ exports.Lexer: class Lexer
tag: 'CALL_START' if value is '('
tag: 'INDEX_START' if value is '['
@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
return @tag_half_assignment(tag) if space and prev_spaced and @prev()[0] is 'ASSIGN' and include HALF_ASSIGNMENTS, tag
@token tag, value
true
# Token Manipulators
@ -299,6 +298,12 @@ exports.Lexer: class Lexer
.replace(MULTILINER, "\\n")
.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
# definitions versus argument lists in function calls. Walk backwards, tagging
# 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'