2018-05-28 13:46:26 +02:00
|
|
|
require_relative "fake_memory"
|
|
|
|
|
|
|
|
|
2019-09-09 19:26:54 +02:00
|
|
|
module Parfait
|
2019-09-22 18:10:47 +02:00
|
|
|
class Object
|
|
|
|
# redefine the runtime version
|
|
|
|
def self.new( *args )
|
|
|
|
object = self.allocate
|
|
|
|
Parfait.set_type_for(object)
|
|
|
|
object.send :initialize , *args
|
|
|
|
object
|
|
|
|
end
|
|
|
|
# Setter fo the boot process, only at runtime.
|
|
|
|
# only one space exists and it is generated at compile time, not runtime
|
|
|
|
def self.set_object_space( space )
|
|
|
|
@object_space = space
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.set_type_for(object)
|
|
|
|
return unless(Parfait.object_space)
|
|
|
|
name = object.class.name.split("::").last.to_sym
|
|
|
|
# have to grab the class, because we are in the ruby class not the parfait one
|
|
|
|
cl = Parfait.object_space.get_class_by_name( name )
|
|
|
|
# and have to set the type before we let the object do anything. otherwise boom
|
|
|
|
raise "No such class #{name} for #{object}" unless cl
|
|
|
|
object.set_type cl.instance_type
|
|
|
|
end
|
|
|
|
|
|
|
|
class Space < Object
|
|
|
|
|
|
|
|
# Space can only ever be creared at compile time, not runtime
|
|
|
|
def initialize( )
|
|
|
|
@classes = Dictionary.new
|
|
|
|
@types = Dictionary.new
|
|
|
|
@factories = Dictionary.new
|
|
|
|
@true_object = Parfait::TrueClass.new
|
|
|
|
@false_object = Parfait::FalseClass.new
|
|
|
|
@nil_object = Parfait::NilClass.new
|
|
|
|
end
|
|
|
|
def init_mem(pages)
|
|
|
|
[:Integer , :ReturnAddress , :Message].each do |fact_name|
|
|
|
|
for_type = classes[fact_name].instance_type
|
|
|
|
page_size = pages[fact_name] || 1024
|
|
|
|
factory = Factory.new( for_type , page_size )
|
|
|
|
factory.get_more
|
|
|
|
factories[ fact_name ] = factory
|
|
|
|
end
|
|
|
|
init_message_chain( factories[ :Message ].reserve )
|
|
|
|
init_message_chain( factories[ :Message ].next_object )
|
|
|
|
end
|
|
|
|
def init_message_chain( message )
|
|
|
|
prev = nil
|
|
|
|
while(message)
|
|
|
|
message.initialize
|
|
|
|
message._set_caller(prev) if prev
|
|
|
|
prev = message
|
|
|
|
message = message.next_message
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2019-09-09 19:26:54 +02:00
|
|
|
class DataObject < Object
|
2018-05-28 13:46:26 +02:00
|
|
|
def self.allocate
|
|
|
|
r = super
|
2018-08-11 18:13:09 +02:00
|
|
|
r.instance_variable_set(:@memory , Risc::FakeMemory.new(r ,self.type_length , self.memory_size))
|
2018-05-28 13:46:26 +02:00
|
|
|
r
|
|
|
|
end
|
|
|
|
# 0 -based index
|
|
|
|
def get_internal_word(index)
|
2019-09-10 13:49:02 +02:00
|
|
|
return super(index) if index < self.class.type_length
|
2019-09-09 19:26:54 +02:00
|
|
|
@memory[ index ]
|
2018-05-28 13:46:26 +02:00
|
|
|
end
|
|
|
|
|
2018-05-28 17:20:09 +02:00
|
|
|
# 0 -based index
|
2018-05-28 13:46:26 +02:00
|
|
|
def set_internal_word(index , value)
|
2019-09-09 19:26:54 +02:00
|
|
|
return super(index,value) if index < self.class.type_length
|
|
|
|
@memory[ index ] = value
|
2018-05-28 13:46:26 +02:00
|
|
|
end
|
2019-09-09 19:26:54 +02:00
|
|
|
end
|
2018-08-11 18:13:09 +02:00
|
|
|
|
2019-09-09 19:26:54 +02:00
|
|
|
class Object
|
|
|
|
|
|
|
|
# 0 -based index
|
|
|
|
def get_internal_word(index)
|
|
|
|
return @type if index == Parfait::TYPE_INDEX
|
|
|
|
name = Parfait.name_for_index(self , index)
|
|
|
|
return nil unless name
|
|
|
|
instance_eval("@#{name}")
|
|
|
|
end
|
|
|
|
|
|
|
|
# 0 -based index
|
|
|
|
def set_internal_word(index , value)
|
|
|
|
name = Parfait.name_for_index(self , index)
|
2019-09-22 18:10:47 +02:00
|
|
|
raise "not sym for #{index} in #{self}:#{self.type}:#{name.class}" unless name.is_a?(Symbol)
|
2019-09-09 19:26:54 +02:00
|
|
|
instance_eval("@#{name}=value" )
|
|
|
|
value
|
2018-08-11 18:13:09 +02:00
|
|
|
end
|
|
|
|
|
2018-08-12 12:09:34 +02:00
|
|
|
def self.variable_index( name)
|
|
|
|
if(name == :type)
|
|
|
|
return Parfait::TYPE_INDEX
|
|
|
|
end
|
|
|
|
clazz = self.name.split("::").last.to_sym
|
|
|
|
type = Parfait.type_names[clazz]
|
|
|
|
i = type.keys.index(name)
|
|
|
|
raise "no #{name} for #{clazz}:#{type.keys}" unless i
|
|
|
|
i + 1
|
|
|
|
end
|
|
|
|
|
2019-03-04 18:56:53 +01:00
|
|
|
def self.cattr( *names )
|
|
|
|
names.each do |ca|
|
|
|
|
class_eval "@@#{ca} = 0"
|
|
|
|
class_eval "def self.#{ca}; return @#{ca};end"
|
|
|
|
class_eval "def self.#{ca}=(val); @#{ca} = val;end"
|
|
|
|
end
|
|
|
|
end
|
2018-05-28 13:46:26 +02:00
|
|
|
end
|
2018-06-29 13:26:25 +02:00
|
|
|
|
|
|
|
# new list from ruby array to be precise
|
|
|
|
def self.new_list array
|
|
|
|
list = Parfait::List.new
|
|
|
|
list.set_length array.length
|
|
|
|
index = 0
|
|
|
|
while index < array.length do
|
|
|
|
list.set(index , array[index])
|
|
|
|
index = index + 1
|
|
|
|
end
|
|
|
|
list
|
|
|
|
end
|
|
|
|
|
|
|
|
# Word from string
|
|
|
|
def self.new_word( string )
|
|
|
|
string = string.to_s if string.is_a? Symbol
|
|
|
|
word = Word.new( string.length )
|
|
|
|
string.codepoints.each_with_index do |code , index |
|
|
|
|
word.set_char(index , code)
|
|
|
|
end
|
|
|
|
word
|
|
|
|
end
|
|
|
|
|
2018-05-28 13:46:26 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
class Symbol
|
|
|
|
|
|
|
|
def has_type?
|
|
|
|
true
|
|
|
|
end
|
|
|
|
def get_type
|
|
|
|
l = Parfait.object_space.classes[:Word].instance_type
|
|
|
|
#puts "LL #{l.class}"
|
|
|
|
l
|
|
|
|
end
|
|
|
|
def padded_length
|
2019-08-17 20:07:07 +02:00
|
|
|
Parfait::Object.padded( to_s.length + 4)
|
2018-05-28 13:46:26 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
end
|