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:
33
test/soml/expressions/helper.rb
Normal file
33
test/soml/expressions/helper.rb
Normal file
@ -0,0 +1,33 @@
|
||||
require_relative '../../helper'
|
||||
require 'parslet/convenience'
|
||||
|
||||
Soml::Compiler.class_eval do
|
||||
def set_main main
|
||||
@clazz = Register.machine.space.get_class_by_name :Object
|
||||
@method = main
|
||||
@current = main.instructions.next
|
||||
end
|
||||
end
|
||||
|
||||
module ExpressionHelper
|
||||
|
||||
def set_main compiler
|
||||
compiler.set_main Register.machine.space.get_main
|
||||
end
|
||||
def check
|
||||
machine = Register.machine
|
||||
machine.boot unless machine.booted
|
||||
parser = Parser::Salama.new
|
||||
parser = parser.send @root
|
||||
syntax = parser.parse_with_debug(@string_input)
|
||||
parts = Parser::Transform.new.apply(syntax)
|
||||
#puts parts.inspect
|
||||
compiler = Soml::Compiler.new
|
||||
set_main(compiler)
|
||||
produced = compiler.process( parts )
|
||||
assert @output , "No output given"
|
||||
assert_equal produced.class, @output , "Wrong class"
|
||||
produced
|
||||
end
|
||||
|
||||
end
|
4
test/soml/expressions/test_all.rb
Normal file
4
test/soml/expressions/test_all.rb
Normal file
@ -0,0 +1,4 @@
|
||||
require_relative "test_basic"
|
||||
require_relative "test_call"
|
||||
require_relative "test_field_access"
|
||||
require_relative "test_ops"
|
52
test/soml/expressions/test_basic.rb
Normal file
52
test/soml/expressions/test_basic.rb
Normal file
@ -0,0 +1,52 @@
|
||||
require_relative "helper"
|
||||
|
||||
|
||||
class TestBasic < MiniTest::Test
|
||||
include ExpressionHelper
|
||||
|
||||
def setup
|
||||
@root = :basic_type
|
||||
@output = Register::RegisterValue
|
||||
end
|
||||
|
||||
def test_number
|
||||
@string_input = '42 '
|
||||
assert_equal 42 , check.value
|
||||
end
|
||||
|
||||
def test_true
|
||||
@string_input = 'true'
|
||||
check
|
||||
end
|
||||
def test_false
|
||||
@string_input = 'false '
|
||||
check
|
||||
end
|
||||
def test_nil
|
||||
@string_input = 'nil '
|
||||
check
|
||||
end
|
||||
|
||||
def test_var
|
||||
@string_input = 'int foo '
|
||||
@root = :field_def
|
||||
@output = AST::Node
|
||||
check
|
||||
end
|
||||
|
||||
def test_self
|
||||
@string_input = 'self '
|
||||
check
|
||||
end
|
||||
|
||||
def test_space
|
||||
@string_input = 'self '
|
||||
check
|
||||
end
|
||||
|
||||
def test_string
|
||||
@string_input = "\"hello\""
|
||||
check
|
||||
end
|
||||
|
||||
end
|
45
test/soml/expressions/test_call.rb
Normal file
45
test/soml/expressions/test_call.rb
Normal file
@ -0,0 +1,45 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Register
|
||||
class TestCall < MiniTest::Test
|
||||
include ExpressionHelper
|
||||
|
||||
def setup
|
||||
Register.machine.boot
|
||||
@root = :call_site
|
||||
@output = Register::RegisterValue
|
||||
end
|
||||
|
||||
def test_call_main_plain
|
||||
@string_input = 'main()'
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_main_int
|
||||
@string_input = 'main(1)'
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_self_main
|
||||
@string_input = 'self.main()'
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_main_string
|
||||
@string_input = 'main("1")'
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_main_op
|
||||
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||
@string_input = 'main( bar )'
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_string_put
|
||||
@string_input = '"Hello Raisa, I am salama".putstring()'
|
||||
check
|
||||
end
|
||||
|
||||
end
|
||||
end
|
61
test/soml/expressions/test_field_access.rb
Normal file
61
test/soml/expressions/test_field_access.rb
Normal file
@ -0,0 +1,61 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Register
|
||||
class TestFields < MiniTest::Test
|
||||
include ExpressionHelper
|
||||
|
||||
def setup
|
||||
Register.machine.boot
|
||||
end
|
||||
|
||||
def test_field_not_defined
|
||||
@root = :field_access
|
||||
@string_input = <<HERE
|
||||
self.a
|
||||
HERE
|
||||
assert_raises(RuntimeError) { check }
|
||||
end
|
||||
|
||||
def test_field_not_space
|
||||
@root = :field_access
|
||||
@string_input = <<HERE
|
||||
self.space
|
||||
HERE
|
||||
assert_raises(RuntimeError) { check }
|
||||
end
|
||||
|
||||
def test_field
|
||||
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro,:Object)
|
||||
@root = :field_access
|
||||
@string_input = <<HERE
|
||||
self.bro
|
||||
HERE
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def test_local
|
||||
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||
@root = :name
|
||||
@string_input = 'bar '
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def test_space
|
||||
@root = :name
|
||||
@string_input = 'space '
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
def test_args
|
||||
Register.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :bar)
|
||||
@root = :name
|
||||
@string_input = 'bar '
|
||||
@output = Register::RegisterValue
|
||||
check
|
||||
end
|
||||
|
||||
end
|
||||
end
|
45
test/soml/expressions/test_ops.rb
Normal file
45
test/soml/expressions/test_ops.rb
Normal file
@ -0,0 +1,45 @@
|
||||
require_relative "helper"
|
||||
|
||||
module Register
|
||||
class TestOps < MiniTest::Test
|
||||
include ExpressionHelper
|
||||
|
||||
def setup
|
||||
Register.machine.boot
|
||||
@root = :operator_value
|
||||
@output = Register::RegisterValue
|
||||
end
|
||||
|
||||
def operators
|
||||
["+" , "-" , "*" , "/" , "=="]
|
||||
end
|
||||
def test_ints
|
||||
operators.each do |op|
|
||||
@string_input = '2 + 3'.sub("+" , op)
|
||||
check
|
||||
end
|
||||
end
|
||||
def test_local_int
|
||||
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||
@string_input = 'bar + 3'
|
||||
check
|
||||
end
|
||||
def test_int_local
|
||||
Register.machine.space.get_main.ensure_local(:bar , :Integer)
|
||||
@string_input = '3 + bar'
|
||||
check
|
||||
end
|
||||
|
||||
def test_field_int
|
||||
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro,:int)
|
||||
@string_input = "self.bro + 3"
|
||||
check
|
||||
end
|
||||
|
||||
def test_int_field
|
||||
Register.machine.space.get_class_by_name(:Object).object_layout.add_instance_variable(:bro,:int)
|
||||
@string_input = "3 + self.bro"
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
36
test/soml/fragments/helper.rb
Normal file
36
test/soml/fragments/helper.rb
Normal file
@ -0,0 +1,36 @@
|
||||
require_relative '../../helper'
|
||||
require "register/interpreter"
|
||||
|
||||
# Fragments are small programs that we run through the interpreter and really only check
|
||||
# - the no. of instructions processed
|
||||
# - the stdout output
|
||||
|
||||
|
||||
|
||||
module Fragments
|
||||
|
||||
def setup
|
||||
@stdout = ""
|
||||
end
|
||||
def check
|
||||
machine = Register.machine.boot
|
||||
machine.parse_and_compile @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 @length , count
|
||||
assert_equal @stdout , @interpreter.stdout
|
||||
end
|
||||
|
||||
def check_return val
|
||||
check
|
||||
assert_equal Parfait::Message , @interpreter.get_register(:r0).class
|
||||
assert_equal val , @interpreter.get_register(:r0).return_value
|
||||
end
|
||||
end
|
11
test/soml/fragments/test_all.rb
Normal file
11
test/soml/fragments/test_all.rb
Normal file
@ -0,0 +1,11 @@
|
||||
|
||||
require_relative "test_if"
|
||||
require_relative "test_class"
|
||||
require_relative "test_functions"
|
||||
require_relative "test_hello"
|
||||
require_relative "test_if"
|
||||
require_relative "test_putint"
|
||||
require_relative "test_recursive_fibo"
|
||||
require_relative "test_return"
|
||||
require_relative "test_while_fibo"
|
||||
require_relative "test_word"
|
24
test/soml/fragments/test_class.rb
Normal file
24
test/soml/fragments/test_class.rb
Normal file
@ -0,0 +1,24 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Register
|
||||
class TestBasicClass < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_class_def
|
||||
@string_input = <<HERE
|
||||
class Bar
|
||||
int buh()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 15
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
65
test/soml/fragments/test_functions.rb
Normal file
65
test/soml/fragments/test_functions.rb
Normal file
@ -0,0 +1,65 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestFunctions < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_functions
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
|
||||
int times(int a, int b)
|
||||
if_zero( b + 0)
|
||||
a = 0
|
||||
else
|
||||
int m = b - 1
|
||||
int t = times(a, m)
|
||||
a = a + t
|
||||
end
|
||||
return a
|
||||
end
|
||||
|
||||
int t_seven()
|
||||
int tim = times(8,10)
|
||||
tim.putint()
|
||||
return tim
|
||||
end
|
||||
|
||||
int main()
|
||||
return t_seven()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 505
|
||||
check_return 80
|
||||
end
|
||||
|
||||
def test_class_method
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
|
||||
int self.some()
|
||||
return 5
|
||||
end
|
||||
|
||||
int main()
|
||||
return Object.some()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 33
|
||||
check_return 5
|
||||
end
|
||||
|
||||
def test_class_method_fails
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
return Object.som()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
assert_raises {check}
|
||||
end
|
||||
|
||||
|
||||
end
|
18
test/soml/fragments/test_hello.rb
Normal file
18
test/soml/fragments/test_hello.rb
Normal file
@ -0,0 +1,18 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestHello < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_hello
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
"Hello Raisa, I am salama".putstring()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 37
|
||||
@stdout = "Hello Raisa, I am salama"
|
||||
check
|
||||
end
|
||||
end
|
60
test/soml/fragments/test_if.rb
Normal file
60
test/soml/fragments/test_if.rb
Normal file
@ -0,0 +1,60 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestIf < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_if_plus
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 10
|
||||
if_plus( n - 12)
|
||||
return 3
|
||||
else
|
||||
return 4
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 25
|
||||
check_return 4
|
||||
end
|
||||
|
||||
def test_if_zero
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 10
|
||||
if_zero(n - 10 )
|
||||
"10".putstring()
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 47
|
||||
@stdout = "10"
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
def test_if_minus
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int itest(int n)
|
||||
if_minus( n - 12)
|
||||
"then".putstring()
|
||||
else
|
||||
"else".putstring()
|
||||
end
|
||||
end
|
||||
|
||||
int main()
|
||||
itest(20)
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 62
|
||||
@stdout = "else"
|
||||
check
|
||||
end
|
||||
end
|
22
test/soml/fragments/test_putint.rb
Normal file
22
test/soml/fragments/test_putint.rb
Normal file
@ -0,0 +1,22 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestPutint < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_putint
|
||||
@string_input = <<HERE
|
||||
class Integer
|
||||
int putint()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
42.putint()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 32
|
||||
check
|
||||
end
|
||||
end
|
34
test/soml/fragments/test_recursive_fibo.rb
Normal file
34
test/soml/fragments/test_recursive_fibo.rb
Normal file
@ -0,0 +1,34 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestRecursinveFibo < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_recursive_fibo
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int fibonaccir( int n )
|
||||
if_plus( n - 2 )
|
||||
int tmp
|
||||
tmp = n - 1
|
||||
int a = fibonaccir( tmp )
|
||||
tmp = n - 2
|
||||
int b = fibonaccir( tmp )
|
||||
return a + b
|
||||
else
|
||||
return n
|
||||
end
|
||||
end
|
||||
int fib_print(int n)
|
||||
int fib = fibonaccir( n )
|
||||
fib.putint()
|
||||
return fib
|
||||
end
|
||||
int main()
|
||||
return fib_print(8)
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 2525
|
||||
check_return 21
|
||||
end
|
||||
end
|
51
test/soml/fragments/test_return.rb
Normal file
51
test/soml/fragments/test_return.rb
Normal file
@ -0,0 +1,51 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestReturn < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_return1
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
return 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 15
|
||||
check_return 5
|
||||
end
|
||||
|
||||
def test_return2
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int foo(int x)
|
||||
return x
|
||||
end
|
||||
|
||||
int main()
|
||||
return foo( 5 )
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 35
|
||||
check_return 5
|
||||
end
|
||||
|
||||
def test_return3
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int foo(int x)
|
||||
int a = 5
|
||||
return a
|
||||
end
|
||||
|
||||
int main()
|
||||
return foo( 4 )
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 39
|
||||
check_return 5
|
||||
end
|
||||
|
||||
end
|
44
test/soml/fragments/test_while_fibo.rb
Normal file
44
test/soml/fragments/test_while_fibo.rb
Normal file
@ -0,0 +1,44 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestWhileFragment < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def fibo num
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int fibonaccit(int n)
|
||||
int a = 0
|
||||
int b = 1
|
||||
while_plus( n - 2)
|
||||
n = n - 1
|
||||
int tmp = a
|
||||
a = b
|
||||
b = tmp + b
|
||||
end
|
||||
b.putint()
|
||||
return b
|
||||
end
|
||||
|
||||
int main()
|
||||
return fibonaccit( 100 )
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@string_input.sub!( "100" , num.to_s )
|
||||
end
|
||||
|
||||
def test_while_fibo48
|
||||
fibo 48
|
||||
@length = 1241
|
||||
# this is not the correct fibo, just what comes from wrapping (smaller than below)
|
||||
check_return 512559680
|
||||
end
|
||||
|
||||
# highest 32 bit fibo
|
||||
def test_while_fibo47
|
||||
fibo 47
|
||||
@length = 1216
|
||||
check_return 2971215073
|
||||
end
|
||||
|
||||
end
|
23
test/soml/fragments/test_word.rb
Normal file
23
test/soml/fragments/test_word.rb
Normal file
@ -0,0 +1,23 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestWord < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_word_new
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
Word self.new()
|
||||
return nil
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
Word w = Word.new()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@length = 34
|
||||
@stdout = ""
|
||||
check
|
||||
end
|
||||
end
|
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
|
37
test/soml/statements/helper.rb
Normal file
37
test/soml/statements/helper.rb
Normal file
@ -0,0 +1,37 @@
|
||||
require_relative '../../helper'
|
||||
|
||||
|
||||
module Statements
|
||||
|
||||
def check
|
||||
machine = Register.machine
|
||||
machine.boot unless machine.booted
|
||||
machine.parse_and_compile @string_input
|
||||
produced = Register.machine.space.get_main.instructions
|
||||
assert @expect , "No output given"
|
||||
#assert_equal @expect.length , produced.instructions.length , "instructions length #{produced.instructions.to_ac}"
|
||||
compare_instructions produced , @expect
|
||||
produced
|
||||
end
|
||||
|
||||
def compare_instructions instruction , expect
|
||||
index = 0
|
||||
start = instruction
|
||||
begin
|
||||
should = expect[index]
|
||||
assert should , "No instruction at #{index}"
|
||||
assert_equal instruction.class , should , "Expected at #{index+1}\n#{should(start)}"
|
||||
index += 1
|
||||
instruction = instruction.next
|
||||
end while( instruction )
|
||||
end
|
||||
def should start
|
||||
str = start.to_ac.to_s
|
||||
str.gsub!("Register::","")
|
||||
ret = ""
|
||||
str.split(",").each_slice(7).each do |line|
|
||||
ret += " " + line.join(",") + " ,\n"
|
||||
end
|
||||
ret
|
||||
end
|
||||
end
|
7
test/soml/statements/test_all.rb
Normal file
7
test/soml/statements/test_all.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require_relative "test_assign"
|
||||
require_relative "test_call"
|
||||
require_relative "test_class"
|
||||
require_relative "test_fields"
|
||||
require_relative "test_if"
|
||||
require_relative "test_return"
|
||||
require_relative "test_while"
|
128
test/soml/statements/test_assign.rb
Normal file
128
test/soml/statements/test_assign.rb
Normal file
@ -0,0 +1,128 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Register
|
||||
class TestAssignStatement < MiniTest::Test
|
||||
include Statements
|
||||
|
||||
def setup
|
||||
Register.machine.boot
|
||||
end
|
||||
|
||||
def test_assign_op
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 10 + 1
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, LoadConstant, OperatorInstruction, GetSlot, SetSlot, Label ,
|
||||
FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_assign_local
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int runner
|
||||
runner = 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_assign_local_assign
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int runner = 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_assign_call
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int r = main()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, GetSlot, SetSlot, LoadConstant, SetSlot, LoadConstant ,
|
||||
SetSlot, LoadConstant, SetSlot, RegisterTransfer, FunctionCall, Label, RegisterTransfer ,
|
||||
GetSlot, GetSlot, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_frame_get
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int r = 5
|
||||
return r
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, GetSlot, SetSlot, GetSlot, GetSlot, SetSlot ,
|
||||
Label, FunctionReturn]
|
||||
was = check
|
||||
get = was.next(5)
|
||||
assert_equal GetSlot , get.class
|
||||
assert_equal 4, get.index , "Get to frame index must be offset, not #{get.index}"
|
||||
end
|
||||
|
||||
def test_assign_arg
|
||||
Register.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :blar)
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main(int blar)
|
||||
blar = 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, SetSlot, Label, FunctionReturn]
|
||||
was = check
|
||||
set = was.next(2)
|
||||
assert_equal SetSlot , set.class
|
||||
assert_equal 10, set.index , "Set to args index must be offset, not #{set.index}"
|
||||
end
|
||||
|
||||
def test_assign_int
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int r = 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
was = check
|
||||
set = was.next(3)
|
||||
assert_equal SetSlot , set.class
|
||||
assert_equal 4, set.index , "Set to frame index must be offset, not #{set.index}"
|
||||
end
|
||||
|
||||
def test_arg_get
|
||||
# have to define bar externally, just because redefining main. Otherwise that would be automatic
|
||||
Register.machine.space.get_main.arguments.push Parfait::Variable.new(:Integer , :balr)
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main(int balr)
|
||||
return balr
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
was = check
|
||||
get = was.next(1)
|
||||
assert_equal GetSlot , get.class
|
||||
assert_equal 10, get.index , "Get to frame index must be offset, not #{get.index}"
|
||||
end
|
||||
end
|
||||
end
|
107
test/soml/statements/test_call.rb
Normal file
107
test/soml/statements/test_call.rb
Normal file
@ -0,0 +1,107 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Register
|
||||
class TestCallStatement < MiniTest::Test
|
||||
include Statements
|
||||
|
||||
def test_call_constant_int
|
||||
@string_input = <<HERE
|
||||
class Integer
|
||||
int putint()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
42.putint()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, LoadConstant, SetSlot, LoadConstant, SetSlot, LoadConstant ,
|
||||
SetSlot, LoadConstant, SetSlot, RegisterTransfer, FunctionCall, Label, RegisterTransfer ,
|
||||
GetSlot, GetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
def test_call_constant_string
|
||||
@string_input = <<HERE
|
||||
class Word
|
||||
int putstring()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
"Hello".putstring()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, LoadConstant, SetSlot, LoadConstant, SetSlot, LoadConstant ,
|
||||
SetSlot, LoadConstant, SetSlot, RegisterTransfer, FunctionCall, Label, RegisterTransfer ,
|
||||
GetSlot, GetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_local_int
|
||||
@string_input = <<HERE
|
||||
class Integer
|
||||
int putint()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
int testi = 20
|
||||
testi.putint()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, GetSlot, SetSlot, GetSlot, GetSlot, GetSlot ,
|
||||
SetSlot, LoadConstant, SetSlot, LoadConstant, SetSlot, LoadConstant, SetSlot ,
|
||||
RegisterTransfer, FunctionCall, Label, RegisterTransfer, GetSlot, GetSlot, Label ,
|
||||
FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_local_class
|
||||
@string_input = <<HERE
|
||||
class List < Object
|
||||
int add()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
List test_l
|
||||
test_l.add()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, GetSlot, GetSlot, SetSlot, LoadConstant, SetSlot ,
|
||||
LoadConstant, SetSlot, LoadConstant, SetSlot, RegisterTransfer, FunctionCall, Label ,
|
||||
RegisterTransfer, GetSlot, GetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_call_puts
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int puts(Word str)
|
||||
return str
|
||||
end
|
||||
int main()
|
||||
puts("Hello")
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, GetSlot, SetSlot, LoadConstant, SetSlot, LoadConstant ,
|
||||
SetSlot, LoadConstant, SetSlot, LoadConstant, SetSlot, RegisterTransfer, FunctionCall ,
|
||||
Label, RegisterTransfer, GetSlot, GetSlot, Label, FunctionReturn]
|
||||
was = check
|
||||
set = was.next(7)
|
||||
assert_equal SetSlot , set.class
|
||||
assert_equal 9, set.index , "Set to message must be offset, not #{set.index}"
|
||||
end
|
||||
end
|
||||
end
|
69
test/soml/statements/test_class.rb
Normal file
69
test/soml/statements/test_class.rb
Normal file
@ -0,0 +1,69 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Register
|
||||
class TestClassStatements < MiniTest::Test
|
||||
include Statements
|
||||
|
||||
def test_class_defs
|
||||
@string_input = <<HERE
|
||||
class Bar
|
||||
int self.buh()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant,SetSlot,Label,FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_class_call
|
||||
@string_input = <<HERE
|
||||
class Bar
|
||||
int self.buh()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
class Object
|
||||
int main()
|
||||
return Bar.buh()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, LoadConstant, SetSlot, LoadConstant, SetSlot, LoadConstant ,
|
||||
SetSlot, LoadConstant, SetSlot, RegisterTransfer, FunctionCall, Label, RegisterTransfer ,
|
||||
GetSlot, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_class_field_value
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
field int boo1 = 1
|
||||
int main()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant,SetSlot,Label,FunctionReturn]
|
||||
assert_raises{check}
|
||||
end
|
||||
|
||||
def test_class_field
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
field int boo2
|
||||
int main()
|
||||
return self.boo2
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot,GetSlot,SetSlot,Label,FunctionReturn]
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
68
test/soml/statements/test_fields.rb
Normal file
68
test/soml/statements/test_fields.rb
Normal file
@ -0,0 +1,68 @@
|
||||
require_relative 'helper'
|
||||
|
||||
|
||||
module Register
|
||||
class TestFieldStatement < MiniTest::Test
|
||||
include Statements
|
||||
|
||||
def test_field_frame
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
Message m
|
||||
return m.name
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, GetSlot, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_field_arg
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int get_name(Message main)
|
||||
return main.name
|
||||
end
|
||||
int main()
|
||||
Message m
|
||||
return get_name(m)
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, GetSlot, SetSlot, LoadConstant, SetSlot, LoadConstant ,
|
||||
SetSlot, GetSlot, GetSlot, SetSlot, LoadConstant, SetSlot, RegisterTransfer ,
|
||||
FunctionCall, Label, RegisterTransfer, GetSlot, GetSlot, SetSlot, Label ,
|
||||
FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_self_field
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
Layout l = self.layout
|
||||
return 1
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, GetSlot, GetSlot, SetSlot, LoadConstant, SetSlot ,
|
||||
Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_message_field
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
Word name = message.name
|
||||
return name
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, RegisterTransfer, GetSlot, GetSlot, SetSlot, GetSlot, GetSlot ,
|
||||
SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
58
test/soml/statements/test_if.rb
Normal file
58
test/soml/statements/test_if.rb
Normal file
@ -0,0 +1,58 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Register
|
||||
class TestIfStatement < MiniTest::Test
|
||||
include Statements
|
||||
|
||||
def test_if_basicr
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
if_plus( 10 - 12)
|
||||
return 3
|
||||
else
|
||||
return 4
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant,LoadConstant, OperatorInstruction,IsPlus ,
|
||||
LoadConstant,SetSlot,Branch , Label , LoadConstant ,SetSlot,
|
||||
Label,Label,FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
def test_if_small_minus
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
if_minus( 10 - 12)
|
||||
return 3
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, LoadConstant, OperatorInstruction, IsMinus, Branch, Label ,
|
||||
LoadConstant, SetSlot, Label, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
def test_if_small_zero
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
if_zero( 10 - 12)
|
||||
return 3
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant,LoadConstant,OperatorInstruction,IsZero ,
|
||||
Branch , Label , LoadConstant ,SetSlot,
|
||||
Label,Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
92
test/soml/statements/test_return.rb
Normal file
92
test/soml/statements/test_return.rb
Normal file
@ -0,0 +1,92 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Register
|
||||
class TestReturnStatement < MiniTest::Test
|
||||
include Statements
|
||||
|
||||
|
||||
def test_return_int
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
return 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant ,SetSlot,Label,FunctionReturn]
|
||||
was = check
|
||||
set = was.next(2)
|
||||
assert_equal SetSlot , set.class
|
||||
should = Register.machine.space.first_message.get_layout.variable_index(:return_value)
|
||||
assert_equal should, set.index , "Set to message must got to return_value(#{should}), not #{set.index}"
|
||||
end
|
||||
|
||||
def test_return_local
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int runner
|
||||
return runner
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot,GetSlot ,SetSlot,Label,FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_return_local_assign
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int runner = 5
|
||||
return runner
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant,GetSlot,SetSlot,GetSlot,GetSlot ,SetSlot,
|
||||
Label,FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_return_field
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
field int runner
|
||||
int main()
|
||||
return self.runner
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot,GetSlot ,SetSlot,Label,FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def pest_return_space_length # need to add runtime first
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
|
||||
int main()
|
||||
Layout l = space.get_layout()
|
||||
return self.runner
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot,GetSlot ,SetSlot,Label,FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_return_call
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
return main()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, GetSlot, GetSlot, SetSlot, LoadConstant, SetSlot, LoadConstant ,
|
||||
SetSlot, LoadConstant, SetSlot, RegisterTransfer, FunctionCall, Label, RegisterTransfer ,
|
||||
GetSlot, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
61
test/soml/statements/test_while.rb
Normal file
61
test/soml/statements/test_while.rb
Normal file
@ -0,0 +1,61 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Register
|
||||
class TestWhile < MiniTest::Test
|
||||
include Statements
|
||||
|
||||
|
||||
def test_while_mini
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
while_plus(1)
|
||||
return 3
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, Branch, Label, LoadConstant, SetSlot, Label, LoadConstant ,
|
||||
IsPlus, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
def test_while_assign
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 5
|
||||
while_plus(n)
|
||||
n = n - 1
|
||||
end
|
||||
return n
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, GetSlot, SetSlot, Branch, Label, GetSlot ,
|
||||
GetSlot, LoadConstant, OperatorInstruction, GetSlot, SetSlot, Label, GetSlot ,
|
||||
GetSlot, IsPlus, GetSlot, GetSlot, SetSlot, Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
def test_while_return
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 10
|
||||
while_plus( n - 5)
|
||||
n = n + 1
|
||||
return n
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [Label, LoadConstant, GetSlot, SetSlot, Branch, Label, GetSlot ,
|
||||
GetSlot, LoadConstant, OperatorInstruction, GetSlot, SetSlot, GetSlot, GetSlot ,
|
||||
SetSlot, Label, GetSlot, GetSlot, LoadConstant, OperatorInstruction, IsPlus ,
|
||||
Label, FunctionReturn]
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
7
test/soml/test_all.rb
Normal file
7
test/soml/test_all.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require_relative "expressions/test_all"
|
||||
|
||||
require_relative "statements/test_all"
|
||||
|
||||
require_relative "fragments/test_all"
|
||||
|
||||
require_relative "parfait/test_all"
|
Reference in New Issue
Block a user