Hi everyone! I am trying to understand the building pieces of JuliaLowering.jl. I am very new to compilers so I apologise in advance if my questions have very obvious answers.
I don’t understand the behaviour of Bindings
in the contexts created at each lowering step. Starting from this script I have a bunch of questions:
text = """
x::Int = 10
"""
in_mod = Module()
ex = parseall(JuliaLowering.SyntaxTree, text)
ctx1, ex_macroexpand = JuliaLowering.expand_forms_1(in_mod, ex)
ctx2, ex_desugar = JuliaLowering.expand_forms_2(ctx1, ex_macroexpand)
ctx3, ex_scoped = JuliaLowering.resolve_scopes(ctx2, ex_desugar)
ctx4, ex_converted = JuliaLowering.convert_closures(ctx3, ex_scoped)
ctx5, ex_compiled = JuliaLowering.linearize_ir(ctx4, ex_converted)
-
Should I expect
ctx*
to have aBindingInfo
forx
? I thought yes, but there is none. Why is that? -
While there’s no binding for
x
, there is a binding for the return value (I think?),return_tmp
:JuliaLowering.BindingInfo(1, "return_tmp", :local, 26, nothing, nothing, 0, false, true, false, true, true, false, false)
. This only appears in thelinearize_ir
step, but it seems that the other contexts are modified as well after each pass (ctx1
doesn’t have that binding after runningexpand_forms_1
but it does have it after runninglinearize_ir
). What is the advantage of not having the contexts independent from each other? -
What is the (theoretical) difference between a lambda binding and a closure binding? My understanding is that lambda bindings are bindings for lambda functions parameters (
x = 2
is a lambda binding in the context of the functionx -> x + 3
being called with the argument2
), while closure bindings are bindings for variables captured by a closure (y = 1
is a closure binding in the context of the functionf(x) = x + y
withy
defined somewhere above and it has the value1
assigned to it). Is this correct? Does the concept of “binding” refer to a name → value association in a particular context, or does it describe something more complex? (For example, is the closure binding the association fromy
to1
in the context of the functionf(x) = x + y
withy = 1
, or is it the entire closure, or something different?) -
Could you maybe point me somewhere I can find some explanations as to how the syntax graph changes from pass to pass? It is quite difficult for me to see this from the source code and I also can’t seem to come up with clarifying examples.
For using the package I followed the instructions in the README.
julia> versioninfo()
Julia Version 1.12.0-DEV.631
Commit a4e793ee31* (2024-05-30 19:25 UTC)
Platform Info:
OS: macOS (arm64-apple-darwin24.3.0)
CPU: 8 × Apple M1
WORD_SIZE: 64
LLVM: libLLVM-17.0.6 (ORCJIT, apple-m1)
Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)