From b1376e83bd3b7cc2a84112aa92a58e6a1c5654cd Mon Sep 17 00:00:00 2001 From: Torsten Ruger Date: Sun, 1 Apr 2018 15:26:53 +0300 Subject: [PATCH] add integer minus rework plus to make that easy --- lib/risc/boot.rb | 2 +- lib/risc/builtin/integer.rb | 26 ++++++++------ lib/risc/method_compiler.rb | 4 +-- test/parfait/test_space.rb | 2 +- test/risc/interpreter/test_minus.rb | 55 +++++++++++++++++++++++++++++ 5 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 test/risc/interpreter/test_minus.rb diff --git a/lib/risc/boot.rb b/lib/risc/boot.rb index c574ecb7..432603ce 100644 --- a/lib/risc/boot.rb +++ b/lib/risc/boot.rb @@ -184,7 +184,7 @@ module Risc end obj = space.get_class_by_name(:Integer) - [ :putint, :mod4, :div10, :+].each do |f| #mod4 is just a forward declaration + [ :putint, :mod4, :div10, :+ , :-].each do |f| #mod4 is just a forward declaration obj.instance_type.add_method Builtin::Integer.send(f , nil) end end diff --git a/lib/risc/builtin/integer.rb b/lib/risc/builtin/integer.rb index a0220c72..35090b8c 100644 --- a/lib/risc/builtin/integer.rb +++ b/lib/risc/builtin/integer.rb @@ -13,7 +13,7 @@ module Risc two = compiler.use_reg :fixnum , 2 compiler.add_load_data( source , 2 , two ) compiler.add_code Risc.op( source , :>> , me , two) - compiler.add_new_int(me , two) + compiler.add_new_int(source,me , two) compiler.add_reg_to_slot( source , two , :message , :return_value) compiler.add_mom( Mom::ReturnSequence.new) return compiler.method @@ -23,16 +23,20 @@ module Risc compiler.add_mom( Mom::ReturnSequence.new) return compiler.method end - def +( context ) - source = "plus" - compiler = compiler_for(:Integer,:+ ,{other: :Integer}) - me , other = compiler.self_and_int_arg(source + "1") - compiler.reduce_int( source + "2", me ) - compiler.reduce_int( source + "3", other ) - compiler.add_code Risc.op( source + "4", :+ , me , other) - compiler.add_new_int(me , other) - compiler.add_reg_to_slot( source + "5" , other , :message , :return_value) + operator_method( "plus" , :+) + end + def -( context ) + operator_method( "minus" , :-) + end + def operator_method(op_name , op_sym ) + compiler = compiler_for(:Integer, op_sym ,{other: :Integer}) + me , other = compiler.self_and_int_arg(op_name + "load receiver and arg") + compiler.reduce_int( op_name + " fix me", me ) + compiler.reduce_int( op_name + " fix arg", other ) + compiler.add_code Risc.op( op_name + " operator", op_sym , me , other) + compiler.add_new_int(op_name + " new int", me , other) + compiler.add_reg_to_slot( op_name + "save ret" , other , :message , :return_value) compiler.add_mom( Mom::ReturnSequence.new) return compiler.method end @@ -92,7 +96,7 @@ module Risc # return q + tmp compiler.add_code Risc.op( s , :+ , q , tmp ) - compiler.add_new_int(q , tmp) + compiler.add_new_int(s,q , tmp) compiler.add_reg_to_slot( s , tmp , :message , :return_value) compiler.add_mom( Mom::ReturnSequence.new) diff --git a/lib/risc/method_compiler.rb b/lib/risc/method_compiler.rb index ceb2df24..c264a17f 100644 --- a/lib/risc/method_compiler.rb +++ b/lib/risc/method_compiler.rb @@ -134,8 +134,8 @@ module Risc # move a machine int from register "from" to a Parfait::Integer in register "to" # have to grab an integer from space and stick it in the "to" register first. - def add_new_int( from, to ) - source = "add_new_int " + def add_new_int( source , from, to ) + source += "add_new_int " space = use_reg(:Space) int = use_reg(:Integer) space_i = Risc.resolve_to_index(:Space, :next_integer) diff --git a/test/parfait/test_space.rb b/test/parfait/test_space.rb index 45c63ea6..e01136ee 100644 --- a/test/parfait/test_space.rb +++ b/test/parfait/test_space.rb @@ -34,7 +34,7 @@ class TestSpace < MiniTest::Test def test_integer int = Parfait.object_space.get_class_by_name :Integer - assert_equal 4, int.instance_type.method_names.get_length + assert_equal 5, int.instance_type.method_names.get_length end def test_classes_class diff --git a/test/risc/interpreter/test_minus.rb b/test/risc/interpreter/test_minus.rb new file mode 100644 index 00000000..7873984e --- /dev/null +++ b/test/risc/interpreter/test_minus.rb @@ -0,0 +1,55 @@ +require_relative "helper" + +module Risc + class InterpreterMinusTest < MiniTest::Test + include Ticker + + def setup + @string_input = as_main("return 6 - 5") + super + end + + def test_minus + #show_ticks # get output of what is + check_chain [Branch, Label, LoadConstant, SlotToReg, LoadConstant, + SlotToReg, SlotToReg, RegToSlot, LoadConstant, SlotToReg, + SlotToReg, SlotToReg, SlotToReg, RegToSlot, LoadConstant, + SlotToReg, SlotToReg, SlotToReg, SlotToReg, RegToSlot, + SlotToReg, RegToSlot, LoadConstant, RegToSlot, FunctionCall, + Label, LoadConstant, SlotToReg, SlotToReg, RegToSlot, + LoadConstant, SlotToReg, SlotToReg, SlotToReg, SlotToReg, + RegToSlot, LoadConstant, SlotToReg, SlotToReg, SlotToReg, + SlotToReg, RegToSlot, LoadConstant, SlotToReg, RegToSlot, + LoadConstant, SlotToReg, SlotToReg, RegToSlot, LoadConstant, + SlotToReg, RegToSlot, SlotToReg, LoadConstant, FunctionCall, + Label, SlotToReg, SlotToReg, SlotToReg, SlotToReg, + SlotToReg, OperatorInstruction, LoadConstant, SlotToReg, SlotToReg, + RegToSlot, RegToSlot, RegToSlot, SlotToReg, SlotToReg, + RegToSlot, SlotToReg, SlotToReg, FunctionReturn, SlotToReg, + SlotToReg, RegToSlot, SlotToReg, SlotToReg, RegToSlot, + SlotToReg, SlotToReg, RegToSlot, SlotToReg, SlotToReg, + FunctionReturn, Transfer, Syscall, NilClass] + assert_equal Parfait::Integer , get_return.class + assert_equal 1 , get_return.value + end + def test_load_5 + lod = ticks( 46 ) + assert_equal LoadConstant , lod.class + assert_equal Parfait::Integer , lod.constant.class + assert_equal 5 , lod.constant.value + end + def test_op + op = ticks(62) + assert_equal OperatorInstruction , op.class + assert_equal :r1 , op.left.symbol + assert_equal :r2 , op.right.symbol + assert_equal 5 , @interpreter.get_register(:r2) + assert_equal 1 , @interpreter.get_register(:r1) + end + def test_sys + sys = ticks(88) + assert_equal Syscall , sys.class + assert_equal :exit , sys.name + end + end +end