-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Add a for .. from ..
loop for generators, see #3832
#4306
Changes from 1 commit
4caa6b7
68f22b0
07da7ad
5361fbf
ab10937
486ab5f
34e83c6
e759662
2267019
813e107
f279fcf
a4531b0
4be5a4d
00fee49
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2095,13 +2095,15 @@ exports.For = class For extends While | |
@body = Block.wrap [body] | ||
@own = !!source.own | ||
@object = !!source.object | ||
[@name, @index] = [@index, @name] if @object | ||
@from = !!source.from | ||
[@name, @index] = [@index, @name] if @object or @from | ||
@index.error 'index cannot be a pattern matching expression' if @index instanceof Value | ||
@range = @source instanceof Value and @source.base instanceof Range and not @source.properties.length | ||
@pattern = @name instanceof Value | ||
@index.error 'indexes do not apply to range loops' if @range and @index | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this can be an issue:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, I've made |
||
@name.error 'cannot pattern match over range loops' if @range and @pattern | ||
@name.error 'cannot use own with for-in' if @own and not @object | ||
@name.error 'cannot use index with for-from' if @from and @name | ||
@returns = false | ||
|
||
children: ['body', 'source', 'guard', 'step'] | ||
|
@@ -2121,7 +2123,7 @@ exports.For = class For extends While | |
scope.find(name) if name and not @pattern | ||
scope.find(index) if index | ||
rvar = scope.freeVariable 'results' if @returns | ||
ivar = (@object and index) or scope.freeVariable 'i', single: true | ||
ivar = ((@object or @from) and index) or scope.freeVariable 'i', single: true | ||
kvar = (@range and name) or index or ivar | ||
kvarAssign = if kvar isnt ivar then "#{kvar} = " else "" | ||
if @step and not @range | ||
|
@@ -2142,7 +2144,7 @@ exports.For = class For extends While | |
svar = ref | ||
if name and not @pattern | ||
namePart = "#{name} = #{svar}[#{kvar}]" | ||
if not @object | ||
if not (@object or @from) | ||
defPart += "#{@tab}#{step};\n" if step isnt stepVar | ||
down = stepNum < 0 | ||
lvar = scope.freeVariable 'len' unless @step and stepNum? and down | ||
|
@@ -2178,6 +2180,9 @@ exports.For = class For extends While | |
if @object | ||
forPartFragments = [@makeCode("#{kvar} in #{svar}")] | ||
guardPart = "\n#{idt1}if (!#{utility 'hasProp', o}.call(#{svar}, #{kvar})) continue;" if @own | ||
if @from | ||
forPartFragments = [@makeCode("#{kvar} of #{svar}")] | ||
guardPart = "\n" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean the guardPart? Yeah, I'll delete that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||
bodyFragments = body.compileToFragments merge(o, indent: idt1), LEVEL_TOP | ||
if bodyFragments and (bodyFragments.length > 0) | ||
bodyFragments = [].concat @makeCode("\n"), bodyFragments, @makeCode("\n") | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -123,3 +123,10 @@ test "#3001: `own` shouldn't be allowed in a `for`-`in` loop", -> | |
|
||
test "#2994: single-line `if` requires `then`", -> | ||
cantCompile "if b else x" | ||
|
||
test "indexes are not supported in for-from loops", -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put these tests in |
||
cantCompile "x for x, i from [1, 2, 3]" | ||
|
||
test "own is not supported in for-from loops", -> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should also go in |
||
cantCompile "x for own x from [1, 2, 3]" | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add
FROM
toRELATIONS
instead (~L939)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from
is not really a relation likein
,of
orinstanceof
. It can't be used as an infix operator. You can do(x in y)
and(x of y)
but not(x from y)
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough. It's still a bit weird to have this part disjointed from the others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well
in
andof
are reserved keywords, whereasfrom
is a context-sensitive identifier. So the lexer can't handle them all in the same way.I've merged the
if tag is 'IDENTIFIER'
conditionals into one, maybe that helps it look cleaner.