2019-08-08 11:19:27 +02:00
|
|
|
module Risc
|
|
|
|
# The Collection for the Risc level is a collection of Risc level Method compilers,
|
2018-11-02 23:54:30 +01:00
|
|
|
# plus functions to translate from the risc to cpu specific code.
|
|
|
|
#
|
2019-08-08 11:19:27 +02:00
|
|
|
class RiscCollection
|
2018-07-02 14:50:54 +02:00
|
|
|
attr_reader :method_compilers
|
2018-06-30 18:20:17 +02:00
|
|
|
|
2018-11-02 23:54:30 +01:00
|
|
|
# Initialize with an array of risc MethodCompilers
|
2018-07-01 20:26:45 +02:00
|
|
|
def initialize(compilers = [])
|
2019-09-28 14:07:20 +02:00
|
|
|
@method_compilers = nil
|
|
|
|
compilers.each{|c| add_compiler(c)}
|
2018-11-02 23:54:30 +01:00
|
|
|
end
|
|
|
|
|
2018-07-03 09:12:22 +02:00
|
|
|
# collects constants from all compilers into one array
|
|
|
|
def constants
|
2019-09-28 14:07:20 +02:00
|
|
|
all = []
|
|
|
|
method_compilers.each_compiler{|comp| all += comp.constants }
|
|
|
|
all
|
2018-11-02 23:54:30 +01:00
|
|
|
end
|
|
|
|
|
2019-09-28 14:07:20 +02:00
|
|
|
def append(collection)
|
|
|
|
@method_compilers.add_method_compiler( collection.method_compilers)
|
|
|
|
self
|
|
|
|
end
|
|
|
|
|
|
|
|
def add_compiler(compiler)
|
|
|
|
if(@method_compilers)
|
|
|
|
@method_compilers.add_method_compiler(compiler)
|
|
|
|
else
|
|
|
|
@method_compilers = compiler
|
|
|
|
end
|
2018-11-02 23:54:30 +01:00
|
|
|
self
|
2018-07-03 09:12:22 +02:00
|
|
|
end
|
|
|
|
|
2018-06-30 21:53:32 +02:00
|
|
|
# Translate code to whatever cpu is specified.
|
|
|
|
# Currently only :arm and :interpret
|
|
|
|
#
|
|
|
|
# Translating means translating the initial jump
|
|
|
|
# and then translating all methods
|
2018-07-01 10:56:09 +02:00
|
|
|
def translate( platform_sym )
|
|
|
|
platform_sym = platform_sym.to_s.capitalize
|
|
|
|
platform = Risc::Platform.for(platform_sym)
|
2018-07-01 20:51:48 +02:00
|
|
|
assemblers = translate_methods( platform.translator )
|
2018-07-03 09:12:22 +02:00
|
|
|
Risc::Linker.new(platform , assemblers , constants)
|
2018-06-30 21:53:32 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
# go through all methods and translate them to cpu, given the translator
|
|
|
|
def translate_methods(translator)
|
2019-09-28 14:07:20 +02:00
|
|
|
collection = []
|
|
|
|
method_compilers.each_compiler do |compiler|
|
2019-09-07 16:56:06 +02:00
|
|
|
#puts "Translate method #{compiler.callable.name}"
|
2019-09-28 14:07:20 +02:00
|
|
|
translate_method(compiler , translator , collection)
|
|
|
|
end
|
|
|
|
collection
|
2018-07-30 09:27:32 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
# translate one method, which means the method itself and all blocks inside it
|
|
|
|
# returns an array of assemblers
|
2019-09-28 14:07:20 +02:00
|
|
|
def translate_method( method_compiler , translator , collection)
|
|
|
|
collection << translate_cpu( method_compiler , translator )
|
2018-07-30 09:27:32 +02:00
|
|
|
method_compiler.block_compilers.each do |block_compiler|
|
2019-09-28 14:07:20 +02:00
|
|
|
collection << translate_cpu(block_compiler , translator)
|
2018-06-30 21:53:32 +02:00
|
|
|
end
|
2019-09-28 14:07:20 +02:00
|
|
|
collection
|
2018-06-30 21:53:32 +02:00
|
|
|
end
|
2018-07-01 10:56:09 +02:00
|
|
|
|
2018-07-30 09:27:32 +02:00
|
|
|
# compile the callable (method or block) to cpu
|
|
|
|
# return an Assembler that will then translate to binary
|
2018-07-01 10:56:09 +02:00
|
|
|
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
|
2018-07-30 13:10:24 +02:00
|
|
|
Risc::Assembler.new(compiler.callable , cpu_instructions )
|
2018-07-01 10:56:09 +02:00
|
|
|
end
|
|
|
|
|
2018-06-30 18:20:17 +02:00
|
|
|
end
|
|
|
|
end
|