move parfait tests to some
after renaming compiler to soml it’s where they wanna be also will allow for unifying test helpers and testing fragments remotely too
This commit is contained in:
94
test/soml/parfait/helper.rb
Normal file
94
test/soml/parfait/helper.rb
Normal file
@ -0,0 +1,94 @@
|
||||
require_relative '../../helper'
|
||||
require "register/interpreter"
|
||||
require "rye"
|
||||
Rye::Cmd.add_command :ld, '/usr/bin/ld'
|
||||
Rye::Cmd.add_command :aout, './a.out'
|
||||
|
||||
module RuntimeTests
|
||||
|
||||
def setup
|
||||
@stdout = ""
|
||||
end
|
||||
def main
|
||||
<<HERE
|
||||
class Object
|
||||
int main()
|
||||
PROGRAM
|
||||
end
|
||||
end
|
||||
HERE
|
||||
end
|
||||
def check ret = nil
|
||||
machine = Register.machine.boot
|
||||
Soml::Compiler.load_parfait
|
||||
machine.parse_and_compile main.sub("PROGRAM" , @string_input )
|
||||
machine.collect
|
||||
@interpreter = Register::Interpreter.new
|
||||
@interpreter.start machine.init
|
||||
count = 0
|
||||
begin
|
||||
count += 1
|
||||
#puts interpreter.instruction
|
||||
@interpreter.tick
|
||||
end while( ! @interpreter.instruction.nil?)
|
||||
assert_equal @stdout , @interpreter.stdout , "stdout wrong locally"
|
||||
if ret
|
||||
assert_equal Parfait::Message , @interpreter.get_register(:r0).class
|
||||
assert_equal ret , @interpreter.get_register(:r0).return_value , "exit wrong #{@string_input}"
|
||||
end
|
||||
check_remote ret
|
||||
file = write_object_file
|
||||
end
|
||||
|
||||
def connected
|
||||
return @@conn if defined?(@@conn)
|
||||
return @@conn = false
|
||||
begin
|
||||
box = Rye::Box.new("localhost" , :port => 2222 , :user => "pi")
|
||||
box.pwd
|
||||
puts "connected, testing also remotely"
|
||||
@@conn = box
|
||||
rescue Rye::Err
|
||||
@@conn = false
|
||||
end
|
||||
return @@conn
|
||||
end
|
||||
def check_remote ret
|
||||
return unless box = connected
|
||||
return unless ret.is_a?(Numeric)
|
||||
file = write_object_file
|
||||
r_file = file.sub("./" , "salama/")
|
||||
box.file_upload file , r_file
|
||||
box.ld "-N", r_file
|
||||
begin #need to rescue here as rye throws if no return 0
|
||||
ret = box.aout # and we use return to mean something
|
||||
rescue Rye::Err => e # so it's basically never 0
|
||||
ret = e.rap
|
||||
end
|
||||
assert_equal @stdout , ret.stdout.join , "remote std was #{ret.stdout}" if @stdout
|
||||
assert_equal "" , ret.stderr.join , "remote had error"
|
||||
if ret
|
||||
should = @interpreter.get_register(:r0).return_value
|
||||
assert_equal should , ret.exit_status.to_i , "remote exit failed for #{@string_input}"
|
||||
end
|
||||
end
|
||||
|
||||
def write_object_file
|
||||
file_name = caller(3).first.split("in ").last.chop.sub("`","")
|
||||
return if file_name.include?("run")
|
||||
file_name = "./tmp/" + file_name + ".o"
|
||||
Register.machine.translate_arm
|
||||
writer = Elf::ObjectWriter.new
|
||||
writer.save file_name
|
||||
file_name
|
||||
end
|
||||
|
||||
def check_return val
|
||||
check val
|
||||
end
|
||||
|
||||
def check_return_class val
|
||||
check
|
||||
assert_equal val , @interpreter.get_register(:r0).return_value.class
|
||||
end
|
||||
end
|
3
test/soml/parfait/test_all.rb
Normal file
3
test/soml/parfait/test_all.rb
Normal file
@ -0,0 +1,3 @@
|
||||
require_relative "test_integer"
|
||||
require_relative "test_layout"
|
||||
require_relative "test_word"
|
155
test/soml/parfait/test_integer.rb
Normal file
155
test/soml/parfait/test_integer.rb
Normal file
@ -0,0 +1,155 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestPutiRT < MiniTest::Test
|
||||
include RuntimeTests
|
||||
|
||||
def test_mod4_2
|
||||
@string_input = "return 2.mod4()"
|
||||
check_return 2 % 4
|
||||
end
|
||||
def test_mod4_3
|
||||
@string_input = "return 3.mod4()"
|
||||
check_return 3 % 4
|
||||
end
|
||||
def test_mod4_4
|
||||
@string_input = "return 4.mod4()"
|
||||
check_return 4 % 4
|
||||
end
|
||||
def test_mod4_5
|
||||
@string_input = "return 5.mod4()"
|
||||
check_return 5 % 4
|
||||
end
|
||||
def test_mod4_12
|
||||
@string_input = "return 12.mod4()"
|
||||
check_return 12 % 4
|
||||
end
|
||||
def test_mod4_10
|
||||
@string_input = "return 10.mod4()"
|
||||
check_return 10 % 4
|
||||
end
|
||||
|
||||
# if you multiply i by "by" the return is the high 32 bits
|
||||
def high_times( i , by_high , by_low)
|
||||
by = by_high * 65536 + by_low
|
||||
by *= i
|
||||
by /= 65536
|
||||
by /= 65536
|
||||
return by
|
||||
end
|
||||
|
||||
# if you multiply i by "by" the return is the low 32 bits
|
||||
def low_times( i , by_high , by_low)
|
||||
by = by_high * 65536 + by_low
|
||||
by *= i
|
||||
return (by & 0xffffffff)
|
||||
end
|
||||
|
||||
def test_hightimes2
|
||||
@string_input = "return 2.high_times(12 , 333)"
|
||||
check_return high_times(2,12,333)
|
||||
end
|
||||
def test_hightimes3456
|
||||
@string_input = "return 3456.high_times(12 , 333)"
|
||||
check_return high_times(3456,12,333)
|
||||
end
|
||||
def test_hightimes234567
|
||||
@string_input = "return 234567.high_times(12 , 333)"
|
||||
check_return high_times(234567,12,333)
|
||||
end
|
||||
def test_hightimes
|
||||
@string_input = "return 234567.high_times(12 , 333)"
|
||||
check_return high_times(234567,12,333)
|
||||
end
|
||||
def test_lowtimes2
|
||||
@string_input = "return 2.low_times(14 , 33)"
|
||||
check_return low_times(2,14,33)
|
||||
end
|
||||
def test_lowtimes3456
|
||||
@string_input = "return 3456.low_times(14 , 33)"
|
||||
check_return low_times(3456,14,33)
|
||||
end
|
||||
def test_lowtimes234567
|
||||
@string_input = "return 234567.low_times(14 , 33)"
|
||||
check_return low_times(234567,14,33)
|
||||
end
|
||||
|
||||
# finally settled on the long version in http://www.sciencezero.org/index.php?title=ARM:_Division_by_10
|
||||
# also the last looked good, but some bug is admittedly in all the ones i tried
|
||||
# (off course the bug is not included in the test, but easy to achieve with random numbers )
|
||||
# for high numbers with ending 0 they are all 1 low. Possibly Interpreter bug ?
|
||||
def test_div10_2
|
||||
@string_input = "return 2.div10()"
|
||||
check_return 2 / 10
|
||||
end
|
||||
def test_div10_10
|
||||
@string_input = "return 10.div10()"
|
||||
check_return 10 / 10
|
||||
end
|
||||
def test_div10_12345
|
||||
@string_input = "return 12345.div10()"
|
||||
check_return 12345 / 10
|
||||
end
|
||||
def test_div10_234567
|
||||
@string_input = "return 234567.div10()"
|
||||
check_return 234567 / 10
|
||||
end
|
||||
|
||||
def test_as_char1
|
||||
@string_input = "return 5.as_char()"
|
||||
check_return 53
|
||||
end
|
||||
|
||||
def test_as_char2
|
||||
@string_input = "return 10.as_char()"
|
||||
check_return 32
|
||||
end
|
||||
|
||||
def test_tos_one_digit
|
||||
@string_input = "Word five = 5.to_s()
|
||||
five.putstring()"
|
||||
@stdout = " 5"
|
||||
check
|
||||
end
|
||||
|
||||
def test_tos_zero
|
||||
@string_input = "Word five = 0.to_s()
|
||||
five.putstring()"
|
||||
@stdout = " 0"
|
||||
check
|
||||
end
|
||||
|
||||
def test_tos_two_digit
|
||||
@string_input = "Word five = 15.to_s()
|
||||
five.putstring()"
|
||||
@stdout = " 15"
|
||||
check
|
||||
end
|
||||
|
||||
def test_tos_three_digit
|
||||
@string_input = "Word five = 150.to_s()
|
||||
five.putstring()"
|
||||
@stdout = " 150"
|
||||
check
|
||||
end
|
||||
|
||||
def test_puti_four_digit
|
||||
@string_input = "return 1234.puti()"
|
||||
@stdout = " 1234"
|
||||
check_return 1234
|
||||
end
|
||||
|
||||
def test_puti_seven_digit
|
||||
@string_input = "int i = 301 * 4096
|
||||
i = i + 1671
|
||||
return i.puti()"
|
||||
@stdout = " 1234567"
|
||||
check_return 1234567
|
||||
end
|
||||
def test_puti_eight_digit
|
||||
@string_input = "int i = 3014 * 4096
|
||||
i = i + 334
|
||||
return i.puti()"
|
||||
@stdout = " 12345678"
|
||||
check_return 12345678
|
||||
end
|
||||
end
|
33
test/soml/parfait/test_layout.rb
Normal file
33
test/soml/parfait/test_layout.rb
Normal file
@ -0,0 +1,33 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestLayoutRT < MiniTest::Test
|
||||
include RuntimeTests
|
||||
|
||||
def test_main
|
||||
@string_input = "return 1"
|
||||
check_return 1
|
||||
end
|
||||
|
||||
def test_get_layout
|
||||
@string_input = "return get_layout()"
|
||||
check_return_class Parfait::Layout
|
||||
|
||||
end
|
||||
|
||||
def test_get_class
|
||||
@string_input = "return get_class()"
|
||||
check_return_class Parfait::Class
|
||||
end
|
||||
|
||||
def test_puts_class
|
||||
@string_input = <<HERE
|
||||
Class c = get_class()
|
||||
Word w = c.get_name()
|
||||
w.putstring()
|
||||
HERE
|
||||
@stdout = "Space"
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
end
|
64
test/soml/parfait/test_word.rb
Normal file
64
test/soml/parfait/test_word.rb
Normal file
@ -0,0 +1,64 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestwordRT < MiniTest::Test
|
||||
include RuntimeTests
|
||||
|
||||
def test_len
|
||||
@string_input = <<HERE
|
||||
Word w = " "
|
||||
return w.char_length
|
||||
HERE
|
||||
check_return 1
|
||||
end
|
||||
|
||||
def test_space
|
||||
@string_input = <<HERE
|
||||
Word w = " "
|
||||
return w.char_at(1)
|
||||
HERE
|
||||
assert_equal 32 , " ".codepoints[0] # just checking
|
||||
check_return 32
|
||||
end
|
||||
|
||||
def test_add_doesnt_change1
|
||||
@string_input = <<HERE
|
||||
Word w = " "
|
||||
w.push_char(48)
|
||||
return w.char_at(1)
|
||||
HERE
|
||||
check_return 32
|
||||
end
|
||||
def test_after_add_get_works
|
||||
@string_input = <<HERE
|
||||
Word w = " "
|
||||
w.push_char(48)
|
||||
return w.char_at(2)
|
||||
HERE
|
||||
check_return 48
|
||||
end
|
||||
|
||||
def test_after_add_length_works
|
||||
@string_input = <<HERE
|
||||
Word w = " "
|
||||
w.push_char(32)
|
||||
return w.char_length
|
||||
HERE
|
||||
check_return 2
|
||||
end
|
||||
|
||||
def test_get1
|
||||
@string_input = <<HERE
|
||||
Word w = "12345"
|
||||
return w.char_at(1)
|
||||
HERE
|
||||
check_return 49
|
||||
end
|
||||
|
||||
def test_get2
|
||||
@string_input = <<HERE
|
||||
Word w = "12345"
|
||||
return w.char_at(2)
|
||||
HERE
|
||||
check_return 50
|
||||
end
|
||||
end
|
Reference in New Issue
Block a user