Ah, thank you! I didn't know you could do things like instantiate a module that way.
On Monday, March 21, 2016 at 3:21:45 PM UTC-7, Yichao Yu wrote: > > On Mon, Mar 21, 2016 at 5:54 PM, <[email protected] <javascript:>> > 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) > ``` > > > > > >
