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
end
require_relative "parfait/integer"
require_relative "parfait/object"
require_relative "parfait/data_object"
require_relative "parfait/integer"
require_relative "parfait/behaviour"
require_relative "parfait/class"
require_relative "parfait/list"

View File

@ -5,13 +5,40 @@
#
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
"BinaryCode #{self.char_length}"
class BinaryCode < Data16
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

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)
module Parfait
class Integer
class Integer < Data2
# :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,

View File

@ -12,14 +12,14 @@ module Parfait
# So all indexes are offset by one in the implementation
# Object length is measured in non-type cells though
class Word < Object
class Word < Data8
attr_reader :char_length
#semi "indexed" methods for interpreter
def self.get_length_index
2 # 2 is the amount of attributes, type and char_length. the offset after which chars start
end
def self.get_indexed i
def self.get_indexed( i )
i + get_length_index * 4
end
# initialize with length. For now we try to keep all non-parfait (including String) out
@ -28,25 +28,12 @@ module Parfait
def initialize len
super()
@char_length = 0
@memory = []
raise "Must init with int, not #{len.class}" unless len.kind_of? Fixnum
raise "Must init with positive, not #{len}" if len < 0
set_length( len , 32 ) unless len == 0 #32 beeing ascii space
#puts "type #{self.get_type} #{self.object_id.to_s(16)}"
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
def copy
@ -100,13 +87,13 @@ module Parfait
# character must be an integer, as is the index
# the index starts at one, but may be negative to count from the end
# 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
index = range_correct_index(at)
set_internal_byte( index , char)
end
def set_internal_byte index , char
def set_internal_byte( index , char )
word_index = (index) / 4
rest = ((index) % 4)
shifted = char << (rest * 8)
@ -128,7 +115,7 @@ module Parfait
# the index starts at one, but may be negative to count from the end
# indexes out of range will raise an error
#the return "character" is an integer
def get_char at
def get_char( at )
index = range_correct_index(at)
get_internal_byte(index)
end

View File

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