diff --git a/lib/parfait/named_list.rb b/lib/parfait/named_list.rb deleted file mode 100644 index 8bd4644d..00000000 --- a/lib/parfait/named_list.rb +++ /dev/null @@ -1,42 +0,0 @@ - -# A NamedList is used to store local variables and arguments when calling methods. -# Also temporary variables, which are local variables named by the system - -# The items are named (and typed) by the objects type instance. In effect the -# variables are like instance variables - -# A Message with is arguments, and a NamedList make up the two sides of message passing: -# A Message (see details there) is created by the caller and control is transferred -# A NamedList is created by the receiver -# PS: it turns out that both messages and named_lists are created at compile, not run-time, and -# just constantly reused. Each message has two named_list object ready and is also linked -# to the next message. -# The better way to say above is that a message is *used* by the caller, and a named_list -# by the callee. - -# Also at runtime Messages and NamedLists remain completely "normal" objects. -# Ie they have have type and instances and so on.* -# Which resolves the dichotomy of objects on the stack or heap. Sama sama. -# -# *Alas the type for each call instance is unique. -# -module Parfait - class NamedList < Object - - def self.memory_size - 16 - end - - def to_s - str = "NamedList len= #{get_length}" - str += " at #{Risc::Position.get(self)}" if Risc::Position.set?(self) - end - def get_length - get_type.get_length - 1 - end - def self.type_for( arguments ) - my_class = Parfait.object_space.classes[:NamedList] - Type.for_hash( my_class , {type: my_class.instance_type}.merge(arguments)) - end - end -end diff --git a/lib/parfait/space.rb b/lib/parfait/space.rb index df1a0c71..465d2b36 100644 --- a/lib/parfait/space.rb +++ b/lib/parfait/space.rb @@ -151,10 +151,17 @@ module Parfait # this is the way to instantiate classes (not Parfait::Class.new) # so we get and keep exactly one per name + # + # The superclass must be known when the class is created, or it raises an error. + # The class is initiated with the type of the superclass (hence above) + # + # Only Vool::ClassExpression really ever creates classes and "grows" the type + # according to the instances it finds, see there + # def create_class( name , superclass = nil ) raise "create_class #{name.class}" unless name.is_a? Symbol superclass = :Object unless superclass - raise "create_class #{superclass.class}" unless superclass.is_a? Symbol + raise "create_class failed for #{name}:#{superclass.class}" unless superclass.is_a? Symbol type = get_type_by_class_name(superclass) c = Class.new(name , superclass , type ) @classes[name] = c diff --git a/lib/parfait/type.rb b/lib/parfait/type.rb index f504a4d9..9df2b87f 100644 --- a/lib/parfait/type.rb +++ b/lib/parfait/type.rb @@ -42,12 +42,19 @@ module Parfait 5 end - def self.for_hash( object_class , hash) + def self.for_hash( hash , object_class = :Object) + name = object_class + if(object_class.is_a?(Symbol)) + object_class = Parfait.object_space.get_class_by_name(object_class) + end + raise "No such class #{name}" unless object_class hash = {type: object_class.name }.merge(hash) unless hash[:type] new_type = Type.new( object_class , hash) Parfait.object_space.add_type(new_type) end + # should not be called directly. Use Type.for_hash instead, that adds the + # type to the global list def initialize( object_class , hash ) super() set_object_class( object_class) @@ -185,7 +192,7 @@ module Parfait raise "No nil type" unless type hash = to_hash hash[name] = type - return Type.for_hash( object_class , hash) + return Type.for_hash( hash , object_class) end def set_object_class(oc) diff --git a/lib/risc/parfait_boot.rb b/lib/risc/parfait_boot.rb index 465721c8..e13c01c0 100644 --- a/lib/risc/parfait_boot.rb +++ b/lib/risc/parfait_boot.rb @@ -156,7 +156,7 @@ module Parfait attribute_name: :Word , page_size: :Integer }, Integer: {next_integer: :Integer}, List: {indexed_length: :Integer , next_list: :List} , - Message: { next_message: :Message, receiver: :Object, frame: :NamedList , + Message: { next_message: :Message, receiver: :Object, frame: :Object , return_address: :Integer, return_value: :Object, caller: :Message , method: :TypedMethod , arguments_given: :Integer , @@ -168,7 +168,6 @@ module Parfait local9: :Object ,local10: :Object, local11: :Object , local12: :Object, local13: :Object, local14: :Object, local15: :Object}, MetaClass: {instance_methods: :List, instance_type: :Type, clazz: :Class }, - NamedList: {}, NilClass: {}, Object: {}, ReturnAddress: {next_integer: :ReturnAddress}, diff --git a/lib/vool/class_expression.rb b/lib/vool/class_expression.rb index bf950ab2..96d31b91 100644 --- a/lib/vool/class_expression.rb +++ b/lib/vool/class_expression.rb @@ -60,20 +60,24 @@ module Vool #FIXME super class check with "sup" #existing class, don't overwrite type (parfait only?) else - @clazz = Parfait.object_space.create_class(@name , @super_class_name ) - #TODO this should start from Object Type and add one name at a time. - # So the "trail" of types leading to this one exists. - # Also the Class always has a valid type. - ivar_hash = {} - self.each do |node| - next unless node.is_a?(InstanceVariable) or node.is_a?(IvarAssignment) - ivar_hash[node.name] = :Object - end - @clazz.set_instance_type( Parfait::Type.for_hash( @clazz , ivar_hash ) ) + create_new_class end @clazz end + def create_new_class + @clazz = Parfait.object_space.create_class(@name , @super_class_name ) + #TODO this should start from Object Type and add one name at a time. + # So the "trail" of types leading to this one exists. + # Also the Class always has a valid type. + ivar_hash = {} + self.each do |node| + next unless node.is_a?(InstanceVariable) or node.is_a?(IvarAssignment) + ivar_hash[node.name] = :Object + end + @clazz.set_instance_type( Parfait::Type.for_hash( ivar_hash , @clazz ) ) + end + def to_s(depth = 0) at_depth(depth , "class #{name}" , @body.to_s(depth + 1) , "end") end diff --git a/lib/vool/class_method_expression.rb b/lib/vool/class_method_expression.rb index 9ba05ca4..77040980 100644 --- a/lib/vool/class_method_expression.rb +++ b/lib/vool/class_method_expression.rb @@ -25,7 +25,7 @@ module Vool def make_arg_type( ) type_hash = {} @args.each {|arg| type_hash[arg] = :Object } - Parfait::NamedList.type_for( type_hash ) + Parfait::Type.for_hash( type_hash ) end def to_s(depth = 0) @@ -43,7 +43,7 @@ module Vool next unless node.is_a?(LocalVariable) or node.is_a?(LocalAssignment) type_hash[node.name] = :Object end - Parfait::NamedList.type_for( type_hash ) + Parfait::Type.for_hash( type_hash ) end end diff --git a/lib/vool/lambda_expression.rb b/lib/vool/lambda_expression.rb index 3f5b9391..51499eb4 100644 --- a/lib/vool/lambda_expression.rb +++ b/lib/vool/lambda_expression.rb @@ -48,7 +48,7 @@ module Vool def make_arg_type( ) type_hash = {} @args.each {|arg| type_hash[arg] = :Object } - Parfait::NamedList.type_for( type_hash ) + Parfait::Type.for_hash( type_hash ) end def make_frame(compiler) type_hash = {} @@ -57,7 +57,7 @@ module Vool next if compiler.in_scope?(node.name) type_hash[node.name] = :Object end - Parfait::NamedList.type_for( type_hash ) + Parfait::Type.for_hash( type_hash ) end end diff --git a/lib/vool/method_expression.rb b/lib/vool/method_expression.rb index 98d829b4..357fc086 100644 --- a/lib/vool/method_expression.rb +++ b/lib/vool/method_expression.rb @@ -38,7 +38,7 @@ module Vool type_hash = {} @args.each {|arg| type_hash[arg] = :Object } type_hash[:implicit_block] = :Block if has_yield? - Parfait::NamedList.type_for( type_hash ) + Parfait::Type.for_hash( type_hash ) end def to_s(depth = 0) @@ -60,7 +60,7 @@ module Vool next unless node.is_a?(LocalVariable) or node.is_a?(LocalAssignment) type_hash[node.name] = :Object end - Parfait::NamedList.type_for( type_hash ) + Parfait::Type.for_hash( type_hash ) end end diff --git a/test/parfait/test_named_list.rb b/test/parfait/test_named_list.rb deleted file mode 100644 index 4ec45e7d..00000000 --- a/test/parfait/test_named_list.rb +++ /dev/null @@ -1,19 +0,0 @@ -require_relative "helper" - -module Parfait - class TestNamedLists < ParfaitTest - - def test_new - list = NamedList.new - assert list.get_type - end - def test_var_names - list = NamedList.new - assert_equal List , list.get_instance_variables.class - end - def test_var_names_length - list = NamedList.new - assert_equal 1 , list.get_instance_variables.get_length - end - end -end diff --git a/test/parfait/test_object2.rb b/test/parfait/test_object2.rb index 180d7dc3..a5b13a5c 100644 --- a/test/parfait/test_object2.rb +++ b/test/parfait/test_object2.rb @@ -32,7 +32,7 @@ module Parfait assert_equal 64 , list.padded_length end def test_type - type = Parfait::Type.for_hash Parfait.object_space.get_class_by_name(:Object) , {} + type = Parfait::Type.for_hash( {} ) type.set_type( type ) assert_equal 32 , type.padded_length end diff --git a/test/parfait/test_space.rb b/test/parfait/test_space.rb index a21301c1..7cd574bb 100644 --- a/test/parfait/test_space.rb +++ b/test/parfait/test_space.rb @@ -6,7 +6,7 @@ module Parfait def classes [:BinaryCode,:Block,:CacheEntry,:Callable,:CallableMethod,:Class, :DataObject,:Data4,:Data8,:Data16,:Data32,:Dictionary,:Factory, :Integer,:FalseClass, - :List,:Message, :MetaClass, :NamedList,:NilClass,:Object,:ReturnAddress, + :List,:Message, :MetaClass,:NilClass,:Object,:ReturnAddress, :Space,:TrueClass,:Type,:VoolMethod,:Word] end @@ -123,7 +123,7 @@ module Parfait end def test_created_class_is_stored - @space.create_class( :NewerClass ) + clazz = @space.create_class( :NewerClass ) assert @space.get_class_by_name(:NewerClass) end diff --git a/test/parfait/type/test_hash.rb b/test/parfait/type/test_hash.rb index 4b9ab24e..6109cf6c 100644 --- a/test/parfait/type/test_hash.rb +++ b/test/parfait/type/test_hash.rb @@ -37,9 +37,8 @@ module Parfait end def test_hash_for_no_ivars - list = @space.get_class_by_name(:NamedList ) - t1 = Parfait::Type.for_hash( list , type: :NewInt) - t2 = Parfait::Type.for_hash( list , type: :NewObj) + t1 = Parfait::Type.for_hash( {type: :NewInt}) + t2 = Parfait::Type.for_hash( {type: :NewObj}) assert t1.hash != t2.hash , "Hashes should differ" end end diff --git a/test/parfait/type/test_method_api.rb b/test/parfait/type/test_method_api.rb index 4b878512..f71bd23b 100644 --- a/test/parfait/type/test_method_api.rb +++ b/test/parfait/type/test_method_api.rb @@ -10,10 +10,10 @@ module Parfait end def empty_frame - Parfait::Type.for_hash( @try_class , { }) + Parfait::Type.for_hash( { } , @try_class) end def foo_method( for_class = :Try) - args = Parfait::Type.for_hash( @try_class , { bar: :Integer}) + args = Parfait::Type.for_hash( { bar: :Integer} , @try_class ) CallableMethod.new( :foo ,@space.get_type_by_class_name(for_class) , args,empty_frame) end def add_foo_to( clazz = :Try ) @@ -44,7 +44,7 @@ module Parfait end end def test_create_method - args = Parfait::Type.for_hash( @try_class , { bar: :Integer}) + args = Parfait::Type.for_hash( { bar: :Integer} , @try_class) @try_type.create_method :bar, args , empty_frame assert @try_type.method_names.inspect.include?("bar") end diff --git a/test/parfait/type/test_type_api.rb b/test/parfait/type/test_type_api.rb index af2a1491..1915f034 100644 --- a/test/parfait/type/test_type_api.rb +++ b/test/parfait/type/test_type_api.rb @@ -5,7 +5,7 @@ module Parfait def setup super - tc = @space.get_class_by_name( :NamedList ) + tc = @space.get_class_by_name( :Object ) @type = tc.instance_type end diff --git a/test/support/parfait_test.rb b/test/support/parfait_test.rb index 4f4cb0da..7d857358 100644 --- a/test/support/parfait_test.rb +++ b/test/support/parfait_test.rb @@ -2,8 +2,8 @@ module Parfait module MethodHelper def make_method(name = :meth , clazz = :Object) @obj = Parfait.object_space.get_type_by_class_name(clazz) - @args = Parfait::Type.for_hash( @obj.object_class , { bar: :Integer , foo: :Type}) - @frame = Parfait::Type.for_hash( @obj.object_class , { local_bar: :Integer , local_foo: :Type}) + @args = Parfait::Type.for_hash( { bar: :Integer , foo: :Type} , @obj.object_class) + @frame = Parfait::Type.for_hash( { local_bar: :Integer , local_foo: :Type},@obj.object_class) @method = Parfait::CallableMethod.new( name , @obj , @args , @frame) end end