fix interpreter overflow issue

flag set for bigness, result reduced
tests for + and *
fixed fibs tests
This commit is contained in:
Torsten Ruger 2015-11-08 15:15:55 +02:00
parent 6ea698d397
commit d6108e7b3a
8 changed files with 73 additions and 33 deletions

View File

@ -1,5 +1,6 @@
require_relative "eventable" require_relative "eventable"
require 'bigdecimal'
module Interpreter module Interpreter
class Interpreter class Interpreter
@ -174,10 +175,10 @@ module Interpreter
end end
def execute_OperatorInstruction def execute_OperatorInstruction
log.debug @instruction
left = get_register(@instruction.left) left = get_register(@instruction.left)
rr = @instruction.right rr = @instruction.right
right = get_register(rr) right = get_register(rr)
@flags[:overflow] = false
case @instruction.operator.to_s case @instruction.operator.to_s
when "+" when "+"
result = left + right result = left + right
@ -193,8 +194,11 @@ module Interpreter
else else
raise "unimplemented '#{@instruction.operator}' #{@instruction}" raise "unimplemented '#{@instruction.operator}' #{@instruction}"
end end
## result not over 2**62 => overflow if( result.is_a? Bignum)
log.debug "#{@instruction} == #{result} (#{left}|#{right})" @flags[:overflow] = true
result = result % 2**62
end
log.debug "#{@instruction} == #{result}(#{result.class}) (#{left}|#{right})"
right = set_register(@instruction.left , result) right = set_register(@instruction.left , result)
true true
end end

View File

@ -10,4 +10,5 @@ def fibonaccit(n)
end end
#1000000.times {fibonaccit( 30 )} #1000000.times {fibonaccit( 30 )}
puts fibonaccit 100 #10.times {|i| puts fibonaccit(i+90).class}
puts fibonaccit 90

View File

@ -28,17 +28,17 @@ HERE
@string_input.sub!( "100" , num.to_s ) @string_input.sub!( "100" , num.to_s )
end end
def test_while_fibo100 def test_while_fibo94
fibo 100 fibo 91
@length = 2345 @length = 2138
#TODO bug, int max is 92 ruby converts to biginteger. # this is not the correct fibo, just what comes from wrapping (smaller than below)
check_return 354224848179261915075 check_return 48360591948142405
end end
def test_while_fibo92 def test_while_fibo90
fibo 92 fibo 90
@length = 2161 @length = 2115
check_return 7540113804746346429 check_return 2880067194370816120
end end
end end

View File

@ -21,6 +21,11 @@ module Ticker
end end
end end
def check_return val
assert_equal Parfait::Message , @interpreter.get_register(:r0).class
assert_equal val , @interpreter.get_register(:r0).return_value
end
def ticks num def ticks num
last = nil last = nil
num.times do num.times do

View File

@ -1,4 +1,5 @@
require_relative "test_add" require_relative "test_add"
require_relative "test_if" require_relative "test_if"
require_relative "test_puts" require_relative "test_puts"
require_relative "test_ops" require_relative "test_plus"
require_relative "test_mult"

View File

@ -1,6 +1,6 @@
require_relative "helper" require_relative "helper"
class AddTest < MiniTest::Test class IfTest < MiniTest::Test
include Ticker include Ticker
def setup def setup

View File

@ -1,6 +1,6 @@
require_relative "helper" require_relative "helper"
class AddTest < MiniTest::Test class MultTest < MiniTest::Test
include Ticker include Ticker
include AST::Sexp include AST::Sexp
@ -8,35 +8,29 @@ class AddTest < MiniTest::Test
@string_input = <<HERE @string_input = <<HERE
class Object class Object
int main() int main()
return 5 + 10 return #{2**31} * #{2**31}
end end
end end
HERE HERE
super super
end end
def test_add
#show_ticks # get output of what is
check_chain ["Branch","Label","LoadConstant","GetSlot","SetSlot",
"LoadConstant","SetSlot","FunctionCall","Label","LoadConstant",
"LoadConstant","OperatorInstruction","SetSlot","Label","FunctionReturn",
"RegisterTransfer","Syscall","NilClass"]
end
def test_mult def test_mult
@string_input = <<HERE
class Object
int main()
return 5 * 10
end
end
HERE
setup
#show_ticks # get output of what is #show_ticks # get output of what is
check_chain ["Branch","Label","LoadConstant","GetSlot","SetSlot", check_chain ["Branch","Label","LoadConstant","GetSlot","SetSlot",
"LoadConstant","SetSlot","FunctionCall","Label","LoadConstant", "LoadConstant","SetSlot","FunctionCall","Label","LoadConstant",
"LoadConstant","OperatorInstruction","SetSlot","Label","FunctionReturn", "LoadConstant","OperatorInstruction","SetSlot","Label","FunctionReturn",
"RegisterTransfer","Syscall","NilClass"] "RegisterTransfer","Syscall","NilClass"]
check_return 0
end
def test_overflow
ticks( 12 )
assert @interpreter.flags[:overflow]
end
def test_zero
ticks( 12 )
assert @interpreter.flags[:zero]
end end
end end

View File

@ -0,0 +1,35 @@
require_relative "helper"
class PlusTest < MiniTest::Test
include Ticker
def setup
@string_input = <<HERE
class Object
int main()
return #{2**62 - 1} + 1
end
end
HERE
super
end
def test_add
#show_ticks # get output of what is
check_chain ["Branch","Label","LoadConstant","GetSlot","SetSlot",
"LoadConstant","SetSlot","FunctionCall","Label","LoadConstant",
"LoadConstant","OperatorInstruction","SetSlot","Label","FunctionReturn",
"RegisterTransfer","Syscall","NilClass"]
check_return 0
end
def test_overflow
ticks( 12 )
assert @interpreter.flags[:overflow]
end
def test_zero
ticks( 12 )
assert @interpreter.flags[:zero]
end
end