diff --git a/lib/parfait/behaviour.rb b/lib/parfait/behaviour.rb index 492c3858..66b3032d 100644 --- a/lib/parfait/behaviour.rb +++ b/lib/parfait/behaviour.rb @@ -1,8 +1,17 @@ -# Behaviour is something that has methods, basically class and modules superclass - -# instance_methods is the attribute in the including class that has the methods - module Parfait + # Behaviour is the old smalltalk name for the duperclass of class and meta_class + # + # Classes and meta_classes are in fact very similar, in that they manage + # - the type of instances + # - the methods for instances + # + # The main way they differ is that Classes manage type for a class of objects (ie many) + # whereas meta_class, or singleton_class manages the type of only one object (here a class) + # + # Singleton classes can manage the type/methods of any single object, and in the + # future off course they will, just not yet. Most single objects don't need that, + # only Classes and Modules _always _ do, so that's where we start. + # class Behaviour < Object attr_reader :instance_type , :instance_methods diff --git a/lib/parfait/meta_class.rb b/lib/parfait/meta_class.rb index da4324e7..cbcfb64b 100644 --- a/lib/parfait/meta_class.rb +++ b/lib/parfait/meta_class.rb @@ -43,6 +43,12 @@ module Parfait inspect end + # adding an instance changes the instance_type to include that variable + def add_instance_variable( name , type) + super(name,type) + @clazz.set_type(@instance_type) + end + # Nil name means no superclass, and so nil returned def super_class return nil diff --git a/lib/risc/parfait_adapter.rb b/lib/risc/parfait_adapter.rb index dd527a98..36dfd265 100644 --- a/lib/risc/parfait_adapter.rb +++ b/lib/risc/parfait_adapter.rb @@ -85,14 +85,14 @@ module Parfait # 0 -based index def get_internal_word(index) return @type if index == Parfait::TYPE_INDEX - name = Parfait.name_for_index(self , index) + name = self.type.names[index] return nil unless name instance_eval("@#{name}") end # 0 -based index def set_internal_word(index , value) - name = Parfait.name_for_index(self , index) + name = self.type.names[index] #unless name.is_a?(Symbol) raise "not sym for #{index} in #{self}:#{self.type}:#{name.class}" unless name.is_a?(Symbol) instance_eval("@#{name}=value" ) value @@ -100,16 +100,6 @@ module Parfait 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 def self.new_list array list = Parfait::List.new diff --git a/test/parfait/test_meta_class.rb b/test/parfait/test_meta_class.rb index 3a284194..71d67b1b 100644 --- a/test/parfait/test_meta_class.rb +++ b/test/parfait/test_meta_class.rb @@ -36,15 +36,18 @@ module Parfait assert_raises{ @try.add_instance_method(nil)} end def test_add_instance_variable_changes_type - before = @space.get_class.instance_type - @space.get_class.add_instance_variable(:counter , :Integer) - assert before != @space.get_class.instance_type + before = @try.instance_type + @try.add_instance_variable(:counter , :Integer) + assert before != @try.instance_type end def test_add_instance_variable_changes_type_hash - before = @space.get_class.instance_type.hash - @space.get_class.add_instance_variable(:counter , :Integer) - assert before != @space.get_class.instance_type.hash + before = @try.instance_type.hash + @try.add_instance_variable(:counter , :Integer) + assert before != @try.instance_type.hash + end + def test_add_instance_variable_changes_class_type + @try.add_instance_variable(:counter , :Integer) + assert_equal @try.clazz.type , @try.instance_type end - end end diff --git a/test/risc/interpreter/class/test_class_inst.rb b/test/risc/interpreter/class/test_class_inst.rb index fdfe4b2d..e549102a 100644 --- a/test/risc/interpreter/class/test_class_inst.rb +++ b/test/risc/interpreter/class/test_class_inst.rb @@ -1,7 +1,7 @@ require_relative "../helper" module Risc - class InterpreterSetters < MiniTest::Test + class InterpreterGetters < MiniTest::Test include Ticker def setup @@ -19,7 +19,7 @@ module Risc MAIN super end - +#Space type is wrong, shold be same as meta_class.instance_type def test_chain #show_main_ticks # get output of what is run_input @string_input diff --git a/test/risc/interpreter/class/test_class_inst_set.rb b/test/risc/interpreter/class/test_class_inst_set.rb index 32b0c2f1..a50b7ef9 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 est_chain + def test_chain #show_main_ticks # get output of what is run_input @string_input assert_equal 5 , get_return diff --git a/test/vool/class_send/test_class_instance.rb b/test/vool/class_send/test_class_instance.rb index 71767e59..f34ff75d 100644 --- a/test/vool/class_send/test_class_instance.rb +++ b/test/vool/class_send/test_class_instance.rb @@ -12,7 +12,7 @@ module Vool return @inst end def main(arg) - return Space.one_plus + return Space.some_inst end end eos @@ -20,16 +20,34 @@ module Vool def setup ret = RubyX::RubyXCompiler.new(RubyX.default_test_options).ruby_to_mom(class_main) - @ins = ret.compilers.find{|c|c.callable.name==:some_inst}.mom_instructions.next + @compiler = ret.compilers.find{|c|c.callable.name==:some_inst} + @main = ret.compilers.find{|c|c.callable.name==:main} + @ins = @compiler.mom_instructions.next end def test_class_inst - space_class = Parfait.object_space.get_class - assert_equal :Space , space_class.name - names = space_class.meta_class.instance_type.names - assert names.index_of(:inst) , names + space_class = Parfait.object_space.get_class + assert_equal :Space , space_class.name + names = space_class.meta_class.instance_type.names + assert names.index_of(:inst) , names + end + def test_compiler + assert_equal Mom::MethodCompiler, @compiler.class + assert_equal Parfait::Type, @compiler.callable.self_type.class + assert_equal 6, @compiler.callable.self_type.names.index_of(:inst) , @compiler.callable.self_type.names end def test_array - check_array [SlotLoad, ReturnJump, Label, ReturnSequence, Label] , @ins + check_array [SlotLoad, ReturnJump, Label, ReturnSequence, Label] , @ins + end + def test_main_array + check_array [MessageSetup, ArgumentTransfer, SimpleCall, SlotLoad, ReturnJump , + Label, ReturnSequence, Label] , @main.mom_instructions.next + end + def test_main_args + args = @main.mom_instructions.next(2) + assert_equal Parfait::Class , args.receiver.known_object.class + assert_equal :Space , args.receiver.known_object.name + assert_equal :some_inst , args.receiver.known_object.type.method_names.first + assert_equal :inst , args.receiver.known_object.type.names.last end def test_load_inst assert_equal SlotLoad, @ins.class diff --git a/test/vool/class_send/test_class_send_inherited.rb b/test/vool/class_send/test_class_send_inherited.rb index f78641ae..54c431f5 100644 --- a/test/vool/class_send/test_class_send_inherited.rb +++ b/test/vool/class_send/test_class_send_inherited.rb @@ -40,7 +40,7 @@ module Vool assert_equal SimpleCall, @ins.next(2).class assert_equal :one_plus, @ins.next(2).method.name assert_equal Parfait::Type, @ins.next(2).method.self_type.class - assert_equal :Object, @ins.next(2).method.self_type.object_class.name + assert_equal :Class, @ins.next(2).method.self_type.object_class.name end end end