diff --git a/lib/typed/parfait/space.rb b/lib/typed/parfait/space.rb index da476663..8785f162 100644 --- a/lib/typed/parfait/space.rb +++ b/lib/typed/parfait/space.rb @@ -21,26 +21,27 @@ module Parfait class Space < Object - def initialize - raise "Space can not be instantiated by new, you'd need a space to do so. Chicken and egg" - end - attributes [:classes , :types, :first_message] - - # need a two phase init for the object space (and generally parfait) because the space - # is an interconnected graph, so not everthing is ready - def late_init + def initialize(classes ) + @classes = classes + @types = Dictionary.new message = Message.new(nil) 50.times do - self.first_message = Message.new message - #puts "INIT caller #{message.object_id} to #{self.first_message.object_id}" - message.set_caller self.first_message - message = self.first_message + @first_message = Message.new message + #puts "INIT caller #{message.object_id} to #{@first_message.object_id}" + message.set_caller @first_message + message = @first_message end - classes.each do |name , cl| - types[cl.instance_type.hash] = cl.instance_type + @classes.each do |name , cl| + @types[cl.instance_type.hash] = cl.instance_type end end + def self.attributes + [:classes , :types, :first_message] + end + + attr_reader :types , :classes , :first_message + # Make the object space globally available def self.object_space @@object_space @@ -65,8 +66,8 @@ module Parfait # return nili if no such class. Use bang version if create should be implicit def get_class_by_name( name ) raise "get_class_by_name #{name}.#{name.class}" unless name.is_a?(Symbol) - c = self.classes[name] - #puts "MISS, no class #{name} #{name.class}" unless c # " #{self.classes}" + c = @classes[name] + #puts "MISS, no class #{name} #{name.class}" unless c # " #{@classes}" #puts "CLAZZ, #{name} #{c.get_type.get_length}" if c c end @@ -76,16 +77,18 @@ module Parfait def get_class_by_name! name c = get_class_by_name(name) return c if c - create_class name , get_class_by_name(:Object) + create_class name end # this is the way to instantiate classes (not Parfait::Class.new) # so we get and keep exactly one per name - def create_class name , superclass + def create_class( name , superclass = nil ) raise "create_class #{name.class}" unless name.is_a? Symbol superclass = :Object unless superclass - c = Class.new(name , superclass ) - self.classes[name] = c + raise "create_class #{superclass.class}" unless superclass.is_a? Symbol + type = get_class_by_name(superclass).instance_type + c = Class.new(name , superclass , type ) + @classes[name] = c end def sof_reference_name diff --git a/lib/typed/parfait/typed_method.rb b/lib/typed/parfait/typed_method.rb index a9ada113..13f092b3 100644 --- a/lib/typed/parfait/typed_method.rb +++ b/lib/typed/parfait/typed_method.rb @@ -22,7 +22,12 @@ module Parfait class TypedMethod < Object - attributes [:name , :source , :instructions , :binary ,:arguments , :for_type, :locals ] + def self.attributes + [:name , :source , :instructions , :binary ,:arguments , :for_type, :locals ] + end + + attr_reader :name , :instructions , :for_type ,:arguments , :locals , :binary + # not part of the parfait model, hence ruby accessor attr_accessor :source @@ -31,12 +36,15 @@ module Parfait raise "No class #{name}" unless type raise "For type, not class #{type}" unless type.is_a?(Type) raise "Wrong argument type, expect Type not #{arguments.class}" unless arguments.is_a? Type - self.for_type = type - self.name = name - self.binary = BinaryCode.new 0 - self.arguments = arguments - self.locals = Type.new Space.object_space.get_class_by_name( :Object ) + @for_type = type + @name = name + @binary = BinaryCode.new 0 + @arguments = arguments + @locals = Type.new Space.object_space.get_class_by_name( :Object ) + end + def set_instructions(inst) + @instructions = inst end # determine whether this method has an argument by the name @@ -47,7 +55,7 @@ module Parfait end def add_argument(name , type) - self.arguments = self.arguments.add_instance_variable(name,type) + @arguments = @arguments.add_instance_variable(name,type) end def arguments_length @@ -55,10 +63,10 @@ module Parfait end def argument_name( index ) - arguments.get(index * 2 + 1) + arguments.names.get(index + 1) end def argument_type( index ) - arguments.get(index * 2 + 2) + arguments.types.get(index + 1) end # determine if method has a local variable or tmp (anonymous local) by given name @@ -71,7 +79,7 @@ module Parfait def add_local( name , type ) index = has_local name return index if index - self.locals = self.locals.add_instance_variable(name,type) + @locals = @locals.add_instance_variable(name,type) end def locals_length @@ -79,18 +87,19 @@ module Parfait end def locals_name( index ) - locals.get(index * 2 + 1) + locals.names.get(index + 1) end + def locals_type( index ) - locals.get(index * 2 + 2) + locals.types.get(index + 1) end def sof_reference_name - "Method: " + self.name.to_s + "Method: " + @name.to_s end def inspect - "#{self.for_type.object_class.name}:#{name}(#{arguments.inspect})" + "#{@for_type.object_class.name}:#{name}(#{arguments.inspect})" end end diff --git a/test/typed/parfait/test_space.rb b/test/typed/parfait/test_space.rb index a87f9570..74fb62d3 100644 --- a/test/typed/parfait/test_space.rb +++ b/test/typed/parfait/test_space.rb @@ -74,4 +74,13 @@ class TestSpace < MiniTest::Test assert all.include?(:next_message) end + def test_create_class + assert @machine.space.create_class( :NewClass ) + end + + def test_created_class_is_stored + @machine.space.create_class( :NewerClass ) + assert @machine.space.get_class_by_name(:NewerClass) + end + end