turned out to be a rewrite of boot process

and also attribute handling and fake_memory
luckily there are tests and all is green again
This commit is contained in:
Torsten Ruger
2015-07-21 15:40:25 +03:00
parent f8cb33ec5e
commit 2d0424a370
19 changed files with 258 additions and 221 deletions

View File

@ -12,9 +12,9 @@ module Parfait
class BinaryCode < Word
def initialize name
super(0)
@name = name
self.name = name
end
attr_reader :name
attribute :name
# this is a sof check if there are instance variables or "structure"
# have to override false, as word answers true
@ -22,7 +22,7 @@ module Parfait
false
end
def to_s
"BinaryCode #{@name}"
"BinaryCode #{self.name}"
end
def == other

View File

@ -14,16 +14,13 @@ require_relative "meta_class"
module Parfait
class Class < Module
attribute :object_layout
def initialize name , super_class
super( name , super_class)
# the layout for this class (class = object of type Class) carries the class
# as an instance. The relation is from an object through the Layout to it's class
@object_layout = Layout.new(self)
end
def object_layout
@object_layout
self.object_layout = Layout.new(self)
end
def allocate_object
@ -31,7 +28,7 @@ module Parfait
end
def add_instance_name name
@object_layout.push name
self.object_layout.push name
end
def sof_reference_name

View File

@ -2,35 +2,25 @@
module Parfait
class Dictionary < Object
attribute :keys
attribute :values
# only empty initialization for now
#
# internally we store keys and values in lists, which means this does **not** scale well
def initialize
super()
@keys = List.new()
@values = List.new()
end
# return all values as a list
# TODO, list should be copied to avoid inconcisencies
def values()
@values
end
# return all keys as a list
# TODO, list should be copied to avoid inconcisencies
def keys()
@keys
self.keys = List.new()
self.values = List.new()
end
# are there any key/value items in the list
def empty?
@keys.empty?
self.keys.empty?
end
# How many key/value pairs there are
def length()
return @keys.get_length()
return self.keys.get_length()
end
# get a value fot the given key
@ -39,7 +29,7 @@ module Parfait
def get(key)
index = key_index(key)
if( index )
@values.get(index)
self.values.get(index)
else
nil
end
@ -52,11 +42,11 @@ module Parfait
# private method
def key_index(key)
len = @keys.get_length()
len = self.keys.get_length()
index = 1
found = nil
while(index <= len)
if( @keys.get(index) == key)
if( self.keys.get(index) == key)
found = index
break
end
@ -69,10 +59,10 @@ module Parfait
def set(key , value)
index = key_index(key)
if( index )
@keys.set(index , value)
self.keys.set(index , value)
else
@keys.push(key)
@values.push(value)
self.keys.push(key)
self.values.push(value)
end
value
end
@ -85,9 +75,9 @@ module Parfait
# yield to each key value pair
def each
index = 1
while index <= @keys.get_length
key = @keys.get(index)
value = @values.get(index)
while index <= self.keys.get_length
key = self.keys.get(index)
value = self.values.get(index)
yield key , value
index = index + 1
end

View File

@ -22,10 +22,11 @@
module Parfait
class Layout < List
attribute :object_class
def initialize( object_class )
super()
@object_class = object_class
self.object_class = object_class
end
def == other
@ -45,23 +46,30 @@ module Parfait
# beat the recursion! fixed known offset for class object in the layout
def get_object_class()
return @object_class
return self.object_class
end
def object_instance_names
names = List.new
index = 1
index = 2 # first is object_class
while index <= self.get_length
item = get(index)
names.push item
index = index + 1
end
self
names
end
# index of a variable name into the layout.
# layout is a list, so lowest index is 1
# :layout is a variable for every object, so 1 is taken for :layout
# still, the index is the same.
def variable_index name
index_of(name)
end
def sof_reference_name
"#{@object_class.name}_Layout"
"#{self.object_class.name}_Layout"
end
end

View File

@ -9,18 +9,19 @@
module Parfait
class Message < Object
attributes [:next_message , :frame, :caller]
attributes [:receiver , :return_address , :return_value , :name]
def initialize next_m
@next_message = next_m
@frame = Frame.new()
@caller = nil
self.next_message = next_m
self.frame = Frame.new()
self.caller = nil
super()
end
attr_reader :next_message , :frame , :caller # aka prev_message
attr_reader :receiver , :return_address , :return_value , :name
def set_caller caller
@caller = caller
self.caller = caller
end
def get_type_for(name)

View File

@ -18,26 +18,26 @@ module Parfait
def initialize(object)
super()
@functions = []
@me_self = object
self.functions = []
self.me_self = object
end
# in a non-booting version this should map to _add_singleton_method
def add_function function
raise "not a function #{function}" unless function.is_a? Virtual::Function
raise "syserr " unless function.name.is_a? Symbol
@functions << function
self.functions << function
end
def get_function name
name = name.to_sym
f = @functions.detect{ |f| f.name == name }
f = self.functions.detect{ |f| f.name == name }
return f if f
if( @me_self == "Object" )
puts "no function for :#{name} in Meta #{@me_self.inspect}"
if( self.me_self == "Object" )
puts "no function for :#{name} in Meta #{self.me_self.inspect}"
return nil
else #recurse up class hierachy unless we're at Object
return @me_self.context.object_space.get_class_by_name(@me_self.super_class).get_function name
return self.me_self.context.object_space.get_class_by_name(self.me_self.super_class).get_function name
end
end
@ -52,7 +52,7 @@ module Parfait
end
def to_s
"#{inspect} on #{@me_self}, #{@functions.length} functions"
"#{inspect} on #{self.me_self}, #{self.functions.length} functions"
end
end
end

View File

@ -22,14 +22,14 @@ module Parfait
def initialize clazz , name , arg_names
super()
raise "No class #{name}" unless clazz
@for_class = clazz
@name = name
@code = BinaryCode.new name
@arg_names = arg_names
@locals = List.new
@tmps = List.new
self.for_class = clazz
self.name = name
self.code = BinaryCode.new name
self.arg_names = arg_names
self.locals = List.new
self.tmps = List.new
end
attr_reader :name , :arg_names , :for_class , :code , :locals , :tmps
attributes [:name , :arg_names , :for_class , :code , :locals , :tmps]
# determine whether this method has a variable by the given name
@ -46,32 +46,32 @@ module Parfait
# determine whether this method has an argument by the name
def has_arg name
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
@arg_names.index_of name
self.arg_names.index_of name
end
# determine if method has a local variable or tmp (anonymous local) by given name
def has_local name
raise "uups #{name}.#{name.class}" unless name.is_a? Symbol
index = @locals.index_of(name)
index = @tmps.index_of(name) unless index
index = self.locals.index_of(name)
index = self.tmps.index_of(name) unless index
index
end
def ensure_local name
index = has_local name
return index if index
@locals.push name
@locals.get_length
self.locals.push name
self.locals.get_length
end
def get_var name
var = has_var name
raise "no var #{name} in method #{self.name} , #{@locals} #{@arg_names}" unless var
raise "no var #{name} in method #{self.name} , #{self.locals} #{self.arg_names}" unless var
var
end
def sof_reference_name
@name
self.name
end
end

View File

@ -13,25 +13,23 @@
module Parfait
class Module < Object
attribute :name
attribute :instance_methods
attribute :super_class
attribute :meta_class
def initialize name , superclass
super()
@name = name
@instance_methods = List.new
@super_class = superclass
@meta_class = nil#MetaClass.new(self)
self.name = name
self.instance_methods = List.new
self.super_class = superclass
self.meta_class = nil#MetaClass.new(self)
end
def name
@name
end
def instance_methods
@instance_methods
end
def method_names
names = List.new
@instance_methods.each do |method|
self.instance_methods.each do |method|
names.push method.name
end
names
@ -42,36 +40,36 @@ module Parfait
raise "syserr #{method.name.class}" unless method.name.is_a? Symbol
found = get_instance_method( method.name )
if found
@instance_methods.delete(found)
self.instance_methods.delete(found)
#raise "existed in #{self.name} #{Sof.write found.source.blocks}"
end
@instance_methods.push method
self.instance_methods.push method
#puts "#{self.name} add #{method.name}"
method
end
def remove_instance_method method
@instance_methods.delete method
self.instance_methods.delete method
end
def create_instance_method name , arg_names
raise "uups #{name}.#{name.class}" unless name.is_a?(Symbol)
clazz = Space.object_space.get_class_by_name(self.name)
raise "??? #{self.name}" unless clazz
Method.new( clazz , name , arg_names )
def create_instance_method method_name , arg_names
raise "uups #{method_name}.#{method_name.class}" unless method_name.is_a?(Symbol)
clazz = get_layout().object_class()
raise "??? #{method_name}" unless clazz
Method.new( clazz , method_name , arg_names )
end
# this needs to be done during booting as we can't have all the classes and superclassses
# instantiated. By that logic it should maybe be part of vm rather.
# On the other hand vague plans to load the hierachy from sof exist, so for now...
def set_super_class sup
@super_class = sup
self.super_class = sup
end
def get_instance_method fname
raise "uups #{fname}.#{fname.class}" unless fname.is_a?(Symbol)
#if we had a hash this would be easier. Detect or find would help too
@instance_methods.each do |m|
self.instance_methods.each do |m|
return m if(m.name == fname )
end
nil
@ -82,8 +80,8 @@ module Parfait
raise "uups #{m_name}.#{m_name.class}" unless m_name.is_a?(Symbol)
method = get_instance_method(m_name)
return method if method
if( @super_class )
method = @super_class.resolve_method(m_name)
if( self.super_class )
method = self.super_class.resolve_method(m_name)
raise "Method not found #{m_name}, for \n#{self}" unless method
end
method

View File

@ -19,11 +19,26 @@ module Parfait
def self.new *args
object = self.allocate
#HACK, but used to do the adapter in the init, bu that is too late now
object.fake_init if object.respond_to?(:fake_init) # at compile, not run-time
# have to grab the class, because we are in the ruby class not the parfait one
cl = Space.object_space.get_class_by_name( self.name.split("::").last.to_sym)
# and have to set the layout before we let the object do anything. otherwise boom
object.set_layout cl.object_layout
object.send :initialize , *args
#puts "NEW #{object.class}"
object
end
def self.attributes names
names.each{|name| attribute(name) }
end
def self.attribute name
define_method(name) { get_instance_variable(name) }
define_method("#{name}=".to_sym) { |value| set_instance_variable(name , value) }
end
def == other
self.object_id == other.object_id
end
@ -42,8 +57,8 @@ module Parfait
# data that every object carries.
def get_class()
l = get_layout()
puts "Layout #{l.class} in #{self.class} , #{self}"
l.get_object_class()
#puts "Layout #{l.class} in #{self.class} , #{self}"
l.object_class()
end
# private
@ -60,6 +75,7 @@ module Parfait
def get_layout()
l = internal_object_get(LAYOUT_INDEX)
#puts "get layout for #{self.class} returns #{l.class}"
raise "No layout #{self.object_id.to_s(16)}:#{self.class} " unless l
return l
end
@ -70,6 +86,7 @@ module Parfait
def get_instance_variable name
index = instance_variable_defined(name)
#puts "getting #{name} at #{index}"
return nil if index == nil
return internal_object_get(index)
end
@ -81,7 +98,7 @@ module Parfait
end
def instance_variable_defined name
get_layout().index_of(name)
get_layout().variable_index(name)
end
def word_length

View File

@ -22,22 +22,19 @@ module Parfait
class Space < Object
def initialize
super()
Parfait::Space.set_object_space self
@classes = Parfait::Dictionary.new
raise "Space can not be instantiated by new, you'd need a space to do so. Chicken and egg"
end
attr_reader :classes , :first_message
attributes [:classes , :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
message = Message.new(nil)
5.times do
@first_message = Message.new message
message.set_caller @first_message
message = @first_message
self.first_message = Message.new message
message.set_caller self.first_message
message = self.first_message
end
init_layout
end
@@object_space = nil
@ -64,8 +61,8 @@ module Parfait
# return nili if no such class. Use bang version if create should be implicit
def get_class_by_name name
raise "uups #{name}.#{name.class}" unless name.is_a?(Symbol)
c = @classes[name]
puts "MISS, no class #{name} #{name.class}" unless c # " #{@classes}"
c = self.classes[name]
#puts "MISS, no class #{name} #{name.class}" unless c # " #{self.classes}"
c
end
@ -82,7 +79,7 @@ module Parfait
def create_class name , superclass
raise "uups #{name.class}" unless name.is_a? Symbol
c = Class.new(name , superclass)
@classes[name] = c
self.classes[name] = c
end
def sof_reference_name