diff --git a/lib/risc/callable_compiler.rb b/lib/risc/callable_compiler.rb index 4343fbb7..095dd4f9 100644 --- a/lib/risc/callable_compiler.rb +++ b/lib/risc/callable_compiler.rb @@ -94,8 +94,7 @@ module Risc # 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) + ins = Risc.load_constant("load to #{object}" , object) ins.register.set_compiler(self) add_code ins # todo for constants (not objects) diff --git a/lib/risc/instructions/load_constant.rb b/lib/risc/instructions/load_constant.rb index a166f02a..da725637 100644 --- a/lib/risc/instructions/load_constant.rb +++ b/lib/risc/instructions/load_constant.rb @@ -33,9 +33,12 @@ module Risc end end def self.load_constant( source , constant ) - if(constant.is_a?(Parfait::Object)) + value = constant + case constant + when Parfait::Object type = constant.get_type - value = constant + when Label + type = constant.address.get_type else type = constant.ct_type value = constant.value diff --git a/lib/risc/register_slot.rb b/lib/risc/register_slot.rb index 63b11fee..0a415f3e 100644 --- a/lib/risc/register_slot.rb +++ b/lib/risc/register_slot.rb @@ -40,15 +40,16 @@ module Risc # Example: message[:caller][:next_message] # message[:caller] returns a RegisterSlot, which would be self for this example # to evaluate self[:next_message] we reduce self to a register with to_reg - def [](index) + def []( index ) reg = to_reg("reduce #{@register.symbol}[@index]") reg[index] end + # push the given register into the slot that self represents # ie create a slot_to_reg instruction and add to the compiler # the register represents and "array", and the content of the # given register from, is pushed to the memory at register[index] - def to_mem(source , from ) + def to_mem( source , from ) reg_to_slot = Risc.reg_to_slot(source , from , register, index) compiler.add_code(reg_to_slot) if compiler reg_to_slot.register @@ -57,9 +58,12 @@ module Risc # load the conntent of the slot that self descibes into a a new register. # the register is created, and the slot_to_reg instruction added to the # compiler. the return is a bit like @register[@index] - def to_reg(source ) + def to_reg( source ) slot_to_reg = Risc.slot_to_reg(source , register, index) - compiler.add_code(slot_to_reg) if compiler + if compiler + compiler.add_code(slot_to_reg) + slot_to_reg.register.set_compiler(compiler) + end slot_to_reg.register end diff --git a/lib/risc/register_value.rb b/lib/risc/register_value.rb index b2686a84..90619f60 100644 --- a/lib/risc/register_value.rb +++ b/lib/risc/register_value.rb @@ -143,8 +143,8 @@ module Risc when RegisterValue ins = Risc.transfer("#{right.type} to #{self.type}" , right , self) when RegisterSlot - raise "logic error, after creating the reg, need to transfer" - ins = Risc::SlotToReg.new("#{right.register.type}[#{right.index}] -> #{self.type}" , right.register , right.index , self) + index = right.register.resolve_index(right.index) + ins = SlotToReg.new("#{right.register.type}[#{right.index}] -> #{self.type}" , right.register , index , self) else raise "not implemented for #{right.class}:#{right}" end diff --git a/lib/slot_machine/instruction/simple_call.rb b/lib/slot_machine/instruction/simple_call.rb index fd853ea3..b55b3ac4 100644 --- a/lib/slot_machine/instruction/simple_call.rb +++ b/lib/slot_machine/instruction/simple_call.rb @@ -26,12 +26,11 @@ module SlotMachine def to_risc(compiler) method = @method return_label = Risc.label(self,"continue_#{object_id}") - compiler.build("SimpleCall") do - return_address! << return_label - next_message! << message[:next_message] - next_message[:return_address] << return_address + return_address = compiler.load_object( return_label ) + compiler.build(self.to_s) do + message[:next_message][:return_address] << return_address message << message[:next_message] - add_code Risc::FunctionCall.new("SimpleCall", method ) + add_code Risc.function_call(self.to_s, method ) add_code return_label end end diff --git a/test/risc/test_register_slot.rb b/test/risc/test_register_slot.rb index 70bad648..67292490 100644 --- a/test/risc/test_register_slot.rb +++ b/test/risc/test_register_slot.rb @@ -72,4 +72,27 @@ module Risc assert_equal :message , inst.array.symbol end end + class TestRegisterSlot4 < MiniTest::Test + def setup + Parfait.boot!(Parfait.default_test_options) + @compiler = Risc.test_compiler + @r0 = RegisterValue.new(:message , :Message).set_compiler(@compiler) + @r0[:next_message][:return_address] << @r0 + end + def test_instructions + assert_equal SlotToReg , @compiler.risc_instructions.next(1).class + assert_equal RegToSlot , @compiler.risc_instructions.next(2).class + assert_equal NilClass , @compiler.risc_instructions.next(3).class + end + def test_slot_to + slot = @compiler.risc_instructions.next(1) + assert_slot_to_reg slot , :message, 1, :"message.next_message" + assert slot.register.compiler + end + def test_reg_to + reg = @compiler.risc_instructions.next(2) + assert_reg_to_slot reg , :message, :"message.next_message" , 4 + assert reg.register.compiler + end + end end diff --git a/test/risc/test_register_value.rb b/test/risc/test_register_value.rb index 5790ac81..83f0aa53 100644 --- a/test/risc/test_register_value.rb +++ b/test/risc/test_register_value.rb @@ -64,12 +64,12 @@ module Risc assert_equal @r0 , instr.register assert_equal 1 , instr.index end - def est_slot_to_reg + def test_slot_to_reg instr = @r0 << @r2[:next_object] assert_equal SlotToReg , instr.class - assert_equal @r0 , instr.register + assert_equal :message , instr.register.symbol assert_equal 2 , instr.index - assert_equal @r1 , instr.array + assert instr.array.is_object? end def test_reg_to_byte instr = @r1[1] <= @r0 diff --git a/test/slot_machine/instruction/test_simple_call.rb b/test/slot_machine/instruction/test_simple_call.rb index bbada983..9df0e4c0 100644 --- a/test/slot_machine/instruction/test_simple_call.rb +++ b/test/slot_machine/instruction/test_simple_call.rb @@ -7,27 +7,30 @@ module SlotMachine def instruction SimpleCall.new( make_method ) end - def test_len + def est_len assert_equal 7 , all.length , all_str end def test_1_load_return_label - assert_load risc(1) , Risc::Label , :r1 + assert_load risc(1) , Risc::Label assert_label risc(1).constant , "continue_" end def test_2_load_next_message - assert_slot_to_reg risc(2) ,:r0 , 1 , :r2 + assert_slot_to_reg risc(2) ,:message , 1 , :"message.next_message" end def test_3_store_return_address - assert_reg_to_slot risc(3) , :r1 , :r2 , 4 + assert risc(3).register.is_object? + assert_equal 4, risc(3).index + assert_equal :"message.next_message", risc(3).array.symbol end def test_4_swap_messages - assert_slot_to_reg risc(4) ,:r0 , 1 , :r0 + assert_slot_to_reg risc(4) ,:message , 1 , :message end def test_5_call assert_equal Risc::FunctionCall , risc(5).class assert_equal :meth , risc(5).method.name end def test_6_label + assert_equal Risc::Label , risc(6).class assert_label risc(6) , "continue_" end end