basic immutability for type

add_instance_variable now uses global type list to check
adds hash and to_has functions
use backdoor (send) for booting
This commit is contained in:
Torsten Ruger
2016-12-08 12:50:25 +02:00
parent 137d3c9231
commit a31f75fe93
5 changed files with 108 additions and 19 deletions

View File

@ -93,8 +93,8 @@ module Register
# helper to create a Type, name is the parfait name, ie :Type
def type_for( name , ivars )
l = Parfait::Type.allocate.compile_time_init
l.add_instance_variable :type , name
ivars.each {|n,t| l.add_instance_variable( n , t) }
l.send(:private_add_instance_variable , :type , name)
ivars.each {|n,t| l.send(:private_add_instance_variable, n , t) }
l
end

View File

@ -10,7 +10,7 @@ module Soml
index = for_class.instance_type.variable_index(statement.name)
#raise "class field already defined:#{name} for class #{for_class.name}" if index
#puts "Define field #{name} on class #{for_class.name}"
index = for_class.instance_type.add_instance_variable( statement.name , statement.type )
for_class.instance_type.add_instance_variable( statement.name , statement.type )
return nil # statements don't reurn values, only expressions
end

View File

@ -40,10 +40,31 @@ module Parfait
include Indexed
self.offset(3)
def initialize( object_class )
def self.new_for_hash( object_class , hash)
new_type = Type.new( object_class , hash)
code = new_type.hash
Space.object_space.types[code] = new_type
new_type
end
def self.hash_code_for( dict )
index = 1
hash = 0
dict.each do |name , type|
item_hash = name.hash + type.hash
hash += item_hash + (item_hash / 256 ) * index
index += 1
end
hash
end
def initialize( object_class , hash = nil)
super()
add_instance_variable :type ,:Type
private_add_instance_variable :type ,:Type
self.object_class = object_class
hash.each do |name , type|
private_add_instance_variable name , type
end if hash
end
def == other
@ -51,17 +72,18 @@ module Parfait
end
# add the name of an instance variable
# The index will be returned and can subsequently be searched with index_of
# The index of the name is the index of the data in the object
#
# TODO , later we would need to COPY the type to keep the old constant
# but now we are concerned with booting, ie getting a working structure
def add_instance_variable name , type
raise "Name shouldn't be nil" unless name
raise "Value Type shouldn't be nil" unless type
self.push(name)
self.push(type)
self.get_length
# Type objects are immutable, so a new object is returned
# As types are also unique, two same adds will result in identical results
def add_instance_variable( name , type )
hash = to_hash
hash[name] = type
code = Type.hash_code_for( hash )
existing = Space.object_space.types[code]
if existing
return existing
else
return Type.new_for_hash( object_class , hash)
end
end
def instance_names
@ -108,8 +130,26 @@ module Parfait
nil # stop resolve recursing up metaclasses
end
def hash
h = name.hash
def to_hash
hash = Dictionary.new
each_pair do |name, type |
hash[name] = type
end
hash
end
def hash
Type.hash_code_for( to_hash )
end
private
def private_add_instance_variable( name , type)
raise "Name shouldn't be nil" unless name
raise "Value Type shouldn't be nil" unless type
self.push(name)
self.push(type)
end
end
end