diff --git a/lib/parfait.rb b/lib/parfait.rb index 84983572..3ca2f8aa 100644 --- a/lib/parfait.rb +++ b/lib/parfait.rb @@ -4,6 +4,7 @@ require "parfait/module" require "parfait/class" require "parfait/dictionary" require "parfait/list" +require "parfait/layout" require "parfait/word" require "parfait/message" require "parfait/frame" @@ -60,6 +61,16 @@ module Parfait end word end + def self.new_list array + list = List.new_object + list.set_length array.length + index = 0 + while index < array.length do + list.set(index , array[index]) + end + list + end + Word.class_eval do def to_s string = "" diff --git a/lib/parfait/class.rb b/lib/parfait/class.rb index 367e086f..50dd9991 100644 --- a/lib/parfait/class.rb +++ b/lib/parfait/class.rb @@ -22,6 +22,7 @@ module Parfait @name = name.to_sym @super_class_name = super_class_name.to_sym @meta_class = Virtual::MetaClass.new(self) + @object_layout = [] end attr_reader :name , :instance_methods , :meta_class , :context , :super_class_name def add_instance_method method @@ -30,6 +31,11 @@ module Parfait @instance_methods << method end + def set_instance_names list + @object_layout = Layout.new_object + @object_layout.set_names list + end + def get_instance_method fname fname = fname.to_sym @instance_methods.detect{ |fun| fun.name == fname } diff --git a/lib/parfait/layout.rb b/lib/parfait/layout.rb index 8f3d6604..9850cc32 100644 --- a/lib/parfait/layout.rb +++ b/lib/parfait/layout.rb @@ -22,6 +22,17 @@ module Parfait class Layout < List + # set the names of the instance variables in one go + # used while booting the classes. At runtime the list would grow dynamically + def set_names list + self.set_length list.length + index = 0 + while index < list.length do + list.set(index , array.get(index)) + end + end + + # beat the recursion! fixed known offset for class object in the layout def get_object_class() return internal_object_get(2) end diff --git a/lib/parfait/list.rb b/lib/parfait/list.rb index 136428d9..8f08628b 100644 --- a/lib/parfait/list.rb +++ b/lib/parfait/list.rb @@ -51,6 +51,10 @@ module Parfait end self end + def set_length len + # TODO check if not shrinking + grow_to len + end def grow_to(len) raise "negative length for grow #{len}" if len < 0 return unless len > self.length diff --git a/lib/parfait/space.rb b/lib/parfait/space.rb index b9463bff..20c351d7 100644 --- a/lib/parfait/space.rb +++ b/lib/parfait/space.rb @@ -55,12 +55,15 @@ module Parfait def get_class_by_name name raise "uups #{name}.#{name.class}" unless name.is_a? Symbol c = @classes[name] - unless c - c = Class.new_object(name) - @classes[name] = c - end c end + + def create_class name , variable_names + c = Class.new_object(name) + c.set_instance_names Parfait.new_list(variable_names) + @classes[name] = c + end + def mem_length padded_words( 5 ) end diff --git a/lib/virtual/machine.rb b/lib/virtual/machine.rb index 7030e6af..8a45c3df 100644 --- a/lib/virtual/machine.rb +++ b/lib/virtual/machine.rb @@ -93,11 +93,12 @@ module Virtual # very fiddly chicken 'n egg problem. Functions need to be in the right order, and in fact we # have to define some dummies, just for the other to compile # TODO: go through the virtual parfait layer and adjust function names to what they really are - obj = @space.get_class_by_name :Object + obj = @space.create_class :Object , [] [:index_of , :_get_instance_variable , :_set_instance_variable].each do |f| obj.add_instance_method Builtin::Object.send(f , nil) end - obj = @space.get_class_by_name :Kernel + obj = @space.create_class :Kernel , [] + puts "CREATE Kernel #{obj}" # create main first, __init__ calls it @main = Builtin::Kernel.send(:main , @context) obj.add_instance_method @main @@ -110,15 +111,15 @@ module Virtual # the point of which is that by the time main executes, all is "normal" @init = Block.new(:_init_ , nil ) @init.add_code(Register::RegisterMain.new(underscore_init)) - obj = @space.get_class_by_name :Integer + obj = @space.create_class :Integer , [] [:putint,:fibo].each do |f| obj.add_instance_method Builtin::Integer.send(f , nil) end - obj = @space.get_class_by_name :Word + obj = @space.create_class :Word , [] [:get , :set , :puts].each do |f| obj.add_instance_method Builtin::Word.send(f , nil) end - obj = space.get_class_by_name :Array + obj = space.create_class :Array , [] [:get , :set , :push].each do |f| obj.add_instance_method Builtin::Array.send(f , nil) end