From 502cfa357df3b389557830129c50d49cf9f2b750 Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 8 Nov 2015 13:39:13 +0200 Subject: [PATCH] implement and test field access --- lib/parfait/variable.rb | 2 +- lib/soml/compiler/field_access.rb | 19 +++++++--- test/compiler/statements/test_fields.rb | 46 +++++++++++++++++++++++++ 3 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 test/compiler/statements/test_fields.rb diff --git a/lib/parfait/variable.rb b/lib/parfait/variable.rb index 5ee7e486..99d7c902 100644 --- a/lib/parfait/variable.rb +++ b/lib/parfait/variable.rb @@ -2,7 +2,7 @@ module Parfait class Variable < Object def initialize type , name , value = nil - raise "not type #{type}" unless Register.machine.space.get_class_by_name(type) + raise "not type #{type}(#{type.class})" unless Register.machine.space.get_class_by_name(type) self.type , self.name , self.value = type , name , value self.value = 0 if self.type == :Integer and value == nil raise "must give name for variable" unless name diff --git a/lib/soml/compiler/field_access.rb b/lib/soml/compiler/field_access.rb index 9a07f216..e7f358ca 100644 --- a/lib/soml/compiler/field_access.rb +++ b/lib/soml/compiler/field_access.rb @@ -11,18 +11,29 @@ module Soml when :self index = @clazz.object_layout.variable_index(field_name) raise "field access, but no such field:#{field_name} for class #{@clazz.name}" unless index - value = use_reg(@clazz.name) #TODO incorrect, this is the self, but should be the type of variable at index + value = use_reg(@clazz.name) #TODO incorrect, this is the self, but should be the type of variable at index add_code Register.get_slot(statement , :message , :receiver , value ) # reuse the register for next move move = Register.get_slot(statement, value , index , value ) add_code move - return value when :message #message Slot raise "message not yet" else - #arg / frame Slot - raise "frame not implemented" + if( index = @method.has_arg(receiver)) #argument + value = use_reg @method.arguments[index].type + code = Register.get_slot(statement , :message , Parfait::Message.get_indexed(index), value) + else # or a local so it is in the frame + index = @method.has_local( receiver ) + if(index) + value = use_reg @method.locals[index].type + frame = use_reg :Frame + add_code Register.get_slot(statement , :message , :frame , frame ) + code = Register.get_slot(statement ,frame , Parfait::Frame.get_indexed(index) , value ) + else + raise "Variable not defined #{name}" + end + end end value diff --git a/test/compiler/statements/test_fields.rb b/test/compiler/statements/test_fields.rb new file mode 100644 index 00000000..bb713145 --- /dev/null +++ b/test/compiler/statements/test_fields.rb @@ -0,0 +1,46 @@ +require_relative 'helper' + + +module Register + class TestFieldStatement < MiniTest::Test + include Statements + + def test_field_frame + @string_input = <