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:
Torsten Ruger
2015-11-18 12:14:31 +02:00
parent 3efdf420a4
commit 18f9ea019e
33 changed files with 4 additions and 4 deletions

View 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

View File

@ -0,0 +1,4 @@
require_relative "test_basic"
require_relative "test_call"
require_relative "test_field_access"
require_relative "test_ops"

View 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

View 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

View 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

View 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

View 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

View 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"

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -0,0 +1,3 @@
require_relative "test_integer"
require_relative "test_layout"
require_relative "test_word"

View 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

View 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

View 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

View 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

View 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"

View 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

View 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

View 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

View 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

View 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

View 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

View 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
View 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"