clearer organization for compiler tests
was slightly messy with small/large now needed different test for expression and statements
This commit is contained in:
@ -1,54 +0,0 @@
|
||||
require_relative '../helper'
|
||||
|
||||
# simple tests to check parsing pworks and the first classes come out right.
|
||||
#
|
||||
# build up from small to check larger statements are correct
|
||||
|
||||
module Fragments
|
||||
|
||||
def check
|
||||
machine = Virtual.machine.boot
|
||||
machine.parse_and_compile @string_input
|
||||
produced = Virtual.machine.space.get_main.source
|
||||
assert @expect , "No output given"
|
||||
assert_equal @expect.length , produced.blocks.length , "Block length"
|
||||
produced.blocks.each_with_index do |b,i|
|
||||
codes = @expect[i]
|
||||
assert codes , "No codes for block #{i}"
|
||||
assert_equal b.codes.length , codes.length , "Code length for block #{i+1}"
|
||||
b.codes.each_with_index do |c , ii |
|
||||
assert_equal codes[ii] , c.class , "Block #{i+1} , code #{ii+1}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# helper to write the file
|
||||
def write name
|
||||
writer = Elf::ObjectWriter.new(@object_machine , Elf::Constants::TARGET_ARM)
|
||||
assembly = writer.text
|
||||
writer.save("#{name}.o")
|
||||
function = @object_machine.classes[@target[0]]
|
||||
assert function , "no class #{@target[0]}"
|
||||
function = function.get_function(@target[1])
|
||||
assert function , "no function #{@target[1]} for class #{@target[0]}"
|
||||
io = StringIO.new
|
||||
function.assemble io
|
||||
assembly = io.string
|
||||
# use this for getting the bytes to compare to :
|
||||
puts bytes(assembly)
|
||||
assembly.bytes.each_with_index do |byte , index|
|
||||
is = @should[index]
|
||||
assert_equal Fixnum , is.class , "@#{index.to_s(16)} = #{is}"
|
||||
assert_equal byte , is , "@#{index.to_s(16)} #{byte.to_s(16)} != #{is.to_s(16)}"
|
||||
end
|
||||
if( RbConfig::CONFIG["build_cpu"] == "arm")
|
||||
system "ld -N #{name}.o"
|
||||
result = %x[./a.out]
|
||||
assert_equal @output , result
|
||||
end
|
||||
end
|
||||
def bytes string
|
||||
"[" + string.bytes.collect{|b| "0x"+ b.to_s(16)}.join(",") + "]"
|
||||
end
|
||||
|
||||
end
|
@ -1,10 +0,0 @@
|
||||
|
||||
require_relative "test_foo"
|
||||
require_relative "test_if"
|
||||
require_relative "test_hello"
|
||||
require_relative "test_class"
|
||||
require_relative "test_putint"
|
||||
require_relative "test_functions"
|
||||
require_relative "test_recursive_fibo"
|
||||
require_relative "test_while_fibo"
|
||||
require_relative "test_methods"
|
@ -1,19 +0,0 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestBasicClass < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_class_basic
|
||||
@string_input = <<HERE
|
||||
class Bar
|
||||
int buh()
|
||||
return 1
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [ [Virtual::MethodEnter] ,[Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
end
|
@ -1,25 +0,0 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestFoo < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_foo2
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int foo(int x)
|
||||
int a = 5
|
||||
return a
|
||||
end
|
||||
|
||||
int main()
|
||||
foo( 4 )
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [ [Virtual::MethodEnter,Register::GetSlot,Virtual::Set,Virtual::Set,
|
||||
Virtual::Set,Virtual::Set,Virtual::MethodCall] ,[Virtual::MethodReturn] ]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
end
|
@ -1,43 +0,0 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestFunctions < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_functions
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
|
||||
int minus(int a,int b)
|
||||
return a - b
|
||||
end
|
||||
|
||||
int plus(int a, int b)
|
||||
return a + b
|
||||
end
|
||||
|
||||
int times(int a, int b)
|
||||
if( b == 0 )
|
||||
a = 0
|
||||
else
|
||||
int m = minus(b, 1)
|
||||
int t = times(a, m)
|
||||
a = plus(a,t)
|
||||
end
|
||||
end
|
||||
|
||||
int t_seven()
|
||||
int tim = times(7,6)
|
||||
tim.putint()
|
||||
end
|
||||
|
||||
int main()
|
||||
t_seven()
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter,Register::GetSlot,Virtual::Set,Virtual::Set,Virtual::MethodCall] ,
|
||||
[Virtual::MethodReturn]]
|
||||
check
|
||||
|
||||
end
|
||||
end
|
@ -1,18 +0,0 @@
|
||||
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
|
||||
@expect = [[Virtual::MethodEnter,Virtual::Set,Register::GetSlot,Virtual::Set,
|
||||
Virtual::Set,Virtual::MethodCall] ,[Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
end
|
@ -1,58 +0,0 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestIf < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_if_basic
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 10
|
||||
if( n < 12)
|
||||
return 3
|
||||
else
|
||||
return 4
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter,Virtual::Set,Virtual::Set,Register::GetSlot,
|
||||
Register::GetSlot,Register::OperatorInstruction,Register::IsZeroBranch] ,
|
||||
[Virtual::Set,Register::AlwaysBranch] ,[Virtual::Set] ,[] ,[Virtual::MethodReturn] ]
|
||||
check
|
||||
end
|
||||
|
||||
def test_return
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
return 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter,Virtual::Set] , [Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
def test_if_function
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int itest(int n)
|
||||
if( n < 12)
|
||||
"then".putstring()
|
||||
else
|
||||
"else".putstring()
|
||||
end
|
||||
end
|
||||
|
||||
int main()
|
||||
itest(20)
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [ [Virtual::MethodEnter,Register::GetSlot,Virtual::Set,Virtual::Set,
|
||||
Virtual::Set,Virtual::Set,Virtual::MethodCall] ,[Virtual::MethodReturn] ]
|
||||
check
|
||||
end
|
||||
end
|
@ -1,174 +0,0 @@
|
||||
require_relative 'helper'
|
||||
|
||||
module Virtual
|
||||
class TestMethods < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_simplest_function
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
return 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[MethodEnter,Set] ,[MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
|
||||
def test_second_simplest_function
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int x = 5
|
||||
return x
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter,Set],[Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_puts_string
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int puts(ref str)
|
||||
return str
|
||||
end
|
||||
int main()
|
||||
puts("Hello")
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[MethodEnter , Register::GetSlot, Set, Set , Set, Set, MethodCall],[MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_int_function
|
||||
@string_input = <<HERE
|
||||
class Integer < Object
|
||||
int times(int x)
|
||||
return x
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter] , [Virtual::MethodReturn]]
|
||||
check
|
||||
cla = Virtual.machine.space.get_class_by_name :Integer
|
||||
assert cla.get_instance_method( :times )
|
||||
end
|
||||
|
||||
def test_function_ops
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int foo(int abba)
|
||||
abba = 5
|
||||
2 + 5
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter] , [Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_function_if
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
if(0)
|
||||
return 42
|
||||
else
|
||||
return 667
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[MethodEnter,Set,Register::IsZeroBranch] , [Set,Register::AlwaysBranch],
|
||||
[Set],[],[MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_while
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int foo()
|
||||
while(1)
|
||||
3
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter],[Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_function_while
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int fibonaccit(int n)
|
||||
int a = 0
|
||||
while(n)
|
||||
int some = 43
|
||||
int other = some * 4
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter],[Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_function_return
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int retvar(int n)
|
||||
int i = 5
|
||||
return i
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter],[Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_function_return_if
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 10
|
||||
if( n > 5)
|
||||
return 10
|
||||
else
|
||||
return 20
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[MethodEnter,Set,Set,Register::GetSlot,Register::GetSlot,
|
||||
Register::OperatorInstruction,Register::IsZeroBranch],
|
||||
[Set,Register::AlwaysBranch],[Set],[],[MethodReturn]]
|
||||
check
|
||||
end
|
||||
|
||||
def test_function_return_while
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int main()
|
||||
int n = 10
|
||||
while( n > 5)
|
||||
n = n + 1
|
||||
return n
|
||||
end
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[MethodEnter,Set],
|
||||
[Set,Register::GetSlot,Register::GetSlot,Register::OperatorInstruction,
|
||||
Register::IsZeroBranch,Set,Register::GetSlot,Register::GetSlot,
|
||||
Register::OperatorInstruction,Set,Register::AlwaysBranch] ,
|
||||
[],[MethodReturn]]
|
||||
check
|
||||
end
|
||||
end
|
||||
end
|
@ -1,23 +0,0 @@
|
||||
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
|
||||
@expect = [ [Virtual::MethodEnter,Virtual::Set,Register::GetSlot,Virtual::Set,
|
||||
Virtual::Set,Virtual::MethodCall] ,[Virtual::MethodReturn] ]
|
||||
check
|
||||
end
|
||||
end
|
@ -1,34 +0,0 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestRecursinveFibo < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_recursive_fibo
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int fibonaccir( int n )
|
||||
if( n <= 1 )
|
||||
return n
|
||||
else
|
||||
int tmp
|
||||
tmp = n - 1
|
||||
int a = fibonaccir( tmp )
|
||||
tmp = n - 2
|
||||
int b = fibonaccir( tmp )
|
||||
return a + b
|
||||
end
|
||||
end
|
||||
int fib_print(int n)
|
||||
int fib = fibonaccir( n )
|
||||
fib.putint()
|
||||
end
|
||||
int main()
|
||||
fib_print(10)
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [[Virtual::MethodEnter,Register::GetSlot,Virtual::Set,Virtual::Set,
|
||||
Virtual::Set,Virtual::Set,Virtual::MethodCall] , [Virtual::MethodReturn]]
|
||||
check
|
||||
end
|
||||
end
|
@ -1,48 +0,0 @@
|
||||
require_relative 'helper'
|
||||
|
||||
class TestWhileFragment < MiniTest::Test
|
||||
include Fragments
|
||||
|
||||
def test_while_fibo
|
||||
@string_input = <<HERE
|
||||
class Object
|
||||
int fibonaccit(int n)
|
||||
int a = 0
|
||||
int b = 1
|
||||
while( n > 1 )
|
||||
int tmp = a
|
||||
a = b
|
||||
b = tmp + b
|
||||
n = n - 1
|
||||
end
|
||||
b.putint()
|
||||
return b
|
||||
end
|
||||
|
||||
int main()
|
||||
fibonaccit( 10 )
|
||||
end
|
||||
end
|
||||
HERE
|
||||
@expect = [ [Virtual::MethodEnter,Register::GetSlot,Virtual::Set,Virtual::Set,
|
||||
Virtual::Set,Virtual::Set,Virtual::MethodCall] ,[Virtual::MethodReturn] ]
|
||||
check
|
||||
end
|
||||
|
||||
# a hand coded version of the fibonachi numbers (moved to kernel to be able to call it)
|
||||
# not my hand off course, found in the net from a basic introduction
|
||||
def ttest_kernel_fibo
|
||||
int = Register::Integer.new(Virtual::RegisterMachine.instance.receiver_register)
|
||||
fibo = @object_space.get_class_by_name(:Object).resolve_method(:fibo)
|
||||
main = @object_space.main
|
||||
main.mov int , 10
|
||||
main.call( fibo )
|
||||
main.mov( Virtual::RegisterMachine.instance.receiver_register , Virtual::RegisterMachine.instance.return_register )
|
||||
putint = @object_space.get_class_by_name(:Object).resolve_method(:putint)
|
||||
main.call( putint )
|
||||
@should = [0x0,0x40,0x2d,0xe9,0x1,0x0,0x52,0xe3,0x2,0x0,0xa0,0xd1,0x7,0x0,0x0,0xda,0x1,0x30,0xa0,0xe3,0x0,0x40,0xa0,0xe3,0x4,0x30,0x83,0xe0,0x4,0x40,0x43,0xe0,0x1,0x20,0x42,0xe2,0x1,0x0,0x52,0xe3,0xfa,0xff,0xff,0x1a,0x3,0x0,0xa0,0xe1,0x0,0x80,0xbd,0xe8]
|
||||
@target = [:Object , :fibo]
|
||||
write "fibo"
|
||||
end
|
||||
|
||||
end
|
Reference in New Issue
Block a user