changing the adapter to have fake memory for every object

Before instance variables were used to store the actual data
While this worked it was a double mental loop and (more importantly) did not allow the same memory access
Ie, in the interpreter the types for args had to be set correctly
But they don't need to be until we walk the list, when we can get the types from the method.
In short, now the fake memory may be used as memory, by indexing into it

We now have to use attr reader/writers that map to the fake memory
And while this is possible, it means a lot more self. than i would like
Also the compiler whill have to undo those attr to instance acess at some point
This commit is contained in:
Torsten Ruger 2018-08-11 19:13:09 +03:00
parent d74e9c2c40
commit e6df473647
2 changed files with 45 additions and 9 deletions

View File

@ -9,8 +9,9 @@ module Risc
# Parfait really does everything else, apart from the internal_get/set
# And our fake memory (other than hte previously used array, does bound check)
class FakeMemory
attr_reader :min
def initialize(from , size)
attr_reader :min , :object
def initialize(object,from , size)
@object = object
@min = from
@memory = Array.new(size)
raise "only multiples of 2 !#{size}" unless size == 2**(Math.log2(size).to_i)
@ -33,8 +34,8 @@ module Risc
end
def range_check(index)
raise "index too low #{index} < #{min}" if index < min
raise "index too big #{index} >= #{size}" if index >= size
raise "index too low #{index} < #{min} in #{object.class}" if index < 0
raise "index too big #{index} >= #{size} #{object.class}" if index >= size
end
end
end

View File

@ -1,27 +1,62 @@
require_relative "fake_memory"
module Parfait
class DataObject < Object
def self.variable_index(clazz_name , name)
clazz = clazz_name.split("::").last.to_sym
type = self.type_names[clazz]
i = type.keys.index(name)
raise "no #{name} for #{clazz}" unless i
i + 1
end
class Object
def self.allocate
r = super
r.instance_variable_set(:@memory , Risc::FakeMemory.new(self.type_length , self.memory_size))
r.instance_variable_set(:@memory , Risc::FakeMemory.new(r ,self.type_length , self.memory_size))
r
end
# 0 -based index
def get_internal_word(index)
return super if index < self.class.type_length
@memory[index]
end
# 0 -based index
def set_internal_word(index , value)
return super if index < self.class.type_length
raise "Word[#{index}] = nil" if( value.nil? and self.class != List)
@memory[index] = value
value
end
def self.attr( *attributes )
attributes = [attributes] unless attributes.is_a?(Array)
attributes.each do |name|
define_getter(name)
define_setter(name)
end
end
def self.define_getter(name)
define_method(name) do
#puts "GETTING #{name} for #{self.class.name} in #{object_id.to_s(16)}"
if(name == :type)
return @memory[0]
end
index = Parfait.variable_index(self.class.name, name)
get_internal_word(index)
end
end
def self.define_setter(name)
define_method("#{name}=".to_sym ) do |value|
#puts "SETTING #{name}= for #{self.class.name} in #{object_id.to_s(16)}"
if(name == :type)
@memory[0] = value
return value
end
index = Parfait.variable_index(self.class.name, name)
set_internal_word(index , value)
end
end
end
# new list from ruby array to be precise