diff --git a/lib/parfait/object2.rb b/lib/parfait/object2.rb new file mode 100644 index 00000000..a450c825 --- /dev/null +++ b/lib/parfait/object2.rb @@ -0,0 +1,93 @@ +# From a programmers perspective an object has hash like data (with instance variables as keys) +# and functions to work on that data. +# Only the object may access it's data directly. + +# From an implementation perspective it is a chunk of memory with a type as the first +# word (instance of class Type). + +# Objects are arranged or layed out (in memory) according to their Type +# every object has a Type. Type objects are immutable and may be reused for a group/class +# of objects. +# The Type of an object may change, but then a new Type is created +# The Type also defines the class of the object +# The Type is **always** the first entry (index 0) in an object + + + class Object + attr :type + + def == other + o_id = other.object_id + m_id = self.object_id + ok = m_id == o_id + return ok +# self.object_id == other.object_id + end + + # This is the core of the object system. + # The class of an object is stored in the objects memory + # + # In RubyX we store the class in the Type, and so the Type is the only fixed + # data that every object carries. + def get_class() + l = get_type() + #puts "Type #{l.class} in #{self.class} , #{self}" + l.object_class() + end + + # private + def set_type(typ) + raise "not type" + typ.class.to_s + "in " + object_id.to_s(16) unless typ.is_a?(Type) + self.type = typ + end + + # so we can keep the raise in get_type + def has_type? + ! type.nil? + end + + def get_type() + raise "No type " + self.object_id.to_s(16) + ":" + self.class.name unless has_type? + type + end + + def get_instance_variables + type.names + end + + def get_instance_variable( name ) + index = instance_variable_defined(name) + #puts "getting #{name} at #{index}" + return nil if index == nil + return get_internal_word(index) + end + + def set_instance_variable( name , value ) + index = instance_variable_defined(name) + return nil if index == nil + return set_internal_word(index , value) + end + + def instance_variable_defined( name ) + type.variable_index(name) + end + + def padded_length + Padding.padded_words( type.instance_length ) + end + + # parfait versions are deliberately called different, so we "relay" + # have to put the "" on the names for rfx to take them off again + def instance_variables + get_instance_variables.to_a.collect{ |n| n.to_s.to_sym } + end + + # name comes in as a ruby var name + def instance_variable_ged( name ) + #TODO the [] shoud be a range, but currenly that is not processed in RubyCompiler + var = get_instance_variable name.to_s[1 , name.to_s.length - 1].to_sym + #puts "getting #{name} #{var}" + var + end + + end diff --git a/lib/vool/return_statement.rb b/lib/vool/return_statement.rb index ce8bba8d..ccb0a230 100644 --- a/lib/vool/return_statement.rb +++ b/lib/vool/return_statement.rb @@ -8,7 +8,8 @@ module Vool end def each(&block) - block.call(@return_value) + block.call(self) + @return_value.each(&block) end # Since the return is normalized to only allow simple values it is simple. diff --git a/lib/vool/variables.rb b/lib/vool/variables.rb index a0977bbd..644cc23b 100644 --- a/lib/vool/variables.rb +++ b/lib/vool/variables.rb @@ -17,6 +17,9 @@ module Vool def to_s name.to_s end + def each(&block) + block.call(self) + end end class InstanceVariable < Expression @@ -31,10 +34,16 @@ module Vool def to_s(depth = 0) at_depth(depth , "@#{name}") end + def each(&block) + block.call(self) + end end class ClassVariable < Expression include Named + def each(&block) + block.call(self) + end end class ModuleName < Expression @@ -48,5 +57,8 @@ module Vool def get_named_class Parfait.object_space.get_class_by_name(self.name) end + def each(&block) + block.call(self) + end end end diff --git a/lib/vool/while_statement.rb b/lib/vool/while_statement.rb index 50cbd7bf..bf6da731 100644 --- a/lib/vool/while_statement.rb +++ b/lib/vool/while_statement.rb @@ -23,7 +23,7 @@ module Vool def each(&block) block.call(self) - block.call(@condition) + @condition.each(&block) @hoisted.each(&block) if @hoisted @body.each(&block) end diff --git a/test/mom/test_return_dynamic.rb b/test/mom/test_return_dynamic.rb index 55d4b7e8..8a9318c2 100644 --- a/test/mom/test_return_dynamic.rb +++ b/test/mom/test_return_dynamic.rb @@ -7,19 +7,19 @@ module Risc def setup super @input = "return @a.div4" - @expect = [LoadConstant, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #5 - OperatorInstruction, IsZero, SlotToReg, SlotToReg, SlotToReg, #10 - LoadConstant, RegToSlot, LoadConstant, LoadConstant, SlotToReg, #15 - SlotToReg, Label, LoadConstant, OperatorInstruction, IsZero, #20 - SlotToReg, OperatorInstruction, IsZero, SlotToReg, Branch, #25 - Label, LoadConstant, SlotToReg, Transfer, Syscall, #30 - Transfer, Transfer, SlotToReg, RegToSlot, Label, #35 - RegToSlot, Label, LoadConstant, SlotToReg, LoadConstant, #40 - SlotToReg, SlotToReg, RegToSlot, RegToSlot, RegToSlot, #45 - RegToSlot, SlotToReg, SlotToReg, SlotToReg, RegToSlot, #50 - LoadConstant, SlotToReg, RegToSlot, SlotToReg, LoadConstant, #55 - SlotToReg, DynamicJump, Label, SlotToReg, SlotToReg, #60 - RegToSlot, SlotToReg, SlotToReg, RegToSlot, Branch] #65 + @expect = [LoadConstant, SlotToReg, SlotToReg, SlotToReg, SlotToReg, #4 + OperatorInstruction, IsZero, SlotToReg, SlotToReg, SlotToReg, #9 + LoadConstant, RegToSlot, LoadConstant, LoadConstant, SlotToReg, #14 + SlotToReg, Label, LoadConstant, OperatorInstruction, IsZero, #19 + SlotToReg, OperatorInstruction, IsZero, SlotToReg, Branch, #24 + Label, LoadConstant, SlotToReg, Transfer, Syscall, #29 + Transfer, Transfer, SlotToReg, RegToSlot, Label, #34 + RegToSlot, Label, LoadConstant, SlotToReg, LoadConstant, #39 + SlotToReg, SlotToReg, RegToSlot, RegToSlot, RegToSlot, #44 + RegToSlot, SlotToReg, SlotToReg, SlotToReg, RegToSlot, #49 + LoadConstant, SlotToReg, RegToSlot, SlotToReg, LoadConstant, #54 + SlotToReg, DynamicJump, Label, SlotToReg, RegToSlot, #59 + Branch] #64 end def test_return_instructions @@ -27,7 +27,7 @@ module Risc end def test_function_return produced = produce_body - assert_equal Branch , produced.next(64).class + assert_equal Branch , produced.next(60).class end def test_cache_check produced = produce_body diff --git a/test/vool/test_class_statement.rb b/test/vool/test_class_statement.rb index 4f67616f..b9198adf 100644 --- a/test/vool/test_class_statement.rb +++ b/test/vool/test_class_statement.rb @@ -5,8 +5,8 @@ module Vool class TestClassStatement < MiniTest::Test include ScopeHelper def setup - Parfait.boot!({}) - ruby_tree = Ruby::RubyCompiler.compile( as_test_main("a = 5") ) + Parfait.boot!(Parfait.default_test_options) + ruby_tree = Ruby::RubyCompiler.compile( as_test_main("@a = 5") ) @vool = ruby_tree.to_vool end def test_class @@ -21,6 +21,47 @@ module Vool def test_create_class assert_equal :Test , @vool.create_class_object.name end + def test_class_instance + assert_equal :a , @vool.create_class_object.instance_type.names[1] + end + end + class TestClassStatementTypeCreation < MiniTest::Test + include ScopeHelper + def setup + Parfait.boot!(Parfait.default_test_options) + end + def assert_type_for(input) + ruby_tree = Ruby::RubyCompiler.compile( as_test_main(input) ) + vool = ruby_tree.to_vool + assert_equal ClassStatement , vool.class + clazz = vool.create_class_object + assert_equal Parfait::Class , clazz.class + assert_equal :a , clazz.instance_type.names[1] + end + def test_while_cond + assert_type_for("while(@a) ; 1 == 1 ; end") + end + def test_while_cond_eq + assert_type_for("while(@a==1); 1 == 1 ; end") + end + def test_if_cond + assert_type_for("if(@a); 1 == 1 ; end") + end + def test_send_1 + assert_type_for("@a.call") + end + def test_send_arg + assert_type_for("call(@a)") + end + def test_return + assert_type_for("return @a") + end + def test_return_call + assert_type_for("return call(@a)") + end + def test_return_rec + assert_type_for("return @a.call()") + end end class TestClassStatementCompile < MiniTest::Test include VoolCompile