From 21817b182ef70831658ac905d80e4440168e2181 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torsten=20R=C3=BCger?= Date: Mon, 17 Feb 2020 14:26:50 +0700 Subject: [PATCH] Start to make slots recursive --- lib/risc/register_value.rb | 2 +- .../instruction/argument_transfer.rb | 2 +- lib/slot_machine/instruction/slot_load.rb | 4 +- lib/slot_machine/instruction/truth_check.rb | 2 +- lib/slot_machine/slot.rb | 43 ++++++++----------- lib/slot_machine/slotted.rb | 23 +++++----- lib/slot_machine/slotted_constant.rb | 2 +- lib/slot_machine/slotted_message.rb | 15 +++---- lib/slot_machine/slotted_object.rb | 2 +- .../{test_slot.rb => test_slotted.rb} | 0 .../{test_slot2.rb => test_slotted2.rb} | 8 ++-- 11 files changed, 48 insertions(+), 55 deletions(-) rename test/slot_machine/{test_slot.rb => test_slotted.rb} (100%) rename test/slot_machine/{test_slot2.rb => test_slotted2.rb} (75%) diff --git a/lib/risc/register_value.rb b/lib/risc/register_value.rb index 36c0471f..28c4ecbf 100644 --- a/lib/risc/register_value.rb +++ b/lib/risc/register_value.rb @@ -46,7 +46,7 @@ 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 , compiler) - index = resolve_index( slot ) + index = resolve_index(slot) new_left = get_new_left( slot , compiler ) compiler.add_code Risc::SlotToReg.new( "SlotLoad #{type}[#{slot}]" , self ,index, new_left) new_left diff --git a/lib/slot_machine/instruction/argument_transfer.rb b/lib/slot_machine/instruction/argument_transfer.rb index 5d8bd478..9ba17438 100644 --- a/lib/slot_machine/instruction/argument_transfer.rb +++ b/lib/slot_machine/instruction/argument_transfer.rb @@ -25,7 +25,7 @@ module SlotMachine def initialize( source , receiver,arguments ) super(source) @receiver , @arguments = receiver , arguments - raise "Receiver not Slot #{@receiver}" unless @receiver.is_a?(Slot) + raise "Receiver not Slot #{@receiver}" unless @receiver.is_a?(Slotted) @arguments.each{|a| raise "args not SlotLoad #{a}" unless a.is_a?(SlotLoad)} end diff --git a/lib/slot_machine/instruction/slot_load.rb b/lib/slot_machine/instruction/slot_load.rb index 98fb7c11..722ebcdd 100644 --- a/lib/slot_machine/instruction/slot_load.rb +++ b/lib/slot_machine/instruction/slot_load.rb @@ -33,8 +33,8 @@ module SlotMachine @left , @right = left , right @left = Slotted.for(@left.shift , @left) if @left.is_a? Array @right = Slotted.for(@right.shift , @right) if @right.is_a? Array - raise "right not SlotMachine, #{@right.to_s}" unless @right.is_a?( Slot ) - raise "left not SlotMachine, #{@left.to_s}" unless @left.is_a?( Slot ) + raise "right not SlotMachine, #{@right.to_s}" unless @right.is_a?( Slotted ) + raise "left not SlotMachine, #{@left.to_s}" unless @left.is_a?( Slotted ) @original_source = original_source || self end diff --git a/lib/slot_machine/instruction/truth_check.rb b/lib/slot_machine/instruction/truth_check.rb index f3cdcfa2..b990dd71 100644 --- a/lib/slot_machine/instruction/truth_check.rb +++ b/lib/slot_machine/instruction/truth_check.rb @@ -11,7 +11,7 @@ module SlotMachine def initialize(condition , false_jump) super(false_jump) @condition = condition - raise "condition must be slot_definition #{condition}" unless condition.is_a?(Slot) + raise "condition must be slot_definition #{condition}" unless condition.is_a?(Slotted) end def to_s diff --git a/lib/slot_machine/slot.rb b/lib/slot_machine/slot.rb index 91d299a7..07d57593 100644 --- a/lib/slot_machine/slot.rb +++ b/lib/slot_machine/slot.rb @@ -1,5 +1,5 @@ module SlotMachine - # A Slot defines a slot. A bit like a variable name but for objects. + # A Slot defines a slot in a slotted. A bit like a variable name but for objects. # # PS: for the interested: A "development" of Smalltalk was the # prototype based language (read: JavaScript equivalent) @@ -7,7 +7,7 @@ module SlotMachine # # Slots are the instance names of objects. But since the language is dynamic # what is it that we can say about instance names at runtime? - # Start with a known object like the Message (in register one), we know all it's + # Start with a Slotted, like the Message (in register one), we know all it's # variables. But there is a Message in there, and for that we know the instances # too. And off course for _all_ objects we know where the type is. # @@ -15,35 +15,26 @@ module SlotMachine # Instructions. Or in the case of constants to ConstantLoad # class Slot - # get the right definition, depending on the object - def self.for(object , slots) - case object - when :message - SlottedMessage.new(slots) - when Constant - SlottedConstant.new(object , slots) - when Parfait::Object , Risc::Label - SlottedObject.new(object , slots) + + attr_reader :name , :next_slot + + def initialize( name ) + raise "No name" unless name + @name = name + end + + def set_next(slot) + if(@next_slot) + @next_slot.set_next(slot) else - raise "not supported type #{object}" + @next_slot = slot end end - attr_reader :slots - # is an array of symbols, that specifies the first the object, and then the Slot. - # The first element is either a known type name (Capitalized symbol of the class name) , - # or the symbol :message - # And subsequent symbols must be instance variables on the previous type. - # Examples: [:message , :receiver] or [:Space , :next_message] - def initialize( slots) - raise "No slots #{object}" unless slots - slots = [slots] unless slots.is_a?(Array) - @slots = slots - end - def to_s - names = [known_name] + @slots - "[#{names.join(', ')}]" + names = name.to_s + names += ".#{@next_slot}" if @next_slot + names end diff --git a/lib/slot_machine/slotted.rb b/lib/slot_machine/slotted.rb index e96ee4f2..ab309001 100644 --- a/lib/slot_machine/slotted.rb +++ b/lib/slot_machine/slotted.rb @@ -15,21 +15,24 @@ module SlotMachine end end - attr_reader :slots - # is an array of symbols, that specifies the first the object, and then the Slot. - # The first element is either a known type name (Capitalized symbol of the class name) , - # or the symbol :message - # And subsequent symbols must be instance variables on the previous type. - # Examples: [:message , :receiver] or [:Space , :next_message] - def initialize( slots) + # The first in a possible chain of slots, that name instance variables in the + # previous object + attr_reader :slot + + def initialize( slots ) raise "No slots #{object}" unless slots slots = [slots] unless slots.is_a?(Array) - @slots = slots + first = slots.shift + @slot = Slot.new(first) + until(slots.empty?) + @slot.set_next( Slot.new( slots.shift )) + end end def to_s - names = [known_name] + @slots - "[#{names.join(', ')}]" + names = known_name.to_s + names += ".#{@slot}" if @slot + names end diff --git a/lib/slot_machine/slotted_constant.rb b/lib/slot_machine/slotted_constant.rb index ce4d3c3f..9542337a 100644 --- a/lib/slot_machine/slotted_constant.rb +++ b/lib/slot_machine/slotted_constant.rb @@ -1,5 +1,5 @@ module SlotMachine - class SlottedConstant < Slot + class SlottedConstant < Slotted attr_reader :known_object diff --git a/lib/slot_machine/slotted_message.rb b/lib/slot_machine/slotted_message.rb index 21a3e802..4986bff4 100644 --- a/lib/slot_machine/slotted_message.rb +++ b/lib/slot_machine/slotted_message.rb @@ -1,9 +1,6 @@ module SlotMachine - class SlottedMessage < Slot + class SlottedMessage < Slotted - def initialize(slots) - super(slots) - end def known_name :message @@ -16,12 +13,14 @@ module SlotMachine def to_register(compiler, source) type = :Message right = compiler.use_reg( type ) - slots = @slots.dup + slots = @slot left = Risc.message_reg - left = left.resolve_and_add( slots.shift , compiler) + left = left.resolve_and_add( slots.name , compiler) reg = compiler.current.register - while( !slots.empty? ) - left = left.resolve_and_add( slots.shift , compiler) + slots = slots.next_slot + while( slots ) + left = left.resolve_and_add( slots , compiler) + slots = slots.next_slot end return reg end diff --git a/lib/slot_machine/slotted_object.rb b/lib/slot_machine/slotted_object.rb index 87daadf6..41b291ef 100644 --- a/lib/slot_machine/slotted_object.rb +++ b/lib/slot_machine/slotted_object.rb @@ -1,5 +1,5 @@ module SlotMachine - class SlottedObject < Slot + class SlottedObject < Slotted attr_reader :known_object diff --git a/test/slot_machine/test_slot.rb b/test/slot_machine/test_slotted.rb similarity index 100% rename from test/slot_machine/test_slot.rb rename to test/slot_machine/test_slotted.rb diff --git a/test/slot_machine/test_slot2.rb b/test/slot_machine/test_slotted2.rb similarity index 75% rename from test/slot_machine/test_slot2.rb rename to test/slot_machine/test_slotted2.rb index 8abb5c4e..c886622a 100644 --- a/test/slot_machine/test_slot2.rb +++ b/test/slot_machine/test_slotted2.rb @@ -4,10 +4,10 @@ module SlotMachine class TestSlotKnown1 < MiniTest::Test def setup Parfait.boot!(Parfait.default_test_options) - @compiler = Risc::FakeCompiler.new - @definition = SlottedMessage.new( :caller) - @register = @definition.to_register(@compiler , "fake source") - @instruction = @compiler.instructions.first + compiler = Risc::FakeCompiler.new + slotted = SlottedMessage.new(:caller) + @register = slotted.to_register(compiler , "fake source") + @instruction = compiler.instructions.first end def test_def_class assert_equal Risc::SlotToReg , @instruction.class