rubyx/lib/rubyx/rubyx_compiler.rb
Torsten Rüger d1f8733623 Rename Vool to Sol
Simple is really the descriptive name for the layer
Sure, it is "virtual" but that is not as important as the fact that it is simple (or simplified)
Also objct (based really) is better, since orientated implies it is a little like that, but only orientated, not really it. Sol only has objects, nothing else
Just cause i was renaming anyway
2019-10-04 00:38:47 +03:00

141 lines
4.4 KiB
Ruby

module RubyX
# The RubyXCompiler provides the main interface to create binaries, and also
# give helper functions to create any intermediate layer.
# Layers are:
# - ruby , always needed as input, string
# - sol - intermediate language layer
# - slot_machine - intermediate machine layer
# - risc - "last" intermediate machine layer
# - target - arm or interpreter binary code
# - binary - "linked" code, everything need to create an elf binary
#
#
# There are methods to go from ruby to any of the layers in the system
# (mainly for testing). ruby_to_binary creates actual binary code
# for a given platform.
# The compiler keeps the sol source as an instance.
# To compile several sources, more sol can be added, ie ruby_to_sol
# can be called several times.
#
# All other methods come in pairs, one takes ruby source (those are for testing)
# and the other uses the stored sol source for further processing.
#
# Only builtin is loaded, so no runtime , but the compiler
# can be used to read the runtime and then any other code
#
class RubyXCompiler
attr_reader :sol , :options
# initialize boots Parfait and Risc (ie load Builin)
def initialize(options)
@options = options
Parfait.boot!(options[:parfait] || {})
Risc.boot!(options[:risc] || {})
end
# The highest level function creates binary code for the given ruby code
# for the given platform (see Platform). Binary code means that sol/slot_machine/risc
# are created and then assembled into BinaryCode objects.
# (no executable is generated, only the binary code and objects needed for a binary)
#
# A Linker is returned that may be used to create an elf binay
#
# The compiling is done by to_binary
def ruby_to_binary(ruby , platform)
ruby_to_sol(ruby)
to_binary(platform)
end
# ruby_to_target creates Target instructions (but does not link)
#
# After creating sol, we call to_target
# Return a Linker
def ruby_to_target(ruby , platform)
ruby_to_sol(ruby)
to_target( platform )
end
# ruby_to_risc creates Risc instructions
#
# After creating sol, we call to_risc
# Return a RiscCollection
def ruby_to_risc(ruby)
ruby_to_sol(ruby)
to_risc()
end
# Transform the incoming ruby source (string) to slot
#
# The sol is stored using ruby_to_sol,the to_slot is called
# Return SlotMachine Statement
def ruby_to_slot(ruby)
ruby_to_sol(ruby)
to_slot
end
# Process previously stored sol source to binary.
# Binary code is generated by calling to_risc, then positioning and calling
# create_binary on the linker. The linker may then be used to creat a binary file.
# The biary the method name refers to is binary code in memory, or in BinaryCode
# objects to be precise.
def to_binary(platform)
linker = to_target(platform)
linker.position_all
linker.create_binary
linker
end
# transform stored sol to target code
# return a linker
def to_target(platform)
raise "No platform given" unless platform
collection = to_risc
collection.translate(platform)
end
# Process previously stored sol source to risc.
# return a Risc::RiscCollection , a collection of MethodCompilers
def to_risc()
slot = to_slot
slot.to_risc()
end
# return slot_machine for the previously stored sol source.
def to_slot
@sol.to_parfait
@sol.to_slot(nil)
end
# ruby_to_sol compiles the ruby to ast, and then to sol
def ruby_to_sol(ruby_source)
ruby_tree = Ruby::RubyCompiler.compile( ruby_source )
unless(@sol)
@sol = ruby_tree.to_sol
return @sol
end
# TODO: should check if this works with reopening classes
# or whether we need to unify the sol for a class
unless(@sol.is_a?(Sol::ScopeStatement))
@sol = Sol::ScopeStatement.new([@sol])
end
@sol << ruby_tree.to_sol
end
def load_parfait
parfait = ["object"]
parfait.each do |file|
path = File.expand_path("../../parfait/#{file}.rb",__FILE__)
ruby_to_sol(File.read(path))
end
end
def self.ruby_to_binary( ruby , options)
compiler = RubyXCompiler.new(options)
compiler.load_parfait if options[:load_parfait]
compiler.ruby_to_sol(ruby)
compiler.to_binary(options[:platform])
end
end
end