Skip to content

Commit

Permalink
Recurse rewrite_generic into :if and :block
Browse files Browse the repository at this point in the history
  • Loading branch information
odow committed Sep 23, 2024
1 parent bc97807 commit 65ab62c
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion src/rewrite_generic.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,54 @@ function _is_kwarg(expr, kwarg::Symbol)
return Meta.isexpr(expr, :kw) && expr.args[1] == kwarg
end

function _rewrite_elseif!(if_expr, expr::Any)
push!(if_expr.args, esc(expr))
return false

Check warning on line 60 in src/rewrite_generic.jl

View check run for this annotation

Codecov / codecov/patch

src/rewrite_generic.jl#L58-L60

Added lines #L58 - L60 were not covered by tests
end

function _rewrite_elseif!(if_expr, expr::Expr)
if Meta.isexpr(expr, :elseif)
new_ifelse_expr = Expr(:elseif, esc(expr.args[1]))
push!(if_expr.args, new_ifelse_expr)
@assert 2 <= length(expr.args) <= 3
return mapreduce(&, 2:length(expr.args)) do i
return _rewrite_elseif!(new_ifelse_expr, expr.args[i])

Check warning on line 69 in src/rewrite_generic.jl

View check run for this annotation

Codecov / codecov/patch

src/rewrite_generic.jl#L63-L69

Added lines #L63 - L69 were not covered by tests
end
else
stack = quote end
root, is_mutable = _rewrite_generic(stack, expr)
push!(stack.args, root)
push!(if_expr.args, stack)
return is_mutable

Check warning on line 76 in src/rewrite_generic.jl

View check run for this annotation

Codecov / codecov/patch

src/rewrite_generic.jl#L72-L76

Added lines #L72 - L76 were not covered by tests
end
end

"""
_rewrite_generic(stack::Expr, expr::Expr)
This method is the heart of the rewrite logic. It converts `expr` into a mutable
equivalent.
"""
function _rewrite_generic(stack::Expr, expr::Expr)
if !Meta.isexpr(expr, :call)
if Meta.isexpr(expr, :block)
root = nothing
for arg in expr.args
root, mutable = _rewrite_generic(stack, arg)
end
return root, false

Check warning on line 92 in src/rewrite_generic.jl

View check run for this annotation

Codecov / codecov/patch

src/rewrite_generic.jl#L88-L92

Added lines #L88 - L92 were not covered by tests
elseif Meta.isexpr(expr, :if)
# If blocks are special, because we can't lift the computation inside
# them into the stack; the values might be defined only if the branch is
# true.
if_expr = Expr(:if, esc(expr.args[1]))
@assert 2 <= length(expr.args) <= 3
is_mutable = mapreduce(&, 2:length(expr.args)) do i
return _rewrite_elseif!(if_expr, expr.args[i])

Check warning on line 100 in src/rewrite_generic.jl

View check run for this annotation

Codecov / codecov/patch

src/rewrite_generic.jl#L97-L100

Added lines #L97 - L100 were not covered by tests
end
root = gensym()
push!(stack.args, :($root = $if_expr))
return root, is_mutable

Check warning on line 104 in src/rewrite_generic.jl

View check run for this annotation

Codecov / codecov/patch

src/rewrite_generic.jl#L102-L104

Added lines #L102 - L104 were not covered by tests
elseif !Meta.isexpr(expr, :call)
# In situations like `x[i]`, we do not attempt to rewrite. Return `expr`
# and don't let future callers mutate.
return esc(expr), false
Expand Down

0 comments on commit 65ab62c

Please sign in to comment.