fixing the binary code indexes

AGAIN, that third of all bugs, the off by one
This commit is contained in:
Torsten Ruger 2018-05-28 18:20:09 +03:00
parent 8ef1a471a4
commit 4b34546c11
5 changed files with 42 additions and 32 deletions

View File

@ -15,9 +15,8 @@ module Parfait
def self.byte_offset def self.byte_offset
self.type_length * 4 # size of type * word_size (4) self.type_length * 4 # size of type * word_size (4)
end end
#16 - 2 -1 , two instance variables and one for the jump
def self.data_length def self.data_length
13 self.memory_size - self.type_length - 1 #one for the jump
end end
def data_length def data_length
self.class.data_length self.class.data_length
@ -29,14 +28,15 @@ module Parfait
def initialize(total_size) def initialize(total_size)
super() super()
extend_to(total_size ) extend_to(total_size )
#puts "Init with #{total_size} for #{object_id}" (0 ... data_length).each{ |index| set_word(index , 0) }
(0 ..(data_length)).each{ |index| set_word(index , 0) } set_last(0)
end end
def extend_to(total_size) def extend_to(total_size)
return unless total_size > self.data_length return if total_size < data_length
extend_one() unless @next extend_one() unless @next
@next.extend_to(total_size - data_length) @next.extend_to(total_size - data_length)
end end
def extend_one() def extend_one()
@next = BinaryCode.new(1) @next = BinaryCode.new(1)
if Risc::Position.set?(self) if Risc::Position.set?(self)
@ -57,34 +57,36 @@ module Parfait
def each_word( all = true) def each_word( all = true)
index = 0 index = 0
length = data_length while( index < data_length)
length += 1 if all
while( index < length)
yield get_word(index) yield get_word(index)
index += 1 index += 1
end end
yield( get_last ) if all
end end
def set_word(index , word) def set_word(index , word)
raise "invalid index #{index}" if index < 0 raise "invalid index #{index}" if index < 0
if index > data_length if index >= data_length
#raise "invalid index #{index}" unless @next #raise "invalid index #{index}" unless @next
extend_to( index ) extend_to( index )
@next.set_word( index - data_length , word) @next.set_word( index - data_length , word)
else else
set_internal_word(index + 2 , word) set_internal_word(index + BinaryCode.type_length , word)
end end
end end
def get_last()
get_internal_word(data_length + BinaryCode.type_length)
end
def set_last(word) def set_last(word)
set_word( data_length , word) set_internal_word(data_length + BinaryCode.type_length , word)
end end
def get_word(index) def get_word(index)
raise "invalid index #{index}" if index < 0 raise "invalid index #{index}" if index < 0
if index > data_length + 1 if index >= data_length
raise "invalid index #{index}" unless @next raise "invalid index #{index}" unless @next
return @next.get_word( index - data_length) return @next.get_word( index - data_length)
end end
get_internal_word(index + 2) get_internal_word(index + BinaryCode.type_length)
end end
def set_char(index , char) def set_char(index , char)
if index >= byte_length if index >= byte_length

View File

@ -15,7 +15,7 @@ module Parfait
@memory[index] @memory[index]
end end
# 1 -based index # 0 -based index
def set_internal_word(index , value) def set_internal_word(index , value)
return super if index < self.class.type_length return super if index < self.class.type_length
raise "Word[#{index}] = nil" if( value.nil? and self.class != List) raise "Word[#{index}] = nil" if( value.nil? and self.class != List)

View File

@ -33,8 +33,8 @@ module Risc
end end
end end
def reset_to(pos , ignored) def reset_to(pos , ignored)
init(pos , ignored)
super(pos, ignored) super(pos, ignored)
init(pos , ignored)
Position.log.debug "ResetCode (#{pos.to_s(16)}) #{code}" Position.log.debug "ResetCode (#{pos.to_s(16)}) #{code}"
end end
# insert a jump to the next instruction, at the last instruction # insert a jump to the next instruction, at the last instruction

View File

@ -23,28 +23,27 @@ module Risc
@binary = binary @binary = binary
end end
def init(at, binary) def init(at, binary)
@binary = binary
return if at == 0 and binary.nil? return if at == 0 and binary.nil?
raise "faux pas" if at < Position.get(binary).at raise "faux pas" if at < Position.get(binary).at
return unless @instruction.next return unless @instruction.next
@binary = binary
nekst = at + @instruction.byte_length nekst = at + @instruction.byte_length
diff = nekst - Position.get(@binary).at diff = nekst - Position.get(@binary).at
Position.log.debug "Diff: #{diff.to_s(16)} , next #{nekst.to_s(16)} , binary #{Position.get(@binary)}" Position.log.debug "Diff: #{diff.to_s(16)} , next #{nekst.to_s(16)} , binary #{Position.get(@binary)}"
raise "Invalid position #{diff.to_s(16)} , next #{nekst.to_s(16)} #{self}" if diff < 8 raise "Invalid position #{diff.to_s(16)} , next #{nekst.to_s(16)} #{self}" if diff < 8
next_binary = @binary if( (diff % (binary.padded_length - @instruction.byte_length)) == 0 )
if( (diff % (@binary.padded_length - @instruction.byte_length)) == 0 ) binary.extend_one unless binary.next
next_binary.extend_one unless next_binary.next binary = binary.next
next_binary = next_binary.next raise "end of line " unless binary
raise "end of line " unless next_binary nekst = Position.get(binary).at + Parfait::BinaryCode.byte_offset
nekst = Position.get(next_binary).at + Parfait::BinaryCode.byte_offset
Position.log.debug "Jump to: #{nekst.to_s(16)}" Position.log.debug "Jump to: #{nekst.to_s(16)}"
end end
Position.set(@instruction.next, nekst , next_binary) Position.set(@instruction.next, nekst , binary)
end end
def reset_to(pos , binary) def reset_to(pos , binary)
init(pos , binary)
super(pos , binary) super(pos , binary)
init(pos , binary)
Position.log.debug "ResetInstruction (#{pos.to_s(16)}) #{instruction}" Position.log.debug "ResetInstruction (#{pos.to_s(16)}) #{instruction}"
end end
end end

View File

@ -52,8 +52,9 @@ module Parfait
assert @code.set_char(56 , 120) assert @code.set_char(56 , 120)
end end
def test_nilled def test_nilled
assert_equal 0 , @code.get_word(1) assert_equal 0 , @code.get_word(0)
assert_equal 0 , @code.get_word(13) assert_equal 0 , @code.get_word(12)
assert_equal 0 , @code.get_last
end end
def test_get_set_self def test_get_set_self
@code.set_word(10,1) @code.set_word(10,1)
@ -91,7 +92,7 @@ module Parfait
assert_equal 14 , len assert_equal 14 , len
end end
def test_each_set def test_each_set
(0..12).each{|i| @code.set_word(i,i)} (0...13).each{|i| @code.set_word(i,i)}
all = [] all = []
@code.each_word(false){ |w| all << w} @code.each_word(false){ |w| all << w}
assert_equal 0 , all.first assert_equal 0 , all.first
@ -106,12 +107,14 @@ module Parfait
assert_equal 1, @code.get_word(1) assert_equal 1, @code.get_word(1)
end end
def test_get_internal_word def test_get_internal_word
@code.set_word(1 , 1) @code.set_word(0 , 1)
assert_equal 1, @code.get_internal_word(@code.data_start + 1) assert_equal 1, @code.get_internal_word(BinaryCode.type_length)
end end
def test_set_13 def test_set_12
@code.set_word(13 , 1) @code.set_word(12 , 12)
assert_equal 0 , @code.get_last
assert_nil @code.next assert_nil @code.next
assert_equal 12 , @code.get_word(12)
end end
def test_set_last_no_extend def test_set_last_no_extend
@code.set_last(1) @code.set_last(1)
@ -119,12 +122,18 @@ module Parfait
end end
def test_set_last_and_get def test_set_last_and_get
@code.set_last(1) @code.set_last(1)
assert_equal 1, @code.get_word(BinaryCode.data_length) assert_equal 1, @code.get_last
end end
def test_has_each def test_has_each
sum = 0 sum = 0
@code.each_block{ sum += 1} @code.each_block{ sum += 1}
assert_equal sum , 1 assert_equal sum , 1
end end
def test_step_13
@code.set_word(13,13)
assert @code.next
assert_equal 13, @code.get_word(13)
assert_equal 13, @code.next.get_word(0)
end
end end
end end