diff --git a/lib/slot_machine/instruction/message_definition.rb b/lib/slot_machine/instruction/message_definition.rb index dec2d849..cc6f12e0 100644 --- a/lib/slot_machine/instruction/message_definition.rb +++ b/lib/slot_machine/instruction/message_definition.rb @@ -25,5 +25,23 @@ module SlotMachine return reg end + # load the data in const_reg into the slot that is named by slot symbols + # actual lifting is done by RegisterValue resolve_and_add + # + # Note: this is the left hand case, the right hand being to_register + # They are very similar (apart from the final reg_to_slot here) and should + # most likely be united + def reduce_and_load(const_reg , compiler , original_source ) + left_slots = slots.dup + raise "Not Message #{object}" unless known_object == :message + left = Risc.message_reg + slot = left_slots.shift + while( !left_slots.empty? ) + left = left.resolve_and_add( slot , compiler) + slot = left_slots.shift + end + compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slot) + end + end end diff --git a/lib/slot_machine/instruction/object_definition.rb b/lib/slot_machine/instruction/object_definition.rb index 335a0664..99a47369 100644 --- a/lib/slot_machine/instruction/object_definition.rb +++ b/lib/slot_machine/instruction/object_definition.rb @@ -1,20 +1,6 @@ module SlotMachine class ObjectDefinition < SlotDefinition - # get the right definition, depending on the object - def self.for(object , slots) - case object - when :message - MessageDefinition.new(slots) - when Constant - ConstantDefinition.new(object , slots) - when Parfait::Object - ObjectDefinition.new(object , slots) - else - SlotDefinition.new(object,slots) - end - end - def initialize( object , slots) super(object , slots ) end @@ -47,5 +33,14 @@ module SlotMachine return const.register end + # Note: this is the left hand case, the right hand being to_register + # They are very similar (apart from the final reg_to_slot here) and should + # most likely be united + def reduce_and_load(const_reg , compiler , original_source ) + raise "only cache" unless known_object.is_a?( Parfait::CacheEntry) + left = compiler.use_reg( :CacheEntry ) + compiler.add_code Risc.load_constant(original_source, known_object , left) + compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slots.first) + end end end diff --git a/lib/slot_machine/instruction/slot_definition.rb b/lib/slot_machine/instruction/slot_definition.rb index 0951fa9b..dab66bb5 100644 --- a/lib/slot_machine/instruction/slot_definition.rb +++ b/lib/slot_machine/instruction/slot_definition.rb @@ -22,10 +22,10 @@ module SlotMachine MessageDefinition.new(slots) when Constant ConstantDefinition.new(object , slots) - when Parfait::Object + when Parfait::Object , Risc::Label ObjectDefinition.new(object , slots) else - SlotDefinition.new(object,slots) + raise "not supported type #{object}" end end @@ -47,47 +47,6 @@ module SlotMachine "[#{names.join(', ')}]" end - def known_name - case known_object - when Risc::Label - known_object.to_s - else - "unknown" - end - end - - # load the slots into a register - # the code is added to compiler - # the register returned - def to_register(compiler, source) - if(known_object.respond_to?(:get_type)) - type = known_object.get_type - else - type = :Object - end - right = compiler.use_reg( type ) - case known_object - when Risc::Label - const = Risc.load_constant(source, known_object , right) - compiler.add_code const - if slots.length > 0 - # desctructively replace the existing value to be loaded if more slots - compiler.add_code Risc.slot_to_reg( source , right ,slots[0], right) - end - else - raise "We have a #{self} #{known_object}" - end - if slots.length > 1 - # desctructively replace the existing value to be loaded if more slots - index = Risc.resolve_to_index(slots[0] , slots[1] ,compiler) - compiler.add_code Risc::SlotToReg.new( source , right ,index, right) - if slots.length > 2 - raise "3 slots only for type #{slots}" unless slots[2] == :type - compiler.add_code Risc::SlotToReg.new( source , right , Parfait::TYPE_INDEX, right) - end - end - return const.register - end end end diff --git a/lib/slot_machine/instruction/slot_load.rb b/lib/slot_machine/instruction/slot_load.rb index 40443415..9b804570 100644 --- a/lib/slot_machine/instruction/slot_load.rb +++ b/lib/slot_machine/instruction/slot_load.rb @@ -34,6 +34,7 @@ module SlotMachine @left = SlotDefinition.for(@left.shift , @left) if @left.is_a? Array @right = SlotDefinition.for(@right.shift , @right) if @right.is_a? Array raise "right not SlotMachine, #{@right.to_s}" unless @right.is_a?( SlotDefinition ) + raise "left not SlotMachine, #{@left.to_s}" unless @left.is_a?( SlotDefinition ) @original_source = original_source || self end @@ -46,37 +47,10 @@ module SlotMachine # after loading the right into register def to_risc(compiler) const_reg = @right.to_register(compiler , original_source) - left_slots = @left.slots - case @left.known_object - when Symbol - sym_to_risc(compiler , const_reg) - when Parfait::CacheEntry - left = compiler.use_reg( :CacheEntry ) - compiler.add_code Risc.load_constant(original_source, @left.known_object , left) - compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, left_slots.first) - else - raise "We have left #{@left.known_object}" - end + @left.reduce_and_load(const_reg , compiler , original_source ) compiler.reset_regs end - # load the data in const_reg into the slot that is named by left symbols - # left may usually be only 3 long, as the first is known, then the second is loaded - # with type known type (as it comes from message) - # - # actual lifting is done by RegisterValue resolve_and_add - def sym_to_risc(compiler , const_reg) - left_slots = @left.slots.dup - raise "Not Message #{object}" unless @left.known_object == :message - left = Risc.message_reg - slot = left_slots.shift - while( !left_slots.empty? ) - left = left.resolve_and_add( slot , compiler) - slot = left_slots.shift - end - compiler.add_code Risc.reg_to_slot(original_source, const_reg , left, slot) - end - end end diff --git a/test/slot_machine/instruction/test_slot_load.rb b/test/slot_machine/instruction/test_slot_load.rb index c536ac44..215d6880 100644 --- a/test/slot_machine/instruction/test_slot_load.rb +++ b/test/slot_machine/instruction/test_slot_load.rb @@ -3,19 +3,22 @@ require_relative "helper" module SlotMachine class TestSlotLoadBasics < MiniTest::Test + def setup + Parfait.boot!({}) + end def test_ins_ok - assert SlotLoad.new("test", [:message, :caller] , [:receiver,:type] ) + assert SlotLoad.new("test", [:message, :caller] , [:message , :receiver,:type] ) end def test_ins_fail1 assert_raises {SlotLoad.new( "test",[:message, :caller] , nil )} end - def test_fail_on_right - @load = SlotLoad.new( "test",[:message, :caller] , [:receiver,:type] ) - assert_raises {@load.to_risc(Risc::FakeCompiler.new)} + def pest_fail_on_right + load = SlotLoad.new( "test",[:message, :caller] , [:message ,:receiver,:type] ) + assert_raises {load.to_risc(Risc::FakeCompiler.new)} end - def test_fail_on_left_long - @load = SlotLoad.new("test", [:message, :caller , :type] , [:receiver,:type] ) - assert_raises {@load.to_risc(Risc::FakeCompiler.new)} + def pest_fail_on_left_long + load = SlotLoad.new("test", [:message, :caller , :type , :type] , [:message,:type] ) + assert_raises {load.to_risc(Risc::FakeCompiler.new)} end end end