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

Broadcasting #4

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
27 changes: 19 additions & 8 deletions src/Hose.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,31 @@ export @hose

const PLACEHOLDER = :_

rewrite_apply(ff::Symbol, target) = :($ff($target)) # Function/macro application
function rewrite_apply(ff::Symbol, target, b::Bool = false)
if b
:(broadcast($ff,$target))
else
:($ff($target)) # Function/macro application
end
end

function rewrite_apply(ff::Expr, target)
function rewrite_apply(ff::Expr, target, b::Bool = false)
if ff.head == :call
insert!(ff.args, 2, target)
ff
elseif ff.head == :macrocall
insert!(ff.args, 3, target)
ff
elseif b
:(broadcast($ff,$target))
else
:($ff($target))
end
end

rewrite(ff::Symbol, target) = ifelse(ff == PLACEHOLDER, target,
rewrite_apply(ff, target))
rewrite(ff::Symbol, target, b::Bool = false) = ifelse(ff == PLACEHOLDER, target, rewrite_apply(ff, target, b))

function rewrite(ff::Expr, target)
function rewrite(ff::Expr, target, b::Bool = false)
replace(arg::Any) = arg # For most things should be an identity.
replace(arg::Symbol) = ifelse(arg == PLACEHOLDER, target, arg) # Placeholder symbol should get replaced.
function replace(arg::Expr)
Expand All @@ -38,16 +45,20 @@ function rewrite(ff::Expr, target)
ff.args = rep_args # Placeholder subsitution
ff
else # No subsitution was done (no placeholder symbol found)
rewrite_apply(ff, target) # Apply to a function/macro that is being returned by ff (ff could be a function call or something more complex).
rewrite_apply(ff, target, b) # Apply to a function/macro that is being returned by ff (ff could be a function call or something more complex).
end
end

funnel(ee::Any) = ee # Identity for first (left most) input.

function funnel(ee::Expr)
if (ee.args[1] == :|>) # If ee is a call to |>
if (ee.args[1] == :|> || ee.args[1] == :.|>) # If ee is a call to |>
target = funnel(ee.args[2]) # Process left hand side
rewrite(ee.args[3], target) # Rewrite |> right hand side using left hand side
if (ee.args[1] == :.|>)
rewrite(ee.args[3], target, true) # Rewrite |> right hand side using left hand side
else
rewrite(ee.args[3], target, false) # Rewrite |> right hand side using left hand side
end
else
ee # Not in a piping situtation
end
Expand Down
3 changes: 2 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ macroexpand(q) = macroexpand(Main, q)
@test macroexpand(:(@hose "foo"|>a)) == :(a("foo")) #Works with literal (string)
@test macroexpand( :(@hose a|>bb[2])) == :((bb[2])(a)) #Should work with RHS that is a array reference


# Test Problem
@test macroexpand( :(@hose a|>bb[2])) == :((bb[2])(a)) #Should work with RHS that is a array reference

#Marked locations
@test macroexpand( :(@hose a |> _)) == :(a) #Identity works
Expand Down