diff --git a/lib/risc/builder.rb b/lib/risc/builder.rb index a66890c0..bffdd2fb 100644 --- a/lib/risc/builder.rb +++ b/lib/risc/builder.rb @@ -33,9 +33,7 @@ module Risc name = name.to_s return @names[name] if @names.has_key?(name) if name == "message" - reg = Risc.message_reg - reg.builder = self - return reg + return Risc.message_reg.set_builder(self) end if name.index("label") reg = Risc.label( @source , "#{name}_#{object_id}") @@ -44,8 +42,7 @@ module Risc raise "Must create (with !) before using #{name}" unless name[-1] == "!" name = name[0 ... -1] type = infer_type(name ) - reg = @compiler.use_reg( type.object_class.name ) - reg.builder = self + reg = @compiler.use_reg( type.object_class.name ).set_builder(self) end @names[name] = reg reg @@ -129,8 +126,8 @@ module Risc # move a machine int from register "from" to a Parfait::Integer in register "to" # have to grab an integer from space and stick it in the "to" register first. def add_new_int( source , from, to ) - to.builder = self # esecially div10 comes in without having used builder - from.builder = self # not named regs, different regs ==> silent errors + to.set_builder( self ) # esecially div10 comes in without having used builder + from.set_builder( self ) # not named regs, different regs ==> silent errors build do space! << Parfait.object_space to << space[:next_integer] diff --git a/lib/risc/builtin/object.rb b/lib/risc/builtin/object.rb index 016db9d0..04ed6e08 100644 --- a/lib/risc/builtin/object.rb +++ b/lib/risc/builtin/object.rb @@ -117,8 +117,8 @@ module Risc # This relies on linux to save and restore all registers # def save_message(builder) - r8 = RegisterValue.new( :r8 , :Message) - builder.add_transfer("save_message", Risc.message_reg , r8 ) + r8 = RegisterValue.new( :r8 , :Message).set_builder(builder) + builder.build {r8 << message} end # restore the message that we save in r8 diff --git a/lib/risc/register_value.rb b/lib/risc/register_value.rb index fad5d999..58bdfdfc 100644 --- a/lib/risc/register_value.rb +++ b/lib/risc/register_value.rb @@ -11,7 +11,7 @@ module Risc attr_reader :symbol , :type , :extra - attr_accessor :builder + attr_reader :builder # 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,6 +34,15 @@ module Risc return :fixnum unless @type @type.class_name end + + # allows to set the builder, which is mainly done by the builder + # 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 + self + end + # 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) diff --git a/test/risc/test_builder.rb b/test/risc/test_builder.rb index 03120f8c..ee7cfc34 100644 --- a/test/risc/test_builder.rb +++ b/test/risc/test_builder.rb @@ -45,15 +45,13 @@ module Risc assert_equal Transfer , built.next.class end def test_returns_slot - r2 = RegisterValue.new(:r2 , :Message) - r2.builder = @builder + r2 = RegisterValue.new(:r2 , :Message).set_builder( @builder ) built = @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) - r2.builder = @builder + r2 = RegisterValue.new(:r2 , :Message).set_builder( @builder ) built = @builder.build{ r2 << space![:next_message] } assert_equal SlotToReg , built.class assert_equal :r1 , built.array.symbol diff --git a/test/risc/test_register_value.rb b/test/risc/test_register_value.rb index a2100bdc..48556f94 100644 --- a/test/risc/test_register_value.rb +++ b/test/risc/test_register_value.rb @@ -35,9 +35,14 @@ module Risc transfer = @r0 << @r1 assert_equal Transfer , transfer.class end + def test_set_builder + reg = @r0.set_builder(FakeBuilder.new) + assert_equal RegisterValue , reg.class + assert reg.builder + end def test_calls_builder builder = FakeBuilder.new - @r0.builder = builder + @r0.set_builder( builder ) @r0 << @r1 assert_equal Transfer , builder.built.class end