starting on mom to risc
some docs too
This commit is contained in:
@ -34,6 +34,12 @@ module Mom
|
||||
@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 )
|
||||
|
@ -37,49 +37,26 @@ module Mom
|
||||
self
|
||||
end
|
||||
|
||||
# Translate code to whatever cpu is specified.
|
||||
# Currently only :arm and :interpret
|
||||
#
|
||||
# Translating means translating the initial jump
|
||||
# and then translating all methods
|
||||
def translate( platform_sym )
|
||||
platform_sym = platform_sym.to_s.capitalize
|
||||
platform = Risc::Platform.for(platform_sym)
|
||||
assemblers = translate_methods( platform.translator )
|
||||
Risc::Linker.new(platform , assemblers , constants)
|
||||
def to_risc( )
|
||||
riscs = []
|
||||
# to_risc all compilers
|
||||
# for each suffling constnts and fist label, then all instructions (see below)
|
||||
# then create risc collection
|
||||
Risc::RiscCollection.new(riscs)
|
||||
end
|
||||
|
||||
# go through all methods and translate them to cpu, given the translator
|
||||
def translate_methods(translator)
|
||||
compilers.collect do |compiler|
|
||||
#log.debug "Translate method #{compiler.method.name}"
|
||||
translate_method(compiler , translator)
|
||||
end.flatten
|
||||
end
|
||||
|
||||
# translate one method, which means the method itself and all blocks inside it
|
||||
# returns an array of assemblers
|
||||
def translate_method( method_compiler , translator)
|
||||
all = []
|
||||
all << translate_cpu( method_compiler , translator )
|
||||
method_compiler.block_compilers.each do |block_compiler|
|
||||
all << translate_cpu(block_compiler , translator)
|
||||
# convert the given mom instruction to_risc and then add it (see add_code)
|
||||
# continue down the instruction chain unti depleted
|
||||
# (adding moves the insertion point so the whole mom chain is added as a risc chain)
|
||||
def add_mom( instruction )
|
||||
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( self )
|
||||
reset_regs
|
||||
#puts "adding risc #{risc.to_s}:#{risc.next.to_s}"
|
||||
instruction = instruction.next
|
||||
end
|
||||
all
|
||||
end
|
||||
|
||||
# compile the callable (method or block) to cpu
|
||||
# return an Assembler that will then translate to binary
|
||||
def translate_cpu(compiler , translator)
|
||||
risc = compiler.risc_instructions
|
||||
cpu_instructions = risc.to_cpu(translator)
|
||||
nekst = risc.next
|
||||
while(nekst)
|
||||
cpu = nekst.to_cpu(translator) # returning nil means no replace
|
||||
cpu_instructions << cpu if cpu
|
||||
nekst = nekst.next
|
||||
end
|
||||
Risc::Assembler.new(compiler.callable , cpu_instructions )
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,90 +0,0 @@
|
||||
module Mom
|
||||
# The Compiler for the Mom level is a collection of Risc level Method compilers,
|
||||
# plus functions to translate from the risc to cpu specific code.
|
||||
#
|
||||
# Builtin functions are created here, lazily, when translate is called.
|
||||
# Instantiating builtin functions results in a MethodCompiler for that function, and
|
||||
# to avoid confusion, these should be instantiated only once.
|
||||
#
|
||||
# As RubyCompiler pools source at the vool level, when several classes are compiled
|
||||
# from vool to mom, several MomCompilers get instantiated. They must be merged before
|
||||
# proceeding with translate. Thus we have a append method.
|
||||
#
|
||||
class MomCompiler
|
||||
attr_reader :method_compilers
|
||||
|
||||
# Initialize with an array of risc MethodCompilers
|
||||
def initialize(compilers = [])
|
||||
@method_compilers = compilers
|
||||
end
|
||||
|
||||
# lazily instantiate the compilers for boot functions
|
||||
# (in the hope of only booting the functions once)
|
||||
def boot_compilers
|
||||
@boot_compilers ||= Risc::Builtin.boot_functions
|
||||
end
|
||||
|
||||
# Return all compilers, namely the MethodCompilers passed in, plus the
|
||||
# boot_function's compilers (boot_compilers)
|
||||
def compilers
|
||||
@method_compilers + boot_compilers
|
||||
end
|
||||
|
||||
# collects constants from all compilers into one array
|
||||
def constants
|
||||
compilers.inject([]){|sum ,comp| sum + comp.constants }
|
||||
end
|
||||
|
||||
# Append another MomCompilers method_compilers to this one.
|
||||
def append(mom_compiler)
|
||||
@method_compilers += mom_compiler.method_compilers
|
||||
self
|
||||
end
|
||||
|
||||
# Translate code to whatever cpu is specified.
|
||||
# Currently only :arm and :interpret
|
||||
#
|
||||
# Translating means translating the initial jump
|
||||
# and then translating all methods
|
||||
def translate( platform_sym )
|
||||
platform_sym = platform_sym.to_s.capitalize
|
||||
platform = Risc::Platform.for(platform_sym)
|
||||
assemblers = translate_methods( platform.translator )
|
||||
Risc::Linker.new(platform , assemblers , constants)
|
||||
end
|
||||
|
||||
# go through all methods and translate them to cpu, given the translator
|
||||
def translate_methods(translator)
|
||||
compilers.collect do |compiler|
|
||||
#log.debug "Translate method #{compiler.method.name}"
|
||||
translate_method(compiler , translator)
|
||||
end.flatten
|
||||
end
|
||||
|
||||
# translate one method, which means the method itself and all blocks inside it
|
||||
# returns an array of assemblers
|
||||
def translate_method( method_compiler , translator)
|
||||
all = []
|
||||
all << translate_cpu( method_compiler , translator )
|
||||
method_compiler.block_compilers.each do |block_compiler|
|
||||
all << translate_cpu(block_compiler , translator)
|
||||
end
|
||||
all
|
||||
end
|
||||
|
||||
# compile the callable (method or block) to cpu
|
||||
# return an Assembler that will then translate to binary
|
||||
def translate_cpu(compiler , translator)
|
||||
risc = compiler.risc_instructions
|
||||
cpu_instructions = risc.to_cpu(translator)
|
||||
nekst = risc.next
|
||||
while(nekst)
|
||||
cpu = nekst.to_cpu(translator) # returning nil means no replace
|
||||
cpu_instructions << cpu if cpu
|
||||
nekst = nekst.next
|
||||
end
|
||||
Risc::Assembler.new(compiler.callable , cpu_instructions )
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user