On Mon, Mar 21, 2016 at 5:54 PM, <[email protected]> wrote:
> Oops, maybe name it differently
>
> function expand(ex::Expr)
> if ex.head == :module
> Expr(:module, ex.args[1], ex.args[2], macroexpand(ex.args[3]))
> else
> macroexpand(ex)
> end
> end
>
FYI, expand is another base function.
>
> So if someone were to give me:
>
>
> module M
>
> include("X.jl")
> import X: @y, @z
>
> f(x) = X.@y(3)
>
> end
>
> I would then...
>
> eval(:(module M
> include("X.jl")
> import X: @y, @z
>
> f(x) = X.@y(3)
>
> end)
>
> expand(:(module M ... end))
>
> ?
> Sorry, not sure how this contextual evaluating/expanding would look like.
> It's not clear to me how evaluating the module M will make relevant
> definitions accessible to the expand function, since that ignores the fact
> that I'm inside module M when expanding each form.
>
As I said, you need to manually go through each of the statement in
the module, macro expand and evaluate them.
Try this:
```
julia> function expand_module(ex::Expr)
@assert ex.head === :module
std_imports = ex.args[1]::Bool
name = ex.args[2]::Symbol
body = ex.args[3]::Expr
mod = Module(name, std_imports)
newbody = quote end
modex = Expr(:module, std_imports, name, newbody)
for subex in body.args
expandf = ()->macroexpand(subex)
subex = eval(mod, :($expandf()))
push!(newbody.args, subex)
eval(mod, subex)
end
modex, mod
end
expand_module (generic function with 1 method)
julia> expand_module(:(module A
macro X()
1
end
b = 1 + @X
@show b
end))
b = 2
(:(module A
eval(x) = begin # none, line 1:
top(Core).eval(A,x)
end
eval(m,x) = begin # none, line 1:
top(Core).eval(m,x)
end # none, line 2:
$(Expr(:macro, :(X()), quote # none, line 3:
1
end)) # none, line 5:
b = 1 + 1 # none, line 6:
begin
Base.println("b = ",Base.repr(begin # show.jl, line 166:
#2#value = b
end))
#2#value
end
end),A)
```
>
>