lots of stuff to move to linked lists
and remove the blocks more position stuff coming, but the list part should be ok
This commit is contained in:
parent
3774f8a5a2
commit
405a6935d4
@ -13,6 +13,7 @@ module Register
|
||||
# Branches fan out, Labels collect
|
||||
# Labels are the only valid branch targets
|
||||
class Instruction
|
||||
include Positioned
|
||||
|
||||
def initialize source , nekst = nil
|
||||
@source = source
|
||||
@ -34,7 +35,7 @@ module Register
|
||||
def replace_next nekst
|
||||
old = @next
|
||||
@next = nekst
|
||||
@next.append old.next
|
||||
@next.append old.next if old
|
||||
end
|
||||
|
||||
# get the next instruction (without arg given )
|
||||
@ -75,6 +76,26 @@ module Register
|
||||
ret
|
||||
end
|
||||
|
||||
# derived classes must provide a byte_length
|
||||
def byte_length
|
||||
raise "Abstract called on #{self}"
|
||||
end
|
||||
|
||||
def total_byte_length labels = []
|
||||
ret = self.byte_length
|
||||
ret += self.next.total_byte_length(labels) if self.next
|
||||
ret
|
||||
end
|
||||
|
||||
def set_position position , labels = []
|
||||
self.position = position
|
||||
position += byte_length
|
||||
if self.next
|
||||
self.next.set_position(position , labels)
|
||||
else
|
||||
position
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -5,7 +5,6 @@ module Register
|
||||
class Branch < Instruction
|
||||
def initialize source , to
|
||||
super(source)
|
||||
raise "No block" unless to
|
||||
@label = to
|
||||
end
|
||||
attr_reader :label
|
||||
@ -16,12 +15,29 @@ module Register
|
||||
alias :inspect :to_s
|
||||
|
||||
def length labels = []
|
||||
super(labels) + self.label.length(labels)
|
||||
ret = super(labels)
|
||||
ret += self.label.length(labels) if self.label
|
||||
ret
|
||||
end
|
||||
|
||||
def to_ac labels = []
|
||||
super(labels) + self.label.to_ac(labels)
|
||||
ret = super(labels)
|
||||
ret += self.label.to_ac(labels) if self.label
|
||||
ret
|
||||
end
|
||||
|
||||
def total_byte_length labels = []
|
||||
ret = super
|
||||
ret += label.total_byte_length(labels) if self.label
|
||||
ret
|
||||
end
|
||||
|
||||
# labels have the same position as their next
|
||||
def set_position position , labels = []
|
||||
position = self.label.set_position( position , labels ) if self.label
|
||||
super(position,labels)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class IsZero < Branch
|
||||
|
@ -21,14 +21,33 @@ module Register
|
||||
def to_ac labels = []
|
||||
return [] if labels.include?(self)
|
||||
labels << self
|
||||
self.next.to_ac(labels)
|
||||
super
|
||||
end
|
||||
|
||||
def length labels = []
|
||||
return 0 if labels.include?(self)
|
||||
labels << self
|
||||
1 + self.next.length(labels)
|
||||
ret = 1
|
||||
ret += self.next.length(labels) if self.next
|
||||
ret
|
||||
end
|
||||
|
||||
def byte_length
|
||||
0
|
||||
end
|
||||
|
||||
def total_byte_length labels = []
|
||||
return 0 if labels.include?(self)
|
||||
labels << self
|
||||
self.next.length(labels)
|
||||
end
|
||||
|
||||
# labels have the same position as their next
|
||||
def set_position position , labels = []
|
||||
return position if labels.include?(self)
|
||||
labels << self
|
||||
self.position = position
|
||||
self.next.set_position(position,labels)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -84,7 +84,7 @@ module Register
|
||||
end
|
||||
|
||||
def byte_length
|
||||
@instructions.byte_length
|
||||
@instructions.total_byte_length
|
||||
end
|
||||
|
||||
# position of the function is the position of the entry block, is where we call
|
||||
|
@ -47,7 +47,7 @@ class Symbol
|
||||
end
|
||||
pos
|
||||
end
|
||||
def set_position pos
|
||||
def position= pos
|
||||
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
|
||||
# in measures (of 32)
|
||||
old = cache_positions[self]
|
||||
|
@ -8,7 +8,7 @@ module Positioned
|
||||
end
|
||||
@position
|
||||
end
|
||||
def set_position pos
|
||||
def position= pos
|
||||
raise "Setting of nil not allowed" if pos.nil?
|
||||
# resetting of position used to be error, but since relink and dynamic instruction size it is ok.
|
||||
# in measures (of 32)
|
||||
|
@ -2,3 +2,4 @@
|
||||
require_relative "test_compat"
|
||||
require_relative "test_padding"
|
||||
require_relative "test_positioning"
|
||||
require_relative "test_instructions"
|
||||
|
46
test/register/test_instructions.rb
Normal file
46
test/register/test_instructions.rb
Normal file
@ -0,0 +1,46 @@
|
||||
require_relative "../helper"
|
||||
|
||||
module Register
|
||||
class TestInstructions < MiniTest::Test
|
||||
def setup
|
||||
@label = Label.new(nil , "test")
|
||||
@branch = Branch.new(nil , @label)
|
||||
@instruction = Instruction.new(nil)
|
||||
end
|
||||
def test_last_empty
|
||||
assert_equal @instruction, @instruction.last
|
||||
end
|
||||
def test_last_not_empty
|
||||
@instruction.set_next @branch
|
||||
assert_equal @branch, @instruction.last
|
||||
end
|
||||
def test_append_empty
|
||||
@instruction.append @branch
|
||||
assert_equal @branch, @instruction.last
|
||||
end
|
||||
def test_insert
|
||||
@instruction.insert @branch
|
||||
assert_equal @branch, @instruction.last
|
||||
end
|
||||
def test_append_not_empty
|
||||
@instruction.append @branch
|
||||
@instruction.append @label
|
||||
assert_equal @label, @instruction.last
|
||||
end
|
||||
def test_next1
|
||||
assert_equal nil , @instruction.next
|
||||
end
|
||||
def test_next2
|
||||
@instruction.set_next @label
|
||||
assert_equal @label , @instruction.next
|
||||
assert_equal nil , @instruction.next(2)
|
||||
end
|
||||
def test_replace
|
||||
@instruction.append @branch
|
||||
@instruction.replace_next @label
|
||||
assert_equal @label, @instruction.last
|
||||
assert_equal @label, @instruction.next
|
||||
assert_equal 2 , @instruction.length , @instruction.to_ac
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user