diff --git a/lib/compiler/basic_expressions.rb b/lib/compiler/basic_expressions.rb index 393bed6f..36bb1e53 100644 --- a/lib/compiler/basic_expressions.rb +++ b/lib/compiler/basic_expressions.rb @@ -13,7 +13,7 @@ module Compiler # attr_reader :value def self.compile_integer expession , method , message int = Virtual::IntegerConstant.new(expession.value) - to = Virtual::NewReturn.new(Virtual::Integer , int) + to = Virtual::Return.new(Virtual::Integer , int) method.add_code Virtual::Set.new( to , int) to end @@ -81,6 +81,6 @@ module Compiler def self.compile_variable expession, method , message method.add_code Virtual::InstanceGet.new(expession.name) - Virtual::NewReturn.new( Virtual::Mystery ) + Virtual::Return.new( Virtual::Mystery ) end end diff --git a/lib/compiler/call_site_expression.rb b/lib/compiler/call_site_expression.rb index 05bc0ab9..a29787e5 100644 --- a/lib/compiler/call_site_expression.rb +++ b/lib/compiler/call_site_expression.rb @@ -21,6 +21,6 @@ module Compiler method.add_code Virtual::MessageSend.new(expession.name , me , compiled_args) #and pass control # the effect of the method is that the NewMessage Return slot will be filled, return it # (this is what is moved _inside_ above loop for such expressions that are calls (or constants)) - Virtual::NewReturn.new( method.return_type ) + Virtual::Return.new( method.return_type ) end end diff --git a/lib/virtual/machine.rb b/lib/virtual/machine.rb index 6d206416..3577b0b7 100644 --- a/lib/virtual/machine.rb +++ b/lib/virtual/machine.rb @@ -70,7 +70,7 @@ require_relative "instruction" require_relative "compiled_method" require_relative "frame" require_relative "message" -require_relative "slot" +require_relative "slots/slot" require_relative "type" require_relative "object" require_relative "constants" diff --git a/lib/virtual/slot.rb b/lib/virtual/slot.rb deleted file mode 100644 index a4c82294..00000000 --- a/lib/virtual/slot.rb +++ /dev/null @@ -1,88 +0,0 @@ -module Virtual - # Slots are named, or rather indexed, storage locations that are typed. - # Four of those locations exist and those correspond to subclasses: - # - the message that has been received: MessageSlot - # - the frame of the method that is executing (local variables): FrameSlot - # - self as an object: SelfSlot - # - a message that will be sent, NewMessageSlot - - # additionally frame, self and return are slots in Message and NewMessage - - class Slot < Object - MESSAGE_REGISTER = :r0 - SELF_REGISTER = :r1 - FRAME_REGISTER = :r2 - NEW_MESSAGE_REGISTER = :r3 - - MESSAGE_CALLER = 0 - MESSAGE_RETURN_ADDRESS = 1 - MESSAGE_EXCEPTION_ADDRESS = 2 - MESSAGE_SELF = 3 - MESSAGE_NAME = 4 - MESSAGE_RETURN_VALUE = 5 - MESSAGE_FRAME = 6 - MESSAGE_PAYLOAD = 7 - - attr_accessor :index , :type , :value - private #abstract base class - def initialize index , type , value - @index = index - @type = type - @value = value - end - end - - class MessageSlot < Slot - def initialize index , type = Mystery , value = nil - super(index ,type , value ) - end - end - class FrameSlot < Slot - def initialize index , type = Mystery, value = nil - super - end - end - class SelfSlot < Slot - def initialize index , type = Mystery, value = nil - super - end - end - class NewMessageSlot < Slot - def initialize index , type = Mystery, value = nil - super(index , type , value ) - end - end - - class Return < MessageSlot - def initialize type = Mystery, value = nil - super( MESSAGE_RETURN_VALUE , type , value ) - end - end - class Self < MessageSlot - def initialize type = Mystery, value = nil - super( MESSAGE_SELF , type , value ) - end - end - class Name < MessageSlot - def initialize type = Mystery, value = nil - super( MESSAGE_NAME , type , value ) - end - end - - class NewReturn < NewMessageSlot - def initialize type = Mystery, value = nil - super( MESSAGE_RETURN_VALUE, type , value ) - end - end - class NewSelf < NewMessageSlot - def initialize type = Mystery, value = nil - super( MESSAGE_SELF , type , value ) - end - end - class NewName < NewMessageSlot - def initialize type = Mystery, value = nil - super( MESSAGE_NAME, type , value ) - end - end - -end diff --git a/lib/virtual/slots/message_slot.rb b/lib/virtual/slots/message_slot.rb new file mode 100644 index 00000000..2e45ac46 --- /dev/null +++ b/lib/virtual/slots/message_slot.rb @@ -0,0 +1,27 @@ +module Virtual + # The message that is being processed has a layout as per the constant above + class MessageSlot < Slot + def initialize index , type = Mystery , value = nil + super(index ,type , value ) + end + end + + class Return < MessageSlot + def initialize type = Mystery, value = nil + super( MESSAGE_RETURN_VALUE , type , value ) + end + end + + class Self < MessageSlot + def initialize type = Mystery, value = nil + super( MESSAGE_SELF , type , value ) + end + end + + # Name of the current message + class Name < MessageSlot + def initialize type = Mystery, value = nil + super( MESSAGE_NAME , type , value ) + end + end +end diff --git a/lib/virtual/slots/new_message_slot.rb b/lib/virtual/slots/new_message_slot.rb new file mode 100644 index 00000000..87778188 --- /dev/null +++ b/lib/virtual/slots/new_message_slot.rb @@ -0,0 +1,25 @@ +module Virtual + class NewMessageSlot < Slot + def initialize index , type = Mystery, value = nil + super(index , type , value ) + end + end + + class NewReturn < NewMessageSlot + def initialize type = Mystery, value = nil + super( MESSAGE_RETURN_VALUE, type , value ) + end + end + + class NewSelf < NewMessageSlot + def initialize type = Mystery, value = nil + super( MESSAGE_SELF , type , value ) + end + end + + class NewName < NewMessageSlot + def initialize type = Mystery, value = nil + super( MESSAGE_NAME, type , value ) + end + end +end diff --git a/lib/virtual/slots/slot.rb b/lib/virtual/slots/slot.rb new file mode 100644 index 00000000..00449cfb --- /dev/null +++ b/lib/virtual/slots/slot.rb @@ -0,0 +1,59 @@ +module Virtual + # A slot is a slot in an object. It is the storage location for a value. + # (Remember, values are typed) + # From a memory perspective a slot is an index into an array (the object) + # But we are not modelling the array here, but the index into it. + + # Four known objects exist and those correspond to subclasses: + # - the message that has been received: MessageSlot + # - the frame of the method that is executing (local variables): FrameSlot + # - self as an object: SelfSlot + # - a message that will be sent, NewMessageSlot + + # additionally frame, self and return are slots in Message and NewMessage + + # Slot has a lot of small subclasses + # Names for the slots avoid indexes + + class Slot < Object + MESSAGE_REGISTER = :r0 + SELF_REGISTER = :r1 + FRAME_REGISTER = :r2 + NEW_MESSAGE_REGISTER = :r3 + + MESSAGE_CALLER = 0 + MESSAGE_RETURN_ADDRESS = 1 + MESSAGE_EXCEPTION_ADDRESS = 2 + MESSAGE_SELF = 3 + MESSAGE_NAME = 4 + MESSAGE_RETURN_VALUE = 5 + MESSAGE_FRAME = 6 + MESSAGE_PAYLOAD = 7 + + attr_accessor :index , :type , :value + + private #abstract base class + + def initialize index , type , value + @index = index + @type = type + @value = value + end + end + + class FrameSlot < Slot + def initialize index , type = Mystery, value = nil + super + end + end + + class SelfSlot < Slot + def initialize index , type = Mystery, value = nil + super + end + end + +end + +require_relative "message_slot" +require_relative "new_message_slot" diff --git a/test/virtual/test_basic.rb b/test/virtual/test_basic.rb index b92d3d40..197a0c25 100644 --- a/test/virtual/test_basic.rb +++ b/test/virtual/test_basic.rb @@ -5,7 +5,7 @@ class TestBasic < MiniTest::Test def test_number @string_input = '42 ' - @output = "-Virtual::NewReturn(:index => 5, :type => Virtual::Integer)*^* :value Virtual::IntegerConstant(:integer => 42)" + @output = "-Virtual::Return(:index => 5, :type => Virtual::Integer)*^* :value Virtual::IntegerConstant(:integer => 42)" check end @@ -40,7 +40,7 @@ class TestBasic < MiniTest::Test def test_instance_variable @string_input = '@foo_bar ' - @output = "-Virtual::NewReturn(:index => 5, :type => Virtual::Mystery)" + @output = "-Virtual::Return(:index => 5, :type => Virtual::Mystery)" check end diff --git a/test/virtual/test_machine.rb b/test/virtual/test_machine.rb index e3634136..a6e17993 100644 --- a/test/virtual/test_machine.rb +++ b/test/virtual/test_machine.rb @@ -11,7 +11,7 @@ class Object end end HERE - @output = "-&5 Virtual::BootClass(:length => -1, :name => :Object, :super_class_name => :Object)*^* :instance_methods -Virtual::CompiledMethod(:name => :index_of, :class_name => :Object, :arg_names => &1 Virtual::Reference, :return_type => Virtual::Integer)*^* :locals []*^* :tmps []*^* :receiver [*1]*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -Virtual::CompiledMethod(:name => :_get_instance_variable, :class_name => :Object, :receiver => &1 Virtual::Reference, :return_type => &2 Virtual::Mystery)*^* :arg_names [*1]*^* :locals []*^* :tmps []*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -Virtual::CompiledMethod(:name => :_set_instance_variable, :class_name => :Object, :receiver => &1 Virtual::Reference, :return_type => &2 Virtual::Mystery)*^* :arg_names [*1, *1]*^* :locals []*^* :tmps []*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -&4 Virtual::CompiledMethod(:name => :get_class, :class_name => :Object)*^* :arg_names []*^* :locals []*^* :tmps []*^* :receiver Virtual::Self(:index => 3, :type => *2)*^* :return_type Virtual::NewReturn(:index => 5, :type => *2)*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::InstanceGet(:name => :layout)*^* -Virtual::NewMessage(:length => -1)*^* -Virtual::Set()*^* :to Virtual::NewSelf(:index => 3, :type => *2)*^* :from &3 Virtual::NewReturn(:index => 5, :type => *2)*^* -Virtual::Set()*^* :to Virtual::NewName(:index => 4, :type => *2)*^* :from Virtual::StringConstant(:string => :get_class)*^* -Virtual::MessageSend(:name => :get_class)*^* :me &3 Virtual::NewReturn(:index => 5, :type => *2)*^* :args []*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -&4 Virtual::CompiledMethod(:name => :get_class, :class_name => :Object)*^* :arg_names []*^* :locals []*^* :tmps []*^* :receiver Virtual::Self(:index => 3, :type => *2)*^* :return_type Virtual::NewReturn(:index => 5, :type => *2)*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::InstanceGet(:name => :layout)*^* -Virtual::NewMessage(:length => -1)*^* -Virtual::Set()*^* :to Virtual::NewSelf(:index => 3, :type => *2)*^* :from &3 Virtual::NewReturn(:index => 5, :type => *2)*^* -Virtual::Set()*^* :to Virtual::NewName(:index => 4, :type => *2)*^* :from Virtual::StringConstant(:string => :get_class)*^* -Virtual::MessageSend(:name => :get_class)*^* :me &3 Virtual::NewReturn(:index => 5, :type => *2)*^* :args []*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* :meta_class Virtual::MetaClass(:length => -1, :me_self => *5)*^* :functions []" + @output = "-&5 Virtual::BootClass(:length => -1, :name => :Object, :super_class_name => :Object)*^* :instance_methods -Virtual::CompiledMethod(:name => :index_of, :class_name => :Object, :arg_names => &1 Virtual::Reference, :return_type => Virtual::Integer)*^* :locals []*^* :tmps []*^* :receiver [*1]*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -Virtual::CompiledMethod(:name => :_get_instance_variable, :class_name => :Object, :receiver => &1 Virtual::Reference, :return_type => &2 Virtual::Mystery)*^* :arg_names [*1]*^* :locals []*^* :tmps []*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -Virtual::CompiledMethod(:name => :_set_instance_variable, :class_name => :Object, :receiver => &1 Virtual::Reference, :return_type => &2 Virtual::Mystery)*^* :arg_names [*1, *1]*^* :locals []*^* :tmps []*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -&4 Virtual::CompiledMethod(:name => :get_class, :class_name => :Object)*^* :arg_names []*^* :locals []*^* :tmps []*^* :receiver Virtual::Self(:index => 3, :type => *2)*^* :return_type Virtual::Return(:index => 5, :type => *2)*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::InstanceGet(:name => :layout)*^* -Virtual::NewMessage(:length => -1)*^* -Virtual::Set()*^* :to Virtual::NewSelf(:index => 3, :type => *2)*^* :from &3 Virtual::Return(:index => 5, :type => *2)*^* -Virtual::Set()*^* :to Virtual::NewName(:index => 4, :type => *2)*^* :from Virtual::StringConstant(:string => :get_class)*^* -Virtual::MessageSend(:name => :get_class)*^* :me &3 Virtual::Return(:index => 5, :type => *2)*^* :args []*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* -&4 Virtual::CompiledMethod(:name => :get_class, :class_name => :Object)*^* :arg_names []*^* :locals []*^* :tmps []*^* :receiver Virtual::Self(:index => 3, :type => *2)*^* :return_type Virtual::Return(:index => 5, :type => *2)*^* :blocks -Virtual::Block(:length => -1, :name => :enter)*^* :codes -Virtual::MethodEnter(:length => -1)*^* -Virtual::InstanceGet(:name => :layout)*^* -Virtual::NewMessage(:length => -1)*^* -Virtual::Set()*^* :to Virtual::NewSelf(:index => 3, :type => *2)*^* :from &3 Virtual::Return(:index => 5, :type => *2)*^* -Virtual::Set()*^* :to Virtual::NewName(:index => 4, :type => *2)*^* :from Virtual::StringConstant(:string => :get_class)*^* -Virtual::MessageSend(:name => :get_class)*^* :me &3 Virtual::Return(:index => 5, :type => *2)*^* :args []*^* -Virtual::Block(:length => -1, :name => :return)*^* :codes -Virtual::MethodReturn(:length => -1)*^* :meta_class Virtual::MetaClass(:length => -1, :me_self => *5)*^* :functions []" check end diff --git a/test/virtual/test_methods.rb b/test/virtual/test_methods.rb index 33ad463e..fe723b2e 100644 --- a/test/virtual/test_methods.rb +++ b/test/virtual/test_methods.rb @@ -2,14 +2,14 @@ require_relative "virtual_helper" class TestMethods < MiniTest::Test include VirtualHelper - + def test_simplest_function @string_input = < 5) do n = n + 1 return n - end + end end HERE @output = "" @@ -124,7 +124,7 @@ HERE def test_function_big_while @string_input = < 1 ) do tmp = a @@ -137,5 +137,5 @@ end HERE @output = "" check - end -end \ No newline at end of file + end +end diff --git a/test/virtual/virtual_helper.rb b/test/virtual/virtual_helper.rb index 487c0e78..8510ab8e 100644 --- a/test/virtual/virtual_helper.rb +++ b/test/virtual/virtual_helper.rb @@ -12,7 +12,7 @@ module VirtualHelper machine = Virtual::Machine.boot expressions = machine.compile_main @string_input is = Sof::Writer.write(expressions) -# puts is + #puts is is.gsub!("\n" , "*^*") assert_equal is , @output end