Mercurial > thymian
diff tests/scripttest.cpp @ 0:a4671277546c tip
created the repository for the thymian project
| author | ferencd |
|---|---|
| date | Tue, 17 Aug 2021 11:19:54 +0200 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/scripttest.cpp Tue Aug 17 11:19:54 2021 +0200 @@ -0,0 +1,847 @@ +#include "tests.h" +#include "nbci.h" +#include "gtest/gtest.h" + +#include "compiler.h" +#include "nap_runtime.h" + +TEST(Simple, Printing) +{ + SCRIPT_START + " \ + print(\"Hello World\n\"); \ + " + SCRIPT_END + + SCRIPT_SHUTDOWN + (void)found_indicator; + +} + +TEST(Assembly, PushPop) +{ + nap_runtime* runtime = nap_runtime_create("$"); + ASSERT_FALSE(runtime == NULL); + int found_indicator; + nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, + " \ + int a; \ + asm \ + { \ + push 23; \ + pop global.a; \ + } \ + " + SCRIPT_END + + ASSERT_EQ(23, VAR_INT(a)); + + SCRIPT_SHUTDOWN +} + +TEST(Definitions, CodeBlocksWithScope) +{ + SCRIPT_START + " \ + int a = 1; \ + { int c = 3;int a = 2;} \ + int b = 2; \ + " + SCRIPT_END + ASSERT_TRUE( 1 == VAR_INT(a)); + ASSERT_TRUE( 2 == VAR_INT(b)); + + SCRIPT_SHUTDOWN +} + +TEST(Floats, BasicRealOperations) +{ + SCRIPT_START + " \ + real a = 5.6; \ + real b = a * 10; \ + " + SCRIPT_END + double _b = (double)VAR_REAL(b); + ASSERT_DOUBLE_EQ((double)56.0, _b); + + SCRIPT_SHUTDOWN +} + +TEST(Operations, UnaryMathOperations) +{ + SCRIPT_START + " \ + int a = 5; \ + int b = -5; \ + int c = +b; \ + int d = -a; \ + int e = 3 - (-2); \ + " + SCRIPT_END + + ASSERT_EQ(5, VAR_INT(c)); + ASSERT_EQ(-5, VAR_INT(d)); + ASSERT_EQ(5, VAR_INT(e)); + + SCRIPT_SHUTDOWN + +} + +TEST(Operations, BasicIntVariableOperations) +{ + + SCRIPT_START + " \ + int a; \ + int b; \ + int a_plus_b; \ + int a_minus_b; \ + int a_mul_b; \ + int a_div_b; \ + int a_mod_b; \ + a = 9; \ + b = 3; \ + a_plus_b = a + b; \ + a_minus_b = a - b; \ + a_mul_b = a * b; \ + a_div_b = a / b; \ + a_mod_b = a % b; \ + " + SCRIPT_END + + ASSERT_TRUE( 9 == VAR_INT(a)); + ASSERT_TRUE( 3 == VAR_INT(b)); + ASSERT_TRUE(12 == VAR_INT(a_plus_b)); + ASSERT_TRUE( 6 == VAR_INT(a_minus_b)); + ASSERT_TRUE( 3 == VAR_INT(a_div_b)); + ASSERT_TRUE(27 == VAR_INT(a_mul_b)); + ASSERT_TRUE( 0 == VAR_INT(a_mod_b)); + + SCRIPT_SHUTDOWN +} + +TEST(Operations, BasicBitwiseOperations) +{ + + SCRIPT_START + " \ + int a1 = 1; \ + int a2 = 2; \ + int a3 = 3; \ + int a4 = 1; \ + int a5 = 2; \ + int a6 = 2; \ + int b1 = a1 << 1; \ + int b2 = a2 >> 1; \ + int b3 = a3 & 1; \ + int b4 = a4 | 2; \ + int b5 = a5 ^ 1; \ + int b6 = ~a6; \ + " + SCRIPT_END + + ASSERT_TRUE( 2 == VAR_INT(b1)); + ASSERT_TRUE( 1 == VAR_INT(b2)); + ASSERT_TRUE( 1 == VAR_INT(b3)); + ASSERT_TRUE( 3 == VAR_INT(b4)); + ASSERT_TRUE( 3 == VAR_INT(b5)); + ASSERT_TRUE(-3 == VAR_INT(b6)); + + SCRIPT_SHUTDOWN +} + + +TEST(Operations, BasicStringVariableOperations1) +{ + + SCRIPT_START + " \ + string a = \"AA\"; \ + string b = \"BB\"; \ + string a_plus_b; \ + a_plus_b = a + b; \ + " + SCRIPT_END + + SCRIPT_ASSERT_STREQ("AABB", a_plus_b); + + SCRIPT_SHUTDOWN +} + +TEST(Operations, BasicStringVariableOperations2) +{ + + SCRIPT_START + " \ + string a = \"A\"; \ + string b = a + \"B\"; \ + " + SCRIPT_END + + SCRIPT_ASSERT_STREQ("AB", b); + + SCRIPT_SHUTDOWN +} + +TEST(Operations, BasicStringVariableOperations4) +{ + + SCRIPT_START + " \ + string sa = \"A\"; \ + string sb ; \ + asm \ + { \ + mov reg string(0), global.sa \ + mov reg string(1), \"B\" \ + add reg string(0), reg string(1) \ + mov global.sb, reg string(0) \ + } \ + " + SCRIPT_END + + SCRIPT_ASSERT_STREQ("AB", sb); + + SCRIPT_SHUTDOWN +} + +/* Define a string variable, copy out one character from it into an int register + see that the conversion succeeded.*/ +TEST(Operations, BasicStringVariableOperations5) +{ + + SCRIPT_START + " \ + string sa = \"A123B\"; \ + int ib = 9; \ + asm \ + { \ + mov reg idx(0), 1 \ + mov reg int(0), @#ccidx(global.sa, 1)\ + mov global.ib, reg int (0) \ + } \ + " + SCRIPT_END + + ASSERT_EQ(1, VAR_INT(ib)); + + SCRIPT_SHUTDOWN +} + +/* Define a string variable, copy out a substring from it into an int register + see that the conversion succeeded.*/ +TEST(Operations, BasicStringVariableOperations6) +{ + + SCRIPT_START + " \ + string sa = \"A123B\"; \ + int ib = 9; \ + asm \ + { \ + mov reg idx(0), 1 \ + mov reg idx(1), 3 \ + mov reg int(0), @#ccidx(global.sa, 2)\ + mov global.ib, reg int (0) \ + } \ + " + SCRIPT_END + + ASSERT_EQ(123, VAR_INT(ib)); + + SCRIPT_SHUTDOWN +} + + +TEST(Operations, BasicImmediateOperations) +{ + SCRIPT_START + " \ + int a_plus_b; \ + int a_minus_b; \ + int a_mul_b; \ + int a_div_b; \ + int a_mod_b; \ + a_plus_b = 9 + 3; \ + a_minus_b = 9 - 3; \ + a_mul_b = 9 * 3; \ + a_div_b = 9 / 3; \ + a_mod_b = 9 % 3; \ + " + SCRIPT_END + + ASSERT_TRUE(12 == VAR_INT(a_plus_b)); + ASSERT_TRUE( 6 == VAR_INT(a_minus_b)); + ASSERT_TRUE( 3 == VAR_INT(a_div_b)); + ASSERT_TRUE(27 == VAR_INT(a_mul_b)); + ASSERT_TRUE( 0 == VAR_INT(a_mod_b)); + + SCRIPT_SHUTDOWN +} + +TEST(Definitions, InvalidVariableName) +{ + nap_runtime* runtime = nap_runtime_create(0); + ASSERT_TRUE(runtime != NULL); + nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, + " \ + int a_ plus_b; \ + " + ,0); + + ASSERT_TRUE(bytecode == NULL); + SCRIPT_SHUTDOWN +} + +TEST(StringToIntConversion, DifferentBases) +{ + SCRIPT_START + " \ + int binary = 0; \ + int decimal = 0; \ + int zero = 1; \ + int hexa = 0; \ + int octal = 0; \ + asm \ + { \ + mov reg string 0, \"9877\" \ + mov reg int 0, reg string 0 \ + mov global.decimal, reg int 0 \ + mov reg string 0, \"0xABCDE\" \ + mov reg int 0, reg string 0 \ + mov global.hexa, reg int 0 \ + mov reg string 0, \"0665544\" \ + mov reg int 0, reg string 0 \ + mov global.octal, reg int 0 \ + mov reg string 0, \"0b1001001\" \ + mov reg int 0, reg string 0 \ + mov global.binary, reg int 0 \ + mov reg string 0, \"0\" \ + mov reg int 0, reg string 0 \ + mov global.zero, reg int 0 \ + } \ + " + SCRIPT_END + + ASSERT_TRUE(9877 == VAR_INT(decimal)); + ASSERT_TRUE(703710 == VAR_INT(hexa)); + ASSERT_TRUE(224100 == VAR_INT(octal)); + ASSERT_TRUE(73 == VAR_INT(binary)); + ASSERT_TRUE(0 == VAR_INT(zero)); + + SCRIPT_SHUTDOWN +} + +TEST(Operations, PostPreIncrement) +{ + SCRIPT_START + " \ + int i=0; \ + int y = i++; \ + int z = ++i; \ + " + SCRIPT_END + + ASSERT_TRUE(2 == VAR_INT(i)); + ASSERT_TRUE(0 == VAR_INT(y)); + ASSERT_TRUE(2 == VAR_INT(z)); + + SCRIPT_SHUTDOWN +} + +TEST(Keywords, Break) +{ + SCRIPT_START + " \ + int y = 1; \ + for(int i = 0; i< 11; i++) \ + { \ + int t = y ++; \ + if (t == 7) \ + { \ + break; \ + } \ + } \ + " + SCRIPT_END + ASSERT_EQ(8, VAR_INT(y)); + + SCRIPT_SHUTDOWN +} + +TEST(InvalidSyntax, PostPreIncMess) +{ + + nap_runtime* runtime = nap_runtime_create(0); + ASSERT_TRUE(runtime != NULL); + nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, + " \ + int z = 3; \ + int g = z++ ++; \ + " + ,0); + + ASSERT_TRUE(bytecode == NULL); + SCRIPT_SHUTDOWN +} + +TEST(RuntimeCompilation, SimpleCheck) +{ + SCRIPT_START + " \ + int a = 2; \ + int b = 3; \ + int c; \ + nap_execute(\"c = a + b\"); \ + " + SCRIPT_END + + ASSERT_EQ(5, VAR_INT(c)); + + SCRIPT_SHUTDOWN +} + +TEST(RuntimeCompilation, CompoundedExpression) +{ + SCRIPT_START + " \ + int a = 2; \ + int b = 3; \ + int c; \ + string sa = \"c=a\"; \ + string sb = \"+b\"; \ + nap_execute(sa + sb); \ + " + SCRIPT_END + + ASSERT_EQ(5, VAR_INT(c)); + + SCRIPT_SHUTDOWN +} + +/* + * TESTS FOR FUNCTIONS AND THEIR ASSOCIATED BEHAVIOUR + */ + +/* Define a function returning an in which takes in an int parameter. Return the + next value of the parameter (ie: par + 1). Check in the calling code the + value. */ +TEST(Functions, SimpleFunctionCall) +{ + SCRIPT_START + " \ + int func(int a) \ + { \ + return a + 1; \ + } \ + int a = 5; \ + a = func(a); \ + " + SCRIPT_END + + ASSERT_EQ(6, VAR_INT(a)); + + SCRIPT_SHUTDOWN; +} + +/* Define a function returning and int. Do not put return statements in the body. + * Use the function, see that it returns the default return value (0). + */ +TEST(Functions, DefaultReturnValue) +{ + SCRIPT_START + " \ + int func() \ + { \ + } \ + int z = func(); \ + " + SCRIPT_END + ASSERT_EQ(0, VAR_INT(z)); + + SCRIPT_SHUTDOWN +} + +/* Define an external function, also implement it in the test file. + * Use the function, see that it does not fail. + */ +TEST(Functions, ExternalCalling) +{ + nap_runtime* runtime = nap_runtime_create("a"); + ASSERT_FALSE(runtime == NULL); + + int found_indicator; + nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, " \ + extern void external_callee(int, int); \ + external_callee(1,2); \ + " + ,0); + ASSERT_FALSE(bytecode == NULL); + nap_runtime_execute(runtime, bytecode); + SCRIPT_SHUTDOWN + + UNUSED(found_indicator); +} + +/* Define a function with an int reference as parameter. Assign a value to + * the parameter in the function body and see that the caller gets modified */ +TEST(Functions, IntReference) +{ + SCRIPT_START + " \ + void func(int& a) \ + { \ + a = 6; \ + } \ + int z = 7; func(z); \ + " + SCRIPT_END + ASSERT_EQ(6, VAR_INT(z)); + + SCRIPT_SHUTDOWN +} + +/* Define a function with an byte reference as parameter. Assign a value to + * the parameter in the function body and see that the caller gets modified */ +TEST(Functions, ByteReference) +{ + SCRIPT_START + " \ + void func(byte& a) \ + { \ + a = 6; \ + } \ + byte z = 7; func(z); \ + " + SCRIPT_END + ASSERT_EQ(6, VAR_BYTE(z)); + + SCRIPT_SHUTDOWN +} + +/* Define a function with an real reference as parameter. Assign a value to + * the parameter in the function body and see that the caller gets modified */ +TEST(Functions, RealReference) +{ + SCRIPT_START + " \ + void func(real& a) \ + { \ + a = 6.7; \ + } \ + real z = 7.8; func(z); \ + " + SCRIPT_END + double _z = (double)VAR_REAL(z); + ASSERT_DOUBLE_EQ((double)6.7, _z); + SCRIPT_SHUTDOWN +} + +/* Define a function with a real array as parameter. Assign a value to + * the parameter in the function body and see that the caller does not get + * modified */ +TEST(Functions, RealArray) +{ + SCRIPT_START + " \ + void func(real a[]) \ + { \ + a[0] = 6.7; \ + } \ + real z[10]; \ + z[0] = 7.8; func(z); \ + real b = z[0]; \ + " + SCRIPT_END + double _b = (double)VAR_REAL(b); + ASSERT_DOUBLE_EQ((double)7.8, _b); + SCRIPT_SHUTDOWN +} + +/* Define a function with an int array as parameter. Assign a value to + * the parameter in the function body and see that the caller does not get + * modified */ +TEST(Functions, IntArray) +{ + SCRIPT_START + " \ + void func(int a[]) \ + { \ + a[0] = 6; \ + } \ + int z[10]; \ + z[0] = 8; func(z); \ + int b = z[0]; \ + " + SCRIPT_END + ASSERT_EQ(8, VAR_INT(b)); + + SCRIPT_SHUTDOWN +} + +/* Define a function with a byte array as parameter. Assign a value to + * the parameter in the function body and see that the caller does not get + * modified */ +TEST(Functions, ByteArray) +{ + SCRIPT_START + " \ + void func(byte a[]) \ + { \ + a[0] = 6; \ + } \ + byte z[10]; \ + z[0] = 8; func(z); \ + byte b = z[0]; \ + " + SCRIPT_END + ASSERT_EQ(8, VAR_BYTE(b)); + + SCRIPT_SHUTDOWN +} + +/* Define a function with a byte array reference parameter. Assign a value to + * the parameter in the function body and see that the caller does get + * modified */ +TEST(Functions, ByteArrayReference) +{ + SCRIPT_START + " \ + void func(byte& a[]) \ + { \ + a[0] = 6; \ + } \ + byte z[10]; \ + z[0] = 8; func(z); \ + byte b = z[0]; \ + " + SCRIPT_END + ASSERT_EQ(6, VAR_BYTE(b)); + + SCRIPT_SHUTDOWN +} + +/* Define a function with an int array reference parameter. Assign a value to + * the parameter in the function body and see that the caller does get + * modified */ +TEST(Functions, IntArrayReference) +{ + SCRIPT_START + " \ + void func(int& a[]) \ + { \ + a[0] = 6; \ + } \ + int z[10]; \ + z[0] = 8; func(z); \ + int b = z[0]; \ + " + SCRIPT_END + ASSERT_EQ(6, VAR_INT(b)); + + SCRIPT_SHUTDOWN +} + +/* Define a function with a real array as parameter. Assign a value to + * the parameter in the function body and see that the caller does not get + * modified */ +TEST(Functions, RealArrayReference) +{ + SCRIPT_START + " \ + void func(real& a[]) \ + { \ + a[0] = 6.7; \ + } \ + real z[10]; \ + z[0] = 7.8; func(z); \ + real b = z[0]; \ + " + SCRIPT_END + double _b = (double)VAR_REAL(b); + ASSERT_DOUBLE_EQ((double)6.7, _b); + SCRIPT_SHUTDOWN +} + +TEST(General, FibonacciAsIntArrayReference) +{ + SCRIPT_START + " \ + void fibo1(int& res[], int n) \ + { \ + int first = 0, second = 1, next, c; \ + int i = 0; \ + for ( c = 0 ; c < n ; c++ ) \ + { \ + if ( c <= 1 ) \ + next = c; \ + else \ + { \ + next = first + second; \ + first = second; \ + second = next; \ + } \ + res[i++] = next; \ + } \ + } \ + \ + int cnt = 20, i; \ + \ + int fib_it[cnt]; \ + fibo1(fib_it, fib_it.len()); \ + int a = fib_it[9]; \ + " + SCRIPT_END + ASSERT_EQ(34, VAR_INT(a)); + + SCRIPT_SHUTDOWN +} + + +/* + * Push an int, peek an int variable + */ +TEST(PushPeek, Ints) +{ + SCRIPT_START + " \ + int a; \ + asm \ + { \ + push 23; \ + peek int 0 global.a; \ + } \ + " + SCRIPT_END + ASSERT_EQ(23, VAR_INT(a)); + + SCRIPT_SHUTDOWN +} + + +NAP_EXPORTS +void external_callee(nap_int_t a, nap_int_t b) +{ + printf("%" PRINT_d " %" PRINT_d "\n", a, b); + if(a != 1 || b != 2) FAIL(); +} + +TEST(FeatureTable, RegisterIntToRegisterXAndRegisterXToVariableX) +{ + SCRIPT_START + " \ + int iv = 1; \ + real vrv = 1.0; \ + string sv = \"1\"; \ + byte bv = 1; \ + asm \ + { \ + mov reg int 0, 5; \ + /* RI->RI */ \ + mov reg int 1, reg int 0; \ + /* RI->VI */ \ + mov global.iv, reg int 1; \ + /* RI->RR */ \ + mov reg real 0, reg int 0; \ + /* RR->VR */ \ + mov global.vrv, reg real 0; \ + /* RI->RB */ \ + mov reg byte 0, reg int 0; \ + /* RB->VB */ \ + mov global.bv, reg byte 0; \ + /* RI-> RS*/ \ + mov reg string 0, reg int 0; \ + /* RS->VS */ \ + mov global.sv, reg string 0; \ + } \ + " + SCRIPT_END + ASSERT_EQ(5, VAR_INT(iv)); + ASSERT_EQ(5, VAR_BYTE(bv)); + + double vrv = (double)VAR_REAL(vrv); + ASSERT_DOUBLE_EQ((double)5.0, vrv); + + SCRIPT_ASSERT_STREQ("5", sv); + + + SCRIPT_SHUTDOWN +} + + +TEST(FeatureTable, RegisterByteToRegisterX) +{ + SCRIPT_START + " \ + int iv = 1; \ + real vrv = 1.0; \ + string sv = \"1\"; \ + byte bv = 1; \ + asm \ + { \ + mov reg byte 0, 5; \ + /* RB->RI */ \ + mov reg int 0, reg byte 0; \ + mov global.iv, reg int 0; \ + /* RB->RR */ \ + mov reg real 0, reg byte 0; \ + mov global.vrv, reg real 0; \ + /* RB->RB */ \ + mov reg byte 1, reg byte 0; \ + mov global.bv, reg byte 1; \ + /* RB-> RS*/ \ + mov reg string 0, reg byte 0; \ + mov global.sv, reg string 0; \ + } \ + " + SCRIPT_END + ASSERT_EQ(5, VAR_INT(iv)); + ASSERT_EQ(5, VAR_BYTE(bv)); + + double vrv = (double)VAR_REAL(vrv); + ASSERT_DOUBLE_EQ((double)5.0, vrv); + + SCRIPT_ASSERT_STREQ("5", sv); + + + SCRIPT_SHUTDOWN +} + +TEST(FeatureTable, DISABLED_RegisterRealToRegisterX) +{ + SCRIPT_START + " \ + int iv = 1; \ + real vrv = 1.0; \ + string sv = \"1\"; \ + byte bv = 1; \ + asm \ + { \ + mov reg real 0, 5.0; \ + /* RR->RI */ \ + mov reg int 0, reg real 0; \ + mov global.iv, reg int 0; \ + /* RR->RR */ \ + mov reg real 1, reg real 0; \ + mov global.vrv, reg real 1; \ + /* RR->RB */ \ + mov reg byte 1, reg real 0; \ + mov global.bv, reg byte 1; \ + /* RR-> RS*/ \ + mov reg string 0, reg real 0; \ + mov global.sv, reg string 0; \ + } \ + " + SCRIPT_END + ASSERT_EQ(5, VAR_INT(iv)); + ASSERT_EQ(5, VAR_BYTE(bv)); + + double vrv = (double)VAR_REAL(vrv); + ASSERT_DOUBLE_EQ((double)5.0, vrv); + + SCRIPT_ASSERT_STREQ("5", sv); + + + SCRIPT_SHUTDOWN +}
