Torsten Rüger
213938075f
apart from things involving builtn, which is not yet conceptually solved (as it codes risc, not mom)
83 lines
2.7 KiB
Ruby
83 lines
2.7 KiB
Ruby
module Risc
|
|
# The Collection for the Risc level is a collection of Risc level Method compilers,
|
|
# plus functions to translate from the risc to cpu specific code.
|
|
#
|
|
class RiscCollection
|
|
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
|