From 21e426be712880729255652a1f07064d509f6653 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Wed, 12 Apr 2017 14:45:02 +0300 Subject: [PATCH] finishes local assignments to_mom --- lib/mom/slot_load.rb | 40 +++++++++++++++++++++ lib/vool/statements/assignment_statement.rb | 4 ++- test/vool/to_mom/test_assignemnt.rb | 22 ++++++++++-- 3 files changed, 63 insertions(+), 3 deletions(-) diff --git a/lib/mom/slot_load.rb b/lib/mom/slot_load.rb index 267c12d6..19e31cfd 100644 --- a/lib/mom/slot_load.rb +++ b/lib/mom/slot_load.rb @@ -1,6 +1,46 @@ module Mom + # SlotLoad is an abstract base class for moving data into a slot + # A Slot is the basically an instance variable, but it must be of known type + # + # The value loaded can be a constant (SlotConstant) or come from another Slot (SlotMove) + # + # The Slot is the left hand side, the right hand side being determined by the subclass. + # The only known object (*) for the left side is the current message, which is a bit like + # the oo version of a PC (program Counter) + # (* off course all class objects are global, and so they are allowed too) + # + # A maybe not immediately obvious corrolar of this design is the total absence of + # general purpose instance variable accessors. Ie only inside an object's functions + # can a method access instance variables, because only inside the method is the type + # guaranteed. + # From the outside a send is neccessary, both for get and set, (which goes through the method + # resolution and guarantees the correct method for a type), in other words perfect data hiding. + # + # @left: 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 + # Ant subsequent symbols must be instance variables on the previous type. + # Examples: [:message , :self] or [:Space : :next_message] + # + # @right: depends on the derived Class + # class SlotLoad < Instruction + attr_reader :left , :right + def initialize(left , right) + @left , @right = left , right + end end + # A SlotConstant moves a constant into a know Slot. + # Eg when you write a = 5 , the 5 becomes a constant, and so the right side + # the a is an instance variable on the current frame, and the frame is an instance + # of the current message, so the effect is something like message.frame.a = 5 + # @left: See SlotLoad, and array of symbols + # @right: A Constant from parse, ie an instance of classes in basc_value, like TrueStatement + class SlotConstant < SlotLoad + end + + class SlotMove < SlotLoad + end end diff --git a/lib/vool/statements/assignment_statement.rb b/lib/vool/statements/assignment_statement.rb index 36fcd523..df17cc05 100644 --- a/lib/vool/statements/assignment_statement.rb +++ b/lib/vool/statements/assignment_statement.rb @@ -14,10 +14,12 @@ module Vool def add_local( array ) array << @name end + def to_mom( method ) - Mom::SlotLoad.new + Mom::SlotConstant.new([:message , :self , @name] , @value) end end + class InstanceAssignment < Assignment # used to collect type information def add_ivar( array ) diff --git a/test/vool/to_mom/test_assignemnt.rb b/test/vool/to_mom/test_assignemnt.rb index 8bc16b86..e0ea77d7 100644 --- a/test/vool/to_mom/test_assignemnt.rb +++ b/test/vool/to_mom/test_assignemnt.rb @@ -6,6 +6,7 @@ module Vool def setup Risc.machine.boot + @method = compile_first_method( "a = 5") end def compile_first_method input @@ -17,8 +18,25 @@ module Vool end def test_class_compiles - meth = compile_first_method( "a = 5") - assert_equal Mom::SlotLoad , meth.first.class , meth + assert_equal Mom::SlotConstant , @method.first.class , @method + end + def test_slot_is_set + assert @method.first.left + end + def test_slot_starts_at_message + assert_equal :message , @method.first.left[0] + end + def test_slot_gets_self + assert_equal :self , @method.first.left[1] + end + def test_slot_assigns_to_local + assert_equal :a , @method.first.left[-1] + end + def test_slot_assigns_something + assert @method.first.right + end + def test_slot_assigns_int + assert_equal IntegerStatement , @method.first.right.class end end end