Consider this source file:
def method
a, b = 4, 5
"str"
end
a, b = 4, 5
puts method
The corresponding AST would have two MultiAssign
nodes, which should be expanded. Consider running this code through syntactic and semantic stages of the compiler:
require "compiler/crystal/**"
src = Crystal::Compiler::Source.new("filename", <<-CODE)
def method
a, b = 4, 5
"str"
end
a, b = 4, 5
puts method
CODE
compiler = Crystal::Compiler.new
compiler.no_codegen = true
compiler.no_cleanup = false
result = compiler.compile(src, "file_out")
puts result.node
It produces the following output:
<Stuff from prelude>
def method
a, b = 4, 5
"str"
end
__temp_305 = 4
__temp_306 = 5
a = __temp_305
b = __temp_306
puts(method)
I am sure method
is called. Also, since I used Crystal::Compiler#compile
and not Crystal::Compiler#top_level_semantic
, I would expect all Visitor
s and Transformer
s to run on the whole code.
Am I missing something that only happens at codegen stage? Or am I somehow getting an untransformed ASTNode
from Compiler#compile
?
What’s really confusing is that if I didn’t set compiler.no_codegen
to true
, the next operation it’d do is the code generation. It uses Crystal::CodeGenVisitor
, which has the following method:
def visit(node : ExpandableNode)
raise "BUG: #{node} at #{node.location} should have been expanded"
end
But this is not raised when compiling the initial source program normally. (MultiAssign
is a subclass of ExpandableNode
)