mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
added 'yield return'
This commit is contained in:
parent
c72556619f
commit
437b9ed65c
7 changed files with 79 additions and 40 deletions
|
@ -552,6 +552,8 @@
|
|||
return new Op('+', $2);
|
||||
}), {
|
||||
prec: 'UNARY_MATH'
|
||||
}), o('YIELD Statement', function() {
|
||||
return new Op($1, $2);
|
||||
}), o('YIELD Expression', function() {
|
||||
return new Op($1, $2);
|
||||
}), o('YIELD FROM Expression', function() {
|
||||
|
|
|
@ -777,7 +777,7 @@
|
|||
|
||||
Lexer.prototype.unfinished = function() {
|
||||
var _ref2;
|
||||
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === '**' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
||||
return LINE_CONTINUER.test(this.chunk) || ((_ref2 = this.tag()) === '\\' || _ref2 === '.' || _ref2 === '?.' || _ref2 === '?::' || _ref2 === 'UNARY' || _ref2 === 'MATH' || _ref2 === 'UNARY_MATH' || _ref2 === '+' || _ref2 === '-' || _ref2 === 'YIELD' || _ref2 === '**' || _ref2 === 'SHIFT' || _ref2 === 'RELATION' || _ref2 === 'COMPARE' || _ref2 === 'LOGIC' || _ref2 === 'THROW' || _ref2 === 'EXTENDS');
|
||||
};
|
||||
|
||||
Lexer.prototype.removeNewlines = function(str) {
|
||||
|
|
|
@ -1817,14 +1817,10 @@
|
|||
this.params = params || [];
|
||||
this.body = body || new Block;
|
||||
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));
|
||||
this.isGenerator = this.body.contains(function(node) {
|
||||
var _ref2;
|
||||
return node instanceof Op && ((_ref2 = node.operator) === 'yield' || _ref2 === 'yield*');
|
||||
});
|
||||
}
|
||||
|
||||
Code.prototype.children = ['params', 'body'];
|
||||
|
@ -2297,6 +2293,11 @@
|
|||
|
||||
Op.prototype.isSimpleNumber = NO;
|
||||
|
||||
Op.prototype.isYield = function() {
|
||||
var _ref2;
|
||||
return (_ref2 = this.operator) === 'yield' || _ref2 === 'yield*';
|
||||
};
|
||||
|
||||
Op.prototype.isUnary = function() {
|
||||
return !this.second;
|
||||
};
|
||||
|
@ -2381,6 +2382,9 @@
|
|||
if (((_ref2 = this.operator) === '--' || _ref2 === '++') && (_ref3 = this.first.unwrapAll().value, __indexOf.call(STRICT_PROSCRIBED, _ref3) >= 0)) {
|
||||
this.error("cannot increment/decrement \"" + (this.first.unwrapAll().value) + "\"");
|
||||
}
|
||||
if (this.isYield()) {
|
||||
return this.compileYield(o);
|
||||
}
|
||||
if (this.isUnary()) {
|
||||
return this.compileUnary(o);
|
||||
}
|
||||
|
@ -2434,9 +2438,6 @@
|
|||
var op, parts, plusMinus;
|
||||
parts = [];
|
||||
op = this.operator;
|
||||
if ((op === 'yield' || op === 'yield*') && (o.scope.parent == null)) {
|
||||
this.error('yield statements must occur within a function generator.');
|
||||
}
|
||||
parts.push([this.makeCode(op)]);
|
||||
if (op === '!' && this.first instanceof Existence) {
|
||||
this.first.negated = !this.first.negated;
|
||||
|
@ -2446,7 +2447,7 @@
|
|||
return (new Parens(this)).compileToFragments(o);
|
||||
}
|
||||
plusMinus = op === '+' || op === '-';
|
||||
if ((op === 'new' || op === 'typeof' || op === 'delete' || op === 'yield' || op === 'yield*') || plusMinus && this.first instanceof Op && this.first.operator === op) {
|
||||
if ((op === 'new' || op === 'typeof' || op === 'delete') || plusMinus && this.first instanceof Op && this.first.operator === op) {
|
||||
parts.push([this.makeCode(' ')]);
|
||||
}
|
||||
if ((plusMinus && this.first instanceof Op) || (op === 'new' && this.first.isStatement(o))) {
|
||||
|
@ -2459,6 +2460,25 @@
|
|||
return this.joinFragmentArrays(parts, '');
|
||||
};
|
||||
|
||||
Op.prototype.compileYield = function(o) {
|
||||
var op, parts;
|
||||
parts = [];
|
||||
op = this.operator;
|
||||
if (o.scope.parent == null) {
|
||||
this.error('yield statements must occur within a function generator.');
|
||||
}
|
||||
if (__indexOf.call(Object.keys(this.first), 'expression') >= 0) {
|
||||
if (this.first.expression != null) {
|
||||
parts.push(this.first.expression.compileToFragments(o, LEVEL_OP));
|
||||
}
|
||||
} else {
|
||||
parts.push([this.makeCode(op)]);
|
||||
parts.push([this.makeCode(' ')]);
|
||||
parts.push(this.first.compileToFragments(o, LEVEL_OP));
|
||||
}
|
||||
return this.joinFragmentArrays(parts, '');
|
||||
};
|
||||
|
||||
Op.prototype.compilePower = function(o) {
|
||||
var pow;
|
||||
pow = new Value(new Literal('Math'), [new Access(new Literal('pow'))]);
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -536,6 +536,7 @@ grammar =
|
|||
o 'UNARY_MATH Expression', -> new Op $1 , $2
|
||||
o '- Expression', (-> new Op '-', $2), prec: 'UNARY_MATH'
|
||||
o '+ Expression', (-> new Op '+', $2), prec: 'UNARY_MATH'
|
||||
o 'YIELD Statement', -> new Op $1 , $2
|
||||
o 'YIELD Expression', -> new Op $1 , $2
|
||||
o 'YIELD FROM Expression', -> new Op $1.concat($2) , $3
|
||||
|
||||
|
|
|
@ -691,7 +691,7 @@ exports.Lexer = class Lexer
|
|||
# Are we in the midst of an unfinished expression?
|
||||
unfinished: ->
|
||||
LINE_CONTINUER.test(@chunk) or
|
||||
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
|
||||
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-', 'YIELD',
|
||||
'**', 'SHIFT', 'RELATION', 'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
|
||||
|
||||
# Remove newlines from beginning and (non escaped) from end of string literals.
|
||||
|
|
|
@ -1314,12 +1314,11 @@ 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'
|
||||
@isGenerator = false
|
||||
@body.traverseChildren false, (child) =>
|
||||
@isGenerator = true if child.operator is 'yield'
|
||||
@params = params or []
|
||||
@body = body or new Block
|
||||
@bound = tag is 'boundfunc'
|
||||
@isGenerator = @body.contains (node) ->
|
||||
node instanceof Op and node.operator in ['yield', 'yield*']
|
||||
|
||||
children: ['params', 'body']
|
||||
|
||||
|
@ -1629,6 +1628,9 @@ exports.Op = class Op extends Base
|
|||
|
||||
isSimpleNumber: NO
|
||||
|
||||
isYield: ->
|
||||
@operator in ['yield', 'yield*']
|
||||
|
||||
isUnary: ->
|
||||
not @second
|
||||
|
||||
|
@ -1695,6 +1697,7 @@ exports.Op = class Op extends Base
|
|||
@error 'delete operand may not be argument or var'
|
||||
if @operator in ['--', '++'] and @first.unwrapAll().value in STRICT_PROSCRIBED
|
||||
@error "cannot increment/decrement \"#{@first.unwrapAll().value}\""
|
||||
return @compileYield o if @isYield()
|
||||
return @compileUnary o if @isUnary()
|
||||
return @compileChain o if isChain
|
||||
switch @operator
|
||||
|
@ -1734,8 +1737,6 @@ exports.Op = class Op extends Base
|
|||
compileUnary: (o) ->
|
||||
parts = []
|
||||
op = @operator
|
||||
if op in ['yield', 'yield*'] and not o.scope.parent?
|
||||
@error 'yield statements must occur within a function generator.'
|
||||
parts.push [@makeCode op]
|
||||
if op is '!' and @first instanceof Existence
|
||||
@first.negated = not @first.negated
|
||||
|
@ -1743,7 +1744,7 @@ 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
|
||||
parts.push [@makeCode(' ')] if op in ['new', 'typeof', 'delete'] 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
|
||||
|
@ -1751,6 +1752,19 @@ exports.Op = class Op extends Base
|
|||
parts.reverse() if @flip
|
||||
@joinFragmentArrays parts, ''
|
||||
|
||||
compileYield: (o) ->
|
||||
parts = []
|
||||
op = @operator
|
||||
if not o.scope.parent?
|
||||
@error 'yield statements must occur within a function generator.'
|
||||
if 'expression' in Object.keys @first
|
||||
parts.push @first.expression.compileToFragments o, LEVEL_OP if @first.expression?
|
||||
else
|
||||
parts.push [@makeCode op]
|
||||
parts.push [@makeCode(' ')]
|
||||
parts.push @first.compileToFragments o, LEVEL_OP
|
||||
@joinFragmentArrays parts, ''
|
||||
|
||||
compilePower: (o) ->
|
||||
# Make a Math.pow call
|
||||
pow = new Value new Literal('Math'), [new Access new Literal 'pow']
|
||||
|
|
Loading…
Reference in a new issue