Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

using 'yield' automatically turns functions into generators #3240

Merged
merged 24 commits into from
Sep 19, 2014
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f51cbd7
removed 'yield' from the reserved keywords
alubbe Nov 15, 2013
dafc7bd
added 'yield' to the unary keywords
alubbe Nov 15, 2013
9941050
using 'yield' automatically turns functions into generators
alubbe Nov 15, 2013
f11ca98
added a test for generators
alubbe Nov 30, 2013
7906a2b
removed yield from the reserved words
alubbe Nov 30, 2013
d712a6c
npm run-script test-harmony executes generator tests
alubbe Nov 30, 2013
74a92db
improved readability of generator test
alubbe Nov 30, 2013
9d29a83
entire generator test file is now ignored if generators are not avail…
alubbe Nov 30, 2013
85c7fff
improved readability of cakefile generator check
alubbe Dec 1, 2013
f4b850d
further improved readability of cakefile generator check
alubbe Dec 3, 2013
c02a403
fixed misspelling in Cakefile
alubbe Dec 5, 2013
e100020
Merge github.com:jashkenas/coffee-script
alubbe Dec 5, 2013
56b04a5
first attempt at using '->*" and '=>*' for generators
alubbe Dec 19, 2013
dab4ae9
'->*' and '=>*' now produce generators
alubbe Dec 20, 2013
25b1eee
first attempt at including 'yield*'
alubbe Dec 24, 2013
64e78a2
updated lexer to allow 'yield*'
alubbe Dec 26, 2013
1e377ed
'yield*' now works as expected
alubbe Dec 28, 2013
f375394
Merge https://github.com/jashkenas/coffee-script
alubbe Jan 26, 2014
7590066
Merge remote-tracking branch 'A/master'
alubbe Sep 6, 2014
565d78f
removed support for '->*" and '=>*'
alubbe Sep 6, 2014
c725566
added 'yield from'
alubbe Sep 6, 2014
437b9ed
added 'yield return'
alubbe Sep 6, 2014
781ea22
always wrap 'yield' in () to allow composability with all other opera…
alubbe Sep 6, 2014
efca286
added tests for yield, yield from, yield return and yield in if state…
alubbe Sep 6, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/coffee-script/lexer.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion lib/coffee-script/nodes.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@
"cake": "./bin/cake"
},
"scripts": {
"test": "node ./bin/cake test"
"test": "node ./bin/cake test",
"test-harmony": "node --harmony ./bin/cake test"
},
"homepage": "http://coffeescript.org",
"bugs": "https://github.com/jashkenas/coffee-script/issues",
Expand Down
6 changes: 3 additions & 3 deletions src/lexer.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -710,7 +710,7 @@ exports.Lexer = class Lexer
JS_KEYWORDS = [
'true', 'false', 'null', 'this'
'new', 'delete', 'typeof', 'in', 'instanceof'
'return', 'throw', 'break', 'continue', 'debugger'
'return', 'throw', 'break', 'continue', 'debugger', 'yield'
'if', 'else', 'switch', 'for', 'while', 'do', 'try', 'catch', 'finally'
'class', 'extends', 'super'
]
Expand Down Expand Up @@ -739,7 +739,7 @@ RESERVED = [
'case', 'default', 'function', 'var', 'void', 'with', 'const', 'let', 'enum'
'export', 'import', 'native', '__hasProp', '__extends', '__slice', '__bind'
'__indexOf', 'implements', 'interface', 'package', 'private', 'protected'
'public', 'static', 'yield'
'public', 'static'
]

STRICT_PROSCRIBED = ['arguments', 'eval']
Expand Down Expand Up @@ -831,7 +831,7 @@ COMPOUND_ASSIGN = [
]

# Unary tokens.
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO']
UNARY = ['!', '~', 'NEW', 'TYPEOF', 'DELETE', 'DO', 'YIELD']

# Logical tokens.
LOGIC = ['&&', '||', '&', '|', '^']
Expand Down
7 changes: 5 additions & 2 deletions src/nodes.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,6 @@ exports.Return = class Return extends Base
answer.push @makeCode ";"
return answer


#### Value

# A value, variable or literal or parenthesized, indexed or dotted into,
Expand Down Expand Up @@ -1302,6 +1301,9 @@ exports.Code = class Code extends Base
@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']

Expand Down Expand Up @@ -1369,6 +1371,7 @@ exports.Code = class Code extends Base
uniqs.push name
@body.makeReturn() unless wasEmpty or @noReturn
code = 'function'
code += '*' if @isGenerator
code += ' ' + @name if @ctor
code += '('
answer = [@makeCode(code)]
Expand Down Expand Up @@ -1699,7 +1702,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'] or
parts.push [@makeCode(' ')] if op in ['new', 'typeof', 'delete', '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
Expand Down
35 changes: 35 additions & 0 deletions test/generators.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Generators
# -----------------

# * Generator Definition

# ensure that these tests are only run if generators are available
generatorsAreAvailable = ->
for execArg in process.execArgv
if execArg.match 'harmony'
return 1
return 0

if generatorsAreAvailable()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# ensure that these tests are only run if generators are available
generatorsAreAvailable = ->
  for execArg in process.execArgv when execArg is '--harmony'
    return yes
  no

return unless generatorsAreAvailable()

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, please do not use top level returns. While node accepts it, it is invalid JavaScript and static analysis tools will reject it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I was mostly concerned with the 1 and 0 :)


# Using the keyword yield should not cause a syntax error.
-> yield 0

test "Generator Definition", ->
x = ->
yield 0
yield 1
yield 2
y = x()
z = y.next()
eq z.value, 0
eq z.done, false
z = y.next()
eq z.value, 1
eq z.done, false
z = y.next()
eq z.value, 2
eq z.done, false
z = y.next()
eq z.value, undefined
eq z.done, true
2 changes: 1 addition & 1 deletion test/strict.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ test "`Future Reserved Word`s, `eval` and `arguments` restrictions", ->
tryCatch = (keyword, check = strict) ->
check "try new Error catch #{keyword}"

future = 'implements interface let package private protected public static yield'.split ' '
future = 'implements interface let package private protected public static'.split ' '
for keyword in future
access keyword
assign keyword
Expand Down