Skip to content

Instantly share code, notes, and snippets.

@mschauer
Last active October 27, 2018 09:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mschauer/9265bd5b70c9abf1391d4ef541d53eca to your computer and use it in GitHub Desktop.
Save mschauer/9265bd5b70c9abf1391d4ef541d53eca to your computer and use it in GitHub Desktop.
Unroll1
"""
@unroll1 for-loop
Unroll the first iteration of a `for`-loop.
Set `$first` to true in the first iteration.
Example:
```
@unroll1 for i in 1:10
if $first
a, state = iterate('A':'Z')
else
a, state = iterate('A':'Z', state)
end
println(i => a)
end
```
"""
macro unroll1(expr)
@assert expr isa Expr
@assert expr.head == :for
iterspec = expr.args[1]
@assert iterspec isa Expr
@assert iterspec.head == :(=)
i = iterspec.args[1]
iter = iterspec.args[2]
body = expr.args[2]
body_1 = eval(Expr(:let, :(first = true), Expr(:quote, body)))
body_i = eval(Expr(:let, :(first = false), Expr(:quote, body)))
quote
local st, $i
@goto enter
while true
@goto exit
@label enter
ϕ = iterate($iter)
ϕ === nothing && break
$i, st = ϕ
$(body_1)
@label exit
while true
ϕ = iterate($iter, st)
ϕ === nothing && break
$i, st = ϕ
$(body_i)
end
break
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment