add branch listener functionaliy
have to store the branches and loop again as labels dont neccessarily have positions yet
This commit is contained in:
parent
3298651238
commit
046617f8dc
@ -23,8 +23,8 @@ module Risc
|
|||||||
end
|
end
|
||||||
alias :inspect :to_s
|
alias :inspect :to_s
|
||||||
|
|
||||||
# if branch is implemented it must return the label it branches to
|
# if branch_to is implemented it must return the label it branches to
|
||||||
def branch
|
def branch_to
|
||||||
label
|
label
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -3,12 +3,13 @@ module Risc
|
|||||||
class BranchListener
|
class BranchListener
|
||||||
|
|
||||||
# initialize with the instruction listener
|
# initialize with the instruction listener
|
||||||
def initialize(listener)
|
def initialize(branch)
|
||||||
@listener = listener
|
@branch = branch
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# incoming position is the labels
|
||||||
def position_changed(position)
|
def position_changed(position)
|
||||||
|
@branch.precheck
|
||||||
end
|
end
|
||||||
|
|
||||||
# don't react to insertion, as the CodeListener will take care
|
# don't react to insertion, as the CodeListener will take care
|
||||||
|
@ -88,16 +88,18 @@ module Risc
|
|||||||
raise "Not Binary Code #{code.class}" unless code.is_a?(Parfait::BinaryCode)
|
raise "Not Binary Code #{code.class}" unless code.is_a?(Parfait::BinaryCode)
|
||||||
raise "Must init with instruction, not nil" unless instruction
|
raise "Must init with instruction, not nil" unless instruction
|
||||||
first = nil
|
first = nil
|
||||||
|
branches = []
|
||||||
while(instruction)
|
while(instruction)
|
||||||
position = Position.get_or_create(instruction)
|
position = Position.get_or_create(instruction)
|
||||||
first = position unless first
|
first = position unless first
|
||||||
position.position_listener( InstructionListener.new( code ) )
|
position.position_listener( InstructionListener.new( code ) )
|
||||||
if instruction.respond_to?(:branch)
|
branches << instruction if instruction.respond_to?(:branch_to)
|
||||||
# label_pos = Position.get(instruction.branch)
|
|
||||||
# label_pos.position_listener( BranchListener.new(il))
|
|
||||||
end
|
|
||||||
instruction = instruction.next
|
instruction = instruction.next
|
||||||
end
|
end
|
||||||
|
branches.each do |branch|
|
||||||
|
label_pos = Position.get(branch.branch_to)
|
||||||
|
label_pos.position_listener( BranchListener.new(branch) )
|
||||||
|
end
|
||||||
first
|
first
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -220,5 +220,6 @@ module Risc
|
|||||||
end
|
end
|
||||||
require_relative "position_listener"
|
require_relative "position_listener"
|
||||||
require_relative "instruction_listener"
|
require_relative "instruction_listener"
|
||||||
|
require_relative "branch_listener"
|
||||||
require_relative "code_listener"
|
require_relative "code_listener"
|
||||||
require_relative "label_listener"
|
require_relative "label_listener"
|
||||||
|
@ -37,6 +37,14 @@ module Risc
|
|||||||
DummyInstruction.new
|
DummyInstruction.new
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
class DummyBranch < Branch
|
||||||
|
attr_reader :precheck_called
|
||||||
|
|
||||||
|
def precheck
|
||||||
|
@precheck_called = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class DummyInstruction < Dummy
|
class DummyInstruction < Dummy
|
||||||
include Util::List
|
include Util::List
|
||||||
def initialize(nekst = nil)
|
def initialize(nekst = nil)
|
||||||
|
@ -1,14 +1,35 @@
|
|||||||
require_relative "helper"
|
require_relative "helper"
|
||||||
|
require 'minitest/mock'
|
||||||
|
|
||||||
module Risc
|
module Risc
|
||||||
class TestBranchListener < MiniTest::Test
|
class TestBranchListenerBooted < MiniTest::Test
|
||||||
|
def setup
|
||||||
|
DummyPlatform.boot
|
||||||
|
@binary = Parfait::BinaryCode.new(1)
|
||||||
|
@bin_pos = CodeListener.init(@binary).set(0)
|
||||||
|
@label = Label.new("HI","ho" , FakeAddress.new(2))
|
||||||
|
@branch = DummyBranch.new( "Dummy" , @label )
|
||||||
|
@branch.insert @label
|
||||||
|
InstructionListener.init(@branch , @binary)
|
||||||
|
@position = Position.get(@label)
|
||||||
|
end
|
||||||
|
def test_init_add_listener
|
||||||
|
assert_equal BranchListener , @position.event_table.values.first.last.class
|
||||||
|
end
|
||||||
|
def test_set
|
||||||
|
Position.get(@branch).set(12)
|
||||||
|
assert_equal 16 , Position.get(@label).at
|
||||||
|
end
|
||||||
|
def test_set_fires
|
||||||
|
Position.get(@label).set(20)
|
||||||
|
assert @branch.precheck_called
|
||||||
|
end
|
||||||
|
end
|
||||||
|
class TestBranchListenerPositioned < MiniTest::Test
|
||||||
def setup
|
def setup
|
||||||
@machine = Risc.machine.boot
|
@machine = Risc.machine.boot
|
||||||
@machine.translate(:interpreter)
|
@machine.translate(:interpreter)
|
||||||
@machine.position_all
|
@machine.position_all
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_has_init
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user