rubyx/lib/mom/callable_compiler.rb
Torsten Rüger dced6b12e6 removing builtin as a concept (wip)
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
2019-09-12 13:09:30 +03:00

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