diff --git a/lib/mom/builtin/comparison.rb b/lib/mom/builtin/comparison.rb index d38335e9..c5f54f0f 100644 --- a/lib/mom/builtin/comparison.rb +++ b/lib/mom/builtin/comparison.rb @@ -12,7 +12,7 @@ module Mom builder.build do integer! << message[:receiver] integer.reduce_int - integer_reg! << message[:arg1] #"other" + integer_reg! << message[:arg1] #"other" integer_reg.reduce_int swap_names(:integer , :integer_reg) if(operator.to_s.start_with?('<') ) integer.op :- , integer_reg @@ -28,6 +28,33 @@ module Mom return compiler end end - + end + class Comparison < ::Mom::Instruction + attr_reader :operator + def initialize(name , operator) + super(name) + @operator = operator.value + end + def to_risc(compiler) + builder = compiler.builder(compiler.source) + operator = @operator # make accessible in block + builder.build do + integer! << message[:receiver] + integer.reduce_int + integer_reg! << message[:arg1] #"other" + integer_reg.reduce_int + 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 + return compiler + end end end diff --git a/lib/mom/builtin/div10.rb b/lib/mom/builtin/div10.rb index 0d54736d..bf1e73d5 100644 --- a/lib/mom/builtin/div10.rb +++ b/lib/mom/builtin/div10.rb @@ -62,4 +62,65 @@ module Mom end end end + class Div10 < ::Mom::Instruction + def to_risc(compiler) + s = "div_10 " + builder = compiler.builder(compiler.source) + integer_tmp = builder.allocate_int + builder.build do + integer_self! << message[:receiver] + integer_self.reduce_int + integer_1! << integer_self + integer_reg! << integer_self + + integer_const! << 1 + integer_1.op :>> , integer_const + + integer_const << 2 + integer_reg.op :>> , integer_const + integer_reg.op :+ , integer_1 + + integer_const << 4 + integer_1 << integer_reg + integer_reg.op :>> , integer_1 + + integer_reg.op :+ , integer_1 + + integer_const << 8 + integer_1 << integer_reg + integer_1.op :>> , integer_const + + integer_reg.op :+ , integer_1 + + integer_const << 16 + integer_1 << integer_reg + integer_1.op :>> , integer_const + + integer_reg.op :+ , integer_1 + + integer_const << 3 + integer_reg.op :>> , integer_const + + integer_const << 10 + integer_1 << integer_reg + integer_1.op :* , integer_const + + integer_self.op :- , integer_1 + integer_1 << integer_self + + integer_const << 6 + integer_1.op :+ , integer_const + + integer_const << 4 + integer_1.op :>> , integer_const + + integer_reg.op :+ , integer_1 + + integer_tmp[Parfait::Integer.integer_index] << integer_reg + message[:return_value] << integer_tmp + + end + return compiler + end + end end diff --git a/lib/mom/builtin/div4.rb b/lib/mom/builtin/div4.rb index b41e04ea..79a2312a 100644 --- a/lib/mom/builtin/div4.rb +++ b/lib/mom/builtin/div4.rb @@ -16,4 +16,19 @@ module Mom end end end + class Div4 < ::Mom::Instruction + def to_risc(compiler) + builder = compiler.builder(compiler.source) + integer_tmp = builder.allocate_int + builder.build do + integer_self! << message[:receiver] + integer_self.reduce_int + integer_1! << 2 + integer_self.op :>> , integer_1 + integer_tmp[Parfait::Integer.integer_index] << integer_self + message[:return_value] << integer_tmp + end + return compiler + end + end end diff --git a/lib/mom/builtin/integer.rb b/lib/mom/builtin/integer.rb index 139b7297..01e7f06c 100644 --- a/lib/mom/builtin/integer.rb +++ b/lib/mom/builtin/integer.rb @@ -61,7 +61,7 @@ module Mom # - returns the new int def operator_method( op_sym ) compiler = compiler_for(:Integer, op_sym ,{other: :Integer }) - compiler.add_code Operator.new("operator" , op_sym) + compiler.add_code Operator.new( "op:#{op_sym}" , op_sym) return compiler end diff --git a/lib/mom/builtin/operator.rb b/lib/mom/builtin/operator.rb index 4c9be8ee..14ed57ae 100644 --- a/lib/mom/builtin/operator.rb +++ b/lib/mom/builtin/operator.rb @@ -23,13 +23,12 @@ module Mom return compiler end end - end class IntOperator < Instruction attr_reader :operator def initialize(name , operator) super(name) - @operator = operator + @operator = operator.value end def to_risc(compiler) diff --git a/lib/risc/instructions/operator_instruction.rb b/lib/risc/instructions/operator_instruction.rb index 9a12218b..0afeb7b1 100644 --- a/lib/risc/instructions/operator_instruction.rb +++ b/lib/risc/instructions/operator_instruction.rb @@ -13,8 +13,9 @@ module Risc class OperatorInstruction < Instruction def initialize( source , operator , left , right ) super(source) + operator = operator.value if operator.is_a?(Vool::Constant) @operator = operator - raise "unsuported operator :#{operator}:" unless Risc.operators.include?(operator) + raise "unsuported operator :#{operator}:#{operator.class}:" unless Risc.operators.include?(operator) @left = left @right = right raise "Not register #{left}" unless RegisterValue.look_like_reg(left) diff --git a/test/rubyx/builtin/test_integer_comparison.rb b/test/rubyx/builtin/test_integer_comparison.rb new file mode 100644 index 00000000..649d4b61 --- /dev/null +++ b/test/rubyx/builtin/test_integer_comparison.rb @@ -0,0 +1,47 @@ +require_relative "helper" + +module RubyX + module Builtin + class TestIntegerSame < MiniTest::Test + include BuiltinHelper + def op ; :== ; end + def len ; 25 ; end + def source + < ; end + def len ; 26 ; end + end + class TestIntegerSm < TestIntegerSame + def op ; :< ; end + def len ; 26 ; end + end + class TestIntegerLe < TestIntegerSame + def op ; :>= ; end + end + class TestIntegerSe < TestIntegerSame + def op ; :<= ; end + end + end +end diff --git a/test/rubyx/builtin/test_integer_div10.rb b/test/rubyx/builtin/test_integer_div10.rb new file mode 100644 index 00000000..2f48e07e --- /dev/null +++ b/test/rubyx/builtin/test_integer_div10.rb @@ -0,0 +1,30 @@ +require_relative "helper" + +module RubyX + module Builtin + class TestIntegerDiv10 < MiniTest::Test + include BuiltinHelper + def source + <> ; end + end + class TestIntegerMul < TestIntegerPlus + def op ; :* ; end + end + class TestIntegerAnd < TestIntegerPlus + def op ; :& ; end + end + class TestIntegerOr < TestIntegerPlus + def op ; :| ; end + end + end +end