diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index 26f59e81..dcc833db 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -90,18 +90,16 @@ module Risc copied end - # releasing a register (accuired by use_reg) makes it available for use again - # thus avoiding possibly using too many registers - def release_reg( reg ) - last = @allocator.pop - raise "released register in wrong order, expect #{last} but was #{reg}" if reg != last - end - - # reset the registers to be used. Start at r4 for next usage. - # Every statement starts with this, meaning each statement may use all registers, but none - # get saved. Statements have affect on objects. - def reset_regs - @allocator.clear_regs + # Load a constant, meaning create a LoadConstant instruction for the constant + # add the instruction to the code and return the register_value that was created + # for further use + def load_object( object ) + raise "must be Parfait, not #{object.class}" unless object.is_a?(Parfait::Object) + ins = Risc.load_constant("load to #{object.type}" , object) + add_code ins + # todo for constants (not objects) + # add_constant(right) if compiler + ins.register end # Build with builder (see there), adding the created instructions diff --git a/lib/risc/register_slot.rb b/lib/risc/register_slot.rb index c872676a..66482bc6 100644 --- a/lib/risc/register_slot.rb +++ b/lib/risc/register_slot.rb @@ -14,10 +14,10 @@ module Risc # or r-vlalue respectively. class RegisterSlot - attr_reader :register , :index , :builder + attr_reader :register , :index , :compiler - def initialize(register, index , builder) - @register , @index , @builder = register , index , builder + def initialize(register, index , compiler) + @register , @index , @compiler = register , index , compiler end # fullfil the objects purpose by creating a RegToSlot instruction from @@ -25,7 +25,7 @@ module Risc def <<( reg ) raise "not reg #{reg}" unless reg.is_a?(RegisterValue) reg_to_slot = Risc.reg_to_slot("#{reg.class_name} -> #{register.class_name}[#{index}]" , reg , register, index) - builder.add_code(reg_to_slot) if builder + compiler.add_code(reg_to_slot) if compiler reg_to_slot end @@ -34,7 +34,7 @@ module Risc def <=( reg ) raise "not reg #{reg}" unless reg.is_a?(RegisterValue) reg_to_byte = Risc.reg_to_byte("#{reg.class_name} -> #{register.class_name}[#{index}]" , reg , register, index) - builder.add_code(reg_to_byte) if builder + compiler.add_code(reg_to_byte) if compiler reg_to_byte end diff --git a/lib/risc/register_value.rb b/lib/risc/register_value.rb index c3ffdaaf..8a9f7e7c 100644 --- a/lib/risc/register_value.rb +++ b/lib/risc/register_value.rb @@ -5,13 +5,13 @@ module Risc # The type is always known, and sometimes the value too # Or something about the value, like some instances types # - # When participating in the builder dsl, a builder may be set to get the - # results of dsl operations (like <<) back to the builder + # When participating in the compiler dsl, a compiler may be set to get the + # results of dsl operations (like <<) back to the compiler class RegisterValue attr_reader :symbol , :type , :extra - attr_reader :builder + attr_reader :compiler # The first arg is a symbol :r0 - :r12 # Second arg is the type, which may be given as the symbol of the class name @@ -34,11 +34,11 @@ module Risc @type.class_name end - # allows to set the builder, which is mainly done by the builder + # allows to set the compiler, which is mainly done by the compiler # but sometimes, eg in exit, one nneds to create the reg by hand and set # return the RegisterValue for chaining in assignment - def set_builder( builder ) - @builder = builder + def set_compiler( compiler ) + @compiler = compiler self end @@ -64,10 +64,10 @@ module Risc type.type_at(index) end - # reduce integer to fixnum and add instruction if builder is used + # reduce integer to fixnum and add instruction if compiler is used def reduce_int reduce = Risc::SlotToReg.new( "int -> fix" , self , Parfait::Integer.integer_index , self) - builder.add_code(reduce) if builder + compiler.add_code(reduce) if compiler reduce end @@ -136,25 +136,19 @@ module Risc # - an RegisterSlot, resulting in an SlotToReg def <<( right ) case right - when Symbol - ins = Risc::LoadConstant.new("#{right.class} to #{self.type}" , right , self) - when Parfait::Object - ins = Risc::LoadConstant.new("#{right.class} to #{self.type}" , right , self) - builder.compiler.add_constant(right) if builder when Label ins = Risc::LoadConstant.new("#{right.class} to #{self.type}" , right , self) - builder.compiler.add_constant(right.address) if builder + compiler.compiler.add_constant(right.address) if compiler when ::Integer ins = Risc.load_data("#{right.class} to #{self.type}" , right , self) when RegisterValue ins = Risc.transfer("#{right.type} to #{self.type}" , right , self) when RegisterSlot - puts right.to_s ins = Risc::SlotToReg.new("#{right.register.type}[#{right.index}] -> #{self.type}" , right.register , right.index , self) else raise "not implemented for #{right.class}:#{right}" end - builder.add_code(ins) if builder + compiler.add_code(ins) if compiler return ins end @@ -163,14 +157,14 @@ module Risc def <=( right ) raise "not implemented for #{right.class}:#{right}" unless right.is_a?( RegisterSlot ) ins = Risc.byte_to_reg("#{right.register.type}[#{right.index}] -> #{self.type}" , right.register , right.index , self) - builder.add_code(ins) if builder + compiler.add_code(ins) if compiler return ins end def -( right ) raise "operators only on registers, not #{right.class}" unless right.is_a? RegisterValue op = Risc.op("#{self.type} - #{right.type}", :- , self , right ) - builder.add_code(op) if builder + compiler.add_code(op) if compiler op end @@ -178,7 +172,7 @@ module Risc # doesn't read quite as smoothly as one would like, but better than the compiler version def op( operator , right) ret = Risc.op( "operator #{operator}" , operator , self , right) - builder.add_code(ret) if builder + compiler.add_code(ret) if compiler ret end @@ -186,7 +180,7 @@ module Risc # The RegisterSlot then gets used in a RegToSlot or SlotToReg, where # the values are unpacked to call Risc.reg_to_slot or Risc.slot_to_reg def []( index ) - RegisterSlot.new( self , index , builder) + RegisterSlot.new( self , index , compiler) end end diff --git a/test/risc/test_callable_compiler.rb b/test/risc/test_callable_compiler.rb index 02b7cbc8..dbddc4be 100644 --- a/test/risc/test_callable_compiler.rb +++ b/test/risc/test_callable_compiler.rb @@ -1,13 +1,5 @@ require_relative "helper" module Risc - class FakeCallableCompiler < CallableCompiler - def initialize(a,c) - super(a,c) - end - def source_name - "luke" - end - end class TestCallableCompiler < MiniTest::Test def setup Parfait.boot!({}) @@ -29,28 +21,15 @@ module Risc def test_const assert_equal Array , @compiler.constants.class end - end - class TestFakeCallableCompiler < MiniTest::Test - def setup - Parfait.boot!({}) - label = SlotMachine::Label.new("hi","ho") - @compiler = FakeCallableCompiler.new(FakeCallable.new , label) + def test_load_class + object = @compiler.load_object(Parfait.object_space) + assert_equal RegisterValue , object.class + assert object.is_object? end - def test_ok - assert @compiler - end - def test_current - assert @compiler.current - end - def test_current_label - assert_equal Label , @compiler.current.class - assert_equal "ho" , @compiler.current.name - end - def test_slot - assert @compiler.risc_instructions - end - def test_const - assert_equal Array , @compiler.constants.class + def test_load_code + object = @compiler.load_object(Parfait.object_space) + assert_equal LoadConstant , @compiler.current.class + assert_equal Parfait::Space , @compiler.current.constant.class end end end diff --git a/test/risc/test_register_slot.rb b/test/risc/test_register_slot.rb index f7114481..4649419e 100644 --- a/test/risc/test_register_slot.rb +++ b/test/risc/test_register_slot.rb @@ -17,14 +17,6 @@ module Risc def test_r0 assert_equal :message , @r0.symbol end - def test_load_space - move = @r0 << Parfait.object_space - assert_equal LoadConstant , move.class - end - def test_load_symbol - move = @r1 << :puts - assert_equal LoadConstant , move.class - end def test_load_label label = Risc::Label.new("HI","ho" , FakeAddress.new(0)) move = @r1 << label diff --git a/test/risc/test_register_value.rb b/test/risc/test_register_value.rb index a3b2c257..c0567edf 100644 --- a/test/risc/test_register_value.rb +++ b/test/risc/test_register_value.rb @@ -1,9 +1,9 @@ require_relative "../helper" -class FakeBuilder - attr_reader :built +class SuperFakeCompiler + attr_reader :code def add_code(ins) - @built = ins + @code = ins end end module Risc @@ -24,14 +24,6 @@ module Risc def test_r0 assert_equal :message , @r0.symbol end - def test_load_space - move = @r0 << Parfait.object_space - assert_equal LoadConstant , move.class - end - def test_load_symbol - move = @r1 << :puts - assert_equal LoadConstant , move.class - end def test_load_label label = Risc::Label.new("HI","ho" , FakeAddress.new(0)) move = @r1 << label @@ -41,16 +33,16 @@ module Risc transfer = @r0 << @r1 assert_equal Transfer , transfer.class end - def test_set_builder - reg = @r0.set_builder(FakeBuilder.new) + def test_set_compiler + reg = @r0.set_compiler(SuperFakeCompiler.new) assert_equal RegisterValue , reg.class - assert reg.builder + assert reg.compiler end - def test_calls_builder - builder = FakeBuilder.new - @r0.set_builder( builder ) + def test_calls_compiler + compiler = SuperFakeCompiler.new + @r0.set_compiler( compiler ) @r0 << @r1 - assert_equal Transfer , builder.built.class + assert_equal Transfer , compiler.code.class end def test_index_op message = @r0[:next_message] diff --git a/test/slot_machine/test_callable_compiler.rb b/test/slot_machine/test_callable_compiler.rb index 68bdfd40..f53b8495 100644 --- a/test/slot_machine/test_callable_compiler.rb +++ b/test/slot_machine/test_callable_compiler.rb @@ -1,5 +1,6 @@ require_relative "helper" module SlotMachine + # need to derive, to overwrite source_name class FakeCallableCompiler < CallableCompiler def source_name "luke"