From 40d81681b5043aa340f2026dbf59a134ce923b3b Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Wed, 18 Nov 2015 11:55:29 +0200 Subject: [PATCH] move parfait adapter into parfait ruby MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in the future parfait will be coded in some and translated back into ruby to “adapt” until then, all ruby code is the adapter --- lib/parfait.rb | 1 + lib/parfait/dictionary.rb | 12 +-- lib/parfait/list.rb | 38 ++++--- lib/parfait/method.rb | 3 +- lib/parfait/object.rb | 46 +++++++-- lib/parfait/symbol_adapter.rb | 43 ++++++++ lib/parfait/word.rb | 31 ++++++ lib/register.rb | 6 +- lib/register/parfait_adapter.rb | 159 ------------------------------ lib/soml/compiler.rb | 2 +- lib/soml/compiler/basic_values.rb | 2 +- test/parfait_ruby/test_class.rb | 4 +- test/parfait_ruby/test_meta.rb | 4 +- test/parfait_ruby/test_method.rb | 2 +- test/register/test_compat.rb | 6 +- test/register/test_positioning.rb | 4 +- 16 files changed, 155 insertions(+), 208 deletions(-) create mode 100644 lib/parfait/symbol_adapter.rb delete mode 100644 lib/register/parfait_adapter.rb diff --git a/lib/parfait.rb b/lib/parfait.rb index 13dcb572..70d1636d 100644 --- a/lib/parfait.rb +++ b/lib/parfait.rb @@ -14,3 +14,4 @@ require "parfait/layout" require "parfait/message" require "parfait/frame" require "parfait/space" +require "parfait/symbol_adapter" diff --git a/lib/parfait/dictionary.rb b/lib/parfait/dictionary.rb index 0e871146..5278ab38 100644 --- a/lib/parfait/dictionary.rb +++ b/lib/parfait/dictionary.rb @@ -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 diff --git a/lib/parfait/list.rb b/lib/parfait/list.rb index 41790e20..0b1bcb76 100644 --- a/lib/parfait/list.rb +++ b/lib/parfait/list.rb @@ -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 diff --git a/lib/parfait/method.rb b/lib/parfait/method.rb index dac6bc1d..86904abb 100644 --- a/lib/parfait/method.rb +++ b/lib/parfait/method.rb @@ -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 diff --git a/lib/parfait/object.rb b/lib/parfait/object.rb index 542c6324..dd804f4e 100644 --- a/lib/parfait/object.rb +++ b/lib/parfait/object.rb @@ -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 diff --git a/lib/parfait/symbol_adapter.rb b/lib/parfait/symbol_adapter.rb new file mode 100644 index 00000000..81c51851 --- /dev/null +++ b/lib/parfait/symbol_adapter.rb @@ -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 diff --git a/lib/parfait/word.rb b/lib/parfait/word.rb index 4b0a09e5..4c45fc76 100644 --- a/lib/parfait/word.rb +++ b/lib/parfait/word.rb @@ -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 diff --git a/lib/register.rb b/lib/register.rb index 2577a9cf..0b6ba648 100644 --- a/lib/register.rb +++ b/lib/register.rb @@ -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" diff --git a/lib/register/parfait_adapter.rb b/lib/register/parfait_adapter.rb deleted file mode 100644 index 6bc359ed..00000000 --- a/lib/register/parfait_adapter.rb +++ /dev/null @@ -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 diff --git a/lib/soml/compiler.rb b/lib/soml/compiler.rb index 682613d5..b4abfb10 100644 --- a/lib/soml/compiler.rb +++ b/lib/soml/compiler.rb @@ -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 diff --git a/lib/soml/compiler/basic_values.rb b/lib/soml/compiler/basic_values.rb index f138234e..fb824596 100644 --- a/lib/soml/compiler/basic_values.rb +++ b/lib/soml/compiler/basic_values.rb @@ -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 ) diff --git a/test/parfait_ruby/test_class.rb b/test/parfait_ruby/test_class.rb index a9ab9c92..dbcebb89 100644 --- a/test/parfait_ruby/test_class.rb +++ b/test/parfait_ruby/test_class.rb @@ -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 diff --git a/test/parfait_ruby/test_meta.rb b/test/parfait_ruby/test_meta.rb index 98c66579..77268389 100644 --- a/test/parfait_ruby/test_meta.rb +++ b/test/parfait_ruby/test_meta.rb @@ -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 diff --git a/test/parfait_ruby/test_method.rb b/test/parfait_ruby/test_method.rb index 7eb69ef5..eab4b7e9 100644 --- a/test/parfait_ruby/test_method.rb +++ b/test/parfait_ruby/test_method.rb @@ -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 diff --git a/test/register/test_compat.rb b/test/register/test_compat.rb index 642054ef..08745ea4 100644 --- a/test/register/test_compat.rb +++ b/test/register/test_compat.rb @@ -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 diff --git a/test/register/test_positioning.rb b/test/register/test_positioning.rb index 704dafb4..ef3db7e4 100644 --- a/test/register/test_positioning.rb +++ b/test/register/test_positioning.rb @@ -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