remove the code_builder
this is core of #11 rename compiler_builder to just builder and change all builder uses to use that some test change as code is not returned anymore
This commit is contained in:
parent
b294208025
commit
57dc6c45bb
@ -2,14 +2,7 @@ module Risc
|
||||
|
||||
# A Builder is used to generate code, either by using it's api, or dsl
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# CodeBuilder: The code can be stored up and returned.
|
||||
# This is used in Mom::to_risc methods
|
||||
# The code is added to the method_compiler.
|
||||
#
|
||||
class Builder
|
||||
|
||||
@ -19,6 +12,7 @@ module Risc
|
||||
# second arg determines weather instructions are added (default true)
|
||||
# call build with a block to build
|
||||
def initialize(compiler, for_source)
|
||||
raise "no compiler" unless compiler
|
||||
@compiler = compiler
|
||||
@source = for_source
|
||||
@source_used = false
|
||||
@ -119,16 +113,16 @@ module Risc
|
||||
# space << Parfait.object_space # load constant
|
||||
# message[:receiver] << space #make current message (r0) receiver the space
|
||||
#
|
||||
# build result is available as built, but also gets added to compiler, if the
|
||||
# builder is created with default args
|
||||
# build result is added to compiler directly
|
||||
#
|
||||
def build(&block)
|
||||
instance_eval(&block)
|
||||
@built
|
||||
end
|
||||
|
||||
# add code straight to the compiler
|
||||
def add_code(ins)
|
||||
raise "Must be implemented in subclass #{self}"
|
||||
@compiler.add_code(ins)
|
||||
return ins
|
||||
end
|
||||
|
||||
# move a machine int from register "from" to a Parfait::Integer in register "to"
|
||||
@ -146,39 +140,4 @@ module Risc
|
||||
end
|
||||
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
|
||||
|
@ -13,7 +13,7 @@ module Risc
|
||||
# return new int with result
|
||||
def div4(context)
|
||||
compiler = compiler_for(:Integer,:div4 ,{})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
compiler.builder(compiler.source).build do
|
||||
integer! << message[:receiver]
|
||||
integer.reduce_int
|
||||
integer_reg! << 2
|
||||
@ -50,7 +50,7 @@ module Risc
|
||||
# - return
|
||||
def comparison( operator )
|
||||
compiler = compiler_for(:Integer, operator ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder = compiler.builder(compiler.source)
|
||||
builder.build do
|
||||
integer! << message[:receiver]
|
||||
integer_reg! << message[:arguments]
|
||||
@ -87,7 +87,7 @@ module Risc
|
||||
# - returns the new int
|
||||
def operator_method( op_sym )
|
||||
compiler = compiler_for(:Integer, op_sym ,{other: :Integer})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder = compiler.builder(compiler.source)
|
||||
builder.build do
|
||||
integer! << message[:receiver]
|
||||
integer_reg! << message[:arguments]
|
||||
@ -113,7 +113,7 @@ module Risc
|
||||
def div10( context )
|
||||
s = "div_10 "
|
||||
compiler = compiler_for(:Integer,:div10 ,{})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder = compiler.builder(compiler.source)
|
||||
builder.build do
|
||||
integer_self! << message[:receiver]
|
||||
integer_self.reduce_int
|
||||
|
@ -8,7 +8,7 @@ module Risc
|
||||
# return is stored in return_value
|
||||
def get_internal_word( context )
|
||||
compiler = compiler_for(:Object , :get_internal_word ,{at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
compiler.builder(compiler.source).build do
|
||||
object! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
integer << integer[1]
|
||||
@ -24,7 +24,7 @@ module Risc
|
||||
# return the value passed in
|
||||
def set_internal_word( context )
|
||||
compiler = compiler_for(:Object , :set_internal_word , {at: :Integer, :value => :Object} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
compiler.builder(compiler.source).build do
|
||||
object! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
object_reg! << integer[ 2]
|
||||
@ -41,7 +41,7 @@ module Risc
|
||||
# Even if it's just this one, sys_exit (later raise)
|
||||
def _method_missing( context )
|
||||
compiler = compiler_for(:Object,:method_missing ,{})
|
||||
emit_syscall( compiler.compiler_builder(compiler.source) , :exit )
|
||||
emit_syscall( compiler.builder(compiler.source) , :exit )
|
||||
return compiler
|
||||
end
|
||||
|
||||
@ -54,7 +54,7 @@ module Risc
|
||||
def __init__( context )
|
||||
compiler = MethodCompiler.compiler_for_class(:Object,:__init__ ,
|
||||
Parfait::NamedList.type_for({}) , Parfait::NamedList.type_for({}))
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder = compiler.builder(compiler.source)
|
||||
builder.build do
|
||||
space! << Parfait.object_space
|
||||
message << space[:next_message]
|
||||
@ -98,7 +98,7 @@ module Risc
|
||||
# mainly calls exit_sequence
|
||||
def exit( context )
|
||||
compiler = compiler_for(:Object,:exit ,{})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder = compiler.builder(compiler.source)
|
||||
exit_sequence(builder)
|
||||
return compiler
|
||||
end
|
||||
|
@ -12,7 +12,7 @@ module Risc
|
||||
# - emit_syscall (which does the return of an integer, see there)
|
||||
def putstring( context)
|
||||
compiler = compiler_for(:Word , :putstring ,{})
|
||||
builder = compiler.compiler_builder(compiler.source)
|
||||
builder = compiler.builder(compiler.source)
|
||||
builder.build do
|
||||
word! << message[:receiver]
|
||||
integer! << word[Parfait::Word.get_length_index]
|
||||
@ -26,7 +26,7 @@ module Risc
|
||||
# return a word sized new int, in return_value
|
||||
def get_internal_byte( context)
|
||||
compiler = compiler_for(:Word , :get_internal_byte , {at: :Integer})
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
compiler.builder(compiler.source).build do
|
||||
object! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
integer << integer[1]
|
||||
@ -44,7 +44,7 @@ module Risc
|
||||
# return value
|
||||
def set_internal_byte( context )
|
||||
compiler = compiler_for(:Word, :set_internal_byte , {at: :Integer , :value => :Integer} )
|
||||
compiler.compiler_builder(compiler.source).build do
|
||||
compiler.builder(compiler.source).build do
|
||||
word! << message[:receiver]
|
||||
integer! << message[:arguments]
|
||||
integer << integer[1]
|
||||
|
@ -13,20 +13,16 @@ module Risc
|
||||
def initialize( callable )
|
||||
@callable = callable
|
||||
@regs = []
|
||||
init_instructions
|
||||
@current = @risc_instructions
|
||||
@constants = []
|
||||
@block_compilers = []
|
||||
end
|
||||
attr_reader :risc_instructions , :constants , :block_compilers , :callable
|
||||
|
||||
def init_instructions
|
||||
@risc_instructions = Risc.label(source_name, source_name)
|
||||
@risc_instructions.append Risc.label( source_name, "return_label")
|
||||
@risc_instructions.append Mom::ReturnSequence.new.to_risc(self)
|
||||
@risc_instructions.append Risc.label( source_name, "unreachable")
|
||||
@current = @risc_instructions
|
||||
add_code Risc.label( source_name, "return_label")
|
||||
Mom::ReturnSequence.new.to_risc(self)
|
||||
add_code Risc.label( source_name, "unreachable")
|
||||
reset_regs
|
||||
end
|
||||
attr_reader :risc_instructions , :constants , :block_compilers , :callable , :current
|
||||
|
||||
def return_label
|
||||
@risc_instructions.each do |ins|
|
||||
@ -42,8 +38,7 @@ module Risc
|
||||
while( instruction )
|
||||
raise "whats this a #{instruction}" unless instruction.is_a?(Mom::Instruction)
|
||||
#puts "adding mom #{instruction.to_s}:#{instruction.next.to_s}"
|
||||
risc = instruction.to_risc( self )
|
||||
add_code(risc)
|
||||
instruction.to_risc( self )
|
||||
reset_regs
|
||||
#puts "adding risc #{risc.to_s}:#{risc.next.to_s}"
|
||||
instruction = instruction.next
|
||||
@ -135,19 +130,12 @@ module Risc
|
||||
|
||||
# Build with builder (see there), adding the created instructions
|
||||
def build(source , &block)
|
||||
code_builder(source).build(&block)
|
||||
builder(source).build(&block)
|
||||
end
|
||||
|
||||
# return a new code builder that uses this compiler
|
||||
# CodeBuilder returns code after building
|
||||
def code_builder( source)
|
||||
CodeBuilder.new(self , source)
|
||||
end
|
||||
|
||||
# return a CompilerBuilder
|
||||
# CompilerBuilder adds the generated code to the compiler
|
||||
def compiler_builder( source)
|
||||
CompilerBuilder.new(self , source)
|
||||
# return a Builder, that adds the generated code to this compiler
|
||||
def builder( source)
|
||||
Builder.new(self , source)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -45,10 +45,10 @@ module Risc
|
||||
|
||||
# using the registers type, resolve the slot to an index
|
||||
# Using the index and the register, add a SlotToReg to the instruction
|
||||
def resolve_and_add(slot , instruction , compiler)
|
||||
def resolve_and_add(slot , compiler)
|
||||
index = resolve_index( slot )
|
||||
new_left = get_new_left( slot , compiler )
|
||||
instruction << Risc::SlotToReg.new( "SlotLoad #{type}[#{slot}]" , self ,index, new_left)
|
||||
compiler.add_code Risc::SlotToReg.new( "SlotLoad #{type}[#{slot}]" , self ,index, new_left)
|
||||
new_left
|
||||
end
|
||||
|
||||
|
@ -38,7 +38,7 @@ module Vool
|
||||
runtime_method = Mom::SlotDefinition.new( :message , [ :method] )
|
||||
check = Mom::NotSameCheck.new(compile_method , runtime_method, ok_label)
|
||||
# TODO? Maybe create mom instructions for this
|
||||
#builder = compiler.code_builder("yield")
|
||||
#builder = compiler.builder("yield")
|
||||
#Risc::Builtin::Object.exit_sequence(builder)
|
||||
#check << builder.built
|
||||
check << ok_label
|
||||
|
@ -7,8 +7,12 @@ module Risc
|
||||
Parfait.boot!
|
||||
Risc.boot!
|
||||
init = Parfait.object_space.get_init
|
||||
@builder = Risc::MethodCompiler.new( init ).code_builder(init)
|
||||
@builder = Risc::MethodCompiler.new( init ).builder(init)
|
||||
@label = Risc.label("source","name")
|
||||
@start = @builder.compiler.current
|
||||
end
|
||||
def built
|
||||
@start.next
|
||||
end
|
||||
def test_has_build
|
||||
assert @builder.respond_to?(:build)
|
||||
@ -36,34 +40,34 @@ module Risc
|
||||
end
|
||||
def test_returns_built
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
built = @builder.build{ space! << r1 }
|
||||
@builder.build{ space! << r1 }
|
||||
assert_equal Transfer , built.class
|
||||
end
|
||||
def test_returns_two
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
built = @builder.build{ space! << r1 ; space << r1}
|
||||
@builder.build{ space! << r1 ; space << r1}
|
||||
assert_equal Transfer , built.next.class
|
||||
end
|
||||
def test_returns_slot
|
||||
r2 = RegisterValue.new(:r2 , :Message).set_builder( @builder )
|
||||
built = @builder.build{ r2 << space![:next_message] }
|
||||
@builder.build{ r2 << space![:next_message] }
|
||||
assert_equal SlotToReg , built.class
|
||||
assert_equal :r1 , built.array.symbol
|
||||
end
|
||||
def test_returns_slot_reverse
|
||||
r2 = RegisterValue.new(:r2 , :Message).set_builder( @builder )
|
||||
built = @builder.build{ r2 << space![:next_message] }
|
||||
@builder.build{ r2 << space![:next_message] }
|
||||
assert_equal SlotToReg , built.class
|
||||
assert_equal :r1 , built.array.symbol
|
||||
end
|
||||
def test_reuses_names
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
built = @builder.build{ space! << r1 ; space << r1}
|
||||
@builder.build{ space! << r1 ; space << r1}
|
||||
assert_equal built.to.symbol , built.next.to.symbol
|
||||
end
|
||||
def test_uses_message_as_message
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
built = @builder.build{ message[:receiver] << r1}
|
||||
@builder.build{ message[:receiver] << r1}
|
||||
assert_equal RegToSlot , built.class
|
||||
assert_equal :r0 , built.array.symbol
|
||||
end
|
||||
|
@ -8,7 +8,7 @@ module Risc
|
||||
Risc.boot!
|
||||
@init = Parfait.object_space.get_init
|
||||
@compiler = Risc::MethodCompiler.new( @init )
|
||||
@builder = @compiler.compiler_builder(@init)
|
||||
@builder = @compiler.builder(@init)
|
||||
end
|
||||
def test_inserts_built
|
||||
r1 = RegisterValue.new(:r1 , :Space)
|
||||
|
@ -8,7 +8,7 @@ module Risc
|
||||
Risc.boot!
|
||||
@init = Parfait.object_space.get_init
|
||||
@compiler = Risc::MethodCompiler.new( @init )
|
||||
@builder = @compiler.compiler_builder(@init)
|
||||
@builder = @compiler.builder(@init)
|
||||
end
|
||||
def test_list
|
||||
assert_equal :List , @builder.infer_type(:list).class_name
|
||||
|
Loading…
Reference in New Issue
Block a user