I’m writing a macro that walks the expression tree of a function definition, and would like to know if certain variables are local or global, e.g. if it saw
@mymacro function foo()
x = 1
return x + y
end
it needs to know that x is a local variable while y is a global one. The information seems like its all there in the expression, so this should be fair game for a macro. However, I’m not sure if scoping happens further down the compile chain after macro expansion, such that there’s no easy / automatic way to do this. Any ideas?
No, because you can’t judge purely from the expression the macro captures whether a corresponding binding in the outer expression (where the macro is contained) exists. At best you can say if a global lookup may be necessary (the variable is read from before written to), but you can’t tell whether that will succeed or throw an UndefVarError.
Scoping happens after AST transforms like macros, which is why you have to apply macro hygiene with esc in the first place.
Indeed, that’s all I need, I don’t need to know if it exists (which can only be known at runtime). I think its the exact thing that @code_lowered is doing:
julia> @code_lowered foo()
CodeInfo(
1 ─ x = 1
│ %2 = x + Main.y
└── return %2
)