avoid adding risc instructions twice
that causes loops in the chain infinite loops in the code that are hard to debug closes #11
This commit is contained in:
parent
f85fe8a2cb
commit
9687d6611f
@ -12,8 +12,7 @@ module Mom
|
|||||||
@label = label
|
@label = label
|
||||||
end
|
end
|
||||||
def to_risc(compiler)
|
def to_risc(compiler)
|
||||||
label = @label.to_risc(compiler)
|
compiler.add_code Risc::Branch.new(self , @label.risc_label)
|
||||||
compiler.add_code Risc::Branch.new(self , label)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -8,16 +8,6 @@ module Mom
|
|||||||
#
|
#
|
||||||
# A Label has a name which is mainly used for debugging.
|
# A Label has a name which is mainly used for debugging.
|
||||||
#
|
#
|
||||||
class Label < Instruction
|
|
||||||
attr_reader :name
|
|
||||||
def initialize(name)
|
|
||||||
@name = name
|
|
||||||
end
|
|
||||||
|
|
||||||
def to_s
|
|
||||||
"Label: #{name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
# A Mom::Label converts one2one to a Risc::Label. So in a way it could not be more
|
# A Mom::Label converts one2one to a Risc::Label. So in a way it could not be more
|
||||||
# simple.
|
# simple.
|
||||||
# Alas, since almost by definition several roads lead to this label, all those
|
# Alas, since almost by definition several roads lead to this label, all those
|
||||||
@ -30,8 +20,31 @@ module Mom
|
|||||||
#
|
#
|
||||||
# Off course some specific place still has to be responsible for actually
|
# Off course some specific place still has to be responsible for actually
|
||||||
# adding the label to the instruction list (usually an if/while)
|
# adding the label to the instruction list (usually an if/while)
|
||||||
def to_risc(compiler)
|
|
||||||
|
class Label < Instruction
|
||||||
|
attr_reader :name
|
||||||
|
def initialize(name)
|
||||||
|
@name = name
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_s
|
||||||
|
"Label: #{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
# generate the risc label lazily
|
||||||
|
def risc_label
|
||||||
@risc_label ||= Risc.label(self,name)
|
@risc_label ||= Risc.label(self,name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# add the risc_label to the compiler (instruction flow)
|
||||||
|
# should only be called once
|
||||||
|
def to_risc(compiler)
|
||||||
|
if( @added )
|
||||||
|
raise "added already #{@added}"
|
||||||
|
else
|
||||||
|
@added = true
|
||||||
|
compiler.add_code( risc_label )
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -26,7 +26,7 @@ module Mom
|
|||||||
l_reg = left.to_register(compiler, self)
|
l_reg = left.to_register(compiler, self)
|
||||||
r_reg = right.to_register(compiler, self)
|
r_reg = right.to_register(compiler, self)
|
||||||
compiler.add_code Risc.op( self , :- , l_reg , r_reg)
|
compiler.add_code Risc.op( self , :- , l_reg , r_reg)
|
||||||
compiler.add_code Risc::IsZero.new( self, false_jump.to_risc(compiler))
|
compiler.add_code Risc::IsZero.new( self, false_jump.risc_label)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,7 @@ module Mom
|
|||||||
end
|
end
|
||||||
|
|
||||||
def to_risc(compiler)
|
def to_risc(compiler)
|
||||||
false_label = @false_jump.to_risc(compiler)
|
false_label = @false_jump.risc_label
|
||||||
builder = compiler.builder("TruthCheck")
|
builder = compiler.builder("TruthCheck")
|
||||||
condition_reg = @condition.to_register(compiler,self)
|
condition_reg = @condition.to_register(compiler,self)
|
||||||
builder.build do
|
builder.build do
|
||||||
|
@ -16,10 +16,11 @@ module Risc
|
|||||||
@constants = []
|
@constants = []
|
||||||
@block_compilers = []
|
@block_compilers = []
|
||||||
@risc_instructions = Risc.label(source_name, source_name)
|
@risc_instructions = Risc.label(source_name, source_name)
|
||||||
@current = @risc_instructions
|
@current = start = @risc_instructions
|
||||||
add_code Risc.label( source_name, "return_label")
|
add_code Risc.label( source_name, "return_label")
|
||||||
Mom::ReturnSequence.new.to_risc(self)
|
Mom::ReturnSequence.new.to_risc(self)
|
||||||
add_code Risc.label( source_name, "unreachable")
|
add_code Risc.label( source_name, "unreachable")
|
||||||
|
@current = start
|
||||||
reset_regs
|
reset_regs
|
||||||
end
|
end
|
||||||
attr_reader :risc_instructions , :constants , :block_compilers , :callable , :current
|
attr_reader :risc_instructions , :constants , :block_compilers , :callable , :current
|
||||||
|
@ -50,5 +50,10 @@ module Risc
|
|||||||
sl = @produced.next( 7 )
|
sl = @produced.next( 7 )
|
||||||
assert_reg_to_slot( sl , :r1 , :r3 , 7 )
|
assert_reg_to_slot( sl , :r1 , :r3 , 7 )
|
||||||
end
|
end
|
||||||
|
def test_label
|
||||||
|
sl = @produced.next( 17 )
|
||||||
|
assert_equal Risc::Label , sl.class
|
||||||
|
assert_equal "return_label" , sl.name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
require_relative "../helper"
|
require_relative "helper"
|
||||||
|
|
||||||
module Risc
|
module Risc
|
||||||
class TestReturnSequence < MiniTest::Test
|
class TestReturnSequence < MiniTest::Test
|
Loading…
Reference in New Issue
Block a user