Torsten Rüger
dced6b12e6
the "old" way of generating compilers is now obsolete we can use ruby code with mom macros to achieve the same Three step wip remove old builtin fix tests (including adding necessary methods) fixup and inclusion of builtin code to parfait
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}"
|
|
risc_compiler.reset_regs
|
|
instruction.to_risc( risc_compiler )
|
|
#puts "adding risc #{risc.to_s}:#{risc.next.to_s}"
|
|
instruction = instruction.next
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|