make all instances attr read writers

unfortunately the writers have to have self.var =
otherwise it is just a local var
Also need to make the type explicit for all
Protocol included memory_length on the class for now
This commit is contained in:
Torsten Ruger 2018-08-11 19:15:34 +03:00
parent e6df473647
commit b0aefe31fe
19 changed files with 243 additions and 216 deletions

View File

@ -7,13 +7,13 @@ module Parfait
def initialize def initialize
super() super()
@instance_methods = List.new instance_methods = List.new
end end
def methods def methods
m = @instance_methods m = instance_methods
return m if m return m if m
@instance_methods = List.new instance_methods = List.new
end end
def method_names def method_names
@ -45,7 +45,7 @@ module Parfait
raise "resolve_method #{m_name}.#{m_name.class}" unless m_name.is_a?(Symbol) raise "resolve_method #{m_name}.#{m_name.class}" unless m_name.is_a?(Symbol)
method = get_instance_method(m_name) method = get_instance_method(m_name)
return method if method return method if method
if( @super_class_name != :Object ) if( super_class_name != :Object )
method = self.super_class.resolve_method(m_name) method = self.super_class.resolve_method(m_name)
end end
method method

View File

@ -7,7 +7,7 @@ module Parfait
# and as the last code of each link is a jump to the next link. # and as the last code of each link is a jump to the next link.
# #
class BinaryCode < Data16 class BinaryCode < Data16
attr_reader :next attr :type, :next_code
def self.type_length def self.type_length
2 #type + next (could get from space, maybe later) 2 #type + next (could get from space, maybe later)
@ -27,35 +27,36 @@ module Parfait
def initialize(total_size) def initialize(total_size)
super() super()
self.next_code = nil
extend_to(total_size ) extend_to(total_size )
(0 ... data_length).each{ |index| set_word(index , 0) } (0 ... data_length).each{ |index| set_word(index , 0) }
set_last(0) set_last(0)
end end
def extend_to(total_size) def extend_to(total_size)
return if total_size < data_length return if total_size < data_length
extend_one() unless @next extend_one() unless next_code
@next.extend_to(total_size - data_length) next_code.extend_to(total_size - data_length)
end end
def extend_one() def extend_one()
@next = BinaryCode.new(1) self.next_code = BinaryCode.new(1)
Risc::Position.get(self).trigger_inserted if Risc::Position.set?(self) Risc::Position.get(self).trigger_inserted if Risc::Position.set?(self)
end end
def ensure_next def ensure_next
extend_one unless @next extend_one unless next_code
@next next_code
end end
def last_code def last_code
last = self last = self
last = last.next while(last.next) last = last.next_code while(last.next_code)
last last
end end
def each_block( &block ) def each_block( &block )
block.call( self ) block.call( self )
@next.each_block( &block ) if @next next_code.each_block( &block ) if next_code
end end
def to_s def to_s
@ -74,9 +75,9 @@ module Parfait
def set_word(index , word) def set_word(index , word)
raise "invalid index #{index}" if index < 0 raise "invalid index #{index}" if index < 0
if index >= data_length if index >= data_length
#raise "invalid index #{index}" unless @next #raise "invalid index #{index}" unless next
extend_to( index ) extend_to( index )
@next.set_word( index - data_length , word) next_code.set_word( index - data_length , word)
else else
set_internal_word(index + BinaryCode.type_length , word) set_internal_word(index + BinaryCode.type_length , word)
end end
@ -90,15 +91,15 @@ module Parfait
def get_word(index) def get_word(index)
raise "invalid index #{index}" if index < 0 raise "invalid index #{index}" if index < 0
if index >= data_length if index >= data_length
raise "invalid index #{index}" unless @next raise "invalid index #{index}" unless next_code
return @next.get_word( index - data_length) return next_code.get_word( index - data_length)
end end
get_internal_word(index + BinaryCode.type_length) get_internal_word(index + BinaryCode.type_length)
end end
def set_char(index , char) def set_char(index , char)
if index >= byte_length if index >= byte_length
#puts "Pass it on #{index} for #{self.object_id}:#{@next.object_id}" #puts "Pass it on #{index} for #{self.object_id}:#{next_code.object_id}"
return @next.set_char( index - byte_length , char ) return next_code.set_char( index - byte_length , char )
end end
word_index = (index - 1) / 4 + 2 word_index = (index - 1) / 4 + 2
old = get_internal_word( word_index ) old = get_internal_word( word_index )
@ -107,8 +108,8 @@ module Parfait
end end
def total_byte_length(start = 0 ) def total_byte_length(start = 0 )
start += self.byte_length start += self.byte_length
return start unless self.next return start unless self.next_code
self.next.total_byte_length(start) self.next_code.total_byte_length(start)
end end
end end
end end

View File

@ -16,7 +16,7 @@ module Parfait
end end
def inspect def inspect
"#{@self_type.object_class.name}(#{arguments_type.inspect})" "#{self_type.object_class.name}(#{arguments_type.inspect})"
end end
end end
end end

View File

@ -8,12 +8,11 @@
module Parfait module Parfait
class CacheEntry < Object class CacheEntry < Object
attr :cached_type attr :type, :cached_type, :cached_method
attr :cached_method
def initialize(type , method) def initialize(type , method)
@cached_type = type self.cached_type = type
@cached_method = method self.cached_method = method
end end
def to_s def to_s

View File

@ -8,34 +8,39 @@ module Parfait
# - frame_type: A type object describing the local variables that the method has # - frame_type: A type object describing the local variables that the method has
# - binary: The binary (jumpable) code that instructions get assembled into # - binary: The binary (jumpable) code that instructions get assembled into
# - blocks: linked list of blocks inside this method/block # - blocks: linked list of blocks inside this method/block
# - next: next block/method at same level # - next_callable: next block/method at same level
# #
class Callable < Object class Callable < Object
attr_reader :self_type , :arguments_type , :frame_type , :binary attr :type, :self_type , :arguments_type , :frame_type , :binary
attr_reader :blocks, :next , :name attr :blocks , :name
attr :next_callable
def self.type_length
8
end
def initialize( name , self_type , arguments_type , frame_type) def initialize( name , self_type , arguments_type , frame_type)
super() super()
raise "No class #{self}" unless self_type raise "No class #{self}" unless self_type
raise "For type, not class #{self_type}" unless self_type.is_a?(Type) raise "For type, not class #{self_type}" unless self_type.is_a?(Type)
raise "Mixup" unless name.is_a?(Symbol) raise "Mixup" unless name.is_a?(Symbol)
@name = name self.name = name
@self_type = self_type self.self_type = self_type
init(arguments_type, frame_type) init(arguments_type, frame_type)
end end
def ==(other) def ==(other)
@self_type == other.self_type self_type == other.self_type
end end
# (re) init with given args and frame types # (re) init with given args and frame types
def init(arguments_type, frame_type) def init(arguments_type, frame_type)
raise "Wrong argument type, expect Type not #{arguments_type.class}" unless arguments_type.is_a? Type raise "Wrong argument type, expect Type not #{arguments_type.class}" unless arguments_type.is_a? Type
raise "Wrong frame type, expect Type not #{frame_type.class}" unless frame_type.is_a? Type raise "Wrong frame type, expect Type not #{frame_type.class}" unless frame_type.is_a? Type
@arguments_type = arguments_type self.arguments_type = arguments_type
@frame_type = frame_type self.frame_type = frame_type
@binary = BinaryCode.new(0) self.binary = BinaryCode.new(0)
end end
# determine if method has a local variable or tmp (anonymous local) by given name # determine if method has a local variable or tmp (anonymous local) by given name
@ -47,19 +52,19 @@ module Parfait
def add_local( name , type ) def add_local( name , type )
index = has_local( name ) index = has_local( name )
return index if index return index if index
@frame_type = @frame_type.add_instance_variable(name,type) self.frame_type = frame_type.add_instance_variable(name,type)
end end
def each_binary( &block ) def each_binary( &block )
bin = binary bin = binary
while(bin) do while(bin) do
block.call( bin ) block.call( bin )
bin = bin.next bin = bin.next_callable
end end
end end
def set_next( method ) def set_next( method )
@next = method self.next_callable = method
end end
end end

View File

@ -14,32 +14,32 @@ module Parfait
def ==(other) def ==(other)
return false unless other.is_a?(CallableMethod) return false unless other.is_a?(CallableMethod)
return false if @name != other.name return false if name != other.name
super super
end end
def rxf_reference_name def rxf_reference_name
"Method: " + @name.to_s "Method: " + name.to_s
end end
def inspect def inspect
"#{@self_type.object_class.name}:#{name}(#{arguments_type.inspect})" "#{self_type.object_class.name}:#{name}(#{arguments_type.inspect})"
end end
def each_method( &block ) def each_method( &block )
block.call( self ) block.call( self )
@next.each_method( &block ) if @next next_callable.each_method( &block ) if next_callable
end end
def create_block(args , frame) def create_block(args , frame)
block_name = "#{@name}_block".to_sym #TODO with id, to distinguish block_name = "#{name}_block".to_sym #TODO with id, to distinguish
add_block( Block.new(block_name , self_type , args , frame)) add_block( Block.new(block_name , self_type , args , frame))
end end
def add_block(bl) def add_block(bl)
was = @blocks was = blocks
bl.set_next(was) if(was) bl.set_next(was) if(was)
@blocks = bl self.blocks = bl
end end
def has_block(block) def has_block(block)
@ -50,7 +50,7 @@ module Parfait
blo = blocks blo = blocks
while( blo ) while( blo )
yield(blo) yield(blo)
blo = blo.next blo = blo.next_callable
end end
end end
end end

View File

@ -18,13 +18,17 @@ module Parfait
class Class < Object class Class < Object
include Behaviour include Behaviour
attr_reader :instance_type , :name , :instance_methods , :super_class_name attr :type, :instance_type , :name , :instance_methods , :super_class_name
def self.type_length
5
end
def initialize( name , superclass , instance_type) def initialize( name , superclass , instance_type)
super() super()
@name = name self.name = name
@super_class_name = superclass self.super_class_name = superclass
@instance_methods = List.new self.instance_methods = List.new
set_instance_type( instance_type ) set_instance_type( instance_type )
end end
@ -44,32 +48,32 @@ module Parfait
def add_method(method) def add_method(method)
raise "Must be untyped method #{method}" unless method.is_a? Parfait::VoolMethod raise "Must be untyped method #{method}" unless method.is_a? Parfait::VoolMethod
@instance_methods.push(method) instance_methods.push(method)
end end
def get_method(name) def get_method(name)
@instance_methods.find{|m| m.name == name } instance_methods.find{|m| m.name == name }
end end
# adding an instance changes the instance_type to include that variable # adding an instance changes the instance_type to include that variable
def add_instance_variable( name , type) def add_instance_variable( name , type)
@instance_type = @instance_type.add_instance_variable( name , type ) self.instance_type = instance_type.add_instance_variable( name , type )
end end
# setting the type generates all methods for this type # setting the type generates all methods for this type
# (or will do, once we store the methods code to do that) # (or will do, once we store the methods code to do that)
def set_instance_type( type ) def set_instance_type( type )
raise "type must be type #{type}" unless type.is_a?(Type) raise "type must be type #{type}" unless type.is_a?(Type)
@instance_type = type self.instance_type = type
end end
# return the super class, but raise exception if either the super class name # return the super class, but raise exception if either the super class name
# or the super classs is nil. # or the super classs is nil.
# Use only for non Object base class # Use only for non Object base class
def super_class! def super_class!
raise "No super_class for class #{@name}" unless @super_class_name raise "No super_class for class #{name}" unless super_class_name
s = super_class s = super_class
raise "superclass not found for class #{@name} (#{@super_class_name})" unless s raise "superclass not found for class #{name} (#{super_class_name})" unless s
s s
end end
@ -77,8 +81,8 @@ module Parfait
# we only store the name, and so have to resolve. # we only store the name, and so have to resolve.
# Nil name means no superclass, and so nil is a valid return value # Nil name means no superclass, and so nil is a valid return value
def super_class def super_class
return nil unless @super_class_name return nil unless super_class_name
Parfait.object_space.get_class_by_name(@super_class_name) Parfait.object_space.get_class_by_name(super_class_name)
end end
# ruby 2.1 list (just for reference, keep at bottom) # ruby 2.1 list (just for reference, keep at bottom)

View File

@ -21,9 +21,7 @@
# A marker class # A marker class
module Parfait module Parfait
class DataObject < Object class DataObject < Object
def initialize
super
end
def self.integer_index def self.integer_index
type_length type_length
end end

View File

@ -3,35 +3,41 @@
module Parfait module Parfait
class Dictionary < Object class Dictionary < Object
attr :type, :i_keys , :i_values
def self.type_length
3
end
# only empty initialization for now # only empty initialization for now
# #
# internally we store keys and values in lists, which means this does **not** scale well # internally we store keys and values in lists, which means this does **not** scale well
def initialize def initialize
super() super()
@keys = List.new() self.i_keys = List.new()
@values = List.new() self.i_values = List.new()
end end
def keys def keys
@keys.dup i_keys.dup
end end
def values def values
@values.dup i_values.dup
end end
# are there any key/value items in the list # are there any key/value items in the list
def empty? def empty?
@keys.empty? i_keys.empty?
end end
# How many key/value pairs there are # How many key/value pairs there are
def length() def length()
return @keys.get_length() return i_keys.get_length()
end end
def next_value(val) def next_value(val)
return @values.next_value(val) return i_values.next_value(val)
end end
# get a value fot the given key # get a value fot the given key
@ -40,7 +46,7 @@ module Parfait
def get(key) def get(key)
index = key_index(key) index = key_index(key)
if( index ) if( index )
@values.get(index) i_values.get(index)
else else
nil nil
end end
@ -53,17 +59,17 @@ module Parfait
# private method # private method
def key_index(key) def key_index(key)
@keys.index_of(key) i_keys.index_of(key)
end end
# set key with value, returns value # set key with value, returns value
def set(key , value) def set(key , value)
index = key_index(key) index = key_index(key)
if( index ) if( index )
@values.set(index , value) i_values.set(index , value)
else else
@keys.push(key) i_keys.push(key)
@values.push(value) i_values.push(value)
end end
value value
end end
@ -76,9 +82,9 @@ module Parfait
# yield to each key value pair # yield to each key value pair
def each def each
index = 0 index = 0
while index < @keys.get_length while index < i_keys.get_length
key = @keys.get(index) key = i_keys.get(index)
value = @values.get(index) value = i_values.get(index)
yield key , value yield key , value
index = index + 1 index = index + 1
end end

View File

@ -9,12 +9,13 @@
module Parfait module Parfait
class Integer < Data4 class Integer < Data4
attr :type, :next_integer
def initialize(value , next_i = nil) def initialize(value , next_i = nil)
super() super()
@next_integer = next_i self.next_integer = next_i
set_internal_word(Integer.integer_index, value) set_internal_word(Integer.integer_index, value)
end end
attr_reader :next_integer
def value def value
get_internal_word(Integer.integer_index) get_internal_word(Integer.integer_index)
@ -28,7 +29,7 @@ module Parfait
end end
def to_s def to_s
"Integer #{@value}" "Integer #{value}"
end end
# compile time method to set the actual value. # compile time method to set the actual value.
# this should not really be part of parfait, as ints are immutable at runtime. # this should not really be part of parfait, as ints are immutable at runtime.
@ -38,12 +39,12 @@ module Parfait
# :integer?, :odd?, :even?, :upto, :downto, :times, :succ, :next, :pred, :chr, :ord, :to_i, :to_int, :floor, # :integer?, :odd?, :even?, :upto, :downto, :times, :succ, :next, :pred, :chr, :ord, :to_i, :to_int, :floor,
# :ceil, :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator, :denominator, :to_r, :rationalize, # :ceil, :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator, :denominator, :to_r, :rationalize,
# :singleton_method_added, :coerce, :i, :+@, :-@, :fdiv, :div, :divmod, :%, :modulo, :remainder, :abs, :magnitude, # :singleton_method_added, :coerce, :i, :+, :-, :fdiv, :div, :divmod, :%, :modulo, :remainder, :abs, :magnitude,
# :real?, :zero?, :nonzero?, :step, :quo, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase, # :real?, :zero?, :nonzero?, :step, :quo, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase,
# :rectangular, :rect, :polar, :conjugate, :conj, :>, :>=, :<, :<=, :between? # :rectangular, :rect, :polar, :conjugate, :conj, :>, :>=, :<, :<=, :between?
# #
# Numeric # Numeric
# :singleton_method_added, :coerce, :i, :+@, :-@, :fdiv, :div, :divmod, :%, :modulo, :remainder, :abs, :magnitude, # :singleton_method_added, :coerce, :i, :+, :-, :fdiv, :div, :divmod, :%, :modulo, :remainder, :abs, :magnitude,
# :to_int, :real?, :integer?, :zero?, :nonzero?, :floor, :ceil, :round, :truncate, :step, :numerator, :denominator, # :to_int, :real?, :integer?, :zero?, :nonzero?, :floor, :ceil, :round, :truncate, :step, :numerator, :denominator,
# :quo, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase, :rectangular, :rect, :polar, :conjugate, :conj, # :quo, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase, :rectangular, :rect, :polar, :conjugate, :conj,
# :>, :>=, :<, :<=, :between? # :>, :>=, :<, :<=, :between?

View File

@ -7,29 +7,31 @@
module Parfait module Parfait
class List < Data16 class List < Data16
attr_reader :indexed_length , :next attr :type, :indexed_length , :next_list
def self.type_length def self.type_length
3 # 0 type , 1 length , 2 - next_list 3 # 0 type , 1 length , 2 - next_list
end end
def self.get_length_index
1
end
def self.data_length def self.data_length
self.memory_size - self.type_length - 1 #one for the jump self.memory_size - self.type_length - 1
end end
def initialize
super
self.indexed_length = 0
end
def data_length def data_length
self.class.data_length self.class.data_length
end end
def get_length def get_length
r = @indexed_length r = indexed_length
r.nil? ? 0 : r r.nil? ? 0 : r
end end
def ensure_next def ensure_next
@next = List.new unless @next self.next_list = List.new unless next_list
@next self.next_list
end end
# set the value at index. # set the value at index.
@ -41,7 +43,7 @@ module Parfait
end end
if index >= data_length if index >= data_length
ensure_next ensure_next
@next.set( index - data_length , value) next_list.set( index - data_length , value)
else else
set_internal_word( index + self.class.type_length, value) set_internal_word( index + self.class.type_length, value)
end end
@ -52,8 +54,8 @@ module Parfait
def get( index ) def get( index )
raise "Only positive indexes, #{index}" if index < 0 raise "Only positive indexes, #{index}" if index < 0
if index >= data_length if index >= data_length
return nil unless @next return nil unless next_list
return @next.get( index - data_length) return next_list.get( index - data_length)
else else
ret = nil ret = nil
if(index < get_length) if(index < get_length)
@ -78,9 +80,9 @@ module Parfait
internal_set_length( len) internal_set_length( len)
end end
def indexed_length # def indexed_length
get_length() # get_length()
end # end
# include? means non nil index # include? means non nil index
def include?( item ) def include?( item )
@ -262,7 +264,7 @@ module Parfait
end end
private private
def internal_set_length( i ) def internal_set_length( i )
@indexed_length = i self.indexed_length = i
end end
end end

View File

@ -15,28 +15,35 @@ module Parfait
# :return_address => :Integer, :return_value => :Integer, # :return_address => :Integer, :return_value => :Integer,
# :caller => :Message , :name => :Word , :arguments => :NamedList # :caller => :Message , :name => :Word , :arguments => :NamedList
attr_accessor :next_message attr :type, :next_message
attr_reader :receiver , :frame attr :receiver , :frame
attr_reader :return_address, :return_value attr :return_address, :return_value
attr_reader :caller , :method , :arguments attr :caller , :method , :arguments
def self.type_length
9
end
def self.memory_size
16
end
def initialize( next_m ) def initialize( next_m )
@next_message = next_m
@frame = NamedList.new()
@arguments = NamedList.new()
super() super()
self.next_message = next_m
self.frame = NamedList.new()
self.arguments = NamedList.new()
end end
def set_receiver(rec) def set_receiver(rec)
@receiver = rec self.receiver = rec
end end
def set_caller(caller) def set_caller(caller)
@caller = caller caller = caller
end end
def get_type_for(name) def get_type_for(name)
index = @type.get_index(name) index = type.get_index(name)
get_at(index) get_at(index)
end end
def to_s def to_s

View File

@ -23,6 +23,8 @@
module Parfait module Parfait
class NamedList < Object class NamedList < Object
attr :type
def to_s def to_s
str = "NamedList len= #{get_length}" str = "NamedList len= #{get_length}"
str += " at #{Risc::Position.get(self)}" if Risc::Position.set?(self) str += " at #{Risc::Position.get(self)}" if Risc::Position.set?(self)

View File

@ -6,7 +6,7 @@
# word (instance of class Type). # word (instance of class Type).
# Objects are arranged or layed out (in memory) according to their Type # Objects are arranged or layed out (in memory) according to their Type
# every object has a Type. Type objects are immutalbe and may be reused for a group/class # every object has a Type. Type objects are immutable and may be reused for a group/class
# of objects. # of objects.
# The Type of an object may change, but then a new Type is created # The Type of an object may change, but then a new Type is created
# The Type also defines the class of the object # The Type also defines the class of the object
@ -16,8 +16,16 @@ module Parfait
TYPE_INDEX = 0 TYPE_INDEX = 0
class Object class Object
attr :type
def self.new *args def self.memory_size
8
end
def self.type_length
1
end
def self.new( *args )
object = self.allocate object = self.allocate
# have to grab the class, because we are in the ruby class not the parfait one # have to grab the class, because we are in the ruby class not the parfait one
@ -25,35 +33,16 @@ module Parfait
# and have to set the type before we let the object do anything. otherwise boom # and have to set the type before we let the object do anything. otherwise boom
object.set_type cl.instance_type object.set_type cl.instance_type
object.send :initialize , *args object.send :initialize , *args
object object
end end
# 0 -based index
def get_internal_word(index)
name = get_type().name_at(index)
return nil unless name
instance_variable_get("@#{name}".to_sym)
end
# 0 -based index
def set_internal_word(index , value)
return set_type(value) if( index == TYPE_INDEX)
raise "not type #{@type.class}" unless @type.is_a?(Type)
name = @type.name_at(index)
#return value unless name
raise "object type (#{@type}) has no name at index #{index} " unless name
instance_variable_set("@#{name}".to_sym, value)
value
end
def == other def == other
self.object_id == other.object_id self.object_id == other.object_id
end end
# This is the crux of the object system. The class of an object is stored in the objects # This is the core of the object system.
# memory (as opposed to an integer that has no memory and so always has the same class) # The class of an object is stored in the objects memory
# #
# In RubyX we store the class in the Type, and so the Type is the only fixed # In RubyX we store the class in the Type, and so the Type is the only fixed
# data that every object carries. # data that every object carries.
@ -64,20 +53,19 @@ module Parfait
end end
# private # private
def set_type(type) def set_type(typ)
# puts "Type was set for #{self.class}" raise "not type #{typ.class} in #{object_id.to_s(16)}" unless typ.is_a?(Type)
raise "not type #{type.class} in #{self}" unless type.is_a?(Type) self.type = typ
@type = type
end end
# so we can keep the raise in get_type # so we can keep the raise in get_type
def has_type? def has_type?
! @type.nil? ! type.nil?
end end
def get_type() def get_type()
raise "No type #{self.object_id.to_s(16)}:#{self.class} " unless has_type? raise "No type #{self.object_id.to_s(16)}:#{self.class} " unless has_type?
@type type
end end
# return the metaclass # return the metaclass
@ -86,7 +74,7 @@ module Parfait
end end
def get_instance_variables def get_instance_variables
@type.names type.names
end end
def get_instance_variable( name ) def get_instance_variable( name )
@ -103,20 +91,20 @@ module Parfait
end end
def instance_variable_defined( name ) def instance_variable_defined( name )
@type.variable_index(name) type.variable_index(name)
end end
def padded_length def padded_length
Padding.padded_words( @type.instance_length ) Padding.padded_words( type.instance_length )
end end
# parfait versions are deliberately called different, so we "relay" # parfait versions are deliberately called different, so we "relay"
# have to put the "@" on the names for rfx to take them off again # have to put the "" on the names for rfx to take them off again
def instance_variables def instance_variables
get_instance_variables.to_a.collect{ |n| "@#{n}".to_sym } get_instance_variables.to_a.collect{ |n| "#{n}".to_sym }
end end
# name comes in as a ruby @var name # name comes in as a ruby var name
def instance_variable_ged name def instance_variable_ged name
var = get_instance_variable name.to_s[1 .. -1].to_sym var = get_instance_variable name.to_s[1 .. -1].to_sym
#puts "getting #{name} #{var}" #puts "getting #{name} #{var}"

View File

@ -10,6 +10,6 @@
module Parfait module Parfait
class Page < Object class Page < Object
attr :type
end end
end end

View File

@ -11,12 +11,12 @@
module Parfait module Parfait
# Make the object space globally available # Make the object space globally available
def self.object_space def self.object_space
@@object_space @object_space
end end
# TODO Must get rid of the setter (move the boot process ?) # TODO Must get rid of the setter (move the boot process ?)
def self.set_object_space( space ) def self.set_object_space( space )
@@object_space = space @object_space = space
end end
# The Space contains all objects for a program. In functional terms it is a program, but in oo # The Space contains all objects for a program. In functional terms it is a program, but in oo
@ -31,51 +31,58 @@ module Parfait
class Space < Object class Space < Object
attr :type, :classes , :types , :next_message , :next_integer , :next_address
attr :messages, :integers , :addresses
attr :true_object , :false_object , :nil_object
def initialize( classes ) def initialize( classes )
@classes = classes self.classes = classes
@types = Dictionary.new self.types = Dictionary.new
@classes.each do |name , cl| classes.each do |name , cl|
add_type(cl.instance_type) add_type(cl.instance_type)
end end
101.times { @integers = Integer.new(0,@integers) } 101.times { self.integers = Integer.new(0,self.integers) }
400.times { @addresses = ReturnAddress.new(0,@addresses) } 400.times { self.addresses = ReturnAddress.new(0,self.addresses) }
message = Message.new(nil) message = Message.new(nil)
50.times do 50.times do
@messages = Message.new message self.messages = Message.new( message )
message.set_caller @messages message.set_caller( self.messages )
message = @messages message = self.messages
end end
@next_message = @messages self.next_message = self.messages
@next_integer = @integers self.next_integer = self.integers
@next_address = @addresses self.next_address = self.addresses
@true_object = Parfait::TrueClass.new self.true_object = Parfait::TrueClass.new
@false_object = Parfait::FalseClass.new self.false_object = Parfait::FalseClass.new
@nil_object = Parfait::NilClass.new self.nil_object = Parfait::NilClass.new
end end
attr_reader :classes , :types , :next_message , :next_integer , :next_address def self.type_length
attr_reader :messages, :integers , :addresses 12
attr_reader :true_object , :false_object , :nil_object end
def self.memory_size
16
end
# hand out one of the preallocated ints for use as constant # hand out one of the preallocated ints for use as constant
# the same code is hardcoded as risc instructions for "normal" use, to # the same code is hardcoded as risc instructions for "normal" use, to
# avoid the method call at runtime. But at compile time we want to keep # avoid the method call at runtime. But at compile time we want to keep
# the number of integers known (fixed). # the number of integers known (fixed).
def get_integer def get_integer
int = @next_integer int = self.next_integer
@next_integer = @next_integer.next_integer self.next_integer = next_integer.next_integer
int int
end end
# hand out a return address for use as constant the address is added # hand out a return address for use as constant the address is added
def get_address def get_address
addr = @next_address addr = next_address
@next_address = @next_address.next_integer next_address = next_address.next_integer
addr addr
end end
def each_type def each_type
@types.values.each do |type| types.values.each do |type|
yield(type) yield(type)
end end
end end
@ -83,13 +90,13 @@ module Parfait
def add_type( type ) def add_type( type )
hash = type.hash hash = type.hash
raise "upps #{hash} #{hash.class}" unless hash.is_a?(Fixnum) raise "upps #{hash} #{hash.class}" unless hash.is_a?(Fixnum)
was = @types[hash] was = types[hash]
return was if was return was if was
@types[hash] = type types[hash] = type
end end
def get_type_for( hash ) def get_type_for( hash )
@types[hash] types[hash]
end end
# all methods form all types # all methods form all types
@ -124,8 +131,8 @@ module Parfait
# return nili if no such class. Use bang version if create should be implicit # return nili if no such class. Use bang version if create should be implicit
def get_class_by_name( name ) def get_class_by_name( name )
raise "get_class_by_name #{name}.#{name.class}" unless name.is_a?(Symbol) raise "get_class_by_name #{name}.#{name.class}" unless name.is_a?(Symbol)
c = @classes[name] c = classes[name]
#puts "MISS, no class #{name} #{name.class}" unless c # " #{@classes}" #puts "MISS, no class #{name} #{name.class}" unless c # " #{classes}"
#puts "CLAZZ, #{name} #{c.get_type.get_length}" if c #puts "CLAZZ, #{name} #{c.get_type.get_length}" if c
c c
end end
@ -146,7 +153,7 @@ module Parfait
raise "create_class #{superclass.class}" unless superclass.is_a? Symbol raise "create_class #{superclass.class}" unless superclass.is_a? Symbol
type = get_type_by_class_name(superclass) type = get_type_by_class_name(superclass)
c = Class.new(name , superclass , type ) c = Class.new(name , superclass , type )
@classes[name] = c classes[name] = c
end end
def rxf_reference_name def rxf_reference_name

View File

@ -36,7 +36,11 @@ module Parfait
class Type < Object class Type < Object
attr_reader :object_class , :names , :types , :methods attr :type, :object_class , :names , :types , :methods
def self.type_length
5
end
def self.for_hash( object_class , hash) def self.for_hash( object_class , hash)
hash = {type: object_class.name }.merge(hash) unless hash[:type] hash = {type: object_class.name }.merge(hash) unless hash[:type]
@ -53,9 +57,9 @@ module Parfait
# this part of the init is seperate because at boot time we can not use normal new # this part of the init is seperate because at boot time we can not use normal new
# new is overloaded to grab the type from space, and before boot, that is not set up # new is overloaded to grab the type from space, and before boot, that is not set up
def init_lists(hash) def init_lists(hash)
@methods = nil self.methods = nil
@names = List.new self.names = List.new
@types = List.new self.types = List.new
raise "No type Type in #{hash}" unless hash[:type] raise "No type Type in #{hash}" unless hash[:type]
private_add_instance_variable(:type , hash[:type]) #first private_add_instance_variable(:type , hash[:type]) #first
hash.each do |name , type| hash.each do |name , type|
@ -64,13 +68,13 @@ module Parfait
end end
def class_name def class_name
@object_class.name object_class.name
end end
def to_s def to_s
str = "#{class_name}-[" str = "#{class_name}-["
first = false first = false
@names.each do |name| names.each do |name|
unless(first) unless(first)
first = true first = true
str += ":#{name}" str += ":#{name}"
@ -83,8 +87,8 @@ module Parfait
def method_names def method_names
names = List.new names = List.new
return names unless @methods return names unless methods
@methods.each_method do |method| methods.each_method do |method|
names.push method.name names.push method.name
end end
names names
@ -114,19 +118,19 @@ module Parfait
if get_method( method.name ) if get_method( method.name )
remove_method(method.name) remove_method(method.name)
end end
method.set_next( @methods ) method.set_next( methods )
@methods = method self.methods = method
#puts "#{self.name} add #{method.name}" #puts "#{self.name} add #{method.name}"
method method
end end
def remove_method( method_name ) def remove_method( method_name )
raise "No such method #{method_name} in #{self.name}" unless @methods raise "No such method #{method_name} in #{self.name}" unless methods
if( @methods.name == method_name) if( methods.name == method_name)
@methods = @methods.next self.methods = methods.next
return true return true
end end
method = @methods method = methods
while(method && method.next) while(method && method.next)
if( method.next.name == method_name) if( method.next.name == method_name)
method.set_next( method.next.next ) method.set_next( method.next.next )
@ -140,8 +144,8 @@ module Parfait
def get_method( fname ) def get_method( fname )
raise "get_method #{fname}.#{fname.class}" unless fname.is_a?(Symbol) raise "get_method #{fname}.#{fname.class}" unless fname.is_a?(Symbol)
return nil unless @methods return nil unless methods
@methods.each_method do |m| methods.each_method do |m|
return m if(m.name == fname ) return m if(m.name == fname )
end end
nil nil
@ -163,9 +167,9 @@ module Parfait
end end
def methods_length def methods_length
return 0 unless @methods return 0 unless methods
len = 0 len = 0
@methods.each_method { len += 1} methods.each_method { len += 1}
return len return len
end end
@ -181,38 +185,38 @@ module Parfait
raise "No nil type" unless type raise "No nil type" unless type
hash = to_hash hash = to_hash
hash[name] = type hash[name] = type
return Type.for_hash( @object_class , hash) return Type.for_hash( object_class , hash)
end end
def set_object_class(oc) def set_object_class(oc)
raise "object class should be a class, not #{oc.class}" unless oc.is_a?(Class) raise "object class should be a class, not #{oc.class}" unless oc.is_a?(Class)
@object_class = oc self.object_class = oc
end end
def instance_length def instance_length
@names.get_length() names.get_length()
end end
# index of the variable when using get_internal_word # index of the variable when using get_internal_word
# (get_internal_word is 0 based and 0 is always the type) # (get_internal_word is 0 based and 0 is always the type)
def variable_index( name ) def variable_index( name )
has = @names.index_of(name) has = names.index_of(name)
return nil unless has return nil unless has
raise "internal error #{name}:#{has}" if has < 0 raise "internal error #{name}:#{has}" if has < 0
has has
end end
def get_length() def get_length()
@names.get_length() names.get_length()
end end
def name_at( index ) def name_at( index )
raise "No names #{index}" unless @names raise "No names #{index}" unless names
@names.get(index) names.get(index)
end end
def type_at( index ) def type_at( index )
@types.get(index) types.get(index)
end end
def type_for( name ) def type_for( name )
@ -226,7 +230,7 @@ module Parfait
end end
def rxf_reference_name def rxf_reference_name
"#{@object_class.name}_Type" "#{object_class.name}_Type"
end end
alias :name :rxf_reference_name alias :name :rxf_reference_name
@ -239,8 +243,8 @@ module Parfait
end end
def each_method(&block) def each_method(&block)
return unless @methods return unless methods
@methods.each_method(&block) methods.each_method(&block)
end end
def to_hash def to_hash
hash = {} hash = {}
@ -254,7 +258,7 @@ module Parfait
def hash def hash
index = 1 index = 1
hash_code = Type.str_hash( @object_class.name ) hash_code = Type.str_hash( object_class.name )
each do |name , type| each do |name , type|
item_hash = Type.str_hash(name) + Type.str_hash(type) item_hash = Type.str_hash(name) + Type.str_hash(type)
hash_code += item_hash + (item_hash / 256 ) * index hash_code += item_hash + (item_hash / 256 ) * index
@ -280,8 +284,8 @@ module Parfait
def private_add_instance_variable( name , type) def private_add_instance_variable( name , type)
raise "Name shouldn't be nil" unless name raise "Name shouldn't be nil" unless name
raise "Value Type shouldn't be nil" unless type raise "Value Type shouldn't be nil" unless type
@names.push(name) names.push(name)
@types.push(type) types.push(type)
end end
end end

View File

@ -12,10 +12,13 @@ module Parfait
# #
class VoolMethod < Object class VoolMethod < Object
attr_reader :name , :args_type , :frame_type , :source attr :type, :name , :args_type , :frame_type , :source
def initialize(name , args_type , frame_type , source ) def initialize(name , args_type , frame_type , source )
@name , @args_type , @frame_type , @source = name , args_type, frame_type , source self.name = name
self.args_type = args_type
self.frame_type = frame_type
self.source = source
raise "Name must be symbol" unless name.is_a?(Symbol) raise "Name must be symbol" unless name.is_a?(Symbol)
raise "args_type must be type" unless args_type.is_a?(Parfait::Type) raise "args_type must be type" unless args_type.is_a?(Parfait::Type)
raise "frame_type must be type" unless frame_type.is_a?(Parfait::Type) raise "frame_type must be type" unless frame_type.is_a?(Parfait::Type)
@ -25,7 +28,7 @@ module Parfait
def create_callable_method( type ) def create_callable_method( type )
raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type raise "create_method #{type.inspect} is not a Type" unless type.is_a? Parfait::Type
type.create_method( @name , @args_type , @frame_type) type.create_method( name , args_type , frame_type)
end end
def compiler_for(self_type) def compiler_for(self_type)

View File

@ -13,7 +13,7 @@ module Parfait
# Object length is measured in non-type cells though # Object length is measured in non-type cells though
class Word < Data8 class Word < Data8
attr_reader :char_length attr :type, :char_length
def self.type_length def self.type_length
2 # 0 type , 1 char_length 2 # 0 type , 1 char_length
@ -26,7 +26,7 @@ module Parfait
# Risc provides methods to create Parfait objects from ruby # Risc provides methods to create Parfait objects from ruby
def initialize( len ) def initialize( len )
super() super()
@char_length = 0 self.char_length = 0
raise "Must init with int, not #{len.class}" unless len.kind_of? Fixnum raise "Must init with int, not #{len.class}" unless len.kind_of? Fixnum
raise "Must init with positive, not #{len}" if len < 0 raise "Must init with positive, not #{len}" if len < 0
set_length( len , 32 ) unless len == 0 #32 being ascii space set_length( len , 32 ) unless len == 0 #32 being ascii space
@ -47,7 +47,7 @@ module Parfait
# return the number of characters # return the number of characters
def length() def length()
obj_len = @char_length obj_len = char_length
return obj_len return obj_len
end end
@ -75,9 +75,9 @@ module Parfait
# #
def set_length(len , fill_char) def set_length(len , fill_char)
return if len <= 0 return if len <= 0
old = @char_length old = char_length
return if old >= len return if old >= len
@char_length = len self.char_length = len
check_length check_length
fill_from_with( old + 1 , fill_char ) fill_from_with( old + 1 , fill_char )
end end
@ -169,7 +169,7 @@ module Parfait
def to_string def to_string
string = "" string = ""
index = 0 index = 0
while( index < @char_length) while( index < char_length)
char = get_char(index) char = get_char(index)
string += char ? char.chr : "*" string += char ? char.chr : "*"
index = index + 1 index = index + 1
@ -183,12 +183,12 @@ module Parfait
end end
def padded_length def padded_length
Padding.padded( 4 * get_type().instance_length + @char_length ) Padding.padded( 4 * get_type().instance_length + char_length )
end end
private private
def check_length def check_length
raise "Length out of bounds #{@char_length}" if @char_length > 1000 raise "Length out of bounds #{char_length}" if char_length > 1000
end end
end end