add data objects
marker class (may change) to be able to check access
This commit is contained in:
parent
bc4d4b428a
commit
82ab8ac4d3
@ -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"
|
||||
|
@ -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
|
||||
|
63
lib/parfait/data_object.rb
Normal file
63
lib/parfait/data_object.rb
Normal 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
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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},
|
||||
|
Loading…
Reference in New Issue
Block a user