On Mon, Mar 21, 2016 at 5:54 PM, <vish...@stanford.edu> 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) ``` > >