2019-08-06 17:33:27 +02:00
|
|
|
module Mom
|
|
|
|
|
|
|
|
# A BlockCompiler is much like a MehtodCompiler, exept for blocks
|
|
|
|
#
|
|
|
|
class BlockCompiler < CallableCompiler
|
|
|
|
|
2019-08-13 18:32:17 +02:00
|
|
|
attr_reader :block , :mom_instructions
|
2019-08-06 17:33:27 +02:00
|
|
|
alias :block :callable
|
|
|
|
|
|
|
|
def initialize( block , method)
|
|
|
|
@method = method
|
|
|
|
super(block)
|
|
|
|
end
|
|
|
|
|
|
|
|
def source_name
|
|
|
|
"#{@method.self_type.name}.init"
|
|
|
|
end
|
|
|
|
|
2019-08-13 18:32:17 +02:00
|
|
|
def to_risc(in_method)
|
|
|
|
risc_compiler = Risc::BlockCompiler.new(@callable , in_method , mom_instructions)
|
|
|
|
instructions_to_risc(risc_compiler)
|
|
|
|
#recursive blocks not done
|
|
|
|
risc_compiler
|
|
|
|
end
|
|
|
|
|
2019-08-06 17:33:27 +02:00
|
|
|
# determine how given name need to be accsessed.
|
|
|
|
# For blocks the options are args or frame
|
|
|
|
# or then the methods arg or frame
|
|
|
|
def slot_type_for(name)
|
2019-08-22 21:56:44 +02:00
|
|
|
if index = @callable.arguments_type.variable_index(name)
|
2019-08-23 09:23:01 +02:00
|
|
|
slot_def = ["arg#{index}".to_sym]
|
|
|
|
elsif index = @callable.frame_type.variable_index(name)
|
|
|
|
slot_def = ["local#{index}".to_sym]
|
2019-08-22 21:56:44 +02:00
|
|
|
elsif index = @method.arguments_type.variable_index(name)
|
2019-08-23 09:23:01 +02:00
|
|
|
slot_def = [:caller , :caller , "arg#{index}".to_sym]
|
|
|
|
elsif index = @method.frame_type.variable_index(name)
|
|
|
|
slot_def = [:caller ,:caller , "local#{index}".to_sym ]
|
2019-08-06 17:33:27 +02:00
|
|
|
elsif
|
|
|
|
raise "no variable #{name} , need to resolve at runtime"
|
|
|
|
end
|
2019-08-23 09:23:01 +02:00
|
|
|
return slot_def
|
2019-08-06 17:33:27 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
end
|
|
|
|
end
|