removed support for '->*" and '=>*'

This commit is contained in:
Andreas Lubbe 2014-09-06 12:55:27 +02:00
parent 75900660fd
commit 565d78f00b
10 changed files with 209 additions and 218 deletions

View File

@ -123,12 +123,8 @@
FuncGlyph: [
o('->', function() {
return 'func';
}), o('->*', function() {
return 'generator';
}), o('=>', function() {
return 'boundfunc';
}), o('=>*', function() {
return 'boundgenerator';
})
],
OptComma: [o(''), o(',')],

View File

@ -59,13 +59,10 @@
Lexer.prototype.identifierToken = function() {
var colon, colonOffset, forcedIdentifier, id, idLength, input, match, poppedToken, prev, tag, tagToken, _ref2, _ref3, _ref4;
if (!(match = /^yield\*/.exec(this.chunk) || IDENTIFIER.exec(this.chunk))) {
if (!(match = IDENTIFIER.exec(this.chunk))) {
return 0;
}
input = match[0], id = match[1], colon = match[2];
if (input === 'yield*') {
id = 'yield*';
}
idLength = id.length;
poppedToken = void 0;
if (id === 'own' && this.tag() === 'FOR') {
@ -829,7 +826,7 @@
})();
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'yield', 'yield*', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
JS_KEYWORDS = ['true', 'false', 'null', 'this', 'new', 'delete', 'typeof', 'in', 'instanceof', 'return', 'throw', 'break', 'continue', 'debugger', 'yield', 'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally', 'class', 'extends', 'super'];
COFFEE_KEYWORDS = ['undefined', 'then', 'unless', 'until', 'loop', 'of', 'by', 'when'];
@ -874,13 +871,13 @@
HEREDOC = /^("""|''')((?:\\[\s\S]|[^\\])*?)(?:\n[^\n\S]*)?\1/;
OPERATOR = /^(?:[-=]>\*?|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?(\.|::)|\.{2,3})/;
OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>*\/%])\2=?|\?(\.|::)|\.{2,3})/;
WHITESPACE = /^[^\n\S]+/;
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/;
CODE = /^[-=]>\*?/;
CODE = /^[-=]>/;
MULTI_DENT = /^(?:\n[^\n\S]*)+/;
@ -906,7 +903,7 @@
COMPOUND_ASSIGN = ['-=', '+=', '/=', '*=', '%=', '||=', '&&=', '?=', '<<=', '>>=', '>>>=', '&=', '^=', '|=', '**=', '//=', '%%='];
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO', 'YIELD', 'YIELD*'];
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO', 'YIELD'];
UNARY_MATH = ['!', '~'];

View File

@ -1816,8 +1816,15 @@
function Code(params, body, tag) {
this.params = params || [];
this.body = body || new Block;
this.bound = tag === 'boundfunc' || tag === 'boundgenerator';
this.generator = tag === 'generator' || tag === 'boundgenerator';
this.bound = tag === 'boundfunc';
this.isGenerator = false;
this.body.traverseChildren(false, (function(_this) {
return function(child) {
if (child.operator === 'yield') {
return _this.isGenerator = true;
}
};
})(this));
}
Code.prototype.children = ['params', 'body'];
@ -1935,7 +1942,7 @@
this.body.makeReturn();
}
code = 'function';
if (this.generator) {
if (this.isGenerator) {
code += '*';
}
if (this.ctor) {

File diff suppressed because one or more lines are too long

View File

@ -230,7 +230,7 @@
return forward(1);
}
if (tag === 'INDENT' && inImplicit()) {
if (prevTag !== '=>' && prevTag !== '->' && prevTag !== '=>*' && prevTag !== '->*' && prevTag !== '[' && prevTag !== '(' && prevTag !== ',' && prevTag !== '{' && prevTag !== 'TRY' && prevTag !== 'ELSE' && prevTag !== '=') {
if (prevTag !== '=>' && prevTag !== '->' && prevTag !== '[' && prevTag !== '(' && prevTag !== ',' && prevTag !== '{' && prevTag !== 'TRY' && prevTag !== 'ELSE' && prevTag !== '=') {
while (inImplicitCall()) {
endImplicitCall();
}
@ -348,7 +348,7 @@
starter = indent = outdent = null;
condition = function(token, i) {
var _ref, _ref1, _ref2, _ref3;
return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'TERMINATOR' && (_ref1 = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref1) >= 0)) && !(token[0] === 'ELSE' && starter !== 'THEN') && !(((_ref2 = token[0]) === 'CATCH' || _ref2 === 'FINALLY') && (starter === '->' || starter === '=>' || starter === '->*' || starter === '=>*')) || (_ref3 = token[0], __indexOf.call(CALL_CLOSERS, _ref3) >= 0) && this.tokens[i - 1].newLine;
return token[1] !== ';' && (_ref = token[0], __indexOf.call(SINGLE_CLOSERS, _ref) >= 0) && !(token[0] === 'TERMINATOR' && (_ref1 = this.tag(i + 1), __indexOf.call(EXPRESSION_CLOSE, _ref1) >= 0)) && !(token[0] === 'ELSE' && starter !== 'THEN') && !(((_ref2 = token[0]) === 'CATCH' || _ref2 === 'FINALLY') && (starter === '->' || starter === '=>')) || (_ref3 = token[0], __indexOf.call(CALL_CLOSERS, _ref3) >= 0) && this.tokens[i - 1].newLine;
};
action = function(token, i) {
return this.tokens.splice((this.tag(i - 1) === ',' ? i - 1 : i), 0, outdent);
@ -464,7 +464,7 @@
IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY', 'LOOP', 'TERMINATOR'];
SINGLE_LINERS = ['ELSE', '->', '=>', '->*', '=>*', 'TRY', 'FINALLY', 'THEN'];
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN'];
SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN'];

View File

@ -189,15 +189,11 @@ grammar =
o 'FuncGlyph Block', -> new Code [], $2, $1
]
# CoffeeScript has two different symbols for functions and two different
# symbols for generators. `->` and `->*` are for ordinary functions and
# generators, and `=>` and `=>*` ares for functions and generators bound to
# the current value of *this*.
# CoffeeScript has two different symbols for functions. `->` is for ordinary
# functions, and `=>` is for functions bound to the current value of *this*.
FuncGlyph: [
o '->', -> 'func'
o '->*', -> 'generator'
o '=>', -> 'boundfunc'
o '=>*', -> 'boundgenerator'
]
# An optional, trailing comma.

View File

@ -99,9 +99,8 @@ exports.Lexer = class Lexer
# referenced as property names here, so you can still do `jQuery.is()` even
# though `is` means `===` otherwise.
identifierToken: ->
return 0 unless match = /^yield\*/.exec(@chunk) or IDENTIFIER.exec @chunk
return 0 unless match = IDENTIFIER.exec @chunk
[input, id, colon] = match
if input is 'yield*' then id = 'yield*'
# Preserve length of id for location data
idLength = id.length
@ -730,7 +729,7 @@ exports.Lexer = class Lexer
JS_KEYWORDS = [
'true', 'false', 'null', 'this'
'new', 'delete', 'typeof', 'in', 'instanceof'
'return', 'throw', 'break', 'continue', 'debugger', 'yield', 'yield*'
'return', 'throw', 'break', 'continue', 'debugger', 'yield'
'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally'
'class', 'extends', 'super'
]
@ -790,7 +789,7 @@ NUMBER = ///
HEREDOC = /// ^ ("""|''') ((?: \\[\s\S] | [^\\] )*?) (?:\n[^\n\S]*)? \1 ///
OPERATOR = /// ^ (
?: [-=]>\*? # function / generator
?: [-=]> # function
| [-+*/%<>&|^!?=]= # compound assign / compare
| >>>=? # zero-fill right shift
| ([-+:])\1 # doubles
@ -803,7 +802,7 @@ WHITESPACE = /^[^\n\S]+/
COMMENT = /^###([^#][\s\S]*?)(?:###[^\n\S]*|###$)|^(?:\s*#(?!##[^#]).*)+/
CODE = /^[-=]>\*?/
CODE = /^[-=]>/
MULTI_DENT = /^(?:\n[^\n\S]*)+/
@ -852,7 +851,7 @@ COMPOUND_ASSIGN = [
]
# Unary tokens.
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO', 'YIELD', 'YIELD*']
UNARY = ['NEW', 'TYPEOF', 'DELETE', 'DO', 'YIELD']
UNARY_MATH = ['!', '~']

View File

@ -1314,10 +1314,12 @@ exports.Assign = class Assign extends Base
# has no *children* -- they're within the inner scope.
exports.Code = class Code extends Base
constructor: (params, body, tag) ->
@params = params or []
@body = body or new Block
@bound = tag is 'boundfunc' or tag is 'boundgenerator'
@generator = tag is 'generator' or tag is 'boundgenerator'
@params = params or []
@body = body or new Block
@bound = tag is 'boundfunc'
@isGenerator = false
@body.traverseChildren false, (child) =>
@isGenerator = true if child.operator is 'yield'
children: ['params', 'body']
@ -1385,7 +1387,7 @@ exports.Code = class Code extends Base
uniqs.push name
@body.makeReturn() unless wasEmpty or @noReturn
code = 'function'
code += '*' if @generator
code += '*' if @isGenerator
code += ' ' + @name if @ctor
code += '('
answer = [@makeCode(code)]
@ -1738,8 +1740,8 @@ exports.Op = class Op extends Base
if o.level >= LEVEL_ACCESS
return (new Parens this).compileToFragments o
plusMinus = op in ['+', '-']
parts.push [@makeCode(' ')] if op in ['new', 'typeof', 'delete', 'yield'
'yield*'] or plusMinus and @first instanceof Op and @first.operator is op
parts.push [@makeCode(' ')] if op in ['new', 'typeof', 'delete', 'yield', 'yield*'] or
plusMinus and @first instanceof Op and @first.operator is op
if (plusMinus and @first instanceof Op) or (op is 'new' and @first.isStatement o)
@first = new Parens @first
parts.push @first.compileToFragments o, LEVEL_OP

View File

@ -185,8 +185,7 @@ class exports.Rewriter
# 1. We have seen a `CONTROL` argument on the line.
# 2. The last token before the indent is part of the list below
#
if prevTag not in ['=>', '->', '=>*', '->*', '[', '(', ',', '{',
'TRY', 'ELSE', '=']
if prevTag not in ['=>', '->', '[', '(', ',', '{', 'TRY', 'ELSE', '=']
endImplicitCall() while inImplicitCall()
stack.pop() if inImplicitControl()
stack.push [tag, i]
@ -366,8 +365,8 @@ class exports.Rewriter
token[1] isnt ';' and token[0] in SINGLE_CLOSERS and
not (token[0] is 'TERMINATOR' and @tag(i + 1) in EXPRESSION_CLOSE) and
not (token[0] is 'ELSE' and starter isnt 'THEN') and
not (token[0] in ['CATCH', 'FINALLY'] and starter in ['->', '=>', '->*',
'=>*']) or token[0] in CALL_CLOSERS and @tokens[i - 1].newLine
not (token[0] in ['CATCH', 'FINALLY'] and starter in ['->', '=>']) or
token[0] in CALL_CLOSERS and @tokens[i - 1].newLine
action = (token, i) ->
@tokens.splice (if @tag(i - 1) is ',' then i - 1 else i), 0, outdent
@ -468,7 +467,7 @@ IMPLICIT_FUNC = ['IDENTIFIER', 'SUPER', ')', 'CALL_END', ']', 'INDEX_END', '@
# If preceded by an `IMPLICIT_FUNC`, indicates a function invocation.
IMPLICIT_CALL = [
'IDENTIFIER', 'NUMBER', 'STRING', 'JS', 'REGEX', 'NEW', 'PARAM_START', 'CLASS'
'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY',
'IF', 'TRY', 'SWITCH', 'THIS', 'BOOL', 'NULL', 'UNDEFINED', 'UNARY'
'UNARY_MATH', 'SUPER', 'THROW', '@', '->', '=>', '[', '(', '{', '--', '++'
]
@ -480,7 +479,7 @@ IMPLICIT_END = ['POST_IF', 'FOR', 'WHILE', 'UNTIL', 'WHEN', 'BY',
# Single-line flavors of block expressions that have unclosed endings.
# The grammar can't disambiguate them, so we insert the implicit indentation.
SINGLE_LINERS = ['ELSE', '->', '=>', '->*', '=>*', 'TRY', 'FINALLY', 'THEN']
SINGLE_LINERS = ['ELSE', '->', '=>', 'TRY', 'FINALLY', 'THEN']
SINGLE_CLOSERS = ['TERMINATOR', 'CATCH', 'FINALLY', 'ELSE', 'OUTDENT', 'LEADING_WHEN']
# Tokens that end a line.

View File

@ -4,15 +4,14 @@
# * Generator Definition
test "generator as argument", ->
ok ->* 1
ok -> yield 0
test "generator definition", ->
x = ->*
x = ->
yield 0
yield 1
yield 2
y = do ->*
yield* x()
y = x()
z = y.next()
eq z.value, 0
eq z.done, false
@ -29,16 +28,16 @@ test "generator definition", ->
test "bound generator", ->
obj =
bound: ->
do =>*
this
do =>
yield this
unbound: ->
do ->*
this
do ->
yield this
nested: ->
do =>*
do =>*
do =>*
this
do =>
yield do =>
yield do =>
yield this
eq obj, obj.bound().next().value
ok obj isnt obj.unbound().next().value