moved the whole parfait into its namespace/module

This commit is contained in:
Torsten Ruger 2015-05-11 18:55:49 +03:00
parent a552e3fbce
commit ab870e3323
13 changed files with 245 additions and 208 deletions

View File

@ -1,6 +1,6 @@
### Parfait: a thin layer
Parfait is the run-time of the vm.
Parfait is the run-time of the **vm**.
To be more precise, it is that part of the run-time that can be expressed in ruby.
The run-time needs to contain quite a lot of functionality for a dynamic system.
@ -19,7 +19,7 @@ And thus parfait can be used at run-time.
It's too simple: just slips off the mind like a fish into water.
Parfait has a brother, the Builtin module. Builtin contains everything that can not be coded in ruby,
but we stil need (things like array access).
but we still need (things like array access).
#### Example: Message send
@ -42,3 +42,16 @@ Part of those are some that we just don't allow to be overridden.
Also what in ruby is object.send is Message.send in salama, as it is the message we are sending and
which defines all the data we need (not the object). The object receives, it does not send.
### Vm vs language- core
Parfait is not the language (ie ruby) core library. Core library functionality differs between
languages and so the language core lib must be on top of the vm parfait.
Also Parfait is meant to be as thin as humanly possibly, so extra (nice to have) functionality
will be in future modules.
So the Namespace of the Runtime is actually Parfait (not nothing as in ruby).
Only in the require does one later have to be clever and see which vm one is running in and either
require or not. Maybe one doesn't even have to be so celver, we'll see (as requiring an existing
module should result in noop)

View File

@ -1,20 +1,23 @@
class Array < Object
#many basic array functions can not be defined in ruby, such as
# get/set/length/add/delete
# so they must be defined as CompiledMethods in Builtin::Kernel
#ruby 2.1 list (just for reference, keep at bottom)
# :at, :fetch, :first, :last, :concat, :<<, :push, :pop, :shift, :unshift, :insert, :each, :each_index, :reverse_each,
# :length, :size, :empty?, :find_index, :index, :rindex, :join, :reverse, :reverse!, :rotate, :rotate!,
# :sort, :sort!, :sort_by!, :collect, :collect!, :map, :map!, :select, :select!, :keep_if,
# :values_at, :delete, :delete_at, :delete_if, :reject, :reject!, :zip, :transpose, :replace, :clear,
# :fill, :include?, :slice, :slice!, :assoc, :rassoc, :+, :*, :-, :&, :|, :uniq, :uniq!, :compact, :compact!,
# :flatten, :flatten!, :count, :shuffle!, :shuffle, :sample, :cycle, :permutation, :combination,
# :repeated_permutation, :repeated_combination, :product, :take, :take_while, :drop, :drop_while,
# :bsearch, :pack, :entries, :sort_by, :grep, :find, :detect, :find_all, :flat_map, :collect_concat,
# :inject, :reduce, :partition, :group_by, :all?, :any?, :one?, :none?,
# :min, :max, :minmax, :min_by, :max_by, :minmax_by, :member?, :each_with_index, :each_entry,
# :each_slice, :each_cons, :each_with_object, :chunk, :slice_before, :lazy
module Parfait
class Array < Object
#many basic array functions can not be defined in ruby, such as
# get/set/length/add/delete
# so they must be defined as CompiledMethods in Builtin::Kernel
#ruby 2.1 list (just for reference, keep at bottom)
# :at, :fetch, :first, :last, :concat, :<<, :push, :pop, :shift, :unshift, :insert, :each, :each_index, :reverse_each,
# :length, :size, :empty?, :find_index, :index, :rindex, :join, :reverse, :reverse!, :rotate, :rotate!,
# :sort, :sort!, :sort_by!, :collect, :collect!, :map, :map!, :select, :select!, :keep_if,
# :values_at, :delete, :delete_at, :delete_if, :reject, :reject!, :zip, :transpose, :replace, :clear,
# :fill, :include?, :slice, :slice!, :assoc, :rassoc, :+, :*, :-, :&, :|, :uniq, :uniq!, :compact, :compact!,
# :flatten, :flatten!, :count, :shuffle!, :shuffle, :sample, :cycle, :permutation, :combination,
# :repeated_permutation, :repeated_combination, :product, :take, :take_while, :drop, :drop_while,
# :bsearch, :pack, :entries, :sort_by, :grep, :find, :detect, :find_all, :flat_map, :collect_concat,
# :inject, :reduce, :partition, :group_by, :all?, :any?, :one?, :none?,
# :min, :max, :minmax, :min_by, :max_by, :minmax_by, :member?, :each_with_index, :each_entry,
# :each_slice, :each_cons, :each_with_object, :chunk, :slice_before, :lazy
end
end

View File

@ -8,7 +8,9 @@
# The Layout lists the names of the instance variables
# The class keeps a list of instance methods, these have a name and code
class Class < Module
# ruby 2.1 list (just for reference, keep at bottom)
#:allocate, :new, :superclass
module Parfait
class Class < Module
# ruby 2.1 list (just for reference, keep at bottom)
#:allocate, :new, :superclass
end
end

View File

@ -20,10 +20,12 @@
# Also at runtime Messages and Frames remain completely "normal" objects. Ie have layouts and so on.
# Which resolves the dichotomy of objects on the stack or heap. Sama sama.
class Frame < Object
def initialize locals , temps
@locals = locals
@tmps = tmps
module Parfait
class Frame < Object
def initialize locals , temps
@locals = locals
@tmps = tmps
end
attr_accessor :locals , :tmps
end
attr_accessor :locals , :tmps
end

View File

@ -1,72 +1,73 @@
# almost simplest hash imaginable. make good use of arrays
class Hash < Object
def initialize
@keys = Array.new()
@values = Array.new()
end
def values()
@values
end
def keys()
@keys
end
def empty?
@keys.empty?
end
def length()
return @keys.length()
end
def get(key)
index = key_index(key)
if( index )
@values[index]
else
nil
module Parfait
class Hash < Object
def initialize
@keys = Array.new()
@values = Array.new()
end
def values()
@values
end
def keys()
@keys
end
def empty?
@keys.empty?
end
end
def [](key)
get(key)
end
def key_index(key)
len = @keys.length()
index = 0
found = nil
while(index < len)
if( @keys[index] == key)
found = index
break
def length()
return @keys.length()
end
def get(key)
index = key_index(key)
if( index )
@values[index]
else
nil
end
index += 1
end
found
end
def set(key , value)
index = key_index(key)
if( index )
@keys[index] = value
else
@keys.push(key)
@values.push(value)
def [](key)
get(key)
end
value
end
def []=(key,val)
set(key,val)
end
# :rehash, :to_hash, :to_h, :to_a, :[], :fetch, :[]=, :store, :default, :default=, :default_proc, :default_proc=,
# :key, :index, :size, :length, :empty?, :each_value, :each_key, :each_pair, :each, :keys, :values,
# :values_at, :shift, :delete, :delete_if, :keep_if, :select, :select!, :reject, :reject!, :clear, :invert,
# :update, :replace, :merge!, :merge, :assoc, :rassoc, :flatten, :include?, :member?, :has_key?, :has_value?,
# :key?, :value?, :compare_by_identity, :compare_by_identity?, :entries, :sort, :sort_by, :grep, :count, :find,
# :detect, :find_index, :find_all, :collect, :map, :flat_map, :collect_concat, :inject, :reduce, :partition,
# :group_by, :first, :all?, :any?, :one?, :none?, :min, :max, :minmax, :min_by, :max_by, :minmax_by, :each_with_index,
# :reverse_each, :each_entry, :each_slice, :each_cons, :each_with_object, :zip, :take, :take_while, :drop, :drop_while,
# :cycle, :chunk, :slice_before, :lazy
def key_index(key)
len = @keys.length()
index = 0
found = nil
while(index < len)
if( @keys[index] == key)
found = index
break
end
index += 1
end
found
end
def set(key , value)
index = key_index(key)
if( index )
@keys[index] = value
else
@keys.push(key)
@values.push(value)
end
value
end
def []=(key,val)
set(key,val)
end
# :rehash, :to_hash, :to_h, :to_a, :[], :fetch, :[]=, :store, :default, :default=, :default_proc, :default_proc=,
# :key, :index, :size, :length, :empty?, :each_value, :each_key, :each_pair, :each, :keys, :values,
# :values_at, :shift, :delete, :delete_if, :keep_if, :select, :select!, :reject, :reject!, :clear, :invert,
# :update, :replace, :merge!, :merge, :assoc, :rassoc, :flatten, :include?, :member?, :has_key?, :has_value?,
# :key?, :value?, :compare_by_identity, :compare_by_identity?, :entries, :sort, :sort_by, :grep, :count, :find,
# :detect, :find_index, :find_all, :collect, :map, :flat_map, :collect_concat, :inject, :reduce, :partition,
# :group_by, :first, :all?, :any?, :one?, :none?, :min, :max, :minmax, :min_by, :max_by, :minmax_by, :each_with_index,
# :reverse_each, :each_entry, :each_slice, :each_cons, :each_with_object, :zip, :take, :take_while, :drop, :drop_while,
# :cycle, :chunk, :slice_before, :lazy
end
end

View File

@ -7,17 +7,19 @@
# TODO how this idea works with Numeric ?
class Integer < Value
module Parfait
class Integer < Value
# :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,
# :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,
# :rectangular, :rect, :polar, :conjugate, :conj, :>, :>=, :<, :<=, :between?
#
# Numeric
# :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,
# :quo, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase, :rectangular, :rect, :polar, :conjugate, :conj,
# :>, :>=, :<, :<=, :between?
# :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,
# :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,
# :rectangular, :rect, :polar, :conjugate, :conj, :>, :>=, :<, :<=, :between?
#
# Numeric
# :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,
# :quo, :to_c, :real, :imaginary, :imag, :abs2, :arg, :angle, :phase, :rectangular, :rect, :polar, :conjugate, :conj,
# :>, :>=, :<, :<=, :between?
end
end

View File

@ -18,14 +18,16 @@
# the Layout is an array of names of length n
# Together they turn the object into a hash like structure
class Layout < Object
module Parfait
class Layout < Object
# given a name as symbol, return the integer index of that entry
# we use 0 as "not found" as we don't want negatives, and can't raise
# luckily 0 is always the type-word in an object and so by returning
# one-offsets we can use the return value straight without adding 1
def index_of( name )
#internal implementation....
end
# given a name as symbol, return the integer index of that entry
# we use 0 as "not found" as we don't want negatives, and can't raise
# luckily 0 is always the type-word in an object and so by returning
# one-offsets we can use the return value straight without adding 1
def index_of( name )
#internal implementation....
end
end

View File

@ -2,41 +2,43 @@
# A message is what is sent when you invoke a method. Args and stuff are packed up in to a Message
# and the Message is sent to the receiver.
class Message < Object
module Parfait
class Message < Object
def get_type_for(name)
index = @layout.get_index(name)
get_at(index)
end
def get_type_for(name)
index = @layout.get_index(name)
get_at(index)
end
def __send
typ = get_type_for( :receiver )
# TODO: this will obviously be recoded as case, once that is done :-)
# depending on value type get method
if( typ == Integer )
method = Integer.get_method @method_name
else
if( typ != ObjectReference )
raise "unimplemented case"
def __send
typ = get_type_for( :receiver )
# TODO: this will obviously be recoded as case, once that is done :-)
# depending on value type get method
if( typ == Integer )
method = Integer.get_method @method_name
else
method = @receiver.get_singeton_method @method_name
# Find the method for the given object (receiver) according to ruby dispatch rules:
# - see if the receiver object has a (singleton) method by the name
# - get receivers class and look for instance methods of the name
# - go up inheritance tree
# - start over with method_missing instead
# -> guaranteed to end at object.method_missing
unless method
cl = @receiver.layout.object_class
method = cl.get_instance_or_super_method @method_name
if( typ != ObjectReference )
raise "unimplemented case"
else
method = @receiver.get_singeton_method @method_name
# Find the method for the given object (receiver) according to ruby dispatch rules:
# - see if the receiver object has a (singleton) method by the name
# - get receivers class and look for instance methods of the name
# - go up inheritance tree
# - start over with method_missing instead
# -> guaranteed to end at object.method_missing
unless method
cl = @receiver.layout.object_class
method = cl.get_instance_or_super_method @method_name
end
end
end
end
unless method
message = Message.new( @receiver , :method_missing , [@method_name] + @args)
message.send
else
method.call
unless method
message = Message.new( @receiver , :method_missing , [@method_name] + @args)
message.send
else
method.call
end
end
end
end

View File

@ -11,12 +11,14 @@
# In fact this property is implemented in the Object, as methods
# may be added to any object at run-time
class Module
# :<, :<=, :>, :>=, :included_modules, :include?, :name, :ancestors, :instance_methods, :public_instance_methods,
# :protected_instance_methods, :private_instance_methods, :constants, :const_get, :const_set, :const_defined?,
# :const_missing, :class_variables, :remove_class_variable, :class_variable_get, :class_variable_set,
# :class_variable_defined?, :public_constant, :private_constant, :singleton_class?, :include, :prepend,
# :module_exec, :class_exec, :module_eval, :class_eval, :method_defined?, :public_method_defined?,
# :private_method_defined?, :protected_method_defined?, :public_class_method, :private_class_method, :autoload,
# :autoload?, :instance_method, :public_instance_method
module Parfait
class Module
# :<, :<=, :>, :>=, :included_modules, :include?, :name, :ancestors, :instance_methods, :public_instance_methods,
# :protected_instance_methods, :private_instance_methods, :constants, :const_get, :const_set, :const_defined?,
# :const_missing, :class_variables, :remove_class_variable, :class_variable_get, :class_variable_set,
# :class_variable_defined?, :public_constant, :private_constant, :singleton_class?, :include, :prepend,
# :module_exec, :class_exec, :module_eval, :class_eval, :method_defined?, :public_method_defined?,
# :private_method_defined?, :protected_method_defined?, :public_class_method, :private_class_method, :autoload,
# :autoload?, :instance_method, :public_instance_method
end
end

View File

@ -3,33 +3,35 @@
# that does lead to the fact that we have Reference functions on the Object though
class Object < Value
module Parfait
class Object < Value
def get_type()
OBJECT_TYPE
def get_type()
OBJECT_TYPE
end
# This is the crux of the object system. The class of an object is stored in the objects
# memory (as opposed to an integer that has no memory and so always has the same class)
#
# In Salama we store the class in the Layout, and so the Layout is the only fixed
# data that every object carries.
def get_class()
@layout.get_class()
end
def get_layout()
@layout
end
# Object
# :nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint,
# :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods,
# :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?,
# :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?,
# :extend, :display, :method, :public_method, :singleton_method, :define_singleton_method,
# :object_id, :to_enum, :enum_for
#
# BasicObject
# :==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__
end
# This is the crux of the object system. The class of an object is stored in the objects
# memory (as opposed to an integer that has no memory and so always has the same class)
#
# In Salama we store the class in the Layout, and so the Layout is the only fixed
# data that every object carries.
def get_class()
@layout.get_class()
end
def get_layout()
@layout
end
# Object
# :nil?, :===, :=~, :!~, :eql?, :hash, :<=>, :class, :singleton_class, :clone, :dup, :taint, :tainted?, :untaint,
# :untrust, :untrusted?, :trust, :freeze, :frozen?, :to_s, :inspect, :methods, :singleton_methods, :protected_methods,
# :private_methods, :public_methods, :instance_variables, :instance_variable_get, :instance_variable_set, :instance_variable_defined?,
# :remove_instance_variable, :instance_of?, :kind_of?, :is_a?, :tap, :send, :public_send, :respond_to?,
# :extend, :display, :method, :public_method, :singleton_method, :define_singleton_method,
# :object_id, :to_enum, :enum_for
#
# BasicObject
# :==, :equal?, :!, :!=, :instance_eval, :instance_exec, :__send__, :__id__
end

View File

@ -8,6 +8,8 @@
# object. The smallest object is usually a cache line, 16 bytes or
# an exponent of two larger.
class Page < Object
module Parfait
class Page < Object
end
end

View File

@ -8,8 +8,10 @@
# "New" is slightly misleading in that normal operation only ever
# recycles objects.
class Space < Object
module Parfait
class Space < Object
# ObjectSpace
# :each_object, :garbage_collect, :define_finalizer, :undefine_finalizer, :_id2ref, :count_objects
# ObjectSpace
# :each_object, :garbage_collect, :define_finalizer, :undefine_finalizer, :_id2ref, :count_objects
end
end

View File

@ -12,26 +12,28 @@
# Value is an abstract class that unifies the "has a type" concept
# Types are not "objectified", but are represented as integer constants
class Value
module Parfait
class Value
# to make the machine work, the constants need
# - to start at 0
# - be unique
# - be smaller enough to fit into the 2-4 bits available
INTEGER_VALUE = 0
OBJECT_VALUE = 1
# to make the machine work, the constants need
# - to start at 0
# - be unique
# - be smaller enough to fit into the 2-4 bits available
INTEGER_VALUE = 0
OBJECT_VALUE = 1
# the type is what identifies the value
def get_type()
raise "abstract clalled on #{self}"
end
# the type is what identifies the value
def get_type()
raise "abstract clalled on #{self}"
end
# Get class works on the type. The value's type is stored by the machine.
# So this function is not overriden in derived classes, because it is used
# to espablish what class a value has! (it's that "fake" oo i mentioned)
def get_class()
type = self.get_type()
return Integer if( type == INTEGER_VALUE )
raise "invalid type"
# Get class works on the type. The value's type is stored by the machine.
# So this function is not overriden in derived classes, because it is used
# to espablish what class a value has! (it's that "fake" oo i mentioned)
def get_class()
type = self.get_type()
return Integer if( type == INTEGER_VALUE )
raise "invalid type"
end
end
end