add seperate builders

remove if with polymorphism for different builders
(easier to understand by naming)
This commit is contained in:
Torsten Ruger
2018-06-29 13:27:57 +03:00
parent 3dffebed3f
commit 86b1edb40c
8 changed files with 73 additions and 37 deletions

View File

@ -2,9 +2,15 @@ module Risc
# A Builder is used to generate code, either by using it's api, or dsl
#
# The code that is generated can be added to the comiled method, ie to the compiler.
# There are two subclasses of Builder, depending of what one wants to do with the
# generated code.
#
# CompilerBuilder: The code is added to the method_compiler.
# This is used to generate the builtin methods.
# Or the code can be stored up and returned. This is used in Mom::to_risc methods
#
# CodeBuilder: The code can be stored up and returned.
# This is used in Mom::to_risc methods
#
class Builder
attr_reader :built , :compiler
@ -12,10 +18,8 @@ module Risc
# pass a compiler, to which instruction are added (usually)
# second arg determines weather instructions are added (default true)
# call build with a block to build
def initialize(compiler, auto_add , for_source)
def initialize(compiler, for_source)
@compiler = compiler
@auto_add = auto_add
@built = nil
@source = for_source
@source_used = false
@names = {}
@ -60,6 +64,7 @@ module Risc
# names (that ruby would resolve to a variable/method) are converted
# to registers. << means assignment and [] is supported both on
# L and R values (but only one at a time). R values may also be constants.
#
# Basically this allows to create LoadConstant, RegToSlot, SlotToReg and
# Transfer instructions with extremely readable code.
# example:
@ -68,21 +73,14 @@ module Risc
#
# build result is available as built, but also gets added to compiler, if the
# builder is created with default args
#
def build(&block)
instance_eval(&block)
@built
end
# adding code to the builder either stores it in the built variable
# or adds it straight to the compiler.
# Depending on wether auto_add was given in construction.
def add_code(ins)
return @compiler.add_code(ins) if @auto_add
if(@built)
@built << ins
else
@built = ins
end
raise "Must be implemented in subclass #{self}"
end
# move a machine int from register "from" to a Parfait::Integer in register "to"
@ -213,5 +211,38 @@ module Risc
return index
end
class CodeBuilder < Builder
attr_reader :built
def initialize(compiler, for_source)
super
@built = nil
end
def build(&block)
super
@built
end
# CodeBuilder stores the code.
# The code can be access through the @built instance, and is returned
# from build method
def add_code(ins)
if(@built)
@built << ins
else
@built = ins
end
end
end
# A CompilerBuilder adds the generated code to the MethodCompiler.
#
class CompilerBuilder < Builder
# add code straight to the compiler
def add_code(ins)
return @compiler.add_code(ins)
end
end
end