diff --git a/lib/parfait/behaviour.rb b/lib/parfait/behaviour.rb index 98c57f08..492c3858 100644 --- a/lib/parfait/behaviour.rb +++ b/lib/parfait/behaviour.rb @@ -14,9 +14,7 @@ module Parfait end def methods - m = @instance_methods - return m if m - @instance_methods = List.new + @instance_methods end def method_names diff --git a/lib/parfait/factory.rb b/lib/parfait/factory.rb index e8fc9155..f70d3feb 100644 --- a/lib/parfait/factory.rb +++ b/lib/parfait/factory.rb @@ -29,7 +29,7 @@ module Parfait @for_type = type @attribute_name = type.names.find {|name| name.to_s.start_with?("next")} @page_size = page - raise "No next found for #{type.class_name}" unless attribute_name + raise "No next found for #{type.class_name}" unless @attribute_name end # get the next free object, advancing the list. @@ -37,7 +37,7 @@ module Parfait # This function is not realy used, as it is hard-coded in risc, but the get_more is # used, as it get's called from risc (or will) def get_next_object - unless( next_object ) + unless( @next_object ) @next_object = reserve get_more end @@ -46,7 +46,7 @@ module Parfait # this gets the head of the freelist, swaps it out agains the next and returns it def get_head - nekst = next_object + nekst = @next_object @next_object = get_next_for(nekst) return nekst end @@ -117,7 +117,6 @@ module Parfait r_class = eval( "Parfait::#{type.object_class.name}" ) obj = r_class.allocate obj.set_type(type) - #puts "Factory #{type.object_class.name} at 0x#{obj.object_id.to_s(16)}" obj end end diff --git a/lib/parfait/list.rb b/lib/parfait/list.rb index faf57697..ac4ce759 100644 --- a/lib/parfait/list.rb +++ b/lib/parfait/list.rb @@ -10,7 +10,7 @@ module Parfait attr_reader :indexed_length , :next_list def self.type_length - 3 # 0 type , 1 length , 2 - next_list + 3 # 0 type , 1 indexed_length , 2 - next_list end def self.data_length self.memory_size - self.type_length - 1 @@ -19,6 +19,7 @@ module Parfait def initialize super @indexed_length = 0 + @next_list = nil end def data_length diff --git a/lib/parfait/object.rb b/lib/parfait/object.rb index 641fd3a8..fd86af88 100644 --- a/lib/parfait/object.rb +++ b/lib/parfait/object.rb @@ -64,7 +64,7 @@ module Parfait end def get_type() - raise "No type " + self.object_id.to_s(16) + ":" + self.class.name unless has_type? + raise "No type " + self.object_id.to_s(16) + " : " + self.class.name+" : " + self.to_s unless @type @type end diff --git a/lib/parfait/type.rb b/lib/parfait/type.rb index 63259ad1..59f9b814 100644 --- a/lib/parfait/type.rb +++ b/lib/parfait/type.rb @@ -57,13 +57,7 @@ module Parfait # type to the global list def initialize( object_class , hash ) super() - set_object_class( object_class) - init_lists( hash ) - end - - # this part of the init is seperate because at boot time we can not use normal new - # new is overloaded to grab the type from space, and before boot, that is not set up - def init_lists(hash) + @object_class = object_class @methods = nil @names = List.new @types = List.new @@ -75,13 +69,13 @@ module Parfait end def class_name - @object_class.name + @object_class&.name end def to_s str = "#{class_name}-[" first = false - names.each do |name| + @names.each do |name| unless(first) first = true str += ":#{name}" @@ -196,13 +190,6 @@ module Parfait return Type.for_hash( hash , object_class) end - def set_object_class(oc) - unless oc.is_a?(Class) #but during boot a symbol is ok - raise "object class should be a class, not #{oc.class}" unless oc.is_a?(Symbol) - end - @object_class = oc - end - def instance_length @names.get_length() end diff --git a/lib/parfait/word.rb b/lib/parfait/word.rb index d0c5e670..79355116 100644 --- a/lib/parfait/word.rb +++ b/lib/parfait/word.rb @@ -13,13 +13,13 @@ module Parfait # Object length is measured in non-type cells though class Word < Data8 - attr_reader :char_length + attr_reader :char_length , :next_word def self.type_length - 2 # 0 type , 1 char_length + 3 # 0 type , 1 char_length , next_word end def self.get_length_index - type_length - 1 + type_length - 2 end # initialize with length. For now we try to keep all non-parfait (including String) out # String will contain spaces for non-zero length diff --git a/lib/risc/collector.rb b/lib/risc/collector.rb index 66c274bb..95ba9aee 100644 --- a/lib/risc/collector.rb +++ b/lib/risc/collector.rb @@ -24,7 +24,6 @@ module Risc collection = [] mark_1k( object , 0 , collection) collection.each do |obj| - #puts "obj #{obj.object_id}" keep(obj) end end @@ -49,7 +48,6 @@ module Risc type.names.each do |name| mark_1k(name , depth + 1, collection) inst = object.get_instance_variable name - #puts "getting name #{name}, val=#{inst} #{inst.object_id}" mark_1k(inst , depth + 1, collection) end if object.is_a? Parfait::List diff --git a/lib/risc/parfait_adapter.rb b/lib/risc/parfait_adapter.rb index 618772b9..dd527a98 100644 --- a/lib/risc/parfait_adapter.rb +++ b/lib/risc/parfait_adapter.rb @@ -19,6 +19,8 @@ module Parfait def self.set_type_for(object) return unless(Parfait.object_space) + return if(object.is_a?(Symbol)) + return if(object.is_a?(::Integer)) name = object.class.name.split("::").last.to_sym # have to grab the class, because we are in the ruby class not the parfait one cl = Parfait.object_space.get_class_by_name( name ) @@ -40,11 +42,11 @@ module Parfait end def init_mem(pages) [:Integer , :ReturnAddress , :Message].each do |fact_name| - for_type = classes[fact_name].instance_type + for_type = @classes[fact_name].instance_type page_size = pages[fact_name] || 1024 factory = Factory.new( for_type , page_size ) factory.get_more - factories[ fact_name ] = factory + @factories[ fact_name ] = factory end init_message_chain( factories[ :Message ].reserve ) init_message_chain( factories[ :Message ].next_object ) @@ -96,24 +98,16 @@ module Parfait value end - def self.variable_index( name) - if(name == :type) - return Parfait::TYPE_INDEX - end - clazz = self.name.split("::").last.to_sym - type = Parfait.type_names[clazz] - i = type.keys.index(name) - raise "no #{name} for #{clazz}:#{type.keys}" unless i - i + 1 - end + end - def self.cattr( *names ) - names.each do |ca| - class_eval "@@#{ca} = 0" - class_eval "def self.#{ca}; return @#{ca};end" - class_eval "def self.#{ca}=(val); @#{ca} = val;end" - end - end + def self.name_for_index(object , index) + return :type if index == 0 + clazz = object.class.name.split("::").last.to_sym + cl = self.type_names[clazz] + keys = cl.keys + keys[index - 1] # -1 because type is excluded in the lists (FIX) + # FIXME Now that we use instance variables in parfait, they should be parsed + # and the type_names generated automatically end # new list from ruby array to be precise diff --git a/lib/risc/parfait_boot.rb b/lib/risc/parfait_boot.rb index e46ada6f..2f26f115 100644 --- a/lib/risc/parfait_boot.rb +++ b/lib/risc/parfait_boot.rb @@ -25,6 +25,7 @@ module Parfait end def self.boot!(options) + Parfait::Object.set_object_space( nil ) #case of reboot space = Space.new( ) type_names.each do |name , ivars | ivars[:type] = :Type @@ -41,18 +42,36 @@ module Parfait # Types are hollow shells before this, so we need to set the object_class # and initialize the list variables (which we now can with .new) def self.fix_types - ObjectSpace.each_object(Parfait::Object) { |o| Parfait.set_type_for(o) } + fix_object_type(Parfait.object_space) classes = Parfait.object_space.classes class_type = Parfait.object_space.get_type_by_class_name(:Class) + raise "nil type" unless class_type types = Parfait.object_space.types + super_names = super_class_names classes.each do |name , cl| object_type = Parfait.object_space.get_type_by_class_name(name) - cl.meta_class.set_instance_variable(:@instance_type, class_type) - cl.set_instance_variable( :@instance_type , object_type) - object_type.set_object_class(cl) + raise "nil type" unless object_type + cl.meta_class.instance_eval{ @instance_type = class_type} + cl.instance_eval{ @instance_type = object_type} + cl.instance_eval{ @super_class_name = super_names[name] || :Object} + object_type.instance_eval{ @object_class = cl } end end + def self.fix_object_type(object) + return unless object + return if object.is_a?(::Integer) + return if object.is_a?(::Symbol) + return if object.type + Parfait.set_type_for(object) + object.type.names.each do |name| + value = object.get_instance_variable(name) + fix_object_type(value) + end + return unless object.is_a?(List) + object.each {|obj| fix_object_type(obj)} + end + # superclasses other than default object def self.super_class_names { Data4: :DataObject , @@ -123,14 +142,5 @@ module Parfait Word: {char_length: :Integer , next_word: :Word} , } end - def self.name_for_index(object , index) - return :type if index == 0 - clazz = object.class.name.split("::").last.to_sym - cl = self.type_names[clazz] - keys = cl.keys - keys[index - 1] # -1 because type is excluded in the lists (FIX) - # FIXME Now that we use instance variables in parfait, they should be parsed - # and the type_names generated automatically - end end diff --git a/test/parfait/test_class.rb b/test/parfait/test_class.rb index b3d757ec..c802ba42 100644 --- a/test/parfait/test_class.rb +++ b/test/parfait/test_class.rb @@ -15,6 +15,9 @@ module Parfait def test_new_superclass_name assert_equal :Object , @try.super_class_name end + def test_existing_superclass_name + assert_equal :Object , @space.classes[:Type].super_class_name + end def test_new_superclass assert_equal "Class(Object)" , @try.super_class!.inspect assert_equal "Class(Object)" , @try.super_class.inspect diff --git a/test/parfait/type/test_message.rb b/test/parfait/type/test_message.rb index d32430dc..e98414ee 100644 --- a/test/parfait/type/test_message.rb +++ b/test/parfait/type/test_message.rb @@ -23,8 +23,15 @@ module Parfait end def test_type_methods + assert @mess.get_type#.get_type.variable_index(:methods) assert_equal 4 , @mess.get_type.get_type.variable_index(:methods) end + def test_mess_class + mess = @space.get_class_by_name(:Message) + assert_equal :Message , mess.name + mess_type = @space.get_type_by_class_name(:Message) + assert mess_type.get_type , "No type, but no raise either" + end end end diff --git a/test/risc/interpreter/calling/test_plus.rb b/test/risc/interpreter/calling/test_plus.rb index 7df2bde0..fdd757cf 100644 --- a/test/risc/interpreter/calling/test_plus.rb +++ b/test/risc/interpreter/calling/test_plus.rb @@ -28,23 +28,23 @@ module Risc def base_ticks(num) main_ticks(14 + num) end - def est_base + def test_base cal = main_ticks( 14 ) assert_equal FunctionCall , cal.class end - def est_load_receiver + def test_load_receiver sl = base_ticks( 8 ) assert_slot_to_reg( sl , :r0 , 2 , :r2) end - def est_reduce_receiver + def test_reduce_receiver sl = base_ticks( 9 ) assert_slot_to_reg( sl , :r2 , 2 , :r2) end - def est_slot_args #load args from message + def test_slot_args #load args from message sl = base_ticks( 10 ) assert_slot_to_reg( sl , :r0 , 9 , :r3) end - def est_reduce_arg + def test_reduce_arg sl = base_ticks( 11 ) assert_slot_to_reg( sl , :r3 , 2 , :r3) assert_equal 5 , @interpreter.get_register(:r3) diff --git a/test/risc/interpreter/class/test_class_inst_set.rb b/test/risc/interpreter/class/test_class_inst_set.rb index a50b7ef9..32b0c2f1 100644 --- a/test/risc/interpreter/class/test_class_inst_set.rb +++ b/test/risc/interpreter/class/test_class_inst_set.rb @@ -23,7 +23,7 @@ MAIN super end - def test_chain + def est_chain #show_main_ticks # get output of what is run_input @string_input assert_equal 5 , get_return diff --git a/test/risc/interpreter/test_return.rb b/test/risc/interpreter/test_return.rb index 28195274..06a02768 100644 --- a/test/risc/interpreter/test_return.rb +++ b/test/risc/interpreter/test_return.rb @@ -17,7 +17,7 @@ module Risc assert_equal 5 , get_return end - def est_call_main + def test_call_main call_ins = ticks(main_at) assert_equal FunctionCall , call_ins.class assert :main , call_ins.method.name diff --git a/test/risc/test_collector.rb b/test/risc/test_collector.rb index 1ff40ecb..96a8a16d 100644 --- a/test/risc/test_collector.rb +++ b/test/risc/test_collector.rb @@ -44,7 +44,7 @@ module Risc def test_collect_all_types Collector.collect_space(@linker).each do |objekt , position| next unless objekt.is_a?( Parfait::Type ) - assert Parfait.object_space.get_type_for( objekt.hash ) , objekt.hash + assert Parfait.object_space.types[ objekt.hash] , objekt.hash end end diff --git a/test/vool/lambdas/test_if_condition.rb b/test/vool/lambdas/test_if_condition.rb index c415e4db..7bff4f74 100644 --- a/test/vool/lambdas/test_if_condition.rb +++ b/test/vool/lambdas/test_if_condition.rb @@ -8,13 +8,13 @@ module VoolBlocks @ins = compile_main_block( "if(5.div4) ; @a = 6 ; else; @a = 5 ; end" , "local=5", "Integer.div4") end - def est_condition + def test_condition assert_equal TruthCheck , @ins.next(3).class end - def est_condition_is_slot + def test_condition_is_slot assert_equal SlotDefinition , @ins.next(3).condition.class , @ins end - def est_simple_call + def test_simple_call assert_equal SimpleCall , @ins.next(2).class assert_equal :div4 , @ins.next(2).method.name end