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
|
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"
|
||||||
|
@ -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
|
||||||
|
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)
|
# 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,
|
||||||
|
@ -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
|
||||||
|
@ -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},
|
||||||
|
Loading…
Reference in New Issue
Block a user