use common list for risc instruction
strange that that was not done before as the code was clearly copied when extracting it Fix bug for insertion
This commit is contained in:
parent
9c052c78a7
commit
c5ec532616
@ -11,6 +11,9 @@ module Common
|
|||||||
end
|
end
|
||||||
|
|
||||||
# during translation we replace one by one
|
# during translation we replace one by one
|
||||||
|
# TODO avoid this by building a new list
|
||||||
|
# Make arm instruction not derive from risc (which is weird anyway)
|
||||||
|
# and include the List into it, translate in same way we go from mom->risc
|
||||||
def replace_next( nekst )
|
def replace_next( nekst )
|
||||||
old = @next
|
old = @next
|
||||||
@next = nekst
|
@next = nekst
|
||||||
@ -26,9 +29,10 @@ module Common
|
|||||||
# set the give instruction as the next, while moving any existing
|
# set the give instruction as the next, while moving any existing
|
||||||
# instruction along to the given ones's next.
|
# instruction along to the given ones's next.
|
||||||
# ie insert into the linked list that the instructions form
|
# ie insert into the linked list that the instructions form
|
||||||
|
# but allowing the instruction to be a list too (ie more than one)
|
||||||
def insert( instruction )
|
def insert( instruction )
|
||||||
instruction.set_next @next
|
instruction.last.set_next @next
|
||||||
@next = instruction
|
@next = instruction.last
|
||||||
end
|
end
|
||||||
|
|
||||||
# return last set instruction. ie follow the linked list until it stops
|
# return last set instruction. ie follow the linked list until it stops
|
||||||
|
@ -1,18 +1,26 @@
|
|||||||
|
require "common/list"
|
||||||
|
|
||||||
module Risc
|
module Risc
|
||||||
|
|
||||||
# the register machine has at least 8 registers, named r0-r5 , :lr and :pc (for historical reasons)
|
# the register machine has at least 8 registers, named r0-r5 , :lr and :pc
|
||||||
# we can load and store their contents and
|
# (for historical reasons , r for register, pc for ProgramCounter ie next instruction address
|
||||||
|
# and lr means LinkRegister, ie the location where to return to when in a function)
|
||||||
|
#
|
||||||
|
# We can load and store their contents, move data between them and
|
||||||
# access (get/set) memory at a constant offset from a register
|
# access (get/set) memory at a constant offset from a register
|
||||||
# while the vm works with objects, the register machine has registers,
|
# While Mom works with objects, the register machine has registers,
|
||||||
# but we keep the names for better understanding, r4/5 are temporary/scratch
|
# but we keep the names for better understanding, r2-5 are temporary/scratch
|
||||||
# there is no direct memory access, only through registers
|
# There is no direct memory access, only through registers
|
||||||
# constants can/must be loaded into registers before use
|
# Constants can/must be loaded into registers before use
|
||||||
|
|
||||||
# Instructions form a graph.
|
# At compile time, Instructions form a linked list (:next attribute is the link)
|
||||||
# Linear instructions form a linked list
|
# At run time Instructions are traversesed as a graph
|
||||||
|
#
|
||||||
# Branches fan out, Labels collect
|
# Branches fan out, Labels collect
|
||||||
# Labels are the only valid branch targets
|
# Labels are the only valid branch targets
|
||||||
|
#
|
||||||
class Instruction
|
class Instruction
|
||||||
|
include Common::List
|
||||||
|
|
||||||
def initialize source , nekst = nil
|
def initialize source , nekst = nil
|
||||||
@source = source
|
@source = source
|
||||||
@ -22,55 +30,7 @@ module Risc
|
|||||||
end
|
end
|
||||||
attr_reader :source
|
attr_reader :source
|
||||||
|
|
||||||
# set the next instruction (also aliased as <<)
|
#TODO check if this is used. Maybe build an each for instructions
|
||||||
# throw an error if that is set, use insert for that use case
|
|
||||||
# return the instruction, so chaining works as one wants (not backwards)
|
|
||||||
def set_next nekst
|
|
||||||
raise "Next already set #{@next}" if @next
|
|
||||||
@next = nekst
|
|
||||||
nekst
|
|
||||||
end
|
|
||||||
alias :<< :set_next
|
|
||||||
|
|
||||||
# during translation we replace one by one
|
|
||||||
def replace_next nekst
|
|
||||||
old = @next
|
|
||||||
@next = nekst
|
|
||||||
@next.append old.next if old
|
|
||||||
end
|
|
||||||
|
|
||||||
# get the next instruction (without arg given )
|
|
||||||
# when given an interger, advance along the line that many time and return.
|
|
||||||
def next( amount = 1)
|
|
||||||
(amount == 1) ? @next : @next.next(amount-1)
|
|
||||||
end
|
|
||||||
# set the give instruction as the next, while moving any existing
|
|
||||||
# instruction along to the given ones's next.
|
|
||||||
# ie insert into the linked list that the instructions form
|
|
||||||
def insert instruction
|
|
||||||
instruction.last.set_next @next
|
|
||||||
@next = instruction
|
|
||||||
end
|
|
||||||
|
|
||||||
# return last set instruction. ie follow the linked list until it stops
|
|
||||||
def last
|
|
||||||
code = self
|
|
||||||
code = code.next while( code.next )
|
|
||||||
return code
|
|
||||||
end
|
|
||||||
|
|
||||||
# set next for the last (see last)
|
|
||||||
# so append the given code to the linked list at the end
|
|
||||||
def append code
|
|
||||||
last.set_next code
|
|
||||||
end
|
|
||||||
|
|
||||||
def length labels = []
|
|
||||||
ret = 1
|
|
||||||
ret += self.next.length( labels ) if self.next
|
|
||||||
ret
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_arr labels = []
|
def to_arr labels = []
|
||||||
ret = [self.class]
|
ret = [self.class]
|
||||||
ret += self.next.to_arr(labels) if self.next
|
ret += self.next.to_arr(labels) if self.next
|
||||||
|
@ -36,6 +36,11 @@ module Risc
|
|||||||
@instruction.insert @branch
|
@instruction.insert @branch
|
||||||
assert_equal @branch, @instruction.last
|
assert_equal @branch, @instruction.last
|
||||||
end
|
end
|
||||||
|
def test_insert_two
|
||||||
|
@branch << @label
|
||||||
|
@instruction.insert @branch
|
||||||
|
assert_equal @label , @instruction.last
|
||||||
|
end
|
||||||
def test_append_not_empty
|
def test_append_not_empty
|
||||||
@instruction.append @branch
|
@instruction.append @branch
|
||||||
@instruction.append @label
|
@instruction.append @label
|
||||||
|
Loading…
Reference in New Issue
Block a user