redid integer comparison with builder
had to add some helpers to builder
This commit is contained in:
parent
fc6aa4e28b
commit
0d52b620ed
@ -77,11 +77,26 @@ module Risc
|
|||||||
@source_used = true
|
@source_used = true
|
||||||
add_code Risc::IsNotZero.new(@source , label)
|
add_code Risc::IsNotZero.new(@source , label)
|
||||||
end
|
end
|
||||||
|
def if_minus( label )
|
||||||
|
@source_used = true
|
||||||
|
add_code Risc::IsMinus.new(@source , label)
|
||||||
|
end
|
||||||
def branch( label )
|
def branch( label )
|
||||||
@source_used = true
|
@source_used = true
|
||||||
add_code Risc::Branch.new(@source, label)
|
add_code Risc::Branch.new(@source, label)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# to avoid many an if, it can be candy to swap variable names.
|
||||||
|
# but since the names in the builder are not variables, we need this method
|
||||||
|
# as it says, swap the two names around. Names must exist
|
||||||
|
def swap_names(left , right)
|
||||||
|
l = @names[left]
|
||||||
|
r = @names[right]
|
||||||
|
raise "No such name #{left}" unless l
|
||||||
|
raise "No such name #{right}" unless r
|
||||||
|
@names[left] = r
|
||||||
|
@names[right] = l
|
||||||
|
end
|
||||||
# build code using dsl (see __init__ or MessageSetup for examples)
|
# build code using dsl (see __init__ or MessageSetup for examples)
|
||||||
# names (that ruby would resolve to a variable/method) are converted
|
# names (that ruby would resolve to a variable/method) are converted
|
||||||
# to registers. << means assignment and [] is supported both on
|
# to registers. << means assignment and [] is supported both on
|
||||||
|
@ -33,28 +33,27 @@ module Risc
|
|||||||
def comparison( operator )
|
def comparison( operator )
|
||||||
compiler = compiler_for(:Integer, operator ,{other: :Integer})
|
compiler = compiler_for(:Integer, operator ,{other: :Integer})
|
||||||
builder = compiler.compiler_builder(compiler.source)
|
builder = compiler.compiler_builder(compiler.source)
|
||||||
me , other = builder.self_and_int_arg("#{operator} load receiver and arg")
|
builder.build do
|
||||||
false_label = Risc.label(compiler.source , "false_label_#{builder.object_id.to_s(16)}")
|
integer << message[:receiver]
|
||||||
merge_label = Risc.label(compiler.source , "merge_label_#{builder.object_id.to_s(16)}")
|
integer_reg << message[:arguments]
|
||||||
builder.reduce_int( "#{operator} fix me", me )
|
integer_reg << integer_reg[ 1]
|
||||||
builder.reduce_int( "#{operator} fix arg", other )
|
integer.reduce_int
|
||||||
if(operator.to_s.start_with?('<') )
|
integer_reg.reduce_int
|
||||||
me , other = other , me
|
swap_names(:integer , :integer_reg) if(operator.to_s.start_with?('<') )
|
||||||
|
integer.op :- , integer_reg
|
||||||
|
if_minus false_label
|
||||||
|
if_zero( false_label ) if operator.to_s.length == 1
|
||||||
|
object << Parfait.object_space.true_object
|
||||||
|
branch merge_label
|
||||||
|
add_code false_label
|
||||||
|
object << Parfait.object_space.false_object
|
||||||
|
add_code merge_label
|
||||||
|
message[:return_value] << object
|
||||||
end
|
end
|
||||||
builder.add_code Risc.op( "#{operator} operator", :- , me , other)
|
|
||||||
builder.add_code IsMinus.new( "#{operator} if", false_label)
|
|
||||||
if(operator.to_s.length == 1)
|
|
||||||
builder.add_code IsZero.new( "#{operator} if", false_label)
|
|
||||||
end
|
|
||||||
builder.add_load_constant("#{operator} new int", Parfait.object_space.true_object , other)
|
|
||||||
builder.add_code Risc::Branch.new("jump over false", merge_label)
|
|
||||||
builder.add_code false_label
|
|
||||||
builder.add_load_constant("#{operator} new int", Parfait.object_space.false_object , other)
|
|
||||||
builder.add_code merge_label
|
|
||||||
builder.add_reg_to_slot( "#{operator} save ret" , other , Risc.message_reg , :return_value)
|
|
||||||
compiler.add_mom( Mom::ReturnSequence.new)
|
compiler.add_mom( Mom::ReturnSequence.new)
|
||||||
return compiler
|
return compiler
|
||||||
end
|
end
|
||||||
|
|
||||||
def putint(context)
|
def putint(context)
|
||||||
compiler = compiler_for(:Integer,:putint ,{})
|
compiler = compiler_for(:Integer,:putint ,{})
|
||||||
compiler.add_mom( Mom::ReturnSequence.new)
|
compiler.add_mom( Mom::ReturnSequence.new)
|
||||||
|
@ -14,7 +14,23 @@ module Risc
|
|||||||
r1 = RegisterValue.new(:r1 , :Space)
|
r1 = RegisterValue.new(:r1 , :Space)
|
||||||
@builder.build{ space << r1 }
|
@builder.build{ space << r1 }
|
||||||
assert_equal Transfer , @compiler.risc_instructions.next.class
|
assert_equal Transfer , @compiler.risc_instructions.next.class
|
||||||
|
assert_equal RegisterValue , @builder.space.class
|
||||||
|
end
|
||||||
|
def test_loads
|
||||||
|
@builder.build{ space << Parfait.object_space }
|
||||||
|
assert_equal LoadConstant , @compiler.risc_instructions.next.class
|
||||||
|
assert_equal RegisterValue , @builder.space.class
|
||||||
|
end
|
||||||
|
def test_two
|
||||||
|
@builder.build{ space << Parfait.object_space ; integer << 1}
|
||||||
|
assert_equal LoadConstant , @compiler.risc_instructions.next.class
|
||||||
|
assert_equal LoadData , @compiler.risc_instructions.next(2).class
|
||||||
|
end
|
||||||
|
def test_swap
|
||||||
|
test_two
|
||||||
|
@builder.swap_names( :space , :integer)
|
||||||
|
assert_equal :Integer , @builder.space.type.class_name
|
||||||
|
assert_equal :Space , @builder.integer.type.class_name
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user