add data objects

marker class (may change) to be able to check access
This commit is contained in:
Torsten Ruger 2018-03-25 18:22:02 +03:00
parent bc4d4b428a
commit 82ab8ac4d3
6 changed files with 110 additions and 28 deletions

View File

@ -2,8 +2,9 @@
module Parfait module Parfait
end end
require_relative "parfait/integer"
require_relative "parfait/object" require_relative "parfait/object"
require_relative "parfait/data_object"
require_relative "parfait/integer"
require_relative "parfait/behaviour" require_relative "parfait/behaviour"
require_relative "parfait/class" require_relative "parfait/class"
require_relative "parfait/list" require_relative "parfait/list"

View File

@ -5,13 +5,40 @@
# #
module Parfait module Parfait
# obviously not a "Word" but a ByteArray , but no such class yet
# As our String (Word) on the other hand has no encoding (yet) it is close enough
class BinaryCode < Word
def to_s class BinaryCode < Data16
"BinaryCode #{self.char_length}" attr_accessor :next
def initialize(total_size)
super()
if total_size > self.data_length
@next = BinaryCode.new(total_size - data_length)
end
#puts "Init with #{total_size} for #{object_id}"
end
def to_s
"BinaryCode #{}"
end
def data_length
14
end
def char_length
4*data_length
end
def set_char(c , index)
if index >= char_length
puts "Pass it on #{index} for #{object_id}"
return @next.set_char( c , index - char_length)
end
word_index = (index - 1) / 4 + 2
old = get_internal_word( word_index )
old = old && c << ((index-1)%4)
set_internal_word(word_index , c)
end
def total_byte_length(start = 0 )
start += 4*14
return start unless self.next
self.next.total_byte_length(start)
end end
end end
end end

View File

@ -0,0 +1,63 @@
#
#
# In rubyx everything truely is an object. (most smalltalk/ruby systems use a union
# for integers/pointers that are called objects, but are really very different)
#
# Objects have type as their first member. No exception.
#
# So where is the data? In DataObjects. DataObjects are opague carriers of data.
# Opague to rubyx that is. There is no way to get at it or pass the data around.
#
# To use Data, Risc instructions have to be used. Luckily there is not soo much one
# actually wants to do with data, moving it between DataObject , comparing and
# logical and math operation that are bundled into the OperatorInstruction.
#
# For safe access the access code needs to know the length of the data, which is
# encoded in the class/type name. Ie An Integer derives from Data2, which is 2 long
# (minus one for the type, so exactly the one word for the integer)
#
# DataObjects still have a type, and so can have objects before the data starts
#
# A marker class
module Parfait
class DataObject < Object
def initialize
@memory = []
end
def data_length
raise "called #{self}"
end
def data_start
return type.length
end
# 1 -based index
def get_internal_word(index)
@memory[index]
end
# 1 -based index
def set_internal_word(index , value)
raise "Word[#{index}] = nil" if( value.nil? )
@memory[index] = value
value
end
end
class Data2 < DataObject
def data_length
1
end
end
class Data8 < DataObject
def data_length
7
end
end
class Data16 < DataObject
def data_length
15
end
end
end

View File

@ -7,7 +7,7 @@
# Ie it would be possible to change the value, we just don't support that) # Ie it would be possible to change the value, we just don't support that)
module Parfait module Parfait
class Integer class Integer < Data2
# :integer?, :odd?, :even?, :upto, :downto, :times, :succ, :next, :pred, :chr, :ord, :to_i, :to_int, :floor, # :integer?, :odd?, :even?, :upto, :downto, :times, :succ, :next, :pred, :chr, :ord, :to_i, :to_int, :floor,
# :ceil, :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator, :denominator, :to_r, :rationalize, # :ceil, :truncate, :round, :gcd, :lcm, :gcdlcm, :numerator, :denominator, :to_r, :rationalize,

View File

@ -12,14 +12,14 @@ module Parfait
# 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-type cells though # Object length is measured in non-type cells though
class Word < Object class Word < Data8
attr_reader :char_length attr_reader :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, type 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
end end
# initialize with length. For now we try to keep all non-parfait (including String) out # initialize with length. For now we try to keep all non-parfait (including String) out
@ -28,25 +28,12 @@ module Parfait
def initialize len def initialize len
super() super()
@char_length = 0 @char_length = 0
@memory = []
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 "type #{self.get_type} #{self.object_id.to_s(16)}" #puts "type #{self.get_type} #{self.object_id.to_s(16)}"
end end
# 1 -based index
def get_internal_word(index)
@memory[index]
end
# 1 -based index
def set_internal_word(index , value)
raise "Word[#{index}] = nil" if( value.nil? )
@memory[index] = value
value
end
# return a copy of self # return a copy of self
def copy def copy
@ -100,13 +87,13 @@ module Parfait
# character must be an integer, as is the index # character must be an integer, as is the index
# the index starts at one, but may be negative to count from the end # the index starts at one, but may be negative to count from the end
# indexes out of range will raise an error # indexes out of range will raise an error
def set_char at , char def set_char( at , char )
raise "char not fixnum #{char.class}" unless char.kind_of? Fixnum raise "char not fixnum #{char.class}" unless char.kind_of? Fixnum
index = range_correct_index(at) index = range_correct_index(at)
set_internal_byte( index , char) set_internal_byte( index , char)
end end
def set_internal_byte index , char def set_internal_byte( index , char )
word_index = (index) / 4 word_index = (index) / 4
rest = ((index) % 4) rest = ((index) % 4)
shifted = char << (rest * 8) shifted = char << (rest * 8)
@ -128,7 +115,7 @@ module Parfait
# the index starts at one, but may be negative to count from the end # the index starts at one, but may be negative to count from the end
# indexes out of range will raise an error # indexes out of range will raise an error
#the return "character" is an integer #the return "character" is an integer
def get_char at def get_char( at )
index = range_correct_index(at) index = range_correct_index(at)
get_internal_byte(index) get_internal_byte(index)
end end

View File

@ -116,7 +116,8 @@ module Risc
# superclasses other than default object # superclasses other than default object
def super_class_names def super_class_names
{ Object: :Kernel , Kernel: :Value , Integer: :Value , BinaryCode: :Word } { Object: :Kernel , Kernel: :Value , BinaryCode: :Word ,
Data2: :DataObject ,Data8: :DataObject , Integer: :Data2, Word: :Data8}
end end
# the function really just returns a constant (just avoiding the constant) # the function really just returns a constant (just avoiding the constant)
@ -129,12 +130,15 @@ module Risc
return_address: :Integer, return_value: :Integer, return_address: :Integer, return_value: :Integer,
caller: :Message , name: :Word , arguments: :NamedList }, caller: :Message , name: :Word , arguments: :NamedList },
Integer: {}, Integer: {},
DataObject: {},
Data2: {},
Data8: {},
TrueClass: {}, TrueClass: {},
FalseClass: {}, FalseClass: {},
NilClass: {}, NilClass: {},
Object: {}, Object: {},
Kernel: {}, #fix, kernel is a class, but should be a module Kernel: {}, #fix, kernel is a class, but should be a module
BinaryCode: {char_length: :Integer} , BinaryCode: {next: :BinaryCode} ,
Space: {classes: :Dictionary , types: :Dictionary , Space: {classes: :Dictionary , types: :Dictionary ,
first_message: :Message , single_true: :TrueClass, first_message: :Message , single_true: :TrueClass,
single_false: :FalseClass , single_nil: :NilClass}, single_false: :FalseClass , single_nil: :NilClass},