comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:a4671277546c
1 #include "tests.h"
2 #include "nbci.h"
3 #include "gtest/gtest.h"
4
5 #include "compiler.h"
6 #include "nap_runtime.h"
7
8 TEST(Simple, Printing)
9 {
10 SCRIPT_START
11 " \
12 print(\"Hello World\n\"); \
13 "
14 SCRIPT_END
15
16 SCRIPT_SHUTDOWN
17 (void)found_indicator;
18
19 }
20
21 TEST(Assembly, PushPop)
22 {
23 nap_runtime* runtime = nap_runtime_create("$");
24 ASSERT_FALSE(runtime == NULL);
25 int found_indicator;
26 nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime,
27 " \
28 int a; \
29 asm \
30 { \
31 push 23; \
32 pop global.a; \
33 } \
34 "
35 SCRIPT_END
36
37 ASSERT_EQ(23, VAR_INT(a));
38
39 SCRIPT_SHUTDOWN
40 }
41
42 TEST(Definitions, CodeBlocksWithScope)
43 {
44 SCRIPT_START
45 " \
46 int a = 1; \
47 { int c = 3;int a = 2;} \
48 int b = 2; \
49 "
50 SCRIPT_END
51 ASSERT_TRUE( 1 == VAR_INT(a));
52 ASSERT_TRUE( 2 == VAR_INT(b));
53
54 SCRIPT_SHUTDOWN
55 }
56
57 TEST(Floats, BasicRealOperations)
58 {
59 SCRIPT_START
60 " \
61 real a = 5.6; \
62 real b = a * 10; \
63 "
64 SCRIPT_END
65 double _b = (double)VAR_REAL(b);
66 ASSERT_DOUBLE_EQ((double)56.0, _b);
67
68 SCRIPT_SHUTDOWN
69 }
70
71 TEST(Operations, UnaryMathOperations)
72 {
73 SCRIPT_START
74 " \
75 int a = 5; \
76 int b = -5; \
77 int c = +b; \
78 int d = -a; \
79 int e = 3 - (-2); \
80 "
81 SCRIPT_END
82
83 ASSERT_EQ(5, VAR_INT(c));
84 ASSERT_EQ(-5, VAR_INT(d));
85 ASSERT_EQ(5, VAR_INT(e));
86
87 SCRIPT_SHUTDOWN
88
89 }
90
91 TEST(Operations, BasicIntVariableOperations)
92 {
93
94 SCRIPT_START
95 " \
96 int a; \
97 int b; \
98 int a_plus_b; \
99 int a_minus_b; \
100 int a_mul_b; \
101 int a_div_b; \
102 int a_mod_b; \
103 a = 9; \
104 b = 3; \
105 a_plus_b = a + b; \
106 a_minus_b = a - b; \
107 a_mul_b = a * b; \
108 a_div_b = a / b; \
109 a_mod_b = a % b; \
110 "
111 SCRIPT_END
112
113 ASSERT_TRUE( 9 == VAR_INT(a));
114 ASSERT_TRUE( 3 == VAR_INT(b));
115 ASSERT_TRUE(12 == VAR_INT(a_plus_b));
116 ASSERT_TRUE( 6 == VAR_INT(a_minus_b));
117 ASSERT_TRUE( 3 == VAR_INT(a_div_b));
118 ASSERT_TRUE(27 == VAR_INT(a_mul_b));
119 ASSERT_TRUE( 0 == VAR_INT(a_mod_b));
120
121 SCRIPT_SHUTDOWN
122 }
123
124 TEST(Operations, BasicBitwiseOperations)
125 {
126
127 SCRIPT_START
128 " \
129 int a1 = 1; \
130 int a2 = 2; \
131 int a3 = 3; \
132 int a4 = 1; \
133 int a5 = 2; \
134 int a6 = 2; \
135 int b1 = a1 << 1; \
136 int b2 = a2 >> 1; \
137 int b3 = a3 & 1; \
138 int b4 = a4 | 2; \
139 int b5 = a5 ^ 1; \
140 int b6 = ~a6; \
141 "
142 SCRIPT_END
143
144 ASSERT_TRUE( 2 == VAR_INT(b1));
145 ASSERT_TRUE( 1 == VAR_INT(b2));
146 ASSERT_TRUE( 1 == VAR_INT(b3));
147 ASSERT_TRUE( 3 == VAR_INT(b4));
148 ASSERT_TRUE( 3 == VAR_INT(b5));
149 ASSERT_TRUE(-3 == VAR_INT(b6));
150
151 SCRIPT_SHUTDOWN
152 }
153
154
155 TEST(Operations, BasicStringVariableOperations1)
156 {
157
158 SCRIPT_START
159 " \
160 string a = \"AA\"; \
161 string b = \"BB\"; \
162 string a_plus_b; \
163 a_plus_b = a + b; \
164 "
165 SCRIPT_END
166
167 SCRIPT_ASSERT_STREQ("AABB", a_plus_b);
168
169 SCRIPT_SHUTDOWN
170 }
171
172 TEST(Operations, BasicStringVariableOperations2)
173 {
174
175 SCRIPT_START
176 " \
177 string a = \"A\"; \
178 string b = a + \"B\"; \
179 "
180 SCRIPT_END
181
182 SCRIPT_ASSERT_STREQ("AB", b);
183
184 SCRIPT_SHUTDOWN
185 }
186
187 TEST(Operations, BasicStringVariableOperations4)
188 {
189
190 SCRIPT_START
191 " \
192 string sa = \"A\"; \
193 string sb ; \
194 asm \
195 { \
196 mov reg string(0), global.sa \
197 mov reg string(1), \"B\" \
198 add reg string(0), reg string(1) \
199 mov global.sb, reg string(0) \
200 } \
201 "
202 SCRIPT_END
203
204 SCRIPT_ASSERT_STREQ("AB", sb);
205
206 SCRIPT_SHUTDOWN
207 }
208
209 /* Define a string variable, copy out one character from it into an int register
210 see that the conversion succeeded.*/
211 TEST(Operations, BasicStringVariableOperations5)
212 {
213
214 SCRIPT_START
215 " \
216 string sa = \"A123B\"; \
217 int ib = 9; \
218 asm \
219 { \
220 mov reg idx(0), 1 \
221 mov reg int(0), @#ccidx(global.sa, 1)\
222 mov global.ib, reg int (0) \
223 } \
224 "
225 SCRIPT_END
226
227 ASSERT_EQ(1, VAR_INT(ib));
228
229 SCRIPT_SHUTDOWN
230 }
231
232 /* Define a string variable, copy out a substring from it into an int register
233 see that the conversion succeeded.*/
234 TEST(Operations, BasicStringVariableOperations6)
235 {
236
237 SCRIPT_START
238 " \
239 string sa = \"A123B\"; \
240 int ib = 9; \
241 asm \
242 { \
243 mov reg idx(0), 1 \
244 mov reg idx(1), 3 \
245 mov reg int(0), @#ccidx(global.sa, 2)\
246 mov global.ib, reg int (0) \
247 } \
248 "
249 SCRIPT_END
250
251 ASSERT_EQ(123, VAR_INT(ib));
252
253 SCRIPT_SHUTDOWN
254 }
255
256
257 TEST(Operations, BasicImmediateOperations)
258 {
259 SCRIPT_START
260 " \
261 int a_plus_b; \
262 int a_minus_b; \
263 int a_mul_b; \
264 int a_div_b; \
265 int a_mod_b; \
266 a_plus_b = 9 + 3; \
267 a_minus_b = 9 - 3; \
268 a_mul_b = 9 * 3; \
269 a_div_b = 9 / 3; \
270 a_mod_b = 9 % 3; \
271 "
272 SCRIPT_END
273
274 ASSERT_TRUE(12 == VAR_INT(a_plus_b));
275 ASSERT_TRUE( 6 == VAR_INT(a_minus_b));
276 ASSERT_TRUE( 3 == VAR_INT(a_div_b));
277 ASSERT_TRUE(27 == VAR_INT(a_mul_b));
278 ASSERT_TRUE( 0 == VAR_INT(a_mod_b));
279
280 SCRIPT_SHUTDOWN
281 }
282
283 TEST(Definitions, InvalidVariableName)
284 {
285 nap_runtime* runtime = nap_runtime_create(0);
286 ASSERT_TRUE(runtime != NULL);
287 nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime,
288 " \
289 int a_ plus_b; \
290 "
291 ,0);
292
293 ASSERT_TRUE(bytecode == NULL);
294 SCRIPT_SHUTDOWN
295 }
296
297 TEST(StringToIntConversion, DifferentBases)
298 {
299 SCRIPT_START
300 " \
301 int binary = 0; \
302 int decimal = 0; \
303 int zero = 1; \
304 int hexa = 0; \
305 int octal = 0; \
306 asm \
307 { \
308 mov reg string 0, \"9877\" \
309 mov reg int 0, reg string 0 \
310 mov global.decimal, reg int 0 \
311 mov reg string 0, \"0xABCDE\" \
312 mov reg int 0, reg string 0 \
313 mov global.hexa, reg int 0 \
314 mov reg string 0, \"0665544\" \
315 mov reg int 0, reg string 0 \
316 mov global.octal, reg int 0 \
317 mov reg string 0, \"0b1001001\" \
318 mov reg int 0, reg string 0 \
319 mov global.binary, reg int 0 \
320 mov reg string 0, \"0\" \
321 mov reg int 0, reg string 0 \
322 mov global.zero, reg int 0 \
323 } \
324 "
325 SCRIPT_END
326
327 ASSERT_TRUE(9877 == VAR_INT(decimal));
328 ASSERT_TRUE(703710 == VAR_INT(hexa));
329 ASSERT_TRUE(224100 == VAR_INT(octal));
330 ASSERT_TRUE(73 == VAR_INT(binary));
331 ASSERT_TRUE(0 == VAR_INT(zero));
332
333 SCRIPT_SHUTDOWN
334 }
335
336 TEST(Operations, PostPreIncrement)
337 {
338 SCRIPT_START
339 " \
340 int i=0; \
341 int y = i++; \
342 int z = ++i; \
343 "
344 SCRIPT_END
345
346 ASSERT_TRUE(2 == VAR_INT(i));
347 ASSERT_TRUE(0 == VAR_INT(y));
348 ASSERT_TRUE(2 == VAR_INT(z));
349
350 SCRIPT_SHUTDOWN
351 }
352
353 TEST(Keywords, Break)
354 {
355 SCRIPT_START
356 " \
357 int y = 1; \
358 for(int i = 0; i< 11; i++) \
359 { \
360 int t = y ++; \
361 if (t == 7) \
362 { \
363 break; \
364 } \
365 } \
366 "
367 SCRIPT_END
368 ASSERT_EQ(8, VAR_INT(y));
369
370 SCRIPT_SHUTDOWN
371 }
372
373 TEST(InvalidSyntax, PostPreIncMess)
374 {
375
376 nap_runtime* runtime = nap_runtime_create(0);
377 ASSERT_TRUE(runtime != NULL);
378 nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime,
379 " \
380 int z = 3; \
381 int g = z++ ++; \
382 "
383 ,0);
384
385 ASSERT_TRUE(bytecode == NULL);
386 SCRIPT_SHUTDOWN
387 }
388
389 TEST(RuntimeCompilation, SimpleCheck)
390 {
391 SCRIPT_START
392 " \
393 int a = 2; \
394 int b = 3; \
395 int c; \
396 nap_execute(\"c = a + b\"); \
397 "
398 SCRIPT_END
399
400 ASSERT_EQ(5, VAR_INT(c));
401
402 SCRIPT_SHUTDOWN
403 }
404
405 TEST(RuntimeCompilation, CompoundedExpression)
406 {
407 SCRIPT_START
408 " \
409 int a = 2; \
410 int b = 3; \
411 int c; \
412 string sa = \"c=a\"; \
413 string sb = \"+b\"; \
414 nap_execute(sa + sb); \
415 "
416 SCRIPT_END
417
418 ASSERT_EQ(5, VAR_INT(c));
419
420 SCRIPT_SHUTDOWN
421 }
422
423 /*
424 * TESTS FOR FUNCTIONS AND THEIR ASSOCIATED BEHAVIOUR
425 */
426
427 /* Define a function returning an in which takes in an int parameter. Return the
428 next value of the parameter (ie: par + 1). Check in the calling code the
429 value. */
430 TEST(Functions, SimpleFunctionCall)
431 {
432 SCRIPT_START
433 " \
434 int func(int a) \
435 { \
436 return a + 1; \
437 } \
438 int a = 5; \
439 a = func(a); \
440 "
441 SCRIPT_END
442
443 ASSERT_EQ(6, VAR_INT(a));
444
445 SCRIPT_SHUTDOWN;
446 }
447
448 /* Define a function returning and int. Do not put return statements in the body.
449 * Use the function, see that it returns the default return value (0).
450 */
451 TEST(Functions, DefaultReturnValue)
452 {
453 SCRIPT_START
454 " \
455 int func() \
456 { \
457 } \
458 int z = func(); \
459 "
460 SCRIPT_END
461 ASSERT_EQ(0, VAR_INT(z));
462
463 SCRIPT_SHUTDOWN
464 }
465
466 /* Define an external function, also implement it in the test file.
467 * Use the function, see that it does not fail.
468 */
469 TEST(Functions, ExternalCalling)
470 {
471 nap_runtime* runtime = nap_runtime_create("a");
472 ASSERT_FALSE(runtime == NULL);
473
474 int found_indicator;
475 nap_bytecode_chunk* bytecode = nap_runtime_compile(runtime, " \
476 extern void external_callee(int, int); \
477 external_callee(1,2); \
478 "
479 ,0);
480 ASSERT_FALSE(bytecode == NULL);
481 nap_runtime_execute(runtime, bytecode);
482 SCRIPT_SHUTDOWN
483
484 UNUSED(found_indicator);
485 }
486
487 /* Define a function with an int reference as parameter. Assign a value to
488 * the parameter in the function body and see that the caller gets modified */
489 TEST(Functions, IntReference)
490 {
491 SCRIPT_START
492 " \
493 void func(int& a) \
494 { \
495 a = 6; \
496 } \
497 int z = 7; func(z); \
498 "
499 SCRIPT_END
500 ASSERT_EQ(6, VAR_INT(z));
501
502 SCRIPT_SHUTDOWN
503 }
504
505 /* Define a function with an byte reference as parameter. Assign a value to
506 * the parameter in the function body and see that the caller gets modified */
507 TEST(Functions, ByteReference)
508 {
509 SCRIPT_START
510 " \
511 void func(byte& a) \
512 { \
513 a = 6; \
514 } \
515 byte z = 7; func(z); \
516 "
517 SCRIPT_END
518 ASSERT_EQ(6, VAR_BYTE(z));
519
520 SCRIPT_SHUTDOWN
521 }
522
523 /* Define a function with an real reference as parameter. Assign a value to
524 * the parameter in the function body and see that the caller gets modified */
525 TEST(Functions, RealReference)
526 {
527 SCRIPT_START
528 " \
529 void func(real& a) \
530 { \
531 a = 6.7; \
532 } \
533 real z = 7.8; func(z); \
534 "
535 SCRIPT_END
536 double _z = (double)VAR_REAL(z);
537 ASSERT_DOUBLE_EQ((double)6.7, _z);
538 SCRIPT_SHUTDOWN
539 }
540
541 /* Define a function with a real array as parameter. Assign a value to
542 * the parameter in the function body and see that the caller does not get
543 * modified */
544 TEST(Functions, RealArray)
545 {
546 SCRIPT_START
547 " \
548 void func(real a[]) \
549 { \
550 a[0] = 6.7; \
551 } \
552 real z[10]; \
553 z[0] = 7.8; func(z); \
554 real b = z[0]; \
555 "
556 SCRIPT_END
557 double _b = (double)VAR_REAL(b);
558 ASSERT_DOUBLE_EQ((double)7.8, _b);
559 SCRIPT_SHUTDOWN
560 }
561
562 /* Define a function with an int array as parameter. Assign a value to
563 * the parameter in the function body and see that the caller does not get
564 * modified */
565 TEST(Functions, IntArray)
566 {
567 SCRIPT_START
568 " \
569 void func(int a[]) \
570 { \
571 a[0] = 6; \
572 } \
573 int z[10]; \
574 z[0] = 8; func(z); \
575 int b = z[0]; \
576 "
577 SCRIPT_END
578 ASSERT_EQ(8, VAR_INT(b));
579
580 SCRIPT_SHUTDOWN
581 }
582
583 /* Define a function with a byte array as parameter. Assign a value to
584 * the parameter in the function body and see that the caller does not get
585 * modified */
586 TEST(Functions, ByteArray)
587 {
588 SCRIPT_START
589 " \
590 void func(byte a[]) \
591 { \
592 a[0] = 6; \
593 } \
594 byte z[10]; \
595 z[0] = 8; func(z); \
596 byte b = z[0]; \
597 "
598 SCRIPT_END
599 ASSERT_EQ(8, VAR_BYTE(b));
600
601 SCRIPT_SHUTDOWN
602 }
603
604 /* Define a function with a byte array reference parameter. Assign a value to
605 * the parameter in the function body and see that the caller does get
606 * modified */
607 TEST(Functions, ByteArrayReference)
608 {
609 SCRIPT_START
610 " \
611 void func(byte& a[]) \
612 { \
613 a[0] = 6; \
614 } \
615 byte z[10]; \
616 z[0] = 8; func(z); \
617 byte b = z[0]; \
618 "
619 SCRIPT_END
620 ASSERT_EQ(6, VAR_BYTE(b));
621
622 SCRIPT_SHUTDOWN
623 }
624
625 /* Define a function with an int array reference parameter. Assign a value to
626 * the parameter in the function body and see that the caller does get
627 * modified */
628 TEST(Functions, IntArrayReference)
629 {
630 SCRIPT_START
631 " \
632 void func(int& a[]) \
633 { \
634 a[0] = 6; \
635 } \
636 int z[10]; \
637 z[0] = 8; func(z); \
638 int b = z[0]; \
639 "
640 SCRIPT_END
641 ASSERT_EQ(6, VAR_INT(b));
642
643 SCRIPT_SHUTDOWN
644 }
645
646 /* Define a function with a real array as parameter. Assign a value to
647 * the parameter in the function body and see that the caller does not get
648 * modified */
649 TEST(Functions, RealArrayReference)
650 {
651 SCRIPT_START
652 " \
653 void func(real& a[]) \
654 { \
655 a[0] = 6.7; \
656 } \
657 real z[10]; \
658 z[0] = 7.8; func(z); \
659 real b = z[0]; \
660 "
661 SCRIPT_END
662 double _b = (double)VAR_REAL(b);
663 ASSERT_DOUBLE_EQ((double)6.7, _b);
664 SCRIPT_SHUTDOWN
665 }
666
667 TEST(General, FibonacciAsIntArrayReference)
668 {
669 SCRIPT_START
670 " \
671 void fibo1(int& res[], int n) \
672 { \
673 int first = 0, second = 1, next, c; \
674 int i = 0; \
675 for ( c = 0 ; c < n ; c++ ) \
676 { \
677 if ( c <= 1 ) \
678 next = c; \
679 else \
680 { \
681 next = first + second; \
682 first = second; \
683 second = next; \
684 } \
685 res[i++] = next; \
686 } \
687 } \
688 \
689 int cnt = 20, i; \
690 \
691 int fib_it[cnt]; \
692 fibo1(fib_it, fib_it.len()); \
693 int a = fib_it[9]; \
694 "
695 SCRIPT_END
696 ASSERT_EQ(34, VAR_INT(a));
697
698 SCRIPT_SHUTDOWN
699 }
700
701
702 /*
703 * Push an int, peek an int variable
704 */
705 TEST(PushPeek, Ints)
706 {
707 SCRIPT_START
708 " \
709 int a; \
710 asm \
711 { \
712 push 23; \
713 peek int 0 global.a; \
714 } \
715 "
716 SCRIPT_END
717 ASSERT_EQ(23, VAR_INT(a));
718
719 SCRIPT_SHUTDOWN
720 }
721
722
723 NAP_EXPORTS
724 void external_callee(nap_int_t a, nap_int_t b)
725 {
726 printf("%" PRINT_d " %" PRINT_d "\n", a, b);
727 if(a != 1 || b != 2) FAIL();
728 }
729
730 TEST(FeatureTable, RegisterIntToRegisterXAndRegisterXToVariableX)
731 {
732 SCRIPT_START
733 " \
734 int iv = 1; \
735 real vrv = 1.0; \
736 string sv = \"1\"; \
737 byte bv = 1; \
738 asm \
739 { \
740 mov reg int 0, 5; \
741 /* RI->RI */ \
742 mov reg int 1, reg int 0; \
743 /* RI->VI */ \
744 mov global.iv, reg int 1; \
745 /* RI->RR */ \
746 mov reg real 0, reg int 0; \
747 /* RR->VR */ \
748 mov global.vrv, reg real 0; \
749 /* RI->RB */ \
750 mov reg byte 0, reg int 0; \
751 /* RB->VB */ \
752 mov global.bv, reg byte 0; \
753 /* RI-> RS*/ \
754 mov reg string 0, reg int 0; \
755 /* RS->VS */ \
756 mov global.sv, reg string 0; \
757 } \
758 "
759 SCRIPT_END
760 ASSERT_EQ(5, VAR_INT(iv));
761 ASSERT_EQ(5, VAR_BYTE(bv));
762
763 double vrv = (double)VAR_REAL(vrv);
764 ASSERT_DOUBLE_EQ((double)5.0, vrv);
765
766 SCRIPT_ASSERT_STREQ("5", sv);
767
768
769 SCRIPT_SHUTDOWN
770 }
771
772
773 TEST(FeatureTable, RegisterByteToRegisterX)
774 {
775 SCRIPT_START
776 " \
777 int iv = 1; \
778 real vrv = 1.0; \
779 string sv = \"1\"; \
780 byte bv = 1; \
781 asm \
782 { \
783 mov reg byte 0, 5; \
784 /* RB->RI */ \
785 mov reg int 0, reg byte 0; \
786 mov global.iv, reg int 0; \
787 /* RB->RR */ \
788 mov reg real 0, reg byte 0; \
789 mov global.vrv, reg real 0; \
790 /* RB->RB */ \
791 mov reg byte 1, reg byte 0; \
792 mov global.bv, reg byte 1; \
793 /* RB-> RS*/ \
794 mov reg string 0, reg byte 0; \
795 mov global.sv, reg string 0; \
796 } \
797 "
798 SCRIPT_END
799 ASSERT_EQ(5, VAR_INT(iv));
800 ASSERT_EQ(5, VAR_BYTE(bv));
801
802 double vrv = (double)VAR_REAL(vrv);
803 ASSERT_DOUBLE_EQ((double)5.0, vrv);
804
805 SCRIPT_ASSERT_STREQ("5", sv);
806
807
808 SCRIPT_SHUTDOWN
809 }
810
811 TEST(FeatureTable, DISABLED_RegisterRealToRegisterX)
812 {
813 SCRIPT_START
814 " \
815 int iv = 1; \
816 real vrv = 1.0; \
817 string sv = \"1\"; \
818 byte bv = 1; \
819 asm \
820 { \
821 mov reg real 0, 5.0; \
822 /* RR->RI */ \
823 mov reg int 0, reg real 0; \
824 mov global.iv, reg int 0; \
825 /* RR->RR */ \
826 mov reg real 1, reg real 0; \
827 mov global.vrv, reg real 1; \
828 /* RR->RB */ \
829 mov reg byte 1, reg real 0; \
830 mov global.bv, reg byte 1; \
831 /* RR-> RS*/ \
832 mov reg string 0, reg real 0; \
833 mov global.sv, reg string 0; \
834 } \
835 "
836 SCRIPT_END
837 ASSERT_EQ(5, VAR_INT(iv));
838 ASSERT_EQ(5, VAR_BYTE(bv));
839
840 double vrv = (double)VAR_REAL(vrv);
841 ASSERT_DOUBLE_EQ((double)5.0, vrv);
842
843 SCRIPT_ASSERT_STREQ("5", sv);
844
845
846 SCRIPT_SHUTDOWN
847 }