Skip to content

Commit

Permalink
fixes #286: support stepped loops
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelficarra committed Mar 22, 2014
1 parent 193ff69 commit 5272d3c
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 14 deletions.
20 changes: 11 additions & 9 deletions lib/compiler.js

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

16 changes: 11 additions & 5 deletions src/compiler.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -445,19 +445,25 @@ class exports.Compiler
block = forceBlock body
block.body.push stmt helpers.undef() unless block.body.length

increment =
if @step? and not ((@step.instanceof CS.Int) and @step.data is 1)
(x) -> new JS.AssignmentExpression '+=', x, step
else
(x) -> new JS.UpdateExpression '++', yes, x

# optimise loops over static, integral ranges
if (@target.instanceof CS.Range) and
# TODO: extract this test to some "static, integral range" helper
((@target.left.instanceof CS.Int) or ((@target.left.instanceof CS.UnaryNegateOp) and @target.left.expression.instanceof CS.Int)) and
((@target.right.instanceof CS.Int) or ((@target.right.instanceof CS.UnaryNegateOp) and @target.right.expression.instanceof CS.Int))
varDeclaration = new JS.AssignmentExpression '=', i, compile @target.left
update = new JS.UpdateExpression '++', yes, i
varDeclaration = new JS.VariableDeclaration 'var', [new JS.VariableDeclarator i, compile @target.left]
update = increment i
if @filter?
block.body.unshift stmt new JS.IfStatement (new JS.UnaryExpression '!', filter), new JS.ContinueStatement
if keyAssignee?
k = genSym 'k'
varDeclaration = new JS.SequenceExpression [(new JS.AssignmentExpression '=', k, new JS.Literal 0), varDeclaration]
update = new JS.SequenceExpression [(new JS.UpdateExpression '++', yes, k), update]
varDeclaration.declarations.unshift new JS.VariableDeclarator k, new JS.Literal 0
update = new JS.SequenceExpression [(increment k), update]
block.body.unshift stmt new JS.AssignmentExpression '=', keyAssignee, k
if valAssignee?
block.body.unshift stmt new JS.AssignmentExpression '=', valAssignee, i
Expand All @@ -478,7 +484,7 @@ class exports.Compiler
block.body.unshift stmt assignment keyAssignee, i
if valAssignee?
block.body.unshift stmt assignment valAssignee, new JS.MemberExpression yes, e, i
new JS.ForStatement varDeclaration, (new JS.BinaryExpression '<', i, length), (new JS.UpdateExpression '++', yes, i), block
new JS.ForStatement varDeclaration, (new JS.BinaryExpression '<', i, length), (increment i), block
]
[CS.ForOf, ({keyAssignee, valAssignee, target, filter, body}) ->
block = forceBlock body
Expand Down
9 changes: 9 additions & 0 deletions test/comprehensions.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,12 @@ suite 'Comprehensions', ->
test 'comprehension over range with index', ->
arrayEq [0..3], (k for v, k in [5..8])
arrayEq [5..8], (v for v, k in [5..8])

test '#286: stepped loops', ->
list = [1..7]
arrayEq [1, 4, 7], (v for v in list by 3)
arrayEq [1, 4, 7], (v for v in [1..7] by 3)
arrayEq [0, 3, 6], (k for v, k in list by 3)
arrayEq [0, 3, 6], (k for v, k in [1..7] by 3)
arrayEq [0, 0, 0], (0 for in list by 3)
arrayEq [0, 0, 0], (0 for in [1..7] by 3)

0 comments on commit 5272d3c

Please sign in to comment.