Torsten Rüger
15d1c07a1c
some copy paste in creating full mom layer left dome unused (untested) code thanks to code climate stats
76 lines
2.5 KiB
Ruby
76 lines
2.5 KiB
Ruby
module Mom
|
|
|
|
# CallableCompiler is used to generate mom instructions. It is an abstact base
|
|
# class shared by BlockCompiler and MethodCompiler
|
|
|
|
# - mom_instructions: The sequence of mom level instructions that mom was compiled to
|
|
# Instructions derive from class Instruction and form a linked list
|
|
|
|
class CallableCompiler
|
|
|
|
def initialize( callable )
|
|
@callable = callable
|
|
@constants = []
|
|
@block_compilers = []
|
|
@mom_instructions = Label.new(source_name, source_name)
|
|
@current = start = @mom_instructions
|
|
add_code Label.new( source_name, "return_label")
|
|
add_code Mom::ReturnSequence.new(source_name)
|
|
add_code Label.new( source_name, "unreachable")
|
|
@current = start
|
|
end
|
|
attr_reader :mom_instructions , :constants , :block_compilers , :callable , :current
|
|
|
|
def return_label
|
|
@mom_instructions.each do |ins|
|
|
next unless ins.is_a?(Label)
|
|
return ins if ins.name == "return_label"
|
|
end
|
|
end
|
|
|
|
# add a constant (which get created during compilation and need to be linked)
|
|
def add_constant(const)
|
|
raise "Must be Parfait #{const}" unless const.is_a?(Parfait::Object)
|
|
@constants << const
|
|
end
|
|
|
|
# translate to Risc, ie a Risc level CallableCompiler
|
|
# abstract functon that needs to be implemented by Method/BlockCompiler
|
|
def to_risc
|
|
raise "abstract in #{self.class}"
|
|
end
|
|
|
|
# add a risc instruction after the current (insertion point)
|
|
# the added instruction will become the new insertion point
|
|
def add_code( instruction )
|
|
raise "Not an instruction:#{instruction.to_s}:#{instruction.class.name}" unless instruction.is_a?(Mom::Instruction)
|
|
new_current = instruction.last #after insertion this point is lost
|
|
@current.insert(instruction) #insert after current
|
|
@current = new_current
|
|
self
|
|
end
|
|
|
|
# return the frame type, ie the blocks self_type
|
|
def receiver_type
|
|
@callable.self_type
|
|
end
|
|
|
|
private
|
|
|
|
# convert al instruction to risc
|
|
# method is called by Method/BlockCompiler from to_risc
|
|
def instructions_to_risc(risc_compiler)
|
|
instruction = mom_instructions.next
|
|
while( instruction )
|
|
raise "whats this a #{instruction}" unless instruction.is_a?(Mom::Instruction)
|
|
#puts "adding mom #{instruction.to_s}:#{instruction.next.to_s}"
|
|
instruction.to_risc( risc_compiler )
|
|
risc_compiler.reset_regs
|
|
#puts "adding risc #{risc.to_s}:#{risc.next.to_s}"
|
|
instruction = instruction.next
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|