mirror of
https://github.com/jashkenas/coffeescript.git
synced 2022-11-09 12:23:24 -05:00
Add support for standalone yield
This breaks compatibility with -> yield for i in [1..3] i * 2 and -> yield i * 2 yield's behaviour now mirrors that of return in that it can be used stand alone as well as with expressions. Thus, it currently also inherits the above limitations.
This commit is contained in:
parent
1739c9d720
commit
c1a9cfa044
6 changed files with 175 additions and 174 deletions
|
@ -47,7 +47,18 @@
|
|||
return new Literal($1);
|
||||
})
|
||||
],
|
||||
Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw')],
|
||||
Expression: [o('Value'), o('Invocation'), o('Code'), o('Operation'), o('Assign'), o('If'), o('Try'), o('While'), o('For'), o('Switch'), o('Class'), o('Throw'), o('Yield')],
|
||||
Yield: [
|
||||
o('YIELD', function() {
|
||||
return new Op($1, new Value(new Literal('')));
|
||||
}), o('YIELD Statement', function() {
|
||||
return new Op($1, $2);
|
||||
}), o('YIELD Expression', function() {
|
||||
return new Op($1, $2);
|
||||
}), o('YIELD FROM Expression', function() {
|
||||
return new Op($1.concat($2), $3);
|
||||
})
|
||||
],
|
||||
Block: [
|
||||
o('INDENT OUTDENT', function() {
|
||||
return new Block;
|
||||
|
@ -580,12 +591,6 @@
|
|||
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() {
|
||||
return new Op($1.concat($2), $3);
|
||||
}), o('-- SimpleAssignable', function() {
|
||||
return new Op('--', $2);
|
||||
}), o('++ SimpleAssignable', function() {
|
||||
|
|
|
@ -794,7 +794,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 === 'YIELD' || 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 === '**' || ref2 === 'SHIFT' || ref2 === 'RELATION' || ref2 === 'COMPARE' || ref2 === 'LOGIC' || ref2 === 'THROW' || ref2 === 'EXTENDS');
|
||||
};
|
||||
|
||||
Lexer.prototype.formatString = function(str) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -113,6 +113,14 @@ grammar =
|
|||
o 'Switch'
|
||||
o 'Class'
|
||||
o 'Throw'
|
||||
o 'Yield'
|
||||
]
|
||||
|
||||
Yield: [
|
||||
o 'YIELD', -> new Op $1, new Value new Literal ''
|
||||
o 'YIELD Statement', -> new Op $1, $2
|
||||
o 'YIELD Expression', -> new Op $1, $2
|
||||
o 'YIELD FROM Expression', -> new Op $1.concat($2), $3
|
||||
]
|
||||
|
||||
# An indented block of expressions. Note that the [Rewriter](rewriter.html)
|
||||
|
@ -558,9 +566,6 @@ 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
|
||||
|
||||
o '-- SimpleAssignable', -> new Op '--', $2
|
||||
o '++ SimpleAssignable', -> new Op '++', $2
|
||||
|
|
|
@ -682,7 +682,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', '+', '-', 'YIELD',
|
||||
@tag() in ['\\', '.', '?.', '?::', 'UNARY', 'MATH', 'UNARY_MATH', '+', '-',
|
||||
'**', 'SHIFT', 'RELATION', 'COMPARE', 'LOGIC', 'THROW', 'EXTENDS']
|
||||
|
||||
formatString: (str) ->
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
# * Generator Definition
|
||||
|
||||
test "most basic generator support", ->
|
||||
ok -> yield 0
|
||||
ok -> yield
|
||||
|
||||
test "empty generator", ->
|
||||
x = do -> yield return
|
||||
|
@ -15,19 +15,21 @@ test "empty generator", ->
|
|||
test "generator iteration", ->
|
||||
x = do ->
|
||||
yield 0
|
||||
yield 1
|
||||
yield
|
||||
yield 2
|
||||
3
|
||||
|
||||
y = x.next()
|
||||
ok y.value is 0 and y.done is false
|
||||
|
||||
y = x.next()
|
||||
ok y.value is 1 and y.done is false
|
||||
ok y.value is undefined and y.done is false
|
||||
|
||||
y = x.next()
|
||||
ok y.value is 2 and y.done is false
|
||||
|
||||
y = x.next()
|
||||
ok y.value is undefined and y.done is true
|
||||
ok y.value is 3 and y.done is true
|
||||
|
||||
test "last line yields are returned", ->
|
||||
x = do ->
|
||||
|
@ -71,9 +73,6 @@ test "bound generator", ->
|
|||
test "error if `yield` occurs outside of a function", ->
|
||||
throws -> CoffeeScript.compile 'yield 1'
|
||||
|
||||
test "`yield` by itself not at the end of a function errors", ->
|
||||
throws -> CoffeeScript.compile 'x = -> yield; return'
|
||||
|
||||
test "`yield from` support", ->
|
||||
x = do ->
|
||||
yield from do ->
|
||||
|
@ -131,18 +130,6 @@ test "yield in for loop expressions", ->
|
|||
arrayEq z.value, [10, 20, 30]
|
||||
ok z.done is true
|
||||
|
||||
test "yielding for loop expressions", ->
|
||||
x = do ->
|
||||
yield for i in [1..3]
|
||||
i * 2
|
||||
|
||||
y = x.next()
|
||||
arrayEq y.value, [2, 4, 6]
|
||||
ok y.done is false
|
||||
|
||||
y = x.next 42
|
||||
ok y.value is 42 and y.done is true
|
||||
|
||||
test "yield in switch expressions", ->
|
||||
x = do ->
|
||||
y = switch yield 1
|
||||
|
@ -223,8 +210,9 @@ test "yield handles 'this' correctly", ->
|
|||
x = ->
|
||||
yield switch
|
||||
when true then yield => this
|
||||
yield for item in [1]
|
||||
array = for item in [1]
|
||||
yield => this
|
||||
yield array
|
||||
yield if true then yield => this
|
||||
yield try throw yield => this
|
||||
throw yield => this
|
||||
|
|
Loading…
Reference in a new issue