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:
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user