rename layout to type
this one goes to caleb for pointing it out. Much better word
This commit is contained in:
parent
3480b97eaa
commit
d32b51c67b
@ -132,7 +132,7 @@ module Register
|
|||||||
obj.position
|
obj.position
|
||||||
end
|
end
|
||||||
|
|
||||||
# write type and layout of the instance, and the variables that are passed
|
# write type and type of the instance, and the variables that are passed
|
||||||
# variables ar values, ie int or refs. For refs the object needs to save the object first
|
# variables ar values, ie int or refs. For refs the object needs to save the object first
|
||||||
def write_object( object )
|
def write_object( object )
|
||||||
log.debug "Write object #{object.class} #{object.inspect}"
|
log.debug "Write object #{object.class} #{object.inspect}"
|
||||||
@ -155,8 +155,8 @@ module Register
|
|||||||
written += 4
|
written += 4
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
log.debug "layout #{lay_len} , total #{written} (array #{written - lay_len})"
|
log.debug "type #{lay_len} , total #{written} (array #{written - lay_len})"
|
||||||
log.debug "Len = #{object.get_length} , inst = #{object.get_layout.instance_length}" if object.is_a? Parfait::Layout
|
log.debug "Len = #{object.get_length} , inst = #{object.get_type.instance_length}" if object.is_a? Parfait::Type
|
||||||
pad_after( written )
|
pad_after( written )
|
||||||
object.position
|
object.position
|
||||||
end
|
end
|
||||||
@ -173,10 +173,10 @@ module Register
|
|||||||
str = string.to_s if string.is_a? Symbol
|
str = string.to_s if string.is_a? Symbol
|
||||||
log.debug "#{string.class} is #{string} at #{string.position} length #{string.length}"
|
log.debug "#{string.class} is #{string} at #{string.position} length #{string.length}"
|
||||||
@stream.write_sint32( MARKER )
|
@stream.write_sint32( MARKER )
|
||||||
write_ref_for( string.get_layout ) #ref
|
write_ref_for( string.get_type ) #ref
|
||||||
@stream.write_sint32( str.length ) #int
|
@stream.write_sint32( str.length ) #int
|
||||||
@stream.write str
|
@stream.write str
|
||||||
pad_after(str.length + 8 ) # layout , length *4 == 12
|
pad_after(str.length + 8 ) # type , length *4 == 12
|
||||||
log.debug "String (#{string.length}) stream #{@stream.length}"
|
log.debug "String (#{string.length}) stream #{@stream.length}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -20,11 +20,11 @@ module Register
|
|||||||
# That graph can be programatically built and written (with this to boot that process :-))
|
# That graph can be programatically built and written (with this to boot that process :-))
|
||||||
|
|
||||||
# There are some helpers below, but the roadmap is something like:
|
# There are some helpers below, but the roadmap is something like:
|
||||||
# - create all the layouts, with thier layouts, but no classes
|
# - create all the types, with thier types, but no classes
|
||||||
# - create a space by "hand" , using allocate, not new
|
# - create a space by "hand" , using allocate, not new
|
||||||
# - create the class objects and assign them to the layouts
|
# - create the class objects and assign them to the types
|
||||||
def boot_parfait!
|
def boot_parfait!
|
||||||
boot_layouts
|
boot_types
|
||||||
boot_space
|
boot_space
|
||||||
boot_classes
|
boot_classes
|
||||||
|
|
||||||
@ -34,43 +34,43 @@ module Register
|
|||||||
boot_functions!
|
boot_functions!
|
||||||
end
|
end
|
||||||
|
|
||||||
# layouts is where the snake bites its tail. Every chain end at a layout and then it
|
# types is where the snake bites its tail. Every chain end at a type and then it
|
||||||
# goes around (circular references). We create them from the list below and keep them
|
# goes around (circular references). We create them from the list below and keep them
|
||||||
# in an instance variable (that is a smell, because after booting it is not needed)
|
# in an instance variable (that is a smell, because after booting it is not needed)
|
||||||
def boot_layouts
|
def boot_types
|
||||||
@layouts = {}
|
@types = {}
|
||||||
layout_names.each do |name , ivars |
|
type_names.each do |name , ivars |
|
||||||
@layouts[name] = layout_for( name , ivars)
|
@types[name] = type_for( name , ivars)
|
||||||
end
|
end
|
||||||
layout_layout = @layouts[:Layout]
|
type_type = @types[:Type]
|
||||||
@layouts.each do |name , layout |
|
@types.each do |name , type |
|
||||||
layout.set_layout(layout_layout)
|
type.set_type(type_type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# once we have the layouts we can create the space by creating the instance variables
|
# once we have the types we can create the space by creating the instance variables
|
||||||
# by hand (can't call new yet as that uses the space)
|
# by hand (can't call new yet as that uses the space)
|
||||||
def boot_space
|
def boot_space
|
||||||
space_dict = object_with_layout Parfait::Dictionary
|
space_dict = object_with_type Parfait::Dictionary
|
||||||
space_dict.keys = object_with_layout Parfait::List
|
space_dict.keys = object_with_type Parfait::List
|
||||||
space_dict.values = object_with_layout Parfait::List
|
space_dict.values = object_with_type Parfait::List
|
||||||
|
|
||||||
@space = object_with_layout Parfait::Space
|
@space = object_with_type Parfait::Space
|
||||||
@space.classes = space_dict
|
@space.classes = space_dict
|
||||||
Parfait::Space.set_object_space @space
|
Parfait::Space.set_object_space @space
|
||||||
end
|
end
|
||||||
|
|
||||||
# when running code instantiates a class, a layout is created automatically
|
# when running code instantiates a class, a type is created automatically
|
||||||
# but even to get our space up, we have already instantiated all layouts
|
# but even to get our space up, we have already instantiated all types
|
||||||
# so we have to continue and allocate classes and fill the data by hand
|
# so we have to continue and allocate classes and fill the data by hand
|
||||||
# and off cource we can't use space.create_class , but still they need to go there
|
# and off cource we can't use space.create_class , but still they need to go there
|
||||||
def boot_classes
|
def boot_classes
|
||||||
classes = space.classes
|
classes = space.classes
|
||||||
layout_names.each do |name , vars|
|
type_names.each do |name , vars|
|
||||||
cl = object_with_layout Parfait::Class
|
cl = object_with_type Parfait::Class
|
||||||
cl.object_layout = @layouts[name]
|
cl.object_type = @types[name]
|
||||||
@layouts[name].object_class = cl
|
@types[name].object_class = cl
|
||||||
cl.instance_methods = object_with_layout Parfait::List
|
cl.instance_methods = object_with_type Parfait::List
|
||||||
# puts "instance_methods is #{cl.instance_methods.class}"
|
# puts "instance_methods is #{cl.instance_methods.class}"
|
||||||
cl.name = name
|
cl.name = name
|
||||||
classes[name] = cl
|
classes[name] = cl
|
||||||
@ -78,7 +78,7 @@ module Register
|
|||||||
# superclasses other than default object
|
# superclasses other than default object
|
||||||
supers = { :Object => :Kernel , :Kernel => :Value,
|
supers = { :Object => :Kernel , :Kernel => :Value,
|
||||||
:Integer => :Value , :BinaryCode => :Word }
|
:Integer => :Value , :BinaryCode => :Word }
|
||||||
layout_names.each do |classname , ivar|
|
type_names.each do |classname , ivar|
|
||||||
next if classname == :Value # has no superclass
|
next if classname == :Value # has no superclass
|
||||||
clazz = classes[classname]
|
clazz = classes[classname]
|
||||||
super_name = supers[classname] || :Object
|
super_name = supers[classname] || :Object
|
||||||
@ -86,28 +86,28 @@ module Register
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# helper to create a Layout, name is the parfait name, ie :Layout
|
# helper to create a Layout, name is the parfait name, ie :Type
|
||||||
def layout_for( name , ivars )
|
def type_for( name , ivars )
|
||||||
l = Parfait::Layout.allocate.fake_init
|
l = Parfait::Type.allocate.fake_init
|
||||||
l.add_instance_variable :layout , :Layout
|
l.add_instance_variable :type , :Type
|
||||||
ivars.each {|n,t| l.add_instance_variable( n , t) }
|
ivars.each {|n,t| l.add_instance_variable( n , t) }
|
||||||
l
|
l
|
||||||
end
|
end
|
||||||
|
|
||||||
# create an object with layout (ie allocate it and assign layout)
|
# create an object with type (ie allocate it and assign type)
|
||||||
# meaning the lauouts have to be booted, @layouts filled
|
# meaning the lauouts have to be booted, @types filled
|
||||||
# here we pass the actual (ruby) class
|
# here we pass the actual (ruby) class
|
||||||
def object_with_layout(cl)
|
def object_with_type(cl)
|
||||||
o = cl.allocate.fake_init
|
o = cl.allocate.fake_init
|
||||||
name = cl.name.split("::").last.to_sym
|
name = cl.name.split("::").last.to_sym
|
||||||
o.set_layout @layouts[name]
|
o.set_type @types[name]
|
||||||
o
|
o
|
||||||
end
|
end
|
||||||
|
|
||||||
# the function really just returns a constant (just avoiding the constant)
|
# the function really just returns a constant (just avoiding the constant)
|
||||||
# unfortuantely that constant condenses every detail about the system, class names
|
# unfortuantely that constant condenses every detail about the system, class names
|
||||||
# and all instance variable names. Really have to find a better way
|
# and all instance variable names. Really have to find a better way
|
||||||
def layout_names
|
def type_names
|
||||||
{ :Word => {:char_length => :Integer} ,
|
{ :Word => {:char_length => :Integer} ,
|
||||||
:List => {:indexed_length => :Integer} ,
|
:List => {:indexed_length => :Integer} ,
|
||||||
:Message => { :next_message => :Message, :receiver => :Object, :frame => :Frame ,
|
:Message => { :next_message => :Message, :receiver => :Object, :frame => :Frame ,
|
||||||
@ -120,8 +120,8 @@ module Register
|
|||||||
:BinaryCode => {:char_length => :Integer} ,
|
:BinaryCode => {:char_length => :Integer} ,
|
||||||
:Space => {:classes => :Dictionary , :first_message => :Message},
|
:Space => {:classes => :Dictionary , :first_message => :Message},
|
||||||
:Frame => {:next_frame => :Frame, :indexed_length => :Integer},
|
:Frame => {:next_frame => :Frame, :indexed_length => :Integer},
|
||||||
:Layout => {:object_class => :Class, :instance_methods => :List , :indexed_length => :Integer} ,
|
:Type => {:object_class => :Class, :instance_methods => :List , :indexed_length => :Integer} ,
|
||||||
:Class => {:instance_methods => :List, :object_layout => :Layout, :name => :Word,
|
:Class => {:instance_methods => :List, :object_type => :Type, :name => :Word,
|
||||||
:super_class_name => :Word},
|
:super_class_name => :Word},
|
||||||
:Dictionary => {:keys => :List , :values => :List } ,
|
:Dictionary => {:keys => :List , :values => :List } ,
|
||||||
:Method => {:name => :Word, :source => :Object, :instructions => :Object, :binary => :Object,
|
:Method => {:name => :Word, :source => :Object, :instructions => :Object, :binary => :Object,
|
||||||
|
@ -17,11 +17,11 @@ module Register
|
|||||||
if object.is_a? Register::Label
|
if object.is_a? Register::Label
|
||||||
object.each_label { |l| self.add_object(l)}
|
object.each_label { |l| self.add_object(l)}
|
||||||
end
|
end
|
||||||
return unless object.respond_to? :has_layout?
|
return unless object.respond_to? :has_type?
|
||||||
layout = object.get_layout
|
type = object.get_type
|
||||||
keep(layout , depth + 1)
|
keep(type , depth + 1)
|
||||||
return if object.is_a? Symbol
|
return if object.is_a? Symbol
|
||||||
layout.instance_names.each do |name|
|
type.instance_names.each do |name|
|
||||||
#puts "Keep #{name} for #{object.class}"
|
#puts "Keep #{name} for #{object.class}"
|
||||||
inst = object.get_instance_variable name
|
inst = object.get_instance_variable name
|
||||||
keep(inst , depth + 1)
|
keep(inst , depth + 1)
|
||||||
|
@ -14,7 +14,7 @@ module Padding
|
|||||||
end
|
end
|
||||||
|
|
||||||
def padding_for length
|
def padding_for length
|
||||||
pad = padded(length) - length # for header, layout
|
pad = padded(length) - length # for header, type
|
||||||
pad
|
pad
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -10,7 +10,7 @@ require_relative "parfait/method"
|
|||||||
require_relative "parfait/meta_class"
|
require_relative "parfait/meta_class"
|
||||||
require_relative "parfait/variable"
|
require_relative "parfait/variable"
|
||||||
require_relative "parfait/dictionary"
|
require_relative "parfait/dictionary"
|
||||||
require_relative "parfait/layout"
|
require_relative "parfait/type"
|
||||||
require_relative "parfait/message"
|
require_relative "parfait/message"
|
||||||
require_relative "parfait/frame"
|
require_relative "parfait/frame"
|
||||||
require_relative "parfait/space"
|
require_relative "parfait/space"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Class is mainly a list of methods with a name (for now)
|
# Class is mainly a list of methods with a name (for now)
|
||||||
# The memory layout of object is seperated into Layout
|
# The memory type of object is seperated into Layout
|
||||||
|
|
||||||
# A class describes the capabilities of a group of objects, ie what data it has
|
# A class describes the capabilities of a group of objects, ie what data it has
|
||||||
# and functions it responds to.
|
# and functions it responds to.
|
||||||
@ -17,16 +17,16 @@
|
|||||||
module Parfait
|
module Parfait
|
||||||
class Class < Object
|
class Class < Object
|
||||||
include Behaviour
|
include Behaviour
|
||||||
attributes [:object_layout , :name , :super_class_name]
|
attributes [:object_type , :name , :super_class_name]
|
||||||
|
|
||||||
def initialize name , superclass
|
def initialize name , superclass
|
||||||
super()
|
super()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.super_class_name = superclass
|
self.super_class_name = superclass
|
||||||
# the layout for this class (class = object of type Class) carries the class
|
# the type 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
|
# as an instance. The relation is from an object through the Layout to it's class
|
||||||
# TODO the object layout should copy the stuff from superclass
|
# TODO the object type should copy the stuff from superclass
|
||||||
self.object_layout = Layout.new(self)
|
self.object_type = Type.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def allocate_object
|
def allocate_object
|
||||||
@ -34,7 +34,7 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
def add_instance_name name
|
def add_instance_name name
|
||||||
self.object_layout.push name
|
self.object_type.push name
|
||||||
end
|
end
|
||||||
|
|
||||||
def sof_reference_name
|
def sof_reference_name
|
||||||
@ -48,7 +48,7 @@ module Parfait
|
|||||||
|
|
||||||
def create_instance_method method_name , arguments
|
def create_instance_method method_name , arguments
|
||||||
raise "create_instance_method #{method_name}.#{method_name.class}" unless method_name.is_a?(Symbol)
|
raise "create_instance_method #{method_name}.#{method_name.class}" unless method_name.is_a?(Symbol)
|
||||||
clazz = object_layout().object_class()
|
clazz = object_type().object_class()
|
||||||
raise "??? #{method_name}" unless clazz
|
raise "??? #{method_name}" unless clazz
|
||||||
#puts "Self: #{self.class} clazz: #{clazz.name}"
|
#puts "Self: #{self.class} clazz: #{clazz.name}"
|
||||||
add_instance_method Method.new( clazz , method_name , arguments )
|
add_instance_method Method.new( clazz , method_name , arguments )
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
# to the next message.
|
# to the next message.
|
||||||
# The better way to say above is that a message is *used* by the caller, and a frame by the callee.
|
# The better way to say above is that a message is *used* by the caller, and a frame by the callee.
|
||||||
|
|
||||||
# Also at runtime Messages and Frames remain completely "normal" objects. Ie have layouts and so on.
|
# Also at runtime Messages and Frames remain completely "normal" objects. Ie have types and so on.
|
||||||
# Which resolves the dichotomy of objects on the stack or heap. Sama sama.
|
# Which resolves the dichotomy of objects on the stack or heap. Sama sama.
|
||||||
|
|
||||||
module Parfait
|
module Parfait
|
||||||
@ -20,7 +20,7 @@ module Parfait
|
|||||||
attribute :next_frame
|
attribute :next_frame
|
||||||
|
|
||||||
include Indexed
|
include Indexed
|
||||||
self.offset(2) # 1 == the next_frame attributes above + layout. (indexed_length gets added)
|
self.offset(2) # 1 == the next_frame attributes above + type. (indexed_length gets added)
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# various classes would derive from array in ruby, ie have indexed variables
|
# various classes would derive from array in ruby, ie have indexed variables
|
||||||
#
|
#
|
||||||
# But for our memory layout we need the variable part of an object to be after
|
# But for our memory type we need the variable part of an object to be after
|
||||||
# the fixed, ie the instance variables
|
# the fixed, ie the instance variables
|
||||||
#
|
#
|
||||||
# Just using ruby derivation will not allow us to offset the index, so instead the
|
# Just using ruby derivation will not allow us to offset the index, so instead the
|
||||||
@ -95,12 +95,12 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
# word length (padded) is the amount of space taken by the object
|
# word length (padded) is the amount of space taken by the object
|
||||||
# For your basic object this means the number of instance variables as determined by layout
|
# For your basic object this means the number of instance variables as determined by type
|
||||||
# This is off course 0 for a list, unless someone squeezed an instance variable in
|
# This is off course 0 for a list, unless someone squeezed an instance variable in
|
||||||
# but additionally, the amount of data comes on top.
|
# but additionally, the amount of data comes on top.
|
||||||
# unfortuntely we can't just use super because of the Padding
|
# unfortuntely we can't just use super because of the Padding
|
||||||
def padded_length
|
def padded_length
|
||||||
padded_words( get_layout().instance_length + get_length() )
|
padded_words( get_type().instance_length + get_length() )
|
||||||
end
|
end
|
||||||
|
|
||||||
def each
|
def each
|
||||||
@ -154,7 +154,7 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
define_method :get_length do
|
define_method :get_length do
|
||||||
r = get_internal_word( offset ) #one for layout
|
r = get_internal_word( offset ) #one for type
|
||||||
r.nil? ? 0 : r
|
r.nil? ? 0 : r
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -187,7 +187,7 @@ module Parfait
|
|||||||
return if old_length >= len
|
return if old_length >= len
|
||||||
# raise "bounds error at #{len}" if( len + offset > 16 )
|
# raise "bounds error at #{len}" if( len + offset > 16 )
|
||||||
# be nice to use the indexed_length , but that relies on booted space
|
# be nice to use the indexed_length , but that relies on booted space
|
||||||
set_internal_word( offset , len) #one for layout
|
set_internal_word( offset , len) #one for type
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method :shrink_to do | len|
|
define_method :shrink_to do | len|
|
||||||
|
@ -13,7 +13,7 @@ module Parfait
|
|||||||
attributes [:return_value, :caller , :name ]
|
attributes [:return_value, :caller , :name ]
|
||||||
|
|
||||||
include Indexed
|
include Indexed
|
||||||
self.offset(8) # 8 == the seven attributes above + layout. (indexed_length gets added)
|
self.offset(8) # 8 == the seven attributes above + type. (indexed_length gets added)
|
||||||
|
|
||||||
def initialize next_m
|
def initialize next_m
|
||||||
self.next_message = next_m
|
self.next_message = next_m
|
||||||
@ -28,7 +28,7 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
def get_type_for(name)
|
def get_type_for(name)
|
||||||
index = @layout.get_index(name)
|
index = @type.get_index(name)
|
||||||
get_at(index)
|
get_at(index)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -8,11 +8,11 @@ module Parfait
|
|||||||
# .... the class object but gives us the ability to use the
|
# .... the class object but gives us the ability to use the
|
||||||
# syntax as if it were a class
|
# syntax as if it were a class
|
||||||
|
|
||||||
# While the "real" metaclass is the layout, we need to honor the constancy of the layout
|
# While the "real" metaclass is the type, we need to honor the constancy of the type
|
||||||
# So the layout needs to be copied and replaced anytime it is edited.
|
# So the type needs to be copied and replaced anytime it is edited.
|
||||||
# And then changed in the original object, and thus we need this level of indirection
|
# And then changed in the original object, and thus we need this level of indirection
|
||||||
|
|
||||||
# Basically we implement the Behaviour protocol, by forwarding to the layout
|
# Basically we implement the Behaviour protocol, by forwarding to the type
|
||||||
|
|
||||||
class MetaClass < Object
|
class MetaClass < Object
|
||||||
include Logging
|
include Logging
|
||||||
@ -25,35 +25,35 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
self.object.get_layout.name
|
self.object.get_type.name
|
||||||
end
|
end
|
||||||
# first part of the protocol is read, just forward to self.object.layout
|
# first part of the protocol is read, just forward to self.object.type
|
||||||
def methods
|
def methods
|
||||||
self.object.get_layout.methods
|
self.object.get_type.methods
|
||||||
end
|
end
|
||||||
def method_names
|
def method_names
|
||||||
self.object.get_layout.method_names
|
self.object.get_type.method_names
|
||||||
end
|
end
|
||||||
def get_instance_method fname
|
def get_instance_method fname
|
||||||
self.object.get_layout.get_instance_method fname
|
self.object.get_type.get_instance_method fname
|
||||||
end
|
end
|
||||||
def resolve_method m_name
|
def resolve_method m_name
|
||||||
self.object.get_layout.resolve_method m_name
|
self.object.get_type.resolve_method m_name
|
||||||
end
|
end
|
||||||
|
|
||||||
# the modifying part creates a new layout
|
# the modifying part creates a new type
|
||||||
# forwards the action and replaces the layout
|
# forwards the action and replaces the type
|
||||||
def add_instance_method method
|
def add_instance_method method
|
||||||
layout = self.object.get_layout.dup
|
type = self.object.get_type.dup
|
||||||
ret = layout.add_instance_method(method)
|
ret = type.add_instance_method(method)
|
||||||
self.object.set_layout layout
|
self.object.set_type type
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
def remove_instance_method method_name
|
def remove_instance_method method_name
|
||||||
layout = self.object.get_layout.dup
|
type = self.object.get_type.dup
|
||||||
ret = layout.remove_instance_method(method_name)
|
ret = type.remove_instance_method(method_name)
|
||||||
self.object.set_layout layout
|
self.object.set_type type
|
||||||
ret
|
ret
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ module Parfait
|
|||||||
object.fake_init if object.respond_to?(:fake_init) # at compile, not run-time
|
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
|
# 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)
|
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
|
# and have to set the type before we let the object do anything. otherwise boom
|
||||||
object.set_layout cl.object_layout
|
object.set_type cl.object_type
|
||||||
|
|
||||||
object.send :initialize , *args
|
object.send :initialize , *args
|
||||||
object
|
object
|
||||||
@ -71,27 +71,27 @@ module Parfait
|
|||||||
# In Salama we store the class in the Layout, and so the Layout is the only fixed
|
# In Salama we store the class in the Layout, and so the Layout is the only fixed
|
||||||
# data that every object carries.
|
# data that every object carries.
|
||||||
def get_class()
|
def get_class()
|
||||||
l = get_layout()
|
l = get_type()
|
||||||
#puts "Layout #{l.class} in #{self.class} , #{self}"
|
#puts "Type #{l.class} in #{self.class} , #{self}"
|
||||||
l.object_class()
|
l.object_class()
|
||||||
end
|
end
|
||||||
|
|
||||||
# private
|
# private
|
||||||
def set_layout(layout)
|
def set_type(type)
|
||||||
# puts "Layout was set for #{self.class}"
|
# puts "Type was set for #{self.class}"
|
||||||
raise "Nil layout" unless layout
|
raise "Nil type" unless type
|
||||||
set_internal_word(LAYOUT_INDEX , layout)
|
set_internal_word(LAYOUT_INDEX , type)
|
||||||
end
|
end
|
||||||
|
|
||||||
# so we can keep the raise in get_layout
|
# so we can keep the raise in get_type
|
||||||
def has_layout?
|
def has_type?
|
||||||
! get_internal_word(LAYOUT_INDEX).nil?
|
! get_internal_word(LAYOUT_INDEX).nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_layout()
|
def get_type()
|
||||||
l = get_internal_word(LAYOUT_INDEX)
|
l = get_internal_word(LAYOUT_INDEX)
|
||||||
#puts "get layout for #{self.class} returns #{l.class}"
|
#puts "get type for #{self.class} returns #{l.class}"
|
||||||
raise "No layout #{self.object_id.to_s(16)}:#{self.class} " unless l
|
raise "No type #{self.object_id.to_s(16)}:#{self.class} " unless l
|
||||||
return l
|
return l
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
def get_instance_variables
|
def get_instance_variables
|
||||||
get_layout().instance_names
|
get_type().instance_names
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_instance_variable name
|
def get_instance_variable name
|
||||||
@ -118,11 +118,11 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
def instance_variable_defined name
|
def instance_variable_defined name
|
||||||
get_layout().variable_index(name)
|
get_type().variable_index(name)
|
||||||
end
|
end
|
||||||
|
|
||||||
def padded_length
|
def padded_length
|
||||||
padded_words( get_layout().instance_length )
|
padded_words( get_type().instance_length )
|
||||||
end
|
end
|
||||||
|
|
||||||
# parfait versions are deliberately called different, so we "relay"
|
# parfait versions are deliberately called different, so we "relay"
|
||||||
|
@ -64,7 +64,7 @@ module Parfait
|
|||||||
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 = self.classes[name]
|
c = self.classes[name]
|
||||||
#puts "MISS, no class #{name} #{name.class}" unless c # " #{self.classes}"
|
#puts "MISS, no class #{name} #{name.class}" unless c # " #{self.classes}"
|
||||||
#puts "CLAZZ, #{name} #{c.get_layout.get_length}" if c
|
#puts "CLAZZ, #{name} #{c.get_type.get_length}" if c
|
||||||
c
|
c
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -3,11 +3,11 @@ class Symbol
|
|||||||
include Positioned
|
include Positioned
|
||||||
include Padding
|
include Padding
|
||||||
|
|
||||||
def has_layout?
|
def has_type?
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
def get_layout
|
def get_type
|
||||||
l = Register.machine.space.classes[:Word].object_layout
|
l = Register.machine.space.classes[:Word].object_type
|
||||||
#puts "LL #{l.class}"
|
#puts "LL #{l.class}"
|
||||||
l
|
l
|
||||||
end
|
end
|
||||||
|
@ -5,17 +5,17 @@
|
|||||||
# Instead we store only the values, and access them by index.
|
# Instead we store only the values, and access them by index.
|
||||||
# The Layout allows the mapping of names to index.
|
# The Layout allows the mapping of names to index.
|
||||||
|
|
||||||
# The Layout of an object describes the memory layout of the object
|
# The Layout of an object describes the memory type of the object
|
||||||
# The Layout is a simple list of the names of instance variables.
|
# The Layout is a simple list of the names of instance variables.
|
||||||
#
|
#
|
||||||
# As every object has a Layout to describe it, the name "layout" is the
|
# As every object has a Layout to describe it, the name "type" is the
|
||||||
# first name in the list for every Layout.
|
# first name in the list for every Layout.
|
||||||
|
|
||||||
# But as we want every Object to have a class, the Layout carries that class.
|
# But as we want every Object to have a class, the Layout carries that class.
|
||||||
# So the layout of layout has an entry "object_class"
|
# So the type of type has an entry "object_class"
|
||||||
|
|
||||||
# But Objects must also be able to carry methods themselves (ruby calls singleton_methods)
|
# But Objects must also be able to carry methods themselves (ruby calls singleton_methods)
|
||||||
# and those too are stored in the Layout (both layout and class include behaviour)
|
# and those too are stored in the Layout (both type and class include behaviour)
|
||||||
|
|
||||||
# In other words, the Layout is a list of names that describe
|
# In other words, the Layout is a list of names that describe
|
||||||
# the values stored in an actual object.
|
# the values stored in an actual object.
|
||||||
@ -24,7 +24,7 @@
|
|||||||
# Together they turn the object into a hash like structure
|
# Together they turn the object into a hash like structure
|
||||||
|
|
||||||
module Parfait
|
module Parfait
|
||||||
class Layout < Object
|
class Type < Object
|
||||||
attribute :object_class
|
attribute :object_class
|
||||||
include Behaviour
|
include Behaviour
|
||||||
|
|
||||||
@ -33,7 +33,7 @@ module Parfait
|
|||||||
|
|
||||||
def initialize( object_class )
|
def initialize( object_class )
|
||||||
super()
|
super()
|
||||||
add_instance_variable :layout ,:Layout
|
add_instance_variable :type ,:Type
|
||||||
self.object_class = object_class
|
self.object_class = object_class
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ module Parfait
|
|||||||
# The index will be returned and can subsequently be searched with index_of
|
# 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
|
# The index of the name is the index of the data in the object
|
||||||
#
|
#
|
||||||
# TODO , later we would need to COPY the layout to keep the old constant
|
# 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
|
# but now we are concerned with booting, ie getting a working structure
|
||||||
def add_instance_variable name , type
|
def add_instance_variable name , type
|
||||||
raise "Name shouldn't be nil" unless name
|
raise "Name shouldn't be nil" unless name
|
||||||
@ -75,7 +75,7 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
# index of the variable when using get_internal_word
|
# index of the variable when using get_internal_word
|
||||||
# (get_internal_word is 1 based and 1 is always the layout)
|
# (get_internal_word is 1 based and 1 is always the type)
|
||||||
def variable_index name
|
def variable_index name
|
||||||
has = super_index(name)
|
has = super_index(name)
|
||||||
return nil unless has
|
return nil unless has
|
||||||
@ -89,11 +89,11 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
"Layout[#{super}]"
|
"Type[#{super}]"
|
||||||
end
|
end
|
||||||
|
|
||||||
def sof_reference_name
|
def sof_reference_name
|
||||||
"#{self.object_class.name}_Layout"
|
"#{self.object_class.name}_Type"
|
||||||
end
|
end
|
||||||
alias :name :sof_reference_name
|
alias :name :sof_reference_name
|
||||||
|
|
@ -10,14 +10,14 @@ module Parfait
|
|||||||
|
|
||||||
# Words are objects, that means they carry Layout as index 0
|
# Words are objects, that means they carry Layout as index 0
|
||||||
# So all indexes are offset by one in the implementation
|
# So all indexes are offset by one in the implementation
|
||||||
# Object length is measured in non-layout cells though
|
# Object length is measured in non-type cells though
|
||||||
|
|
||||||
class Word < Object
|
class Word < Object
|
||||||
attribute :char_length
|
attribute :char_length
|
||||||
|
|
||||||
#semi "indexed" methods for interpreter
|
#semi "indexed" methods for interpreter
|
||||||
def self.get_length_index
|
def self.get_length_index
|
||||||
2 # 2 is the amount of attributes, layout and char_length. the offset after which chars start
|
2 # 2 is the amount of attributes, type and char_length. the offset after which chars start
|
||||||
end
|
end
|
||||||
def self.get_indexed i
|
def self.get_indexed i
|
||||||
i + get_length_index * 4
|
i + get_length_index * 4
|
||||||
@ -31,7 +31,7 @@ module Parfait
|
|||||||
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 beeing ascii space
|
set_length( len , 32 ) unless len == 0 #32 beeing ascii space
|
||||||
#puts "layout #{self.get_layout} #{self.object_id.to_s(16)}"
|
#puts "type #{self.get_type} #{self.object_id.to_s(16)}"
|
||||||
end
|
end
|
||||||
|
|
||||||
# return a copy of self
|
# return a copy of self
|
||||||
@ -182,7 +182,7 @@ module Parfait
|
|||||||
end
|
end
|
||||||
|
|
||||||
def padded_length
|
def padded_length
|
||||||
padded( 4 * get_layout().instance_length + self.char_length )
|
padded( 4 * get_type().instance_length + self.char_length )
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
@ -84,7 +84,7 @@ module Register
|
|||||||
end
|
end
|
||||||
|
|
||||||
# The first arg is a class name (possibly lowercase) and the second an instance variable name.
|
# The first arg is a class name (possibly lowercase) and the second an instance variable name.
|
||||||
# By looking up the class and the layout for that class, we can resolve the instance
|
# By looking up the class and the type for that class, we can resolve the instance
|
||||||
# variable name to an index.
|
# variable name to an index.
|
||||||
# The class can be mapped to a register, and so we get a memory address (reg+index)
|
# The class can be mapped to a register, and so we get a memory address (reg+index)
|
||||||
def self.resolve_index( clazz_name , instance_name )
|
def self.resolve_index( clazz_name , instance_name )
|
||||||
@ -92,9 +92,9 @@ module Register
|
|||||||
real_name = clazz_name.to_s.split('_').last.capitalize.to_sym
|
real_name = clazz_name.to_s.split('_').last.capitalize.to_sym
|
||||||
clazz = Parfait::Space.object_space.get_class_by_name(real_name)
|
clazz = Parfait::Space.object_space.get_class_by_name(real_name)
|
||||||
raise "Class name not given #{real_name}" unless clazz
|
raise "Class name not given #{real_name}" unless clazz
|
||||||
index = clazz.object_layout.variable_index( instance_name )
|
index = clazz.object_type.variable_index( instance_name )
|
||||||
raise "Instance name=#{instance_name} not found on #{real_name}" unless index.is_a?(Numeric)
|
raise "Instance name=#{instance_name} not found on #{real_name}" unless index.is_a?(Numeric)
|
||||||
return index # the type word is at index 0, but layout is a list and starts at 1 == layout
|
return index # the type word is at index 0, but type is a list and starts at 1 == type
|
||||||
end
|
end
|
||||||
|
|
||||||
# if a symbol is given, it may be one of the four objects that the vm knows.
|
# if a symbol is given, it may be one of the four objects that the vm knows.
|
||||||
|
@ -155,7 +155,7 @@ module Soml
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.each_parfait
|
def self.each_parfait
|
||||||
["word","class","layout","message" ,"integer", "object"].each do |o|
|
["word","class","type","message" ,"integer", "object"].each do |o|
|
||||||
str = File.open(File.expand_path("parfait/#{o}.soml", File.dirname(__FILE__))).read
|
str = File.open(File.expand_path("parfait/#{o}.soml", File.dirname(__FILE__))).read
|
||||||
syntax = Parser::Salama.new.parse_with_debug(str, reporter: Parslet::ErrorReporter::Deepest.new)
|
syntax = Parser::Salama.new.parse_with_debug(str, reporter: Parslet::ErrorReporter::Deepest.new)
|
||||||
parts = Parser::Transform.new.apply(syntax)
|
parts = Parser::Transform.new.apply(syntax)
|
||||||
|
@ -7,10 +7,10 @@ module Soml
|
|||||||
|
|
||||||
for_class = @clazz
|
for_class = @clazz
|
||||||
raise "no class" unless for_class
|
raise "no class" unless for_class
|
||||||
index = for_class.object_layout.variable_index(name)
|
index = for_class.object_type.variable_index(name)
|
||||||
#raise "class field already defined:#{name} for class #{for_class.name}" if index
|
#raise "class field already defined:#{name} for class #{for_class.name}" if index
|
||||||
#puts "Define field #{name} on class #{for_class.name}"
|
#puts "Define field #{name} on class #{for_class.name}"
|
||||||
index = for_class.object_layout.add_instance_variable( name , type )
|
index = for_class.object_type.add_instance_variable( name , type )
|
||||||
|
|
||||||
# not sure how to run class code yet. later
|
# not sure how to run class code yet. later
|
||||||
raise "value #{value}" if value
|
raise "value #{value}" if value
|
||||||
|
@ -10,9 +10,9 @@ module Soml
|
|||||||
field_name = field_ast.first_from(:name)
|
field_name = field_ast.first_from(:name)
|
||||||
|
|
||||||
|
|
||||||
index = clazz.object_layout.variable_index(field_name)
|
index = clazz.object_type.variable_index(field_name)
|
||||||
raise "field access, but no such field:#{field_name} for class #{clazz.name}" unless index
|
raise "field access, but no such field:#{field_name} for class #{clazz.name}" unless index
|
||||||
value = use_reg(clazz.object_layout.type_at(index))
|
value = use_reg(clazz.object_type.type_at(index))
|
||||||
|
|
||||||
add_code Register.get_slot(statement , receiver , index, value)
|
add_code Register.get_slot(statement , receiver , index, value)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
class Class < Object
|
class Class < Object
|
||||||
field List instance_methods
|
field List instance_methods
|
||||||
field Layout object_layout
|
field Type object_type
|
||||||
field Word name
|
field Word name
|
||||||
field Word super_class_name
|
field Word super_class_name
|
||||||
|
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
class Object
|
class Object
|
||||||
|
|
||||||
Layout get_layout()
|
Type get_type()
|
||||||
return self.layout
|
return self.type
|
||||||
end
|
end
|
||||||
|
|
||||||
Class get_class()
|
Class get_class()
|
||||||
Layout l = self.layout
|
Type l = self.type
|
||||||
return l.object_class
|
return l.object_class
|
||||||
end
|
end
|
||||||
|
|
||||||
Word get_class_name()
|
Word get_class_name()
|
||||||
Layout l = self.layout
|
Type l = self.type
|
||||||
Class c = l.object_class
|
Class c = l.object_class
|
||||||
return c.name
|
return c.name
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
class Layout < Object
|
class Type < Object
|
||||||
field Class object_class
|
field Class object_class
|
||||||
field List instance_methods
|
field List instance_methods
|
||||||
field Integer indexed_length
|
field Integer indexed_length
|
@ -1,7 +1,7 @@
|
|||||||
require_relative "test_attributes"
|
require_relative "test_attributes"
|
||||||
require_relative "test_class"
|
require_relative "test_class"
|
||||||
require_relative "test_dictionary"
|
require_relative "test_dictionary"
|
||||||
require_relative "test_layout"
|
require_relative "test_type"
|
||||||
require_relative "test_list"
|
require_relative "test_list"
|
||||||
require_relative "test_message"
|
require_relative "test_message"
|
||||||
require_relative "test_meta"
|
require_relative "test_meta"
|
||||||
|
@ -4,19 +4,19 @@ class TestAttributes < MiniTest::Test
|
|||||||
|
|
||||||
def setup
|
def setup
|
||||||
@mess = Register.machine.boot.space.first_message
|
@mess = Register.machine.boot.space.first_message
|
||||||
@layout = @mess.get_layout
|
@type = @mess.get_type
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_message_get_layout
|
def test_message_get_type
|
||||||
assert_equal Parfait::Layout , @layout.class
|
assert_equal Parfait::Type , @type.class
|
||||||
end
|
end
|
||||||
def test_message_layout_first
|
def test_message_type_first
|
||||||
@layout.object_class = :next_message
|
@type.object_class = :next_message
|
||||||
assert_equal :layout , @layout.instance_names.first
|
assert_equal :type , @type.instance_names.first
|
||||||
assert_equal :next_message , @layout.object_class
|
assert_equal :next_message , @type.object_class
|
||||||
end
|
end
|
||||||
def test_message_name_nil
|
def test_message_name_nil
|
||||||
last = @layout.instance_names.last
|
last = @type.instance_names.last
|
||||||
assert_equal :indexed_length , last
|
assert_equal :indexed_length , last
|
||||||
assert_equal nil , @mess.name
|
assert_equal nil , @mess.name
|
||||||
end
|
end
|
||||||
@ -24,26 +24,26 @@ class TestAttributes < MiniTest::Test
|
|||||||
@mess.next_message = :next_message
|
@mess.next_message = :next_message
|
||||||
assert_equal :next_message , @mess.next_message
|
assert_equal :next_message , @mess.next_message
|
||||||
end
|
end
|
||||||
def test_message_layout_set
|
def test_message_type_set
|
||||||
@mess.set_layout :layout
|
@mess.set_type :type
|
||||||
assert_equal :layout , @mess.get_layout
|
assert_equal :type , @mess.get_type
|
||||||
end
|
end
|
||||||
def test_attribute_index
|
def test_attribute_index
|
||||||
@mess.next_message = :message
|
@mess.next_message = :message
|
||||||
assert_equal Parfait::Layout , @mess.get_layout.class
|
assert_equal Parfait::Type , @mess.get_type.class
|
||||||
end
|
end
|
||||||
def test_layout_attribute
|
def test_type_attribute
|
||||||
@layout.object_class = :message
|
@type.object_class = :message
|
||||||
assert_equal :message , @layout.object_class
|
assert_equal :message , @type.object_class
|
||||||
end
|
end
|
||||||
def test_layout_attribute_check
|
def test_type_attribute_check
|
||||||
@layout.object_class = :message
|
@type.object_class = :message
|
||||||
assert_equal Parfait::Layout , @layout.get_layout.class
|
assert_equal Parfait::Type , @type.get_type.class
|
||||||
end
|
end
|
||||||
def test_layout_layout
|
def test_type_type
|
||||||
assert_equal Parfait::Layout , @layout.get_layout.get_layout.class
|
assert_equal Parfait::Type , @type.get_type.get_type.class
|
||||||
end
|
end
|
||||||
def test_layout_layout_layout
|
def test_type_type_type
|
||||||
assert_equal Parfait::Layout , @layout.get_layout.get_layout.get_layout.class
|
assert_equal Parfait::Type , @type.get_type.get_type.get_type.class
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,9 +12,9 @@ class TestClass < MiniTest::Test
|
|||||||
::Parfait::Method.new @space.get_class_by_name(for_class) , :foo , args
|
::Parfait::Method.new @space.get_class_by_name(for_class) , :foo , args
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_layout_forclass
|
def test_type_forclass
|
||||||
assert_equal "Class(Space)" , @space.get_layout.object_class.inspect
|
assert_equal "Class(Space)" , @space.get_type.object_class.inspect
|
||||||
assert_equal :Space , @space.get_layout.object_class.name
|
assert_equal :Space , @space.get_type.object_class.name
|
||||||
end
|
end
|
||||||
def test_new_superclass_name
|
def test_new_superclass_name
|
||||||
assert_equal :Object , @try.super_class_name
|
assert_equal :Object , @try.super_class_name
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
require_relative "../helper"
|
require_relative "../helper"
|
||||||
|
|
||||||
class TestDictionary < MiniTest::Test
|
class TestDictionary < MiniTest::Test
|
||||||
Register.machine.boot #have to book, otherwise layouts etc not set
|
Register.machine.boot #have to book, otherwise types etc not set
|
||||||
|
|
||||||
def setup
|
def setup
|
||||||
@lookup = ::Parfait::Dictionary.new
|
@lookup = ::Parfait::Dictionary.new
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
require_relative "../helper"
|
|
||||||
|
|
||||||
class TestLayout < MiniTest::Test
|
|
||||||
|
|
||||||
def setup
|
|
||||||
@mess = Register.machine.boot.space.first_message
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_message_layout
|
|
||||||
layout = @mess.get_layout
|
|
||||||
assert layout
|
|
||||||
assert @mess.instance_variable_defined :next_message
|
|
||||||
assert_equal @mess.next_message , @mess.get_instance_variable(:next_message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_message_by_index
|
|
||||||
assert_equal @mess.next_message , @mess.get_instance_variable(:next_message)
|
|
||||||
index = @mess.get_layout.variable_index :next_message
|
|
||||||
assert_equal 2 , index
|
|
||||||
assert_equal @mess.next_message , @mess.get_internal_word(index)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_layout_index
|
|
||||||
assert_equal @mess.get_layout , @mess.get_internal_word(Parfait::LAYOUT_INDEX) , "mess"
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_inspect
|
|
||||||
assert @mess.get_layout.inspect.start_with?("Layout")
|
|
||||||
end
|
|
||||||
def test_layout_is_first
|
|
||||||
layout = @mess.get_layout
|
|
||||||
assert_equal 1 , layout.variable_index(:layout)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_length
|
|
||||||
assert_equal 9 , @mess.get_layout.instance_length , @mess.get_layout.inspect
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_layout_length
|
|
||||||
assert_equal 9 , @mess.get_layout.instance_length , @mess.get_layout.inspect
|
|
||||||
assert_equal 18 , @mess.get_layout.get_internal_word(4)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_layout_length_index
|
|
||||||
assert_equal 4 , @mess.get_layout.get_layout.variable_index(:indexed_length)
|
|
||||||
assert_equal 4 , @mess.get_layout.get_layout.get_offset
|
|
||||||
assert_equal 4 , @mess.get_layout.get_offset
|
|
||||||
assert_equal 8 , @mess.get_layout.get_layout.indexed_length
|
|
||||||
assert_equal 8 , @mess.get_layout.get_layout.get_internal_word(4)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_layout_methods
|
|
||||||
assert_equal 3 , @mess.get_layout.get_layout.variable_index(:instance_methods)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_no_index_below_1
|
|
||||||
layout = @mess.get_layout
|
|
||||||
names = layout.instance_names
|
|
||||||
assert_equal 9 , names.get_length , names.inspect
|
|
||||||
names.each do |n|
|
|
||||||
assert layout.variable_index(n) >= 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_class_layout
|
|
||||||
oc = Register.machine.boot.space.get_class_by_name( :Object )
|
|
||||||
assert_equal Parfait::Class , oc.class
|
|
||||||
layout = oc.object_layout
|
|
||||||
assert_equal Parfait::Layout , layout.class
|
|
||||||
assert_equal 1 , layout.instance_names.get_length
|
|
||||||
assert_equal layout.first , :layout
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
def test_class_space
|
|
||||||
space = Register.machine.space
|
|
||||||
assert_equal Parfait::Space , space.class
|
|
||||||
layout = space.get_layout
|
|
||||||
assert_equal Parfait::Layout , layout.class
|
|
||||||
assert_equal 3 , layout.instance_names.get_length
|
|
||||||
assert_equal layout.object_class.class , Parfait::Class
|
|
||||||
assert_equal layout.object_class.name , :Space
|
|
||||||
end
|
|
||||||
def test_attribute_set
|
|
||||||
@mess.receiver = 55
|
|
||||||
assert_equal 55 , @mess.receiver
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_add_name
|
|
||||||
layout = Parfait::Layout.new Register.machine.space.get_class_by_name(:Layout)
|
|
||||||
layout.add_instance_variable :boo , :Object
|
|
||||||
assert_equal 2 , layout.variable_index(:boo)
|
|
||||||
assert_equal 4 , layout.get_length
|
|
||||||
assert_equal :layout , layout.get(1)
|
|
||||||
assert_equal :boo , layout.get(3)
|
|
||||||
layout
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_inspect
|
|
||||||
layout = test_add_name
|
|
||||||
assert layout.inspect.include?("boo") , layout.inspect
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_each
|
|
||||||
layout = test_add_name
|
|
||||||
assert_equal 4 , layout.get_length
|
|
||||||
counter = [:boo , :Object, :layout , :Layout]
|
|
||||||
layout.each do |item|
|
|
||||||
assert_equal item , counter.delete(item)
|
|
||||||
end
|
|
||||||
assert counter.empty?
|
|
||||||
end
|
|
||||||
|
|
||||||
# not really parfait test, but related and no other place currently
|
|
||||||
def test_reg_index
|
|
||||||
message_ind = Register.resolve_index( :message , :receiver )
|
|
||||||
assert_equal 3 , message_ind
|
|
||||||
@mess.receiver = 55
|
|
||||||
assert_equal 55 , @mess.get_internal_word(message_ind)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_object_layout
|
|
||||||
assert_equal 2 , @mess.get_layout.variable_index(:next_message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_remove_me
|
|
||||||
layout = @mess.get_layout
|
|
||||||
assert_equal layout , @mess.get_internal_word(1)
|
|
||||||
end
|
|
||||||
end
|
|
@ -10,27 +10,27 @@ class TestList < MiniTest::Test
|
|||||||
assert @list.is_a? Parfait::List
|
assert @list.is_a? Parfait::List
|
||||||
assert @list.is_a? Parfait::Indexed
|
assert @list.is_a? Parfait::Indexed
|
||||||
end
|
end
|
||||||
def test_old_layout
|
def test_old_type
|
||||||
assert_equal Parfait::Layout , Register.machine.space.classes.keys.get_layout.class
|
assert_equal Parfait::Type , Register.machine.space.classes.keys.get_type.class
|
||||||
end
|
end
|
||||||
def test_old_layout_push
|
def test_old_type_push
|
||||||
list = Register.machine.space.classes.keys
|
list = Register.machine.space.classes.keys
|
||||||
assert_equal Parfait::Layout , list.get_layout.class
|
assert_equal Parfait::Type , list.get_type.class
|
||||||
end
|
end
|
||||||
def test_new_layout
|
def test_new_type
|
||||||
assert_equal Parfait::Layout , @list.get_layout.class
|
assert_equal Parfait::Type , @list.get_type.class
|
||||||
end
|
end
|
||||||
def test_new_layout_push
|
def test_new_type_push
|
||||||
@list.push(1)
|
@list.push(1)
|
||||||
assert_equal Parfait::Layout , @list.get_layout.class
|
assert_equal Parfait::Type , @list.get_type.class
|
||||||
end
|
end
|
||||||
def notest_layout_is_first
|
def notest_type_is_first
|
||||||
layout = @list.get_layout
|
type = @list.get_type
|
||||||
assert_equal 1 , layout.variable_index(:layout)
|
assert_equal 1 , type.variable_index(:type)
|
||||||
end
|
end
|
||||||
def notest_layout_is_first_old
|
def notest_type_is_first_old
|
||||||
layout = Register.machine.space.classes.keys.get_layout
|
type = Register.machine.space.classes.keys.get_type
|
||||||
assert_equal 1 , layout.variable_index(:layout)
|
assert_equal 1 , type.variable_index(:type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_length0
|
def test_length0
|
||||||
@ -41,8 +41,8 @@ class TestList < MiniTest::Test
|
|||||||
assert_equal 2 , @list.get_offset
|
assert_equal 2 , @list.get_offset
|
||||||
end
|
end
|
||||||
def test_indexed_index
|
def test_indexed_index
|
||||||
# 1 layout , 2 indexed_length
|
# 1 type , 2 indexed_length
|
||||||
assert_equal 2 , @list.get_layout.variable_index(:indexed_length)
|
assert_equal 2 , @list.get_type.variable_index(:indexed_length)
|
||||||
end
|
end
|
||||||
def test_length1
|
def test_length1
|
||||||
@list.push :one
|
@list.push :one
|
||||||
|
@ -7,7 +7,7 @@ class TestMessage < MiniTest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_length
|
def test_length
|
||||||
assert_equal 9 , @mess.get_layout.instance_length , @mess.get_layout.inspect
|
assert_equal 9 , @mess.get_type.instance_length , @mess.get_type.inspect
|
||||||
assert_equal 9 , Parfait::Message.get_length_index
|
assert_equal 9 , Parfait::Message.get_length_index
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -17,7 +17,7 @@ class TestMessage < MiniTest::Test
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_indexed
|
def test_indexed
|
||||||
assert_equal 9 , @mess.get_layout.variable_index(:indexed_length)
|
assert_equal 9 , @mess.get_type.variable_index(:indexed_length)
|
||||||
end
|
end
|
||||||
def test_push1
|
def test_push1
|
||||||
@mess.push :name
|
@mess.push :name
|
||||||
|
@ -9,8 +9,8 @@ class TestObject < MiniTest::Test
|
|||||||
def test_object_create
|
def test_object_create
|
||||||
# another test sometime adds a field variable. Maybe should reboot ?
|
# another test sometime adds a field variable. Maybe should reboot ?
|
||||||
res = 1
|
res = 1
|
||||||
[:boo1 , :boo2 , :bro , :runner].each { |v| res += 1 if @object.get_layout.variable_index(v) }
|
[:boo1 , :boo2 , :bro , :runner].each { |v| res += 1 if @object.get_type.variable_index(v) }
|
||||||
assert_equal res , @object.get_layout.instance_length , @object.get_layout.inspect
|
assert_equal res , @object.get_type.instance_length , @object.get_type.inspect
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_empty_object_doesnt_return
|
def test_empty_object_doesnt_return
|
||||||
|
@ -6,7 +6,7 @@ class TestSpace < MiniTest::Test
|
|||||||
@machine = Register.machine.boot
|
@machine = Register.machine.boot
|
||||||
end
|
end
|
||||||
def classes
|
def classes
|
||||||
[:Kernel,:Word,:List,:Message,:Frame,:Layout,:Object,:Class,:Dictionary,:Method , :Integer]
|
[:Kernel,:Word,:List,:Message,:Frame,:Type,:Object,:Class,:Dictionary,:Method , :Integer]
|
||||||
end
|
end
|
||||||
def test_booted
|
def test_booted
|
||||||
assert_equal true , @machine.booted
|
assert_equal true , @machine.booted
|
||||||
@ -29,9 +29,9 @@ class TestSpace < MiniTest::Test
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_classes_layout
|
def test_classes_type
|
||||||
classes.each do |name|
|
classes.each do |name|
|
||||||
assert_equal Parfait::Layout , @machine.space.classes[name].get_layout.class
|
assert_equal Parfait::Type , @machine.space.classes[name].get_type.class
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
130
test/register/parfait/test_type.rb
Normal file
130
test/register/parfait/test_type.rb
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
require_relative "../helper"
|
||||||
|
|
||||||
|
class TestType < MiniTest::Test
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@mess = Register.machine.boot.space.first_message
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_message_type
|
||||||
|
type = @mess.get_type
|
||||||
|
assert type
|
||||||
|
assert @mess.instance_variable_defined :next_message
|
||||||
|
assert_equal @mess.next_message , @mess.get_instance_variable(:next_message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_message_by_index
|
||||||
|
assert_equal @mess.next_message , @mess.get_instance_variable(:next_message)
|
||||||
|
index = @mess.get_type.variable_index :next_message
|
||||||
|
assert_equal 2 , index
|
||||||
|
assert_equal @mess.next_message , @mess.get_internal_word(index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_type_index
|
||||||
|
assert_equal @mess.get_type , @mess.get_internal_word(Parfait::LAYOUT_INDEX) , "mess"
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_inspect
|
||||||
|
assert @mess.get_type.inspect.start_with?("Type")
|
||||||
|
end
|
||||||
|
def test_type_is_first
|
||||||
|
type = @mess.get_type
|
||||||
|
assert_equal 1 , type.variable_index(:type)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_length
|
||||||
|
assert_equal 9 , @mess.get_type.instance_length , @mess.get_type.inspect
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_type_length
|
||||||
|
assert_equal 9 , @mess.get_type.instance_length , @mess.get_type.inspect
|
||||||
|
assert_equal 18 , @mess.get_type.get_internal_word(4)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_type_length_index
|
||||||
|
assert_equal 4 , @mess.get_type.get_type.variable_index(:indexed_length)
|
||||||
|
assert_equal 4 , @mess.get_type.get_type.get_offset
|
||||||
|
assert_equal 4 , @mess.get_type.get_offset
|
||||||
|
assert_equal 8 , @mess.get_type.get_type.indexed_length
|
||||||
|
assert_equal 8 , @mess.get_type.get_type.get_internal_word(4)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_type_methods
|
||||||
|
assert_equal 3 , @mess.get_type.get_type.variable_index(:instance_methods)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_no_index_below_1
|
||||||
|
type = @mess.get_type
|
||||||
|
names = type.instance_names
|
||||||
|
assert_equal 9 , names.get_length , names.inspect
|
||||||
|
names.each do |n|
|
||||||
|
assert type.variable_index(n) >= 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_class_type
|
||||||
|
oc = Register.machine.boot.space.get_class_by_name( :Object )
|
||||||
|
assert_equal Parfait::Class , oc.class
|
||||||
|
type = oc.object_type
|
||||||
|
assert_equal Parfait::Type , type.class
|
||||||
|
assert_equal 1 , type.instance_names.get_length
|
||||||
|
assert_equal type.first , :type
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def test_class_space
|
||||||
|
space = Register.machine.space
|
||||||
|
assert_equal Parfait::Space , space.class
|
||||||
|
type = space.get_type
|
||||||
|
assert_equal Parfait::Type , type.class
|
||||||
|
assert_equal 3 , type.instance_names.get_length
|
||||||
|
assert_equal type.object_class.class , Parfait::Class
|
||||||
|
assert_equal type.object_class.name , :Space
|
||||||
|
end
|
||||||
|
def test_attribute_set
|
||||||
|
@mess.receiver = 55
|
||||||
|
assert_equal 55 , @mess.receiver
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_add_name
|
||||||
|
type = Parfait::Type.new Register.machine.space.get_class_by_name(:Type)
|
||||||
|
type.add_instance_variable :boo , :Object
|
||||||
|
assert_equal 2 , type.variable_index(:boo)
|
||||||
|
assert_equal 4 , type.get_length
|
||||||
|
assert_equal :type , type.get(1)
|
||||||
|
assert_equal :boo , type.get(3)
|
||||||
|
type
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_inspect
|
||||||
|
type = test_add_name
|
||||||
|
assert type.inspect.include?("boo") , type.inspect
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_each
|
||||||
|
type = test_add_name
|
||||||
|
assert_equal 4 , type.get_length
|
||||||
|
counter = [:boo , :Object, :type , :Type]
|
||||||
|
type.each do |item|
|
||||||
|
assert_equal item , counter.delete(item)
|
||||||
|
end
|
||||||
|
assert counter.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
# not really parfait test, but related and no other place currently
|
||||||
|
def test_reg_index
|
||||||
|
message_ind = Register.resolve_index( :message , :receiver )
|
||||||
|
assert_equal 3 , message_ind
|
||||||
|
@mess.receiver = 55
|
||||||
|
assert_equal 55 , @mess.get_internal_word(message_ind)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_object_type
|
||||||
|
assert_equal 2 , @mess.get_type.variable_index(:next_message)
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_remove_me
|
||||||
|
type = @mess.get_type
|
||||||
|
assert_equal type , @mess.get_internal_word(1)
|
||||||
|
end
|
||||||
|
end
|
@ -6,19 +6,19 @@ class TestPositioning < MiniTest::Test
|
|||||||
end
|
end
|
||||||
def test_list1
|
def test_list1
|
||||||
list = Parfait.new_list([1])
|
list = Parfait.new_list([1])
|
||||||
list.set_layout( Parfait::Layout.new Object)
|
list.set_type( Parfait::Type.new Object)
|
||||||
assert_equal 32 , list.padded_length
|
assert_equal 32 , list.padded_length
|
||||||
end
|
end
|
||||||
def test_list5
|
def test_list5
|
||||||
list = Parfait.new_list([1,2,3,4,5])
|
list = Parfait.new_list([1,2,3,4,5])
|
||||||
list.set_layout( Parfait::Layout.new Object)
|
list.set_type( Parfait::Type.new Object)
|
||||||
assert_equal 32 , list.padded_length
|
assert_equal 32 , list.padded_length
|
||||||
end
|
end
|
||||||
def test_layout
|
def test_type
|
||||||
layout = Parfait::Layout.new Object
|
type = Parfait::Type.new Object
|
||||||
layout.set_layout( Parfait::Layout.new Object)
|
type.set_type( Parfait::Type.new Object)
|
||||||
layout.push 5
|
type.push 5
|
||||||
assert_equal 32 , layout.padded_length
|
assert_equal 32 , type.padded_length
|
||||||
end
|
end
|
||||||
def test_word
|
def test_word
|
||||||
word = Parfait::Word.new(12)
|
word = Parfait::Word.new(12)
|
||||||
|
@ -25,7 +25,7 @@ HERE
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_field
|
def test_field
|
||||||
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro,:Object)
|
Register.machine.space.get_class_by_name(:Object).object_type.add_instance_variable(:bro,:Object)
|
||||||
@root = :field_access
|
@root = :field_access
|
||||||
@string_input = <<HERE
|
@string_input = <<HERE
|
||||||
self.bro
|
self.bro
|
||||||
|
@ -31,13 +31,13 @@ module Register
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_field_int
|
def test_field_int
|
||||||
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro,:int)
|
Register.machine.space.get_class_by_name(:Object).object_type.add_instance_variable(:bro,:int)
|
||||||
@string_input = "self.bro + 3"
|
@string_input = "self.bro + 3"
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_int_field
|
def test_int_field
|
||||||
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro,:int)
|
Register.machine.space.get_class_by_name(:Object).object_type.add_instance_variable(:bro,:int)
|
||||||
@string_input = "3 + self.bro"
|
@string_input = "3 + self.bro"
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
require_relative "test_integer"
|
require_relative "test_integer"
|
||||||
require_relative "test_layout"
|
require_relative "test_type"
|
||||||
require_relative "test_word"
|
require_relative "test_word"
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
require_relative 'helper'
|
require_relative 'helper'
|
||||||
|
|
||||||
class TestLayoutRT < MiniTest::Test
|
class TestTypeRT < MiniTest::Test
|
||||||
include ParfaitTests
|
include ParfaitTests
|
||||||
|
|
||||||
def test_main
|
def test_main
|
||||||
@ -11,10 +11,10 @@ class TestLayoutRT < MiniTest::Test
|
|||||||
def check_return_class val
|
def check_return_class val
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_get_layout
|
def test_get_type
|
||||||
@main = "return get_layout()"
|
@main = "return get_type()"
|
||||||
interpreter = check
|
interpreter = check
|
||||||
assert_equal Parfait::Layout , interpreter.get_register(:r0).return_value.class
|
assert_equal Parfait::Type , interpreter.get_register(:r0).return_value.class
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_get_class
|
def test_get_class
|
||||||
@ -32,18 +32,18 @@ HERE
|
|||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_puts_layout_space
|
def test_puts_type_space
|
||||||
@main = <<HERE
|
@main = <<HERE
|
||||||
Layout l = get_layout()
|
Type l = get_type()
|
||||||
Word w = l.get_class_name()
|
Word w = l.get_class_name()
|
||||||
w.putstring()
|
w.putstring()
|
||||||
HERE
|
HERE
|
||||||
@stdout = "Layout"
|
@stdout = "Type"
|
||||||
check
|
check
|
||||||
end
|
end
|
||||||
|
|
||||||
# copy of register parfait tests, in order
|
# copy of register parfait tests, in order
|
||||||
def test_message_layout
|
def test_message_type
|
||||||
@main = <<HERE
|
@main = <<HERE
|
||||||
Message m = self.first_message
|
Message m = self.first_message
|
||||||
m = m.next_message
|
m = m.next_message
|
@ -41,7 +41,7 @@ HERE
|
|||||||
@string_input = <<HERE
|
@string_input = <<HERE
|
||||||
class Space
|
class Space
|
||||||
int main()
|
int main()
|
||||||
Layout l = self.layout
|
Type l = self.type
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -49,7 +49,7 @@ HERE
|
|||||||
class Space
|
class Space
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
Layout l = space.get_layout()
|
Type l = space.get_type()
|
||||||
return self.runner
|
return self.runner
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user