move parfait adapter into parfait ruby
in the future parfait will be coded in some and translated back into ruby to “adapt” until then, all ruby code is the adapter
This commit is contained in:
parent
aa30864fcb
commit
40d81681b5
@ -14,3 +14,4 @@ require "parfait/layout"
|
||||
require "parfait/message"
|
||||
require "parfait/frame"
|
||||
require "parfait/space"
|
||||
require "parfait/symbol_adapter"
|
||||
|
@ -84,14 +84,8 @@ module Parfait
|
||||
self
|
||||
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 to_sof_node(writer , level , ref)
|
||||
Sof.hash_to_sof_node( self , writer , level , ref)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -23,18 +23,30 @@ module Parfait
|
||||
|
||||
alias :[] :get
|
||||
|
||||
#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
|
||||
|
||||
def to_sof_node(writer , level , ref )
|
||||
Sof.array_to_sof_node(self , writer , level , ref )
|
||||
end
|
||||
def to_a
|
||||
array = []
|
||||
index = 1
|
||||
while( index <= self.get_length)
|
||||
array[index - 1] = get(index)
|
||||
index = index + 1
|
||||
end
|
||||
array
|
||||
end
|
||||
end
|
||||
|
||||
# new list from ruby array to be precise
|
||||
def self.new_list array
|
||||
list = Parfait::List.new
|
||||
list.set_length array.length
|
||||
index = 1
|
||||
while index <= array.length do
|
||||
list.set(index , array[index - 1])
|
||||
index = index + 1
|
||||
end
|
||||
list
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -32,7 +32,8 @@ module Parfait
|
||||
self.locals = List.new
|
||||
end
|
||||
attributes [:name , :source , :instructions , :binary ,:arguments , :for_class, :locals ]
|
||||
|
||||
# not part of the parfait model, hence ruby accessor
|
||||
attr_accessor :source
|
||||
|
||||
# determine whether this method has an argument by the name
|
||||
def has_arg name
|
||||
|
@ -28,6 +28,30 @@ module Parfait
|
||||
object
|
||||
end
|
||||
|
||||
# Objects memory functions. Object memory is 1 based
|
||||
# but we implement it with ruby array (0 based) and don't use 0
|
||||
# These are the same functions that Builtin implements for run-time
|
||||
include Padding
|
||||
include Positioned
|
||||
|
||||
def fake_init
|
||||
@memory = Array.new(16)
|
||||
@position = nil
|
||||
self # for chaining
|
||||
end
|
||||
|
||||
# 1 -based index
|
||||
def get_internal(index)
|
||||
@memory[index]
|
||||
end
|
||||
# 1 -based index
|
||||
def set_internal(index , value)
|
||||
raise "failed init for #{self.class}" unless @memory
|
||||
raise "Word[#{index}] = " if((self.class == Parfait::Word) and value.nil? )
|
||||
@memory[index] = value
|
||||
value
|
||||
end
|
||||
|
||||
def self.attributes names
|
||||
names.each{|name| attribute(name) }
|
||||
end
|
||||
@ -101,15 +125,17 @@ module Parfait
|
||||
padded_words( get_layout().instance_length )
|
||||
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, :get_instance_variables, :get_instance_variable, :set_instance_variable, :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__
|
||||
# parfait versions are deliberately called different, so we "relay"
|
||||
# have to put the "@" on the names for sof to take them off again
|
||||
def instance_variables
|
||||
get_instance_variables.to_a.collect{ |n| "@#{n}".to_sym }
|
||||
end
|
||||
# name comes in as a ruby @var name
|
||||
def instance_variable_get name
|
||||
var = get_instance_variable name.to_s[1 .. -1].to_sym
|
||||
#puts "getting #{name} #{var}"
|
||||
var
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
43
lib/parfait/symbol_adapter.rb
Normal file
43
lib/parfait/symbol_adapter.rb
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
class Symbol
|
||||
include Positioned
|
||||
include Padding
|
||||
|
||||
def has_layout?
|
||||
true
|
||||
end
|
||||
def get_layout
|
||||
l = Register.machine.space.classes[:Word].object_layout
|
||||
#puts "LL #{l.class}"
|
||||
l
|
||||
end
|
||||
def padded_length
|
||||
padded to_s.length + 4
|
||||
end
|
||||
# not the prettiest addition to the game, but it wasn't me who decided symbols are frozen in 2.x
|
||||
def cache_positions
|
||||
unless defined?(@@symbol_positions)
|
||||
@@symbol_positions = {}
|
||||
end
|
||||
@@symbol_positions
|
||||
end
|
||||
def position
|
||||
pos = cache_positions[self]
|
||||
if pos == nil
|
||||
str = "position accessed but not set, "
|
||||
str += "Machine has object=#{Register.machine.objects.has_key?(self.object_id)} "
|
||||
raise str + " for Symbol:#{self}"
|
||||
end
|
||||
pos
|
||||
end
|
||||
def position= pos
|
||||
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
|
||||
# in measures (of 32)
|
||||
old = cache_positions[self]
|
||||
if old != nil and ((old - pos).abs > 20000)
|
||||
raise "position set again #{pos}!=#{old} for #{self}"
|
||||
end
|
||||
cache_positions[self] = pos
|
||||
end
|
||||
|
||||
end
|
@ -147,6 +147,26 @@ module Parfait
|
||||
return true
|
||||
end
|
||||
|
||||
def == other
|
||||
return false unless other.is_a?(String) or other.is_a?(Word)
|
||||
as_string = self.to_string
|
||||
unless other.is_a? String
|
||||
other = other.to_string
|
||||
end
|
||||
as_string == other
|
||||
end
|
||||
|
||||
def to_string
|
||||
string = ""
|
||||
index = 1
|
||||
while( index <= self.char_length)
|
||||
char = get_char(index)
|
||||
string += char ? char.chr : "*"
|
||||
index = index + 1
|
||||
end
|
||||
string
|
||||
end
|
||||
|
||||
# as we answered is_value? with true, sof will create a basic node with this string
|
||||
def to_sof
|
||||
"'" + to_s + "'"
|
||||
@ -161,4 +181,15 @@ module Parfait
|
||||
raise "Length out of bounds #{self.char_length}" if self.char_length > 1000
|
||||
end
|
||||
end
|
||||
|
||||
# Word from string
|
||||
def self.new_word( string )
|
||||
string = string.to_s if string.is_a? Symbol
|
||||
word = Parfait::Word.new( string.length )
|
||||
string.codepoints.each_with_index do |code , index |
|
||||
word.set_char(index + 1 , code)
|
||||
end
|
||||
word
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,9 +1,7 @@
|
||||
require "register/padding"
|
||||
require "register/positioned"
|
||||
require "parfait"
|
||||
require "register/machine"
|
||||
#if we are in the ruby run-time / generating an executable
|
||||
require "register/positioned"
|
||||
require "register/padding"
|
||||
require "register/parfait_adapter"
|
||||
|
||||
require "soml/compiler"
|
||||
|
||||
|
@ -1,159 +0,0 @@
|
||||
# Below we define functions (in different classes) that are not part of the run-time
|
||||
# They are used for the boot process, ie when this codes executes in the vm that builds salama
|
||||
|
||||
# To stay sane, we use the same classes that we use later, but "adapt" them to work in ruby
|
||||
# This affects mainly memory layout
|
||||
|
||||
module Register
|
||||
def self.new_list array
|
||||
list = Parfait::List.new
|
||||
list.set_length array.length
|
||||
index = 1
|
||||
while index <= array.length do
|
||||
list.set(index , array[index - 1])
|
||||
index = index + 1
|
||||
end
|
||||
list
|
||||
end
|
||||
# Functions to generate parfait objects
|
||||
def self.new_word( string )
|
||||
string = string.to_s if string.is_a? Symbol
|
||||
word = Parfait::Word.new( string.length )
|
||||
string.codepoints.each_with_index do |code , index |
|
||||
word.set_char(index + 1 , code)
|
||||
end
|
||||
word
|
||||
end
|
||||
end
|
||||
class Symbol
|
||||
include Positioned
|
||||
include Padding
|
||||
|
||||
def has_layout?
|
||||
true
|
||||
end
|
||||
def get_layout
|
||||
l = Register.machine.space.classes[:Word].object_layout
|
||||
#puts "LL #{l.class}"
|
||||
l
|
||||
end
|
||||
def padded_length
|
||||
padded to_s.length + 4
|
||||
end
|
||||
# not the prettiest addition to the game, but it wasn't me who decided symbols are frozen in 2.x
|
||||
def cache_positions
|
||||
unless defined?(@@symbol_positions)
|
||||
@@symbol_positions = {}
|
||||
end
|
||||
@@symbol_positions
|
||||
end
|
||||
def position
|
||||
pos = cache_positions[self]
|
||||
if pos == nil
|
||||
str = "position accessed but not set, "
|
||||
str += "Machine has object=#{Register.machine.objects.has_key?(self.object_id)} "
|
||||
raise str + " for Symbol:#{self}"
|
||||
end
|
||||
pos
|
||||
end
|
||||
def position= pos
|
||||
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
|
||||
# in measures (of 32)
|
||||
old = cache_positions[self]
|
||||
if old != nil and ((old - pos).abs > 20000)
|
||||
raise "position set again #{pos}!=#{old} for #{self}"
|
||||
end
|
||||
cache_positions[self] = pos
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module Parfait
|
||||
# Objects memory functions. Object memory is 1 based
|
||||
# but we implement it with ruby array (0 based) and don't use 0
|
||||
# These are the same functions that Builtin implements for run-time
|
||||
class Object
|
||||
include Padding
|
||||
include Positioned
|
||||
|
||||
def fake_init
|
||||
@memory = Array.new(16)
|
||||
@position = nil
|
||||
self # for chaining
|
||||
end
|
||||
|
||||
# 1 -based index
|
||||
def get_internal(index)
|
||||
@memory[index]
|
||||
end
|
||||
# 1 -based index
|
||||
def set_internal(index , value)
|
||||
raise "failed init for #{self.class}" unless @memory
|
||||
raise "Word[#{index}] = " if((self.class == Parfait::Word) and value.nil? )
|
||||
@memory[index] = value
|
||||
value
|
||||
end
|
||||
end
|
||||
class List
|
||||
def to_sof_node(writer , level , ref )
|
||||
Sof.array_to_sof_node(self , writer , level , ref )
|
||||
end
|
||||
def to_a
|
||||
array = []
|
||||
index = 1
|
||||
while( index <= self.get_length)
|
||||
array[index - 1] = get(index)
|
||||
index = index + 1
|
||||
end
|
||||
array
|
||||
end
|
||||
end
|
||||
class Dictionary
|
||||
def to_sof_node(writer , level , ref)
|
||||
Sof.hash_to_sof_node( self , writer , level , ref)
|
||||
end
|
||||
end
|
||||
|
||||
class Method
|
||||
attr_accessor :source
|
||||
end
|
||||
|
||||
class Word
|
||||
|
||||
def == other
|
||||
return false unless other.is_a?(String) or other.is_a?(Word)
|
||||
as_string = self.to_string
|
||||
unless other.is_a? String
|
||||
other = other.to_string
|
||||
end
|
||||
as_string == other
|
||||
end
|
||||
|
||||
def to_string
|
||||
string = ""
|
||||
index = 1
|
||||
while( index <= self.char_length)
|
||||
char = get_char(index)
|
||||
string += char ? char.chr : "*"
|
||||
index = index + 1
|
||||
end
|
||||
string
|
||||
end
|
||||
end
|
||||
|
||||
## sof related stuff
|
||||
class Object
|
||||
# parfait versions are deliberately called different, so we "relay"
|
||||
# have to put the "@" on the names for sof to take them off again
|
||||
def instance_variables
|
||||
get_instance_variables.to_a.collect{ |n| "@#{n}".to_sym }
|
||||
end
|
||||
# name comes in as a ruby @var name
|
||||
def instance_variable_get name
|
||||
var = get_instance_variable name.to_s[1 .. -1].to_sym
|
||||
#puts "getting #{name} #{var}"
|
||||
var
|
||||
end
|
||||
end
|
||||
|
||||
end
|
@ -74,7 +74,7 @@ module Soml
|
||||
end
|
||||
arguments << arg
|
||||
end
|
||||
@method = clazz.create_instance_method( method_name , Register.new_list(arguments))
|
||||
@method = clazz.create_instance_method( method_name , Parfait.new_list(arguments))
|
||||
self
|
||||
end
|
||||
|
||||
|
@ -36,7 +36,7 @@ module Soml
|
||||
end
|
||||
|
||||
def on_string expression
|
||||
value = Register.new_word expression.first.to_sym
|
||||
value = Parfait.new_word expression.first.to_sym
|
||||
reg = use_reg :Word
|
||||
Register.machine.constants << value
|
||||
add_code Register::LoadConstant.new( expression, value , reg )
|
||||
|
@ -8,7 +8,7 @@ class TestClass < MiniTest::Test
|
||||
end
|
||||
|
||||
def foo_method for_class = :Try
|
||||
args = Register.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
||||
args = Parfait.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
||||
::Parfait::Method.new @space.get_class_by_name(for_class) , :foo , args
|
||||
end
|
||||
|
||||
@ -42,7 +42,7 @@ class TestClass < MiniTest::Test
|
||||
end
|
||||
end
|
||||
def test_create_method
|
||||
@try.create_instance_method :bar, Register.new_list( [ Parfait::Variable.new(:Integer , :bar )])
|
||||
@try.create_instance_method :bar, Parfait.new_list( [ Parfait::Variable.new(:Integer , :bar )])
|
||||
assert_equal ":bar" , @try.method_names.inspect
|
||||
end
|
||||
def test_method_get
|
||||
|
@ -8,7 +8,7 @@ class TestMeta < MiniTest::Test
|
||||
end
|
||||
|
||||
def foo_method for_class = :Try
|
||||
args = Register.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
||||
args = Parfait.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
||||
::Parfait::Method.new @space.get_class_by_name(for_class) , :foo , args
|
||||
end
|
||||
|
||||
@ -24,7 +24,7 @@ class TestMeta < MiniTest::Test
|
||||
end
|
||||
|
||||
def test_create_method
|
||||
@try.create_instance_method :bar, Register.new_list( [ Parfait::Variable.new(:Integer , :bar )])
|
||||
@try.create_instance_method :bar, Parfait.new_list( [ Parfait::Variable.new(:Integer , :bar )])
|
||||
assert_equal ":bar" , @try.method_names.inspect
|
||||
end
|
||||
def test_add_method
|
||||
|
@ -4,7 +4,7 @@ class TestMethod < MiniTest::Test
|
||||
|
||||
def setup
|
||||
obj = Register.machine.boot.space.get_class_by_name(:Object)
|
||||
args = Register.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
||||
args = Parfait.new_list [ Parfait::Variable.new(:Integer , :bar )]
|
||||
@method = ::Parfait::Method.new obj , :foo , args
|
||||
end
|
||||
|
||||
|
@ -9,14 +9,14 @@ class TestCompat < MiniTest::Test
|
||||
|
||||
def test_list_create_from_array
|
||||
array = [1,2,3]
|
||||
list = Register.new_list(array)
|
||||
list = Parfait.new_list(array)
|
||||
assert_equal array , list.to_a
|
||||
end
|
||||
|
||||
def test_word_create_from_string
|
||||
string = "something"
|
||||
word = Register.new_word(string)
|
||||
assert_equal word , Register.new_word(string)
|
||||
word = Parfait.new_word(string)
|
||||
assert_equal word , Parfait.new_word(string)
|
||||
assert_equal string , word.to_string
|
||||
end
|
||||
end
|
||||
|
@ -5,12 +5,12 @@ class TestPositioning < MiniTest::Test
|
||||
Register.machine.boot unless Register.machine.booted
|
||||
end
|
||||
def test_list1
|
||||
list = Register.new_list([1])
|
||||
list = Parfait.new_list([1])
|
||||
list.set_layout( Parfait::Layout.new Object)
|
||||
assert_equal 32 , list.padded_length
|
||||
end
|
||||
def test_list5
|
||||
list = Register.new_list([1,2,3,4,5])
|
||||
list = Parfait.new_list([1,2,3,4,5])
|
||||
list.set_layout( Parfait::Layout.new Object)
|
||||
assert_equal 32 , list.padded_length
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user