/[svn]/linuxsampler/trunk/src/scriptvm/tests/NKSPCoreLangTest.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/scriptvm/tests/NKSPCoreLangTest.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

linuxsampler/trunk/src/scriptvm/tests/NKSPTest.cpp revision 3551 by schoenebeck, Thu Aug 1 10:22:56 2019 UTC linuxsampler/trunk/src/scriptvm/tests/NKSPCoreLangTest.cpp revision 3790 by schoenebeck, Sun Jun 14 14:29:41 2020 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2019 Christian Schoenebeck   * Copyright (c) 2019 - 2020 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 12  Line 12 
12    
13  #include "../../common/global.h"  #include "../../common/global.h"
14  #include "../../common/optional.h"  #include "../../common/optional.h"
15    #include "../../common/RTMath.h"
16  #include "../ScriptVM.h"  #include "../ScriptVM.h"
17  #include "../common.h"  #include "../common.h"
18  #include <sstream>  #include <sstream>
# Line 30  using namespace std; Line 31  using namespace std;
31  struct RunScriptOpt {  struct RunScriptOpt {
32      String code;      String code;
33      bool expectParseError;      bool expectParseError;
34        bool expectParseWarning;
35      bool expectRuntimeError;      bool expectRuntimeError;
36      bool expectNoExitResult;      bool expectNoExitResult;
37        bool expectExitResultIsInt;
38        bool expectExitResultIsReal;
39      bool prohibitExitFunctionArguments;      bool prohibitExitFunctionArguments;
40      optional<int> expectIntExitResult;      optional<vmint> expectIntExitResult;
41      optional<bool> expectBoolExitResult;      optional<bool> expectBoolExitResult;
42        optional<vmfloat> expectRealExitResult;
43      optional<String> expectStringExitResult;      optional<String> expectStringExitResult;
44        vector<MetricPrefix_t> expectExitResultUnitPrefix;
45        optional<StdUnit_t> expectExitResultUnit;
46        optional<bool> expectExitResultFinal;
47  };  };
48    
49  static void runScript(const RunScriptOpt& opt) {  static void runScript(const RunScriptOpt& opt) {
# Line 47  static void runScript(const RunScriptOpt Line 55  static void runScript(const RunScriptOpt
55          vm.loadScript(opt.code)          vm.loadScript(opt.code)
56      );      );
57      vector<ParserIssue> errors = parserCtx->errors();      vector<ParserIssue> errors = parserCtx->errors();
58        vector<ParserIssue> warnings = parserCtx->warnings();
59      if (opt.expectParseError) {      if (opt.expectParseError) {
60          TEST_ASSERT(!errors.empty());          TEST_ASSERT(!errors.empty());
61          return;          return;
# Line 56  static void runScript(const RunScriptOpt Line 65  static void runScript(const RunScriptOpt
65          }          }
66          TEST_ASSERT(errors.empty());          TEST_ASSERT(errors.empty());
67      }      }
68        if (opt.expectParseWarning) {
69            TEST_ASSERT(!warnings.empty());
70        } else {
71            for (ParserIssue& wrn : warnings) {
72                wrn.dump();
73            }
74        }
75      TEST_ASSERT(parserCtx->eventHandler(0));      TEST_ASSERT(parserCtx->eventHandler(0));
76      unique_ptr<VMExecContext> execCtx(      unique_ptr<VMExecContext> execCtx(
77          vm.createExecContext(&*parserCtx)          vm.createExecContext(&*parserCtx)
# Line 72  static void runScript(const RunScriptOpt Line 88  static void runScript(const RunScriptOpt
88              VMExpr* resExpr = execCtx->exitResult();              VMExpr* resExpr = execCtx->exitResult();
89              TEST_ASSERT(!resExpr);              TEST_ASSERT(!resExpr);
90          }          }
91            if (opt.expectExitResultIsInt) {
92                VMExpr* resExpr = execCtx->exitResult();
93                TEST_ASSERT(resExpr);
94                TEST_ASSERT(resExpr->exprType() == INT_EXPR);
95            }
96            if (opt.expectExitResultIsReal) {
97                VMExpr* resExpr = execCtx->exitResult();
98                TEST_ASSERT(resExpr);
99                TEST_ASSERT(resExpr->exprType() == REAL_EXPR);
100            }
101          if (opt.expectIntExitResult) {          if (opt.expectIntExitResult) {
102              VMExpr* resExpr = execCtx->exitResult();              VMExpr* resExpr = execCtx->exitResult();
103              TEST_ASSERT(resExpr);              TEST_ASSERT(resExpr);
104              TEST_ASSERT(resExpr->exprType() == INT_EXPR);              TEST_ASSERT(resExpr->exprType() == INT_EXPR);
105              TEST_ASSERT(resExpr->asInt()->evalInt() == *opt.expectIntExitResult);              TEST_ASSERT(resExpr->asInt()->evalInt() == *opt.expectIntExitResult);
106          }          }
107            if (opt.expectRealExitResult) {
108                VMExpr* resExpr = execCtx->exitResult();
109                TEST_ASSERT(resExpr);
110                TEST_ASSERT(resExpr->exprType() == REAL_EXPR);
111                if (sizeof(vmfloat) == sizeof(float)) {
112                    TEST_ASSERT(RTMath::fEqual32(resExpr->asReal()->evalReal(), *opt.expectRealExitResult));
113                } else {
114                    TEST_ASSERT(RTMath::fEqual64(resExpr->asReal()->evalReal(), *opt.expectRealExitResult));
115                }
116            }
117          if (opt.expectBoolExitResult) {          if (opt.expectBoolExitResult) {
118              VMExpr* resExpr = execCtx->exitResult();              VMExpr* resExpr = execCtx->exitResult();
119              TEST_ASSERT(resExpr);              TEST_ASSERT(resExpr);
# Line 90  static void runScript(const RunScriptOpt Line 126  static void runScript(const RunScriptOpt
126              TEST_ASSERT(resExpr->exprType() == STRING_EXPR);              TEST_ASSERT(resExpr->exprType() == STRING_EXPR);
127              TEST_ASSERT(resExpr->asString()->evalStr() == *opt.expectStringExitResult);              TEST_ASSERT(resExpr->asString()->evalStr() == *opt.expectStringExitResult);
128          }          }
129            if (opt.expectExitResultUnit) {
130                VMExpr* resExpr = execCtx->exitResult();
131                TEST_ASSERT(resExpr);
132                VMNumberExpr* numberExpr = resExpr->asNumber();
133                TEST_ASSERT(numberExpr);
134                TEST_ASSERT(numberExpr->unitType() == *opt.expectExitResultUnit);
135            }
136            if (!opt.expectExitResultUnitPrefix.empty()) {
137                VMExpr* resExpr = execCtx->exitResult();
138                TEST_ASSERT(resExpr);
139                VMNumberExpr* numberExpr = resExpr->asNumber();
140                TEST_ASSERT(numberExpr);
141                auto prefixes = opt.expectExitResultUnitPrefix;
142                if (*prefixes.rbegin() != VM_NO_PREFIX)
143                    prefixes.push_back(VM_NO_PREFIX); // VM_NO_PREFIX termination required by unitFactr() call
144                vmfloat expectedFactor = VMUnit::unitFactor(&prefixes[0]);
145                vmfloat actualFactor = numberExpr->unitFactor();
146                if (sizeof(vmfloat) == sizeof(float)) {
147                    TEST_ASSERT(RTMath::fEqual32(expectedFactor, actualFactor));
148                } else {
149                    TEST_ASSERT(RTMath::fEqual64(expectedFactor, actualFactor));
150                }
151            }
152            if (opt.expectExitResultFinal) {
153                VMExpr* resExpr = execCtx->exitResult();
154                TEST_ASSERT(resExpr);
155                VMNumberExpr* numberExpr = resExpr->asNumber();
156                TEST_ASSERT(numberExpr);
157                TEST_ASSERT(numberExpr->isFinal() == *opt.expectExitResultFinal);
158            }
159      }      }
160  }  }
161    
# Line 124  end on Line 190  end on
190          .expectNoExitResult = true          .expectNoExitResult = true
191      });      });
192    
193        // integer tests ...
194    
195      runScript({      runScript({
196          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
197  on init  on init
# Line 158  end on Line 226  end on
226          .expectIntExitResult = 99          .expectIntExitResult = 99
227      });      });
228    
229        // string tests ...
230    
231      runScript({      runScript({
232          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
233  on init  on init
# Line 179  end on Line 249  end on
249          .prohibitExitFunctionArguments = true // simulate production environment          .prohibitExitFunctionArguments = true // simulate production environment
250      });      });
251    
252        // real number tests ...
253    
254        runScript({
255            .code = R"NKSP_CODE(
256    on init
257      exit(3.14)
258    end on
259    )NKSP_CODE",
260            .expectRealExitResult = 3.14
261        });
262    
263        runScript({
264            .code = R"NKSP_CODE(
265    on init
266      declare $foo := 1
267      if ($foo)
268        exit(3.14)
269      end if
270    end on
271    )NKSP_CODE",
272            .expectRealExitResult = 3.14
273        });
274    
275        runScript({
276            .code = R"NKSP_CODE(
277    on init
278      declare $foo := 0
279      if ($foo)
280        exit(3.14)
281      end if
282      exit(6.9)
283    end on
284    )NKSP_CODE",
285            .expectRealExitResult = 6.9
286        });
287    
288        // int array tests ...
289    
290        runScript({
291            .code = R"NKSP_CODE(
292    on init
293      declare %foo[3]
294      %foo[0] := 21
295      exit(%foo[0])
296    end on
297    )NKSP_CODE",
298            .expectIntExitResult = 21
299        });
300    
301        runScript({
302            .code = R"NKSP_CODE(
303    on init
304      declare %foo[3] := ( 12, 23, 34 )
305      exit(%foo[0])
306    end on
307    )NKSP_CODE",
308            .expectIntExitResult = 12
309        });
310    
311        runScript({
312            .code = R"NKSP_CODE(
313    on init
314      declare %foo[3] := ( 12, 23, 34 )
315      exit(%foo[1])
316    end on
317    )NKSP_CODE",
318            .expectIntExitResult = 23
319        });
320    
321        runScript({
322            .code = R"NKSP_CODE(
323    on init
324      declare %foo[3] := ( 12, 23, 34 )
325      exit(%foo[2])
326    end on
327    )NKSP_CODE",
328            .expectIntExitResult = 34
329        });
330    
331        runScript({ // make sure array is entirely initialized with zeroes
332            .code = R"NKSP_CODE(
333    on init
334      declare $i
335      declare $result
336      declare %foo[100]
337      while ($i < 100)
338          $result := $result .or. %foo[$i]
339          inc($i)
340      end while
341      exit($result)
342    end on
343    )NKSP_CODE",
344            .expectIntExitResult = 0
345        });
346    
347        // real array tests ...
348    
349        runScript({
350            .code = R"NKSP_CODE(
351    on init
352      declare ?foo[3]
353      ?foo[0] := 34.9
354      exit(?foo[0])
355    end on
356    )NKSP_CODE",
357            .expectRealExitResult = 34.9
358        });
359    
360        runScript({
361            .code = R"NKSP_CODE(
362    on init
363      declare ?foo[3] := ( 0.3, 23.5, 900.1 )
364      exit(?foo[0])
365    end on
366    )NKSP_CODE",
367            .expectRealExitResult = 0.3
368        });
369    
370        runScript({
371            .code = R"NKSP_CODE(
372    on init
373      declare ?foo[3] := ( 0.3, 23.5, 900.1 )
374      exit(?foo[1])
375    end on
376    )NKSP_CODE",
377            .expectRealExitResult = 23.5
378        });
379    
380        runScript({
381            .code = R"NKSP_CODE(
382    on init
383      declare ?foo[3] := ( 0.3, 23.5, 900.1 )
384      exit(?foo[2])
385    end on
386    )NKSP_CODE",
387            .expectRealExitResult = 900.1
388        });
389    
390        runScript({ // make sure array is entirely initialized with zeroes
391            .code = R"NKSP_CODE(
392    on init
393      declare $i
394      declare ?foo[100]
395      while ($i < 100)
396          if (?foo[$i] # 0.0)
397            exit(-1) { test failed }
398          end if
399          inc($i)
400      end while
401      exit(0) { test succeeded }
402    end on
403    )NKSP_CODE",
404            .expectIntExitResult = 0
405        });
406    
407        // std unit tests ...
408    
409        runScript({
410            .code = R"NKSP_CODE(
411    on init
412      exit(42s)
413    end on
414    )NKSP_CODE",
415            .expectIntExitResult = 42,
416            .expectExitResultUnit = VM_SECOND
417        });
418    
419        runScript({
420            .code = R"NKSP_CODE(
421    on init
422      exit(42Hz)
423    end on
424    )NKSP_CODE",
425            .expectIntExitResult = 42,
426            .expectExitResultUnit = VM_HERTZ
427        });
428    
429        runScript({
430            .code = R"NKSP_CODE(
431    on init
432      exit(42B)
433    end on
434    )NKSP_CODE",
435            .expectIntExitResult = 42,
436            .expectExitResultUnit = VM_BEL
437        });
438    
439        runScript({
440            .code = R"NKSP_CODE(
441    on init
442      exit(42us)
443    end on
444    )NKSP_CODE",
445            .expectIntExitResult = 42,
446            .expectExitResultUnitPrefix = { VM_MICRO },
447            .expectExitResultUnit = VM_SECOND
448        });
449    
450        runScript({
451            .code = R"NKSP_CODE(
452    on init
453      exit(42ms)
454    end on
455    )NKSP_CODE",
456            .expectIntExitResult = 42,
457            .expectExitResultUnitPrefix = { VM_MILLI },
458            .expectExitResultUnit = VM_SECOND
459        });
460    
461        runScript({
462            .code = R"NKSP_CODE(
463    on init
464      exit(42cs)
465    end on
466    )NKSP_CODE",
467            .expectIntExitResult = 42,
468            .expectExitResultUnitPrefix = { VM_CENTI },
469            .expectExitResultUnit = VM_SECOND
470        });
471    
472        runScript({
473            .code = R"NKSP_CODE(
474    on init
475      exit(42ds)
476    end on
477    )NKSP_CODE",
478            .expectIntExitResult = 42,
479            .expectExitResultUnitPrefix = { VM_DECI },
480            .expectExitResultUnit = VM_SECOND
481        });
482    
483        runScript({
484            .code = R"NKSP_CODE(
485    on init
486      exit(42das)
487    end on
488    )NKSP_CODE",
489            .expectIntExitResult = 42,
490            .expectExitResultUnitPrefix = { VM_DECA },
491            .expectExitResultUnit = VM_SECOND
492        });
493    
494        runScript({
495            .code = R"NKSP_CODE(
496    on init
497      exit(42hs)
498    end on
499    )NKSP_CODE",
500            .expectIntExitResult = 42,
501            .expectExitResultUnitPrefix = { VM_HECTO },
502            .expectExitResultUnit = VM_SECOND
503        });
504    
505        runScript({
506            .code = R"NKSP_CODE(
507    on init
508      exit(42ks)
509    end on
510    )NKSP_CODE",
511            .expectIntExitResult = 42,
512            .expectExitResultUnitPrefix = { VM_KILO },
513            .expectExitResultUnit = VM_SECOND
514        });
515    
516        runScript({
517            .code = R"NKSP_CODE(
518    on init
519      exit(42s)
520    end on
521    )NKSP_CODE",
522            .expectIntExitResult = 42,
523            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
524            .expectExitResultUnit = VM_SECOND
525        });
526    
527        runScript({
528            .code = R"NKSP_CODE(
529    on init
530      exit(42uHz)
531    end on
532    )NKSP_CODE",
533            .expectIntExitResult = 42,
534            .expectExitResultUnitPrefix = { VM_MICRO },
535            .expectExitResultUnit = VM_HERTZ
536        });
537    
538        runScript({
539            .code = R"NKSP_CODE(
540    on init
541      exit(42mHz)
542    end on
543    )NKSP_CODE",
544            .expectIntExitResult = 42,
545            .expectExitResultUnitPrefix = { VM_MILLI },
546            .expectExitResultUnit = VM_HERTZ
547        });
548    
549        runScript({
550            .code = R"NKSP_CODE(
551    on init
552      exit(42cHz)
553    end on
554    )NKSP_CODE",
555            .expectIntExitResult = 42,
556            .expectExitResultUnitPrefix = { VM_CENTI },
557            .expectExitResultUnit = VM_HERTZ
558        });
559    
560        runScript({
561            .code = R"NKSP_CODE(
562    on init
563      exit(42dHz)
564    end on
565    )NKSP_CODE",
566            .expectIntExitResult = 42,
567            .expectExitResultUnitPrefix = { VM_DECI },
568            .expectExitResultUnit = VM_HERTZ
569        });
570    
571        runScript({
572            .code = R"NKSP_CODE(
573    on init
574      exit(42daHz)
575    end on
576    )NKSP_CODE",
577            .expectIntExitResult = 42,
578            .expectExitResultUnitPrefix = { VM_DECA },
579            .expectExitResultUnit = VM_HERTZ
580        });
581    
582        runScript({
583            .code = R"NKSP_CODE(
584    on init
585      exit(42hHz)
586    end on
587    )NKSP_CODE",
588            .expectIntExitResult = 42,
589            .expectExitResultUnitPrefix = { VM_HECTO },
590            .expectExitResultUnit = VM_HERTZ
591        });
592    
593        runScript({
594            .code = R"NKSP_CODE(
595    on init
596      exit(42kHz)
597    end on
598    )NKSP_CODE",
599            .expectIntExitResult = 42,
600            .expectExitResultUnitPrefix = { VM_KILO },
601            .expectExitResultUnit = VM_HERTZ
602        });
603    
604        runScript({
605            .code = R"NKSP_CODE(
606    on init
607      exit(42Hz)
608    end on
609    )NKSP_CODE",
610            .expectIntExitResult = 42,
611            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
612            .expectExitResultUnit = VM_HERTZ
613        });
614    
615        runScript({
616            .code = R"NKSP_CODE(
617    on init
618      exit(42uB)
619    end on
620    )NKSP_CODE",
621            .expectIntExitResult = 42,
622            .expectExitResultUnitPrefix = { VM_MICRO },
623            .expectExitResultUnit = VM_BEL
624        });
625    
626        runScript({
627            .code = R"NKSP_CODE(
628    on init
629      exit(42mB)
630    end on
631    )NKSP_CODE",
632            .expectIntExitResult = 42,
633            .expectExitResultUnitPrefix = { VM_MILLI },
634            .expectExitResultUnit = VM_BEL
635        });
636    
637        runScript({
638            .code = R"NKSP_CODE(
639    on init
640      exit(42cB)
641    end on
642    )NKSP_CODE",
643            .expectIntExitResult = 42,
644            .expectExitResultUnitPrefix = { VM_CENTI },
645            .expectExitResultUnit = VM_BEL
646        });
647    
648        runScript({
649            .code = R"NKSP_CODE(
650    on init
651      exit(42dB)
652    end on
653    )NKSP_CODE",
654            .expectIntExitResult = 42,
655            .expectExitResultUnitPrefix = { VM_DECI },
656            .expectExitResultUnit = VM_BEL
657        });
658    
659        runScript({
660            .code = R"NKSP_CODE(
661    on init
662      exit(42daB)
663    end on
664    )NKSP_CODE",
665            .expectIntExitResult = 42,
666            .expectExitResultUnitPrefix = { VM_DECA },
667            .expectExitResultUnit = VM_BEL
668        });
669    
670        runScript({
671            .code = R"NKSP_CODE(
672    on init
673      exit(42hB)
674    end on
675    )NKSP_CODE",
676            .expectIntExitResult = 42,
677            .expectExitResultUnitPrefix = { VM_HECTO },
678            .expectExitResultUnit = VM_BEL
679        });
680    
681        runScript({
682            .code = R"NKSP_CODE(
683    on init
684      exit(42kB)
685    end on
686    )NKSP_CODE",
687            .expectIntExitResult = 42,
688            .expectExitResultUnitPrefix = { VM_KILO },
689            .expectExitResultUnit = VM_BEL
690        });
691    
692        runScript({
693            .code = R"NKSP_CODE(
694    on init
695      exit(42B)
696    end on
697    )NKSP_CODE",
698            .expectIntExitResult = 42,
699            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
700            .expectExitResultUnit = VM_BEL
701        });
702    
703        runScript({
704            .code = R"NKSP_CODE(
705    on init
706      exit(42udB)
707    end on
708    )NKSP_CODE",
709            .expectIntExitResult = 42,
710            .expectExitResultUnitPrefix = { VM_MICRO, VM_DECI },
711            .expectExitResultUnit = VM_BEL
712        });
713    
714        runScript({
715            .code = R"NKSP_CODE(
716    on init
717      exit(42mdB)
718    end on
719    )NKSP_CODE",
720            .expectIntExitResult = 42,
721            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
722            .expectExitResultUnit = VM_BEL
723        });
724    
725        runScript({
726            .code = R"NKSP_CODE(
727    on init
728      exit(42cdB)
729    end on
730    )NKSP_CODE",
731            .expectIntExitResult = 42,
732            .expectExitResultUnitPrefix = { VM_CENTI, VM_DECI },
733            .expectExitResultUnit = VM_BEL
734        });
735    
736        runScript({
737            .code = R"NKSP_CODE(
738    on init
739      exit(42ddB)
740    end on
741    )NKSP_CODE",
742            .expectIntExitResult = 42,
743            .expectExitResultUnitPrefix = { VM_DECI, VM_DECI },
744            .expectExitResultUnit = VM_BEL
745        });
746    
747        runScript({
748            .code = R"NKSP_CODE(
749    on init
750      exit(42dadB)
751    end on
752    )NKSP_CODE",
753            .expectIntExitResult = 42,
754            .expectExitResultUnitPrefix = { VM_DECA, VM_DECI },
755            .expectExitResultUnit = VM_BEL
756        });
757    
758        runScript({
759            .code = R"NKSP_CODE(
760    on init
761      exit(42hdB)
762    end on
763    )NKSP_CODE",
764            .expectIntExitResult = 42,
765            .expectExitResultUnitPrefix = { VM_HECTO, VM_DECI },
766            .expectExitResultUnit = VM_BEL
767        });
768    
769        runScript({
770            .code = R"NKSP_CODE(
771    on init
772      exit(42kdB)
773    end on
774    )NKSP_CODE",
775            .expectIntExitResult = 42,
776            .expectExitResultUnitPrefix = { VM_KILO, VM_DECI },
777            .expectExitResultUnit = VM_BEL
778        });
779    
780        runScript({
781            .code = R"NKSP_CODE(
782    on init
783      declare $foo := 42mdB
784      exit($foo)
785    end on
786    )NKSP_CODE",
787            .expectIntExitResult = 42,
788            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
789            .expectExitResultUnit = VM_BEL
790        });
791    
792        runScript({
793            .code = R"NKSP_CODE(
794    on init
795      exit(3.14s)
796    end on
797    )NKSP_CODE",
798            .expectRealExitResult = 3.14,
799            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
800            .expectExitResultUnit = VM_SECOND
801        });
802    
803        runScript({
804            .code = R"NKSP_CODE(
805    on init
806      exit(3.14us)
807    end on
808    )NKSP_CODE",
809            .expectRealExitResult = 3.14,
810            .expectExitResultUnitPrefix = { VM_MICRO },
811            .expectExitResultUnit = VM_SECOND
812        });
813    
814        runScript({
815            .code = R"NKSP_CODE(
816    on init
817      exit(3.14ms)
818    end on
819    )NKSP_CODE",
820            .expectRealExitResult = 3.14,
821            .expectExitResultUnitPrefix = { VM_MILLI },
822            .expectExitResultUnit = VM_SECOND
823        });
824    
825        runScript({
826            .code = R"NKSP_CODE(
827    on init
828      exit(-0.1B)
829    end on
830    )NKSP_CODE",
831            .expectRealExitResult = -0.1,
832            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
833            .expectExitResultUnit = VM_BEL
834        });
835    
836        runScript({
837            .code = R"NKSP_CODE(
838    on init
839      exit(-0.1dB)
840    end on
841    )NKSP_CODE",
842            .expectRealExitResult = -0.1,
843            .expectExitResultUnitPrefix = { VM_DECI },
844            .expectExitResultUnit = VM_BEL
845        });
846    
847        runScript({
848            .code = R"NKSP_CODE(
849    on init
850      exit(-0.1mdB)
851    end on
852    )NKSP_CODE",
853            .expectRealExitResult = -0.1,
854            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
855            .expectExitResultUnit = VM_BEL
856        });
857    
858        runScript({
859            .code = R"NKSP_CODE(
860    on init
861      declare ~foo := -0.1mdB
862      exit(~foo)
863    end on
864    )NKSP_CODE",
865            .expectRealExitResult = -0.1,
866            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
867            .expectExitResultUnit = VM_BEL
868        });
869    
870        runScript({
871            .code = R"NKSP_CODE(
872    on init
873      declare ~foo := 0.0dB
874      ~foo := -0.1mdB
875      exit(~foo)
876    end on
877    )NKSP_CODE",
878            .expectRealExitResult = -0.1,
879            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
880            .expectExitResultUnit = VM_BEL
881        });
882    
883        runScript({
884            .code = R"NKSP_CODE(
885    on init
886      declare ~foo := 0.0dB
887      ~foo := -0.1Hz
888      exit(~foo)
889    end on
890    )NKSP_CODE",
891            .expectParseError = true // assigning different unit type to a variable is not allowed
892        });
893    
894        // 'final' ('!') operator tests ...
895    
896        runScript({
897            .code = R"NKSP_CODE(
898    on init
899      exit(!42)
900    end on
901    )NKSP_CODE",
902            .expectIntExitResult = 42,
903            .expectExitResultFinal = true
904        });
905    
906        runScript({
907            .code = R"NKSP_CODE(
908    on init
909      exit(42)
910    end on
911    )NKSP_CODE",
912            .expectIntExitResult = 42,
913            .expectExitResultFinal = false
914        });
915    
916        runScript({
917            .code = R"NKSP_CODE(
918    on init
919      declare $foo := !42
920      exit($foo)
921    end on
922    )NKSP_CODE",
923            .expectIntExitResult = 42,
924            .expectExitResultFinal = true
925        });
926    
927        runScript({
928            .code = R"NKSP_CODE(
929    on init
930      declare $foo := 42
931      exit($foo)
932    end on
933    )NKSP_CODE",
934            .expectIntExitResult = 42,
935            .expectExitResultFinal = false
936        });
937    
938        runScript({
939            .code = R"NKSP_CODE(
940    on init
941      declare ~foo := !3.14
942      exit(~foo)
943    end on
944    )NKSP_CODE",
945            .expectRealExitResult = 3.14,
946            .expectExitResultFinal = true
947        });
948    
949        runScript({
950            .code = R"NKSP_CODE(
951    on init
952      declare ~foo := 3.14
953      exit(~foo)
954    end on
955    )NKSP_CODE",
956            .expectRealExitResult = 3.14,
957            .expectExitResultFinal = false
958        });
959    
960        runScript({
961            .code = R"NKSP_CODE(
962    on init
963      declare ~foo := !3.14mdB
964      exit(~foo)
965    end on
966    )NKSP_CODE",
967            .expectRealExitResult = 3.14,
968            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
969            .expectExitResultUnit = VM_BEL,
970            .expectExitResultFinal = true
971        });
972    
973        runScript({
974            .code = R"NKSP_CODE(
975    on init
976      declare ~foo := !0.0mdB
977      ~foo := !3.14mdB
978      exit(~foo)
979    end on
980    )NKSP_CODE",
981            .expectRealExitResult = 3.14,
982            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
983            .expectExitResultUnit = VM_BEL,
984            .expectExitResultFinal = true
985        });
986    
987        runScript({
988            .code = R"NKSP_CODE(
989    on init
990      declare ~foo := !0.0mdB
991      ~foo := 3.14mdB
992      exit(~foo)
993    end on
994    )NKSP_CODE",
995            .expectParseError = true // assigning non-final to a final variable not allowed
996        });
997    
998        runScript({
999            .code = R"NKSP_CODE(
1000    on init
1001      declare ~foo := 0.0mdB
1002      ~foo := !3.14mdB
1003      exit(~foo)
1004    end on
1005    )NKSP_CODE",
1006            .expectParseError = true // assigning final to a non-final variable not allowed
1007        });
1008    
1009      #if !SILENT_TEST      #if !SILENT_TEST
1010      std::cout << std::endl;      std::cout << std::endl;
1011      #endif      #endif
# Line 189  static void testStringConcatOperator() { Line 1016  static void testStringConcatOperator() {
1016      std::cout << "UNIT TEST: string concatenation (&) operator\n";      std::cout << "UNIT TEST: string concatenation (&) operator\n";
1017      #endif      #endif
1018    
1019        // strings only tests ...
1020    
1021      runScript({      runScript({
1022          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
1023  on init  on init
# Line 199  end on Line 1028  end on
1028          .expectStringExitResult = "foo bar"          .expectStringExitResult = "foo bar"
1029      });      });
1030    
1031        // integer tests ...
1032    
1033      runScript({      runScript({
1034          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
1035  on init  on init
# Line 220  end on Line 1051  end on
1051          .expectStringExitResult = "foo bar 123"          .expectStringExitResult = "foo bar 123"
1052      });      });
1053    
1054        // real number tests ...
1055    
1056        runScript({
1057            .code = R"NKSP_CODE(
1058    on init
1059      declare @s := "foo" & " bar" & " " & 1.23
1060      exit(@s)
1061    end on
1062    )NKSP_CODE",
1063            .expectStringExitResult = "foo bar 1.23"
1064        });
1065    
1066        runScript({
1067            .code = R"NKSP_CODE(
1068    on init
1069      declare ~r := 3.14
1070      declare @s := "foo" & " bar" & " " & ~r
1071      exit(@s)
1072    end on
1073    )NKSP_CODE",
1074            .expectStringExitResult = "foo bar 3.14"
1075        });
1076    
1077        // std unit tests ...
1078    
1079        runScript({
1080            .code = R"NKSP_CODE(
1081    on init
1082      declare $i := 500Hz
1083      declare @s := "foo" & " bar" & " " & $i
1084      exit(@s)
1085    end on
1086    )NKSP_CODE",
1087            .expectStringExitResult = "foo bar 500Hz"
1088        });
1089    
1090        runScript({
1091            .code = R"NKSP_CODE(
1092    on init
1093      declare ~r := 3.14s
1094      declare @s := "foo" & " bar" & " " & ~r
1095      exit(@s)
1096    end on
1097    )NKSP_CODE",
1098            .expectStringExitResult = "foo bar 3.14s"
1099        });
1100    
1101        runScript({
1102            .code = R"NKSP_CODE(
1103    on init
1104      declare ~r := -22.3mdB
1105      declare @s := "foo" & " bar" & " " & ~r
1106      exit(@s)
1107    end on
1108    )NKSP_CODE",
1109            .expectStringExitResult = "foo bar -22.3mdB"
1110        });
1111    
1112        runScript({
1113            .code = R"NKSP_CODE(
1114    on init
1115      declare $i := 20us
1116      declare @s := "foo" & " bar" & " " & $i
1117      exit(@s)
1118    end on
1119    )NKSP_CODE",
1120            .expectStringExitResult = "foo bar 20us"
1121        });
1122    
1123        runScript({
1124            .code = R"NKSP_CODE(
1125    on init
1126      declare $i := 20kHz
1127      declare @s := "foo" & " bar" & " " & $i
1128      exit(@s)
1129    end on
1130    )NKSP_CODE",
1131            .expectStringExitResult = "foo bar 20kHz"
1132        });
1133    
1134        runScript({
1135            .code = R"NKSP_CODE(
1136    on init
1137      declare $i := -6dB
1138      declare @s := "foo" & " bar" & " " & $i
1139      exit(@s)
1140    end on
1141    )NKSP_CODE",
1142            .expectStringExitResult = "foo bar -6dB"
1143        });
1144    
1145        runScript({
1146            .code = R"NKSP_CODE(
1147    on init
1148      declare $i := 1us * 1d
1149      declare @s := "foo" & " bar" & " " & $i
1150      exit(@s)
1151    end on
1152    )NKSP_CODE",
1153            .expectStringExitResult = "foo bar 1*10^-7s"
1154        });
1155    
1156        runScript({
1157            .code = R"NKSP_CODE(
1158    on init
1159      declare ~r := 12.4mc
1160      declare @s := "foo" & " bar" & " " & ~r
1161      exit(@s)
1162    end on
1163    )NKSP_CODE",
1164            .expectStringExitResult = "foo bar 12.4mc"
1165        });
1166    
1167        #if !SILENT_TEST
1168        std::cout << std::endl;
1169        #endif
1170    }
1171    
1172    static void testNegOperator() {
1173        #if !SILENT_TEST
1174        std::cout << "UNIT TEST: negate (-) operator\n";
1175        #endif
1176    
1177        // integer tests ...
1178    
1179        runScript({
1180            .code = R"NKSP_CODE(
1181    on init
1182      exit(-87)
1183    end on
1184    )NKSP_CODE",
1185            .expectIntExitResult = -87
1186        });
1187    
1188        runScript({
1189            .code = R"NKSP_CODE(
1190    on init
1191      declare $foo := -87
1192      exit(-$foo)
1193    end on
1194    )NKSP_CODE",
1195            .expectIntExitResult = 87
1196        });
1197    
1198        // real number tests ...
1199    
1200        runScript({
1201            .code = R"NKSP_CODE(
1202    on init
1203      exit(-99.3)
1204    end on
1205    )NKSP_CODE",
1206            .expectRealExitResult = -99.3
1207        });
1208    
1209        runScript({
1210            .code = R"NKSP_CODE(
1211    on init
1212      declare ~foo := -99.3
1213      exit(-~foo)
1214    end on
1215    )NKSP_CODE",
1216            .expectRealExitResult = 99.3
1217        });
1218    
1219        // std unit tests
1220    
1221        runScript({
1222            .code = R"NKSP_CODE(
1223    on init
1224      declare $foo := -87mdB
1225      exit(-$foo)
1226    end on
1227    )NKSP_CODE",
1228            .expectIntExitResult = 87,
1229            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
1230            .expectExitResultUnit = VM_BEL
1231        });
1232    
1233        // 'final' ('!') operator tests ...
1234    
1235        runScript({
1236            .code = R"NKSP_CODE(
1237    on init
1238      declare $foo := !-87
1239      exit(-$foo)
1240    end on
1241    )NKSP_CODE",
1242            .expectIntExitResult = 87,
1243            .expectExitResultFinal = true
1244        });
1245    
1246        runScript({
1247            .code = R"NKSP_CODE(
1248    on init
1249      declare $foo := -87
1250      exit(-$foo)
1251    end on
1252    )NKSP_CODE",
1253            .expectIntExitResult = 87,
1254            .expectExitResultFinal = false
1255        });
1256    
1257        //TODO: the following are unary '+' operator tests which should be moved to their own function (lazy me).
1258    
1259        runScript({
1260            .code = R"NKSP_CODE(
1261    on init
1262      exit(+54)
1263    end on
1264    )NKSP_CODE",
1265            .expectIntExitResult = 54
1266        });
1267    
1268        runScript({
1269            .code = R"NKSP_CODE(
1270    on init
1271      declare $foo := +54
1272      exit( $foo )
1273    end on
1274    )NKSP_CODE",
1275            .expectIntExitResult = 54
1276        });
1277    
1278        runScript({
1279            .code = R"NKSP_CODE(
1280    on init
1281      exit(+0.45)
1282    end on
1283    )NKSP_CODE",
1284            .expectRealExitResult = 0.45
1285        });
1286    
1287        runScript({
1288            .code = R"NKSP_CODE(
1289    on init
1290      declare ~foo := +0.29
1291      exit( ~foo )
1292    end on
1293    )NKSP_CODE",
1294            .expectRealExitResult = 0.29
1295        });
1296    
1297      #if !SILENT_TEST      #if !SILENT_TEST
1298      std::cout << std::endl;      std::cout << std::endl;
1299      #endif      #endif
# Line 230  static void testPlusOperator() { Line 1304  static void testPlusOperator() {
1304      std::cout << "UNIT TEST: plus (+) operator\n";      std::cout << "UNIT TEST: plus (+) operator\n";
1305      #endif      #endif
1306    
1307        // integer tests ...
1308    
1309      runScript({      runScript({
1310          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
1311  on init  on init
# Line 257  end on Line 1333  end on
1333          .expectIntExitResult = -2          .expectIntExitResult = -2
1334      });      });
1335    
1336        // real number tests ...
1337    
1338        runScript({
1339            .code = R"NKSP_CODE(
1340    on init
1341      exit(4.0 + 3.0)
1342    end on
1343    )NKSP_CODE",
1344            .expectRealExitResult = 7.0
1345        });
1346    
1347        runScript({
1348            .code = R"NKSP_CODE(
1349    on init
1350      exit(42.3 + 145.2)
1351    end on
1352    )NKSP_CODE",
1353            .expectRealExitResult = 187.5
1354        });
1355    
1356        runScript({
1357            .code = R"NKSP_CODE(
1358    on init
1359      exit(-4.0 + 2.2)
1360    end on
1361    )NKSP_CODE",
1362            .expectRealExitResult = -1.8
1363        });
1364    
1365        // std unit tests ...
1366    
1367        runScript({
1368            .code = R"NKSP_CODE(
1369    on init
1370      exit(42ms + 145ms)
1371    end on
1372    )NKSP_CODE",
1373            .expectIntExitResult = 187,
1374            .expectExitResultUnitPrefix = { VM_MILLI },
1375            .expectExitResultUnit = VM_SECOND
1376        });
1377    
1378        runScript({
1379            .code = R"NKSP_CODE(
1380    on init
1381      exit(1s + 145ms)
1382    end on
1383    )NKSP_CODE",
1384            .expectIntExitResult = 1145,
1385            .expectExitResultUnitPrefix = { VM_MILLI },
1386            .expectExitResultUnit = VM_SECOND
1387        });
1388    
1389        runScript({
1390            .code = R"NKSP_CODE(
1391    on init
1392      exit(42ms + 145)
1393    end on
1394    )NKSP_CODE",
1395            .expectParseError = true // units must match for + operator
1396        });
1397    
1398        runScript({
1399            .code = R"NKSP_CODE(
1400    on init
1401      exit(42 + 145ms)
1402    end on
1403    )NKSP_CODE",
1404            .expectParseError = true // units must match for + operator
1405        });
1406    
1407        runScript({
1408            .code = R"NKSP_CODE(
1409    on init
1410      exit(42Hz + 145s)
1411    end on
1412    )NKSP_CODE",
1413            .expectParseError = true // units must match for + operator
1414        });
1415    
1416        runScript({
1417            .code = R"NKSP_CODE(
1418    on init
1419      exit(42.1ms + 145.3ms)
1420    end on
1421    )NKSP_CODE",
1422            .expectRealExitResult = 187.4,
1423            .expectExitResultUnitPrefix = { VM_MILLI },
1424            .expectExitResultUnit = VM_SECOND
1425        });
1426    
1427        runScript({
1428            .code = R"NKSP_CODE(
1429    on init
1430      exit(1.1s + 145.0ms)
1431    end on
1432    )NKSP_CODE",
1433            .expectRealExitResult = 1245.0,
1434            .expectExitResultUnitPrefix = { VM_MILLI },
1435            .expectExitResultUnit = VM_SECOND
1436        });
1437    
1438        runScript({
1439            .code = R"NKSP_CODE(
1440    on init
1441      exit(42.1ms + 145.3)
1442    end on
1443    )NKSP_CODE",
1444            .expectParseError = true // units must match for + operator
1445        });
1446    
1447        runScript({
1448            .code = R"NKSP_CODE(
1449    on init
1450      exit(42.0 + 145.0ms)
1451    end on
1452    )NKSP_CODE",
1453            .expectParseError = true // units must match for + operator
1454        });
1455    
1456        runScript({
1457            .code = R"NKSP_CODE(
1458    on init
1459      exit(42.0Hz + 145.0s)
1460    end on
1461    )NKSP_CODE",
1462            .expectParseError = true // units must match for + operator
1463        });
1464    
1465        // 'final' ('!') operator tests ...
1466    
1467        runScript({
1468            .code = R"NKSP_CODE(
1469    on init
1470      exit(!4 + !3)
1471    end on
1472    )NKSP_CODE",
1473            .expectIntExitResult = 7,
1474            .expectExitResultFinal = true
1475        });
1476    
1477        runScript({
1478            .code = R"NKSP_CODE(
1479    on init
1480      exit(4 + 3)
1481    end on
1482    )NKSP_CODE",
1483            .expectIntExitResult = 7,
1484            .expectExitResultFinal = false
1485        });
1486    
1487        runScript({
1488            .code = R"NKSP_CODE(
1489    on init
1490      exit(!4.1 + !3.3)
1491    end on
1492    )NKSP_CODE",
1493            .expectRealExitResult = 7.4,
1494            .expectExitResultFinal = true
1495        });
1496    
1497        runScript({
1498            .code = R"NKSP_CODE(
1499    on init
1500      exit(4.1 + 3.3)
1501    end on
1502    )NKSP_CODE",
1503            .expectRealExitResult = 7.4,
1504            .expectExitResultFinal = false
1505        });
1506    
1507      #if !SILENT_TEST      #if !SILENT_TEST
1508      std::cout << std::endl;      std::cout << std::endl;
1509      #endif      #endif
# Line 267  static void testMinusOperator() { Line 1514  static void testMinusOperator() {
1514      std::cout << "UNIT TEST: minus (-) operator\n";      std::cout << "UNIT TEST: minus (-) operator\n";
1515      #endif      #endif
1516    
1517        // integer tests ...
1518    
1519      runScript({      runScript({
1520          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
1521  on init  on init
# Line 303  end on Line 1552  end on
1552          .expectIntExitResult = -21          .expectIntExitResult = -21
1553      });      });
1554    
1555        // real number tests ...
1556    
1557        runScript({
1558            .code = R"NKSP_CODE(
1559    on init
1560      exit(4.0 - 0.2)
1561    end on
1562    )NKSP_CODE",
1563            .expectRealExitResult = 3.8
1564        });
1565    
1566        runScript({
1567            .code = R"NKSP_CODE(
1568    on init
1569      exit(3.1 - 9.65)
1570    end on
1571    )NKSP_CODE",
1572            .expectRealExitResult = -6.55
1573        });
1574    
1575        runScript({
1576            .code = R"NKSP_CODE(
1577    on init
1578      exit(-3.0 - 18.1)
1579    end on
1580    )NKSP_CODE",
1581            .expectRealExitResult = -21.1
1582        });
1583    
1584        // std unit tests ...
1585    
1586        runScript({
1587            .code = R"NKSP_CODE(
1588    on init
1589      exit(1000ms - 145ms)
1590    end on
1591    )NKSP_CODE",
1592            .expectIntExitResult = 855,
1593            .expectExitResultUnitPrefix = { VM_MILLI },
1594            .expectExitResultUnit = VM_SECOND
1595        });
1596    
1597        runScript({
1598            .code = R"NKSP_CODE(
1599    on init
1600      exit(1s - 145ms)
1601    end on
1602    )NKSP_CODE",
1603            .expectIntExitResult = 855,
1604            .expectExitResultUnitPrefix = { VM_MILLI },
1605            .expectExitResultUnit = VM_SECOND
1606        });
1607    
1608        runScript({
1609            .code = R"NKSP_CODE(
1610    on init
1611      exit(1s - 145)
1612    end on
1613    )NKSP_CODE",
1614            .expectParseError = true // units must match for - operator
1615        });
1616    
1617        runScript({
1618            .code = R"NKSP_CODE(
1619    on init
1620      exit(1 - 145s)
1621    end on
1622    )NKSP_CODE",
1623            .expectParseError = true // units must match for - operator
1624        });
1625    
1626        runScript({
1627            .code = R"NKSP_CODE(
1628    on init
1629      exit(1ms - 145mB)
1630    end on
1631    )NKSP_CODE",
1632            .expectParseError = true // units must match for - operator
1633        });
1634    
1635        runScript({
1636            .code = R"NKSP_CODE(
1637    on init
1638      exit(1.0ms - 0.1ms)
1639    end on
1640    )NKSP_CODE",
1641            .expectRealExitResult = 0.9,
1642            .expectExitResultUnitPrefix = { VM_MILLI },
1643            .expectExitResultUnit = VM_SECOND
1644        });
1645    
1646        runScript({
1647            .code = R"NKSP_CODE(
1648    on init
1649      exit(1.1s - 106.0ms)
1650    end on
1651    )NKSP_CODE",
1652            .expectRealExitResult = 994.0,
1653            .expectExitResultUnitPrefix = { VM_MILLI },
1654            .expectExitResultUnit = VM_SECOND
1655        });
1656    
1657        runScript({
1658            .code = R"NKSP_CODE(
1659    on init
1660      exit(1100.0ms - 0.106s)
1661    end on
1662    )NKSP_CODE",
1663            .expectRealExitResult = 994.0,
1664            .expectExitResultUnitPrefix = { VM_MILLI },
1665            .expectExitResultUnit = VM_SECOND
1666        });
1667    
1668        runScript({
1669            .code = R"NKSP_CODE(
1670    on init
1671      exit(1.0s - 145.0)
1672    end on
1673    )NKSP_CODE",
1674            .expectParseError = true // units must match for - operator
1675        });
1676    
1677        runScript({
1678            .code = R"NKSP_CODE(
1679    on init
1680      exit(1.0 - 145.0s)
1681    end on
1682    )NKSP_CODE",
1683            .expectParseError = true // units must match for - operator
1684        });
1685    
1686        runScript({
1687            .code = R"NKSP_CODE(
1688    on init
1689      exit(1.0ms - 145.0mB)
1690    end on
1691    )NKSP_CODE",
1692            .expectParseError = true // units must match for - operator
1693        });
1694    
1695        // 'final' ('!') operator tests ...
1696    
1697        runScript({
1698            .code = R"NKSP_CODE(
1699    on init
1700      exit(!5 - !3)
1701    end on
1702    )NKSP_CODE",
1703            .expectIntExitResult = 2,
1704            .expectExitResultFinal = true
1705        });
1706    
1707        runScript({
1708            .code = R"NKSP_CODE(
1709    on init
1710      exit(5 - 3)
1711    end on
1712    )NKSP_CODE",
1713            .expectIntExitResult = 2,
1714            .expectExitResultFinal = false
1715        });
1716    
1717        runScript({
1718            .code = R"NKSP_CODE(
1719    on init
1720      exit(!5.9 - !3.3)
1721    end on
1722    )NKSP_CODE",
1723            .expectRealExitResult = 2.6,
1724            .expectExitResultFinal = true
1725        });
1726    
1727        runScript({
1728            .code = R"NKSP_CODE(
1729    on init
1730      exit(5.9 - 3.3)
1731    end on
1732    )NKSP_CODE",
1733            .expectRealExitResult = 2.6,
1734            .expectExitResultFinal = false
1735        });
1736    
1737      #if !SILENT_TEST      #if !SILENT_TEST
1738      std::cout << std::endl;      std::cout << std::endl;
1739      #endif      #endif
# Line 313  static void testModuloOperator() { Line 1744  static void testModuloOperator() {
1744      std::cout << "UNIT TEST: modulo (mod) operator\n";      std::cout << "UNIT TEST: modulo (mod) operator\n";
1745      #endif      #endif
1746    
1747        // integer tests ...
1748    
1749      runScript({      runScript({
1750          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
1751  on init  on init
# Line 322  end on Line 1755  end on
1755          .expectIntExitResult = 2          .expectIntExitResult = 2
1756      });      });
1757    
1758        runScript({
1759            .code = R"NKSP_CODE(
1760    on init
1761      declare $a := 10
1762      declare $b := 8
1763      exit($a mod $b)
1764    end on
1765    )NKSP_CODE",
1766            .expectIntExitResult = 2
1767        });
1768    
1769        // real number tests ...
1770        // (mod operator prohibits real numbers ATM)
1771    
1772        runScript({
1773            .code = R"NKSP_CODE(
1774    on init
1775      exit(10.0 mod 8.0)
1776    end on
1777    )NKSP_CODE",
1778            .expectParseError = true // mod operator prohibits real numbers ATM
1779        });
1780    
1781        runScript({
1782            .code = R"NKSP_CODE(
1783    on init
1784      exit(10 mod 8.0)
1785    end on
1786    )NKSP_CODE",
1787            .expectParseError = true // mod operator prohibits real numbers ATM
1788        });
1789    
1790        runScript({
1791            .code = R"NKSP_CODE(
1792    on init
1793      exit(10.0 mod 8)
1794    end on
1795    )NKSP_CODE",
1796            .expectParseError = true // mod operator prohibits real numbers ATM
1797        });
1798    
1799        runScript({
1800            .code = R"NKSP_CODE(
1801    on init
1802      declare ~a := 10.0
1803      declare ~b := 8.0
1804      exit(~a mod ~b)
1805    end on
1806    )NKSP_CODE",
1807            .expectParseError = true // mod operator prohibits real numbers ATM
1808        });
1809    
1810        // std unit tests ...
1811    
1812        runScript({
1813            .code = R"NKSP_CODE(
1814    on init
1815      exit(10s mod 8)
1816    end on
1817    )NKSP_CODE",
1818            .expectParseError = true // mod operator prohibits std units ATM
1819        });
1820    
1821        runScript({
1822            .code = R"NKSP_CODE(
1823    on init
1824      exit(10 mod 8s)
1825    end on
1826    )NKSP_CODE",
1827            .expectParseError = true // mod operator prohibits std units ATM
1828        });
1829    
1830        runScript({
1831            .code = R"NKSP_CODE(
1832    on init
1833      exit(10s mod 8s)
1834    end on
1835    )NKSP_CODE",
1836            .expectParseError = true // mod operator prohibits std units ATM
1837        });
1838    
1839        // 'final' ('!') operator tests ...
1840    
1841        runScript({
1842            .code = R"NKSP_CODE(
1843    on init
1844      exit(!10 mod !8)
1845    end on
1846    )NKSP_CODE",
1847            .expectIntExitResult = 2,
1848            .expectExitResultFinal = true
1849        });
1850    
1851        runScript({
1852            .code = R"NKSP_CODE(
1853    on init
1854      exit(10 mod 8)
1855    end on
1856    )NKSP_CODE",
1857            .expectIntExitResult = 2,
1858            .expectExitResultFinal = false
1859        });
1860    
1861      #if !SILENT_TEST      #if !SILENT_TEST
1862      std::cout << std::endl;      std::cout << std::endl;
1863      #endif      #endif
# Line 332  static void testMultiplyOperator() { Line 1868  static void testMultiplyOperator() {
1868      std::cout << "UNIT TEST: multiply (*) operator\n";      std::cout << "UNIT TEST: multiply (*) operator\n";
1869      #endif      #endif
1870    
1871        // integer tests ...
1872    
1873      runScript({      runScript({
1874          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
1875  on init  on init
# Line 368  end on Line 1906  end on
1906          .expectIntExitResult = -7257          .expectIntExitResult = -7257
1907      });      });
1908    
1909        // real number tests ...
1910    
1911        runScript({
1912            .code = R"NKSP_CODE(
1913    on init
1914      exit(10.2 * 8.4)
1915    end on
1916    )NKSP_CODE",
1917            .expectRealExitResult = 85.68
1918        });
1919    
1920        runScript({
1921            .code = R"NKSP_CODE(
1922    on init
1923      exit(10.0 * -3.33)
1924    end on
1925    )NKSP_CODE",
1926            .expectRealExitResult = -33.3
1927        });
1928    
1929        runScript({
1930            .code = R"NKSP_CODE(
1931    on init
1932      exit(-3.33 * 10.0)
1933    end on
1934    )NKSP_CODE",
1935            .expectRealExitResult = -33.3
1936        });
1937    
1938        runScript({
1939            .code = R"NKSP_CODE(
1940    on init
1941      exit(-3.33 * -10.0)
1942    end on
1943    )NKSP_CODE",
1944            .expectRealExitResult = 33.3
1945        });
1946    
1947        // mixed type tests ...
1948        // (mixed int * real forbidden ATM)
1949    
1950        runScript({
1951            .code = R"NKSP_CODE(
1952    on init
1953      exit(2 * 3.0)
1954    end on
1955    )NKSP_CODE",
1956            .expectParseError = true // mixed int * real forbidden ATM
1957        });
1958    
1959        runScript({
1960            .code = R"NKSP_CODE(
1961    on init
1962      exit(2.0 * 3)
1963    end on
1964    )NKSP_CODE",
1965            .expectParseError = true // mixed int * real forbidden ATM
1966        });
1967    
1968        // std unit tests ...
1969    
1970        runScript({
1971            .code = R"NKSP_CODE(
1972    on init
1973      exit(10ms * 8)
1974    end on
1975    )NKSP_CODE",
1976            .expectIntExitResult = 80,
1977            .expectExitResultUnitPrefix = { VM_MILLI },
1978            .expectExitResultUnit = VM_SECOND
1979        });
1980    
1981        runScript({
1982            .code = R"NKSP_CODE(
1983    on init
1984      exit(10 * 8ms)
1985    end on
1986    )NKSP_CODE",
1987            .expectIntExitResult = 80,
1988            .expectExitResultUnitPrefix = { VM_MILLI },
1989            .expectExitResultUnit = VM_SECOND
1990        });
1991    
1992        runScript({
1993            .code = R"NKSP_CODE(
1994    on init
1995      exit(10s * 8s)
1996    end on
1997    )NKSP_CODE",
1998            .expectParseError = true // units on both sides not allowed for * ATM
1999        });
2000    
2001        runScript({
2002            .code = R"NKSP_CODE(
2003    on init
2004      exit(10cs * 8d)
2005    end on
2006    )NKSP_CODE",
2007            .expectIntExitResult = 80,
2008            .expectExitResultUnitPrefix = { VM_MILLI },
2009            .expectExitResultUnit = VM_SECOND
2010        });
2011    
2012        runScript({
2013            .code = R"NKSP_CODE(
2014    on init
2015      exit(10m * 8ms)
2016    end on
2017    )NKSP_CODE",
2018            .expectIntExitResult = 80,
2019            .expectExitResultUnitPrefix = { VM_MICRO },
2020            .expectExitResultUnit = VM_SECOND
2021        });
2022    
2023        runScript({
2024            .code = R"NKSP_CODE(
2025    on init
2026      exit(10ms * 8k)
2027    end on
2028    )NKSP_CODE",
2029            .expectIntExitResult = 80,
2030            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
2031            .expectExitResultUnit = VM_SECOND
2032        });
2033    
2034        runScript({
2035            .code = R"NKSP_CODE(
2036    on init
2037      exit(10.1ms * 8.0)
2038    end on
2039    )NKSP_CODE",
2040            .expectRealExitResult = 80.8,
2041            .expectExitResultUnitPrefix = { VM_MILLI },
2042            .expectExitResultUnit = VM_SECOND
2043        });
2044    
2045        runScript({
2046            .code = R"NKSP_CODE(
2047    on init
2048      exit(10.1 * 8.0ms)
2049    end on
2050    )NKSP_CODE",
2051            .expectRealExitResult = 80.8,
2052            .expectExitResultUnitPrefix = { VM_MILLI },
2053            .expectExitResultUnit = VM_SECOND
2054        });
2055    
2056        runScript({
2057            .code = R"NKSP_CODE(
2058    on init
2059      exit(10.0s * 8.0s)
2060    end on
2061    )NKSP_CODE",
2062            .expectParseError = true // units on both sides not allowed for * ATM
2063        });
2064    
2065        runScript({
2066            .code = R"NKSP_CODE(
2067    on init
2068      exit(10.1ds * 8.0c)
2069    end on
2070    )NKSP_CODE",
2071            .expectRealExitResult = 80.8,
2072            .expectExitResultUnitPrefix = { VM_MILLI },
2073            .expectExitResultUnit = VM_SECOND
2074        });
2075    
2076        runScript({
2077            .code = R"NKSP_CODE(
2078    on init
2079      exit(10.1m * 8.0ms)
2080    end on
2081    )NKSP_CODE",
2082            .expectRealExitResult = 80.8,
2083            .expectExitResultUnitPrefix = { VM_MICRO },
2084            .expectExitResultUnit = VM_SECOND
2085        });
2086    
2087        runScript({
2088            .code = R"NKSP_CODE(
2089    on init
2090      exit(10.1m * 8.0ks)
2091    end on
2092    )NKSP_CODE",
2093            .expectRealExitResult = 80.8,
2094            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
2095            .expectExitResultUnit = VM_SECOND
2096        });
2097    
2098        runScript({
2099            .code = R"NKSP_CODE(
2100    on init
2101      declare ~foo := 1.0  { neutral }
2102      declare $bar := 7000ms
2103      exit(~foo * real($bar))
2104    end on
2105    )NKSP_CODE",
2106            .expectRealExitResult = 7000.0,
2107            .expectExitResultUnitPrefix = { VM_MILLI },
2108            .expectExitResultUnit = VM_SECOND
2109        });
2110    
2111     runScript({
2112            .code = R"NKSP_CODE(
2113    on init
2114      declare $foo := 1  { neutral }
2115      declare $bar := 7000ms
2116      exit(real($foo) * real($bar))
2117    end on
2118    )NKSP_CODE",
2119            .expectRealExitResult = 7000.0,
2120            .expectExitResultUnitPrefix = { VM_MILLI },
2121            .expectExitResultUnit = VM_SECOND
2122        });
2123    
2124        // 'final' ('!') operator tests ...
2125    
2126        runScript({
2127            .code = R"NKSP_CODE(
2128    on init
2129      exit(!10 * !8)
2130    end on
2131    )NKSP_CODE",
2132            .expectIntExitResult = 80,
2133            .expectExitResultFinal = true
2134        });
2135    
2136        runScript({
2137            .code = R"NKSP_CODE(
2138    on init
2139      exit(10 * 8)
2140    end on
2141    )NKSP_CODE",
2142            .expectIntExitResult = 80,
2143            .expectExitResultFinal = false
2144        });
2145    
2146        runScript({
2147            .code = R"NKSP_CODE(
2148    on init
2149      exit(!10 * 8)
2150    end on
2151    )NKSP_CODE",
2152            .expectIntExitResult = 80,
2153            .expectExitResultFinal = true,
2154            .expectParseWarning = true // since final only on one side, result will be final though
2155        });
2156    
2157        runScript({
2158            .code = R"NKSP_CODE(
2159    on init
2160      exit(10 * !8)
2161    end on
2162    )NKSP_CODE",
2163            .expectIntExitResult = 80,
2164            .expectExitResultFinal = true,
2165            .expectParseWarning = true // since final only on one side, result will be final though
2166        });
2167    
2168        runScript({
2169            .code = R"NKSP_CODE(
2170    on init
2171      exit(!10.1 * !8.0)
2172    end on
2173    )NKSP_CODE",
2174            .expectRealExitResult = 80.8,
2175            .expectExitResultFinal = true
2176        });
2177    
2178        runScript({
2179            .code = R"NKSP_CODE(
2180    on init
2181      exit(10.1 * 8.0)
2182    end on
2183    )NKSP_CODE",
2184            .expectRealExitResult = 80.8,
2185            .expectExitResultFinal = false
2186        });
2187    
2188        runScript({
2189            .code = R"NKSP_CODE(
2190    on init
2191      exit(!10.1 * 8.0)
2192    end on
2193    )NKSP_CODE",
2194            .expectRealExitResult = 80.8,
2195            .expectExitResultFinal = true,
2196            .expectParseWarning = true // since final only on one side, result will be final though
2197        });
2198    
2199        runScript({
2200            .code = R"NKSP_CODE(
2201    on init
2202      exit(10.1 * !8.0)
2203    end on
2204    )NKSP_CODE",
2205            .expectRealExitResult = 80.8,
2206            .expectExitResultFinal = true,
2207            .expectParseWarning = true // since final only on one side, result will be final though
2208        });
2209    
2210      #if !SILENT_TEST      #if !SILENT_TEST
2211      std::cout << std::endl;      std::cout << std::endl;
2212      #endif      #endif
# Line 378  static void testDivideOperator() { Line 2217  static void testDivideOperator() {
2217      std::cout << "UNIT TEST: divide (/) operator\n";      std::cout << "UNIT TEST: divide (/) operator\n";
2218      #endif      #endif
2219    
2220        // integer tests ...
2221    
2222      runScript({      runScript({
2223          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
2224  on init  on init
# Line 414  end on Line 2255  end on
2255          .expectIntExitResult = -7          .expectIntExitResult = -7
2256      });      });
2257    
2258        // real number tests ...
2259    
2260        runScript({
2261            .code = R"NKSP_CODE(
2262    on init
2263      exit(9.0 / 10.0)
2264    end on
2265    )NKSP_CODE",
2266            .expectRealExitResult = 0.9
2267        });
2268    
2269        runScript({
2270            .code = R"NKSP_CODE(
2271    on init
2272      exit(-9.0 / 10.0)
2273    end on
2274    )NKSP_CODE",
2275            .expectRealExitResult = -0.9
2276        });
2277    
2278        runScript({
2279            .code = R"NKSP_CODE(
2280    on init
2281      exit(9.0 / -10.0)
2282    end on
2283    )NKSP_CODE",
2284            .expectRealExitResult = -0.9
2285        });
2286    
2287        runScript({
2288            .code = R"NKSP_CODE(
2289    on init
2290      exit(-9.0 / -10.0)
2291    end on
2292    )NKSP_CODE",
2293            .expectRealExitResult = 0.9
2294        });
2295    
2296        // mixed type tests ...
2297        // (mixed int / real forbidden ATM)
2298    
2299        runScript({
2300            .code = R"NKSP_CODE(
2301    on init
2302      exit(9 / 10.0)
2303    end on
2304    )NKSP_CODE",
2305            .expectParseError = true // mixed int / real forbidden ATM
2306        });
2307    
2308        runScript({
2309            .code = R"NKSP_CODE(
2310    on init
2311      exit(9.0 / 10)
2312    end on
2313    )NKSP_CODE",
2314            .expectParseError = true // mixed int / real forbidden ATM
2315        });
2316    
2317        // std unit tests ...
2318    
2319        runScript({
2320            .code = R"NKSP_CODE(
2321    on init
2322      exit(-27us / 3)
2323    end on
2324    )NKSP_CODE",
2325            .expectIntExitResult = -9,
2326            .expectExitResultUnitPrefix = { VM_MICRO },
2327            .expectExitResultUnit = VM_SECOND
2328        });
2329    
2330        runScript({
2331            .code = R"NKSP_CODE(
2332    on init
2333      exit(-27mdB / 3mdB)
2334    end on
2335    )NKSP_CODE",
2336            .expectIntExitResult = -9,
2337            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
2338            .expectExitResultUnit = VM_NO_UNIT
2339        });
2340    
2341        runScript({
2342            .code = R"NKSP_CODE(
2343    on init
2344      exit(-27s / 3m)
2345    end on
2346    )NKSP_CODE",
2347            .expectIntExitResult = -9,
2348            .expectExitResultUnitPrefix = { VM_KILO },
2349            .expectExitResultUnit = VM_SECOND
2350        });
2351    
2352        runScript({
2353            .code = R"NKSP_CODE(
2354    on init
2355      exit(-27us / 3m)
2356    end on
2357    )NKSP_CODE",
2358            .expectIntExitResult = -9,
2359            .expectExitResultUnitPrefix = { VM_MILLI },
2360            .expectExitResultUnit = VM_SECOND
2361        });
2362    
2363        runScript({
2364            .code = R"NKSP_CODE(
2365    on init
2366      exit(-27 / 3s)
2367    end on
2368    )NKSP_CODE",
2369            .expectParseError = true // illegal unit type arrangement for divisions
2370        });
2371    
2372        runScript({
2373            .code = R"NKSP_CODE(
2374    on init
2375      exit(-27s / 3Hz)
2376    end on
2377    )NKSP_CODE",
2378            .expectParseError = true // unit types are not matching
2379        });
2380    
2381        runScript({
2382            .code = R"NKSP_CODE(
2383    on init
2384      declare $foo := 1000000
2385      declare $bar := 7000ms
2386      exit(real($foo) / 1000000.0 * real($bar))
2387    end on
2388    )NKSP_CODE",
2389            .expectRealExitResult = 7000.0,
2390            .expectExitResultUnitPrefix = { VM_MILLI },
2391            .expectExitResultUnit = VM_SECOND
2392        });
2393    
2394        // 'final' ('!') operator tests ...
2395    
2396        runScript({
2397            .code = R"NKSP_CODE(
2398    on init
2399      exit(!-27 / !3)
2400    end on
2401    )NKSP_CODE",
2402            .expectIntExitResult = -9,
2403            .expectExitResultFinal = true
2404        });
2405    
2406        runScript({
2407            .code = R"NKSP_CODE(
2408    on init
2409      exit(-27 / 3)
2410    end on
2411    )NKSP_CODE",
2412            .expectIntExitResult = -9,
2413            .expectExitResultFinal = false
2414        });
2415    
2416        runScript({
2417            .code = R"NKSP_CODE(
2418    on init
2419      exit(!-27 / 3)
2420    end on
2421    )NKSP_CODE",
2422            .expectIntExitResult = -9,
2423            .expectExitResultFinal = true,
2424            .expectParseWarning = true // final only on one side, result will be final though
2425        });
2426    
2427        runScript({
2428            .code = R"NKSP_CODE(
2429    on init
2430      exit(-27 / !3)
2431    end on
2432    )NKSP_CODE",
2433            .expectIntExitResult = -9,
2434            .expectExitResultFinal = true,
2435            .expectParseWarning = true // final only on one side, result will be final though
2436        });
2437    
2438      #if !SILENT_TEST      #if !SILENT_TEST
2439      std::cout << std::endl;      std::cout << std::endl;
2440      #endif      #endif
# Line 424  static void testSmallerThanOperator() { Line 2445  static void testSmallerThanOperator() {
2445      std::cout << "UNIT TEST: smaller than (<) operator\n";      std::cout << "UNIT TEST: smaller than (<) operator\n";
2446      #endif      #endif
2447    
2448        // integer tests ...
2449    
2450      runScript({      runScript({
2451          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
2452  on init  on init
# Line 478  end on Line 2501  end on
2501          .expectBoolExitResult = true          .expectBoolExitResult = true
2502      });      });
2503    
2504        // real number tests ...
2505    
2506        runScript({
2507            .code = R"NKSP_CODE(
2508    on init
2509      exit(3.0 < 4.0)
2510    end on
2511    )NKSP_CODE",
2512            .expectBoolExitResult = true
2513        });
2514    
2515        runScript({
2516            .code = R"NKSP_CODE(
2517    on init
2518      exit(4.0 < 3.0)
2519    end on
2520    )NKSP_CODE",
2521            .expectBoolExitResult = false
2522        });
2523    
2524        runScript({
2525            .code = R"NKSP_CODE(
2526    on init
2527      exit(1.2 < 1.23)
2528    end on
2529    )NKSP_CODE",
2530            .expectBoolExitResult = true
2531        });
2532    
2533        runScript({
2534            .code = R"NKSP_CODE(
2535    on init
2536      exit(1.23 < 1.2)
2537    end on
2538    )NKSP_CODE",
2539            .expectBoolExitResult = false
2540        });
2541    
2542        runScript({
2543            .code = R"NKSP_CODE(
2544    on init
2545      exit(-4.0 < 3.0)
2546    end on
2547    )NKSP_CODE",
2548            .expectBoolExitResult = true
2549        });
2550    
2551        runScript({
2552            .code = R"NKSP_CODE(
2553    on init
2554      exit(3.0 < -4.0)
2555    end on
2556    )NKSP_CODE",
2557            .expectBoolExitResult = false
2558        });
2559    
2560        runScript({
2561            .code = R"NKSP_CODE(
2562    on init
2563      exit(123.0 < -45.0)
2564    end on
2565    )NKSP_CODE",
2566            .expectBoolExitResult = false
2567        });
2568    
2569        runScript({
2570            .code = R"NKSP_CODE(
2571    on init
2572      exit(-45.0 < 123.0)
2573    end on
2574    )NKSP_CODE",
2575            .expectBoolExitResult = true
2576        });
2577    
2578        // mixed type tests ...
2579    
2580        runScript({
2581            .code = R"NKSP_CODE(
2582    on init
2583      exit(9 < 9.1)
2584    end on
2585    )NKSP_CODE",
2586            .expectBoolExitResult = true
2587        });
2588    
2589        runScript({
2590            .code = R"NKSP_CODE(
2591    on init
2592      exit(9.1 < 9)
2593    end on
2594    )NKSP_CODE",
2595            .expectBoolExitResult = false
2596        });
2597    
2598        // std unit tests ...
2599    
2600        runScript({
2601            .code = R"NKSP_CODE(
2602    on init
2603      exit(13ms < 14ms)
2604    end on
2605    )NKSP_CODE",
2606            .expectBoolExitResult = true
2607        });
2608    
2609        runScript({
2610            .code = R"NKSP_CODE(
2611    on init
2612      exit(14ms < 13ms)
2613    end on
2614    )NKSP_CODE",
2615            .expectBoolExitResult = false
2616        });
2617    
2618        runScript({
2619            .code = R"NKSP_CODE(
2620    on init
2621      exit(1s < 990ms)
2622    end on
2623    )NKSP_CODE",
2624            .expectBoolExitResult = false
2625        });
2626    
2627        runScript({
2628            .code = R"NKSP_CODE(
2629    on init
2630      exit(990ms < 1s)
2631    end on
2632    )NKSP_CODE",
2633            .expectBoolExitResult = true
2634        });
2635    
2636        runScript({
2637            .code = R"NKSP_CODE(
2638    on init
2639      exit(1000ms < 1s)
2640    end on
2641    )NKSP_CODE",
2642            .expectBoolExitResult = false
2643        });
2644    
2645        runScript({
2646            .code = R"NKSP_CODE(
2647    on init
2648      exit(1s < 1000ms)
2649    end on
2650    )NKSP_CODE",
2651            .expectBoolExitResult = false
2652        });
2653    
2654        runScript({
2655            .code = R"NKSP_CODE(
2656    on init
2657      exit(1s < 1)
2658    end on
2659    )NKSP_CODE",
2660            .expectParseError = true // units on both sides must match
2661        });
2662    
2663        runScript({
2664            .code = R"NKSP_CODE(
2665    on init
2666      exit(1 < 1s)
2667    end on
2668    )NKSP_CODE",
2669            .expectParseError = true // units on both sides must match
2670        });
2671    
2672        runScript({
2673            .code = R"NKSP_CODE(
2674    on init
2675      exit(1Hz < 1B)
2676    end on
2677    )NKSP_CODE",
2678            .expectParseError = true // units on both sides must match
2679        });
2680    
2681        runScript({
2682            .code = R"NKSP_CODE(
2683    on init
2684      exit(13.0ms < 13.1ms)
2685    end on
2686    )NKSP_CODE",
2687            .expectBoolExitResult = true
2688        });
2689    
2690        runScript({
2691            .code = R"NKSP_CODE(
2692    on init
2693      exit(13.1ms < 13.0ms)
2694    end on
2695    )NKSP_CODE",
2696            .expectBoolExitResult = false
2697        });
2698    
2699        runScript({
2700            .code = R"NKSP_CODE(
2701    on init
2702      exit(0.9s < 600.0ms)
2703    end on
2704    )NKSP_CODE",
2705            .expectBoolExitResult = false
2706        });
2707    
2708        runScript({
2709            .code = R"NKSP_CODE(
2710    on init
2711      exit(600.0ms < 0.9s)
2712    end on
2713    )NKSP_CODE",
2714            .expectBoolExitResult = true
2715        });
2716    
2717        runScript({
2718            .code = R"NKSP_CODE(
2719    on init
2720      exit(5.1kHz < 5100.0Hz)
2721    end on
2722    )NKSP_CODE",
2723            .expectBoolExitResult = false
2724        });
2725    
2726        runScript({
2727            .code = R"NKSP_CODE(
2728    on init
2729      exit(5100.0Hz < 5.1kHz)
2730    end on
2731    )NKSP_CODE",
2732            .expectBoolExitResult = false
2733        });
2734    
2735        runScript({
2736            .code = R"NKSP_CODE(
2737    on init
2738      exit(1.0Hz < 1.1)
2739    end on
2740    )NKSP_CODE",
2741            .expectParseError = true // units on both sides must match
2742        });
2743    
2744        runScript({
2745            .code = R"NKSP_CODE(
2746    on init
2747      exit(1.2 < 1.34mdB)
2748    end on
2749    )NKSP_CODE",
2750            .expectParseError = true // units on both sides must match
2751        });
2752    
2753        runScript({
2754            .code = R"NKSP_CODE(
2755    on init
2756      exit(9.23us < 3.14kHz)
2757    end on
2758    )NKSP_CODE",
2759            .expectParseError = true // units on both sides must match
2760        });
2761    
2762        // 'final' ('!') operator tests ...
2763        // (should always yield in false for relation operators)
2764    
2765        runScript({
2766            .code = R"NKSP_CODE(
2767    on init
2768      exit(!-4 < !3)
2769    end on
2770    )NKSP_CODE",
2771            .expectBoolExitResult = true,
2772            .expectExitResultFinal = false
2773        });
2774    
2775        runScript({
2776            .code = R"NKSP_CODE(
2777    on init
2778      exit(-4 < 3)
2779    end on
2780    )NKSP_CODE",
2781            .expectBoolExitResult = true,
2782            .expectExitResultFinal = false
2783        });
2784    
2785      #if !SILENT_TEST      #if !SILENT_TEST
2786      std::cout << std::endl;      std::cout << std::endl;
2787      #endif      #endif
# Line 488  static void testGreaterThanOperator() { Line 2792  static void testGreaterThanOperator() {
2792      std::cout << "UNIT TEST: greater than (>) operator\n";      std::cout << "UNIT TEST: greater than (>) operator\n";
2793      #endif      #endif
2794    
2795        // integer tests ...
2796    
2797      runScript({      runScript({
2798          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
2799  on init  on init
# Line 542  end on Line 2848  end on
2848          .expectBoolExitResult = false          .expectBoolExitResult = false
2849      });      });
2850    
2851        // real number tests ...
2852    
2853        runScript({
2854            .code = R"NKSP_CODE(
2855    on init
2856      exit(3.0 > 4.0)
2857    end on
2858    )NKSP_CODE",
2859            .expectBoolExitResult = false
2860        });
2861    
2862        runScript({
2863            .code = R"NKSP_CODE(
2864    on init
2865      exit(4.0 > 3.0)
2866    end on
2867    )NKSP_CODE",
2868            .expectBoolExitResult = true
2869        });
2870    
2871        runScript({
2872            .code = R"NKSP_CODE(
2873    on init
2874      exit(1.2 > 1.23)
2875    end on
2876    )NKSP_CODE",
2877            .expectBoolExitResult = false
2878        });
2879    
2880        runScript({
2881            .code = R"NKSP_CODE(
2882    on init
2883      exit(1.23 > 1.2)
2884    end on
2885    )NKSP_CODE",
2886            .expectBoolExitResult = true
2887        });
2888    
2889        runScript({
2890            .code = R"NKSP_CODE(
2891    on init
2892      exit(-4.0 > 3.0)
2893    end on
2894    )NKSP_CODE",
2895            .expectBoolExitResult = false
2896        });
2897    
2898        runScript({
2899            .code = R"NKSP_CODE(
2900    on init
2901      exit(3.0 > -4.0)
2902    end on
2903    )NKSP_CODE",
2904            .expectBoolExitResult = true
2905        });
2906    
2907        runScript({
2908            .code = R"NKSP_CODE(
2909    on init
2910      exit(123.0 > -45.0)
2911    end on
2912    )NKSP_CODE",
2913            .expectBoolExitResult = true
2914        });
2915    
2916        runScript({
2917            .code = R"NKSP_CODE(
2918    on init
2919      exit(-45.0 > 123.0)
2920    end on
2921    )NKSP_CODE",
2922            .expectBoolExitResult = false
2923        });
2924    
2925        // mixed type tests ...
2926    
2927        runScript({
2928            .code = R"NKSP_CODE(
2929    on init
2930      exit(9 > 9.1)
2931    end on
2932    )NKSP_CODE",
2933            .expectBoolExitResult = false
2934        });
2935    
2936        runScript({
2937            .code = R"NKSP_CODE(
2938    on init
2939      exit(9.1 > 9)
2940    end on
2941    )NKSP_CODE",
2942            .expectBoolExitResult = true
2943        });
2944    
2945        // std unit tests ...
2946    
2947        runScript({
2948            .code = R"NKSP_CODE(
2949    on init
2950      exit(13ms > 14ms)
2951    end on
2952    )NKSP_CODE",
2953            .expectBoolExitResult = false
2954        });
2955    
2956        runScript({
2957            .code = R"NKSP_CODE(
2958    on init
2959      exit(14ms > 13ms)
2960    end on
2961    )NKSP_CODE",
2962            .expectBoolExitResult = true
2963        });
2964    
2965        runScript({
2966            .code = R"NKSP_CODE(
2967    on init
2968      exit(1s > 990ms)
2969    end on
2970    )NKSP_CODE",
2971            .expectBoolExitResult = true
2972        });
2973    
2974        runScript({
2975            .code = R"NKSP_CODE(
2976    on init
2977      exit(990ms > 1s)
2978    end on
2979    )NKSP_CODE",
2980            .expectBoolExitResult = false
2981        });
2982    
2983        runScript({
2984            .code = R"NKSP_CODE(
2985    on init
2986      exit(1000ms > 1s)
2987    end on
2988    )NKSP_CODE",
2989            .expectBoolExitResult = false
2990        });
2991    
2992        runScript({
2993            .code = R"NKSP_CODE(
2994    on init
2995      exit(1s > 1000ms)
2996    end on
2997    )NKSP_CODE",
2998            .expectBoolExitResult = false
2999        });
3000    
3001        runScript({
3002            .code = R"NKSP_CODE(
3003    on init
3004      exit(1s > 1)
3005    end on
3006    )NKSP_CODE",
3007            .expectParseError = true // units on both sides must match
3008        });
3009    
3010        runScript({
3011            .code = R"NKSP_CODE(
3012    on init
3013      exit(1 > 1s)
3014    end on
3015    )NKSP_CODE",
3016            .expectParseError = true // units on both sides must match
3017        });
3018    
3019        runScript({
3020            .code = R"NKSP_CODE(
3021    on init
3022      exit(1Hz > 1B)
3023    end on
3024    )NKSP_CODE",
3025            .expectParseError = true // units on both sides must match
3026        });
3027    
3028        runScript({
3029            .code = R"NKSP_CODE(
3030    on init
3031      exit(13.0ms > 13.1ms)
3032    end on
3033    )NKSP_CODE",
3034            .expectBoolExitResult = false
3035        });
3036    
3037        runScript({
3038            .code = R"NKSP_CODE(
3039    on init
3040      exit(13.1ms > 13.0ms)
3041    end on
3042    )NKSP_CODE",
3043            .expectBoolExitResult = true
3044        });
3045    
3046        runScript({
3047            .code = R"NKSP_CODE(
3048    on init
3049      exit(0.9s > 600.0ms)
3050    end on
3051    )NKSP_CODE",
3052            .expectBoolExitResult = true
3053        });
3054    
3055        runScript({
3056            .code = R"NKSP_CODE(
3057    on init
3058      exit(600.0ms > 0.9s)
3059    end on
3060    )NKSP_CODE",
3061            .expectBoolExitResult = false
3062        });
3063    
3064        runScript({
3065            .code = R"NKSP_CODE(
3066    on init
3067      exit(5.1kHz > 5100.0Hz)
3068    end on
3069    )NKSP_CODE",
3070            .expectBoolExitResult = false
3071        });
3072    
3073        runScript({
3074            .code = R"NKSP_CODE(
3075    on init
3076      exit(5100.0Hz > 5.1kHz)
3077    end on
3078    )NKSP_CODE",
3079            .expectBoolExitResult = false
3080        });
3081    
3082        runScript({
3083            .code = R"NKSP_CODE(
3084    on init
3085      exit(1.0Hz > 1.1)
3086    end on
3087    )NKSP_CODE",
3088            .expectParseError = true // units on both sides must match
3089        });
3090    
3091        runScript({
3092            .code = R"NKSP_CODE(
3093    on init
3094      exit(1.2 > 1.34mdB)
3095    end on
3096    )NKSP_CODE",
3097            .expectParseError = true // units on both sides must match
3098        });
3099    
3100        runScript({
3101            .code = R"NKSP_CODE(
3102    on init
3103      exit(9.23us > 3.14kHz)
3104    end on
3105    )NKSP_CODE",
3106            .expectParseError = true // units on both sides must match
3107        });
3108    
3109        // 'final' ('!') operator tests ...
3110        // (should always yield in false for relation operators)
3111    
3112        runScript({
3113            .code = R"NKSP_CODE(
3114    on init
3115      exit(!-4 > !3)
3116    end on
3117    )NKSP_CODE",
3118            .expectBoolExitResult = false,
3119            .expectExitResultFinal = false
3120        });
3121    
3122        runScript({
3123            .code = R"NKSP_CODE(
3124    on init
3125      exit(-4 > 3)
3126    end on
3127    )NKSP_CODE",
3128            .expectBoolExitResult = false,
3129            .expectExitResultFinal = false
3130        });
3131    
3132      #if !SILENT_TEST      #if !SILENT_TEST
3133      std::cout << std::endl;      std::cout << std::endl;
3134      #endif      #endif
# Line 552  static void testSmallerOrEqualOperator() Line 3139  static void testSmallerOrEqualOperator()
3139      std::cout << "UNIT TEST: smaller-or-equal (<=) operator\n";      std::cout << "UNIT TEST: smaller-or-equal (<=) operator\n";
3140      #endif      #endif
3141    
3142        // integer tests ...
3143    
3144      runScript({      runScript({
3145          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
3146  on init  on init
# Line 642  end on Line 3231  end on
3231          .expectBoolExitResult = true          .expectBoolExitResult = true
3232      });      });
3233    
3234        // real number tests ...
3235    
3236        runScript({
3237            .code = R"NKSP_CODE(
3238    on init
3239      exit(3.0 <= 3.0)
3240    end on
3241    )NKSP_CODE",
3242            .expectBoolExitResult = true
3243        });
3244    
3245        runScript({
3246            .code = R"NKSP_CODE(
3247    on init
3248      exit(4.33 <= 4.33)
3249    end on
3250    )NKSP_CODE",
3251            .expectBoolExitResult = true
3252        });
3253    
3254        runScript({
3255            .code = R"NKSP_CODE(
3256    on init
3257      exit(-23.1 <= -23.1)
3258    end on
3259    )NKSP_CODE",
3260            .expectBoolExitResult = true
3261        });
3262    
3263        runScript({
3264            .code = R"NKSP_CODE(
3265    on init
3266      exit(23.3 <= -23.3)
3267    end on
3268    )NKSP_CODE",
3269            .expectBoolExitResult = false
3270        });
3271    
3272        runScript({
3273            .code = R"NKSP_CODE(
3274    on init
3275      exit(3.0 <= 4.0)
3276    end on
3277    )NKSP_CODE",
3278            .expectBoolExitResult = true
3279        });
3280    
3281        runScript({
3282            .code = R"NKSP_CODE(
3283    on init
3284      exit(4.0 <= 3.0)
3285    end on
3286    )NKSP_CODE",
3287            .expectBoolExitResult = false
3288        });
3289    
3290        runScript({
3291            .code = R"NKSP_CODE(
3292    on init
3293      exit(-4.0 <= 3.0)
3294    end on
3295    )NKSP_CODE",
3296            .expectBoolExitResult = true
3297        });
3298    
3299        runScript({
3300            .code = R"NKSP_CODE(
3301    on init
3302      exit(3.0 <= -4.0)
3303    end on
3304    )NKSP_CODE",
3305            .expectBoolExitResult = false
3306        });
3307    
3308        runScript({
3309            .code = R"NKSP_CODE(
3310    on init
3311      exit(123.0 <= -45.0)
3312    end on
3313    )NKSP_CODE",
3314            .expectBoolExitResult = false
3315        });
3316    
3317        runScript({
3318            .code = R"NKSP_CODE(
3319    on init
3320      exit(-45.0 <= 123.0)
3321    end on
3322    )NKSP_CODE",
3323            .expectBoolExitResult = true
3324        });
3325    
3326        // mixed type tests ...
3327    
3328        runScript({
3329            .code = R"NKSP_CODE(
3330    on init
3331      exit(9 <= 9.1)
3332    end on
3333    )NKSP_CODE",
3334            .expectBoolExitResult = true
3335        });
3336    
3337        runScript({
3338            .code = R"NKSP_CODE(
3339    on init
3340      exit(9.1 <= 9)
3341    end on
3342    )NKSP_CODE",
3343            .expectBoolExitResult = false
3344        });
3345    
3346        runScript({
3347            .code = R"NKSP_CODE(
3348    on init
3349      exit(9 <= 9.0)
3350    end on
3351    )NKSP_CODE",
3352            .expectBoolExitResult = true
3353        });
3354    
3355        runScript({
3356            .code = R"NKSP_CODE(
3357    on init
3358      exit(9.0 <= 9)
3359    end on
3360    )NKSP_CODE",
3361            .expectBoolExitResult = true
3362        });
3363    
3364        // std unit tests ...
3365    
3366        runScript({
3367            .code = R"NKSP_CODE(
3368    on init
3369      exit(13ms <= 14ms)
3370    end on
3371    )NKSP_CODE",
3372            .expectBoolExitResult = true
3373        });
3374    
3375        runScript({
3376            .code = R"NKSP_CODE(
3377    on init
3378      exit(14ms <= 13ms)
3379    end on
3380    )NKSP_CODE",
3381            .expectBoolExitResult = false
3382        });
3383    
3384        runScript({
3385            .code = R"NKSP_CODE(
3386    on init
3387      exit(1s <= 990ms)
3388    end on
3389    )NKSP_CODE",
3390            .expectBoolExitResult = false
3391        });
3392    
3393        runScript({
3394            .code = R"NKSP_CODE(
3395    on init
3396      exit(990ms <= 1s)
3397    end on
3398    )NKSP_CODE",
3399            .expectBoolExitResult = true
3400        });
3401    
3402        runScript({
3403            .code = R"NKSP_CODE(
3404    on init
3405      exit(1000ms <= 1s)
3406    end on
3407    )NKSP_CODE",
3408            .expectBoolExitResult = true
3409        });
3410    
3411        runScript({
3412            .code = R"NKSP_CODE(
3413    on init
3414      exit(1s <= 1000ms)
3415    end on
3416    )NKSP_CODE",
3417            .expectBoolExitResult = true
3418        });
3419    
3420        runScript({
3421            .code = R"NKSP_CODE(
3422    on init
3423      exit(1s <= 1)
3424    end on
3425    )NKSP_CODE",
3426            .expectParseError = true // units on both sides must match
3427        });
3428    
3429        runScript({
3430            .code = R"NKSP_CODE(
3431    on init
3432      exit(1 <= 1s)
3433    end on
3434    )NKSP_CODE",
3435            .expectParseError = true // units on both sides must match
3436        });
3437    
3438        runScript({
3439            .code = R"NKSP_CODE(
3440    on init
3441      exit(1Hz <= 1B)
3442    end on
3443    )NKSP_CODE",
3444            .expectParseError = true // units on both sides must match
3445        });
3446    
3447        runScript({
3448            .code = R"NKSP_CODE(
3449    on init
3450      exit(13.0ms <= 13.1ms)
3451    end on
3452    )NKSP_CODE",
3453            .expectBoolExitResult = true
3454        });
3455    
3456        runScript({
3457            .code = R"NKSP_CODE(
3458    on init
3459      exit(13.1ms <= 13.0ms)
3460    end on
3461    )NKSP_CODE",
3462            .expectBoolExitResult = false
3463        });
3464    
3465        runScript({
3466            .code = R"NKSP_CODE(
3467    on init
3468      exit(0.9s <= 600.0ms)
3469    end on
3470    )NKSP_CODE",
3471            .expectBoolExitResult = false
3472        });
3473    
3474        runScript({
3475            .code = R"NKSP_CODE(
3476    on init
3477      exit(600.0ms <= 0.9s)
3478    end on
3479    )NKSP_CODE",
3480            .expectBoolExitResult = true
3481        });
3482    
3483        runScript({
3484            .code = R"NKSP_CODE(
3485    on init
3486      exit(5.1kHz <= 5100.0Hz)
3487    end on
3488    )NKSP_CODE",
3489            .expectBoolExitResult = true
3490        });
3491    
3492        runScript({
3493            .code = R"NKSP_CODE(
3494    on init
3495      exit(5100.0Hz <= 5.1kHz)
3496    end on
3497    )NKSP_CODE",
3498            .expectBoolExitResult = true
3499        });
3500    
3501        runScript({
3502            .code = R"NKSP_CODE(
3503    on init
3504      exit(1.0Hz <= 1.1)
3505    end on
3506    )NKSP_CODE",
3507            .expectParseError = true // units on both sides must match
3508        });
3509    
3510        runScript({
3511            .code = R"NKSP_CODE(
3512    on init
3513      exit(1.2 <= 1.34mdB)
3514    end on
3515    )NKSP_CODE",
3516            .expectParseError = true // units on both sides must match
3517        });
3518    
3519        runScript({
3520            .code = R"NKSP_CODE(
3521    on init
3522      exit(9.23us <= 3.14kHz)
3523    end on
3524    )NKSP_CODE",
3525            .expectParseError = true // units on both sides must match
3526        });
3527    
3528        // 'final' ('!') operator tests ...
3529        // (should always yield in false for relation operators)
3530    
3531        runScript({
3532            .code = R"NKSP_CODE(
3533    on init
3534      exit(!-4 <= !3)
3535    end on
3536    )NKSP_CODE",
3537            .expectBoolExitResult = true,
3538            .expectExitResultFinal = false
3539        });
3540    
3541        runScript({
3542            .code = R"NKSP_CODE(
3543    on init
3544      exit(-4 <= 3)
3545    end on
3546    )NKSP_CODE",
3547            .expectBoolExitResult = true,
3548            .expectExitResultFinal = false
3549        });
3550    
3551      #if !SILENT_TEST      #if !SILENT_TEST
3552      std::cout << std::endl;      std::cout << std::endl;
3553      #endif      #endif
# Line 652  static void testGreaterOrEqualOperator() Line 3558  static void testGreaterOrEqualOperator()
3558      std::cout << "UNIT TEST: greater-or-equal (>=) operator\n";      std::cout << "UNIT TEST: greater-or-equal (>=) operator\n";
3559      #endif      #endif
3560    
3561        // integer tests ...
3562    
3563      runScript({      runScript({
3564          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
3565  on init  on init
# Line 742  end on Line 3650  end on
3650          .expectBoolExitResult = false          .expectBoolExitResult = false
3651      });      });
3652    
3653        // real number tests ...
3654    
3655        runScript({
3656            .code = R"NKSP_CODE(
3657    on init
3658      exit(3.0 >= 3.0)
3659    end on
3660    )NKSP_CODE",
3661            .expectBoolExitResult = true
3662        });
3663    
3664        runScript({
3665            .code = R"NKSP_CODE(
3666    on init
3667      exit(3.1 >= 3.1)
3668    end on
3669    )NKSP_CODE",
3670            .expectBoolExitResult = true
3671        });
3672    
3673        runScript({
3674            .code = R"NKSP_CODE(
3675    on init
3676      exit(3.1 >= 3.0)
3677    end on
3678    )NKSP_CODE",
3679            .expectBoolExitResult = true
3680        });
3681    
3682        runScript({
3683            .code = R"NKSP_CODE(
3684    on init
3685      exit(3.0 >= 3.1)
3686    end on
3687    )NKSP_CODE",
3688            .expectBoolExitResult = false
3689        });
3690    
3691        runScript({
3692            .code = R"NKSP_CODE(
3693    on init
3694      exit(-23.33 >= -23.33)
3695    end on
3696    )NKSP_CODE",
3697            .expectBoolExitResult = true
3698        });
3699    
3700        runScript({
3701            .code = R"NKSP_CODE(
3702    on init
3703      exit(23.0 >= -23.0)
3704    end on
3705    )NKSP_CODE",
3706            .expectBoolExitResult = true
3707        });
3708    
3709        runScript({
3710            .code = R"NKSP_CODE(
3711    on init
3712      exit(3.0 >= 4.0)
3713    end on
3714    )NKSP_CODE",
3715            .expectBoolExitResult = false
3716        });
3717    
3718        runScript({
3719            .code = R"NKSP_CODE(
3720    on init
3721      exit(4.0 >= 3.0)
3722    end on
3723    )NKSP_CODE",
3724            .expectBoolExitResult = true
3725        });
3726    
3727        runScript({
3728            .code = R"NKSP_CODE(
3729    on init
3730      exit(-4.0 >= 3.0)
3731    end on
3732    )NKSP_CODE",
3733            .expectBoolExitResult = false
3734        });
3735    
3736        runScript({
3737            .code = R"NKSP_CODE(
3738    on init
3739      exit(3.0 >= -4.0)
3740    end on
3741    )NKSP_CODE",
3742            .expectBoolExitResult = true
3743        });
3744    
3745        runScript({
3746            .code = R"NKSP_CODE(
3747    on init
3748      exit(123.0 >= -45.0)
3749    end on
3750    )NKSP_CODE",
3751            .expectBoolExitResult = true
3752        });
3753    
3754        runScript({
3755            .code = R"NKSP_CODE(
3756    on init
3757      exit(-45.0 >= 123.0)
3758    end on
3759    )NKSP_CODE",
3760            .expectBoolExitResult = false
3761        });
3762    
3763        // mixed type tests ...
3764    
3765        runScript({
3766            .code = R"NKSP_CODE(
3767    on init
3768      exit(9 >= 9.1)
3769    end on
3770    )NKSP_CODE",
3771            .expectBoolExitResult = false
3772        });
3773    
3774        runScript({
3775            .code = R"NKSP_CODE(
3776    on init
3777      exit(9.1 >= 9)
3778    end on
3779    )NKSP_CODE",
3780            .expectBoolExitResult = true
3781        });
3782    
3783        runScript({
3784            .code = R"NKSP_CODE(
3785    on init
3786      exit(9 >= 9.0)
3787    end on
3788    )NKSP_CODE",
3789            .expectBoolExitResult = true
3790        });
3791    
3792        runScript({
3793            .code = R"NKSP_CODE(
3794    on init
3795      exit(9.0 >= 9)
3796    end on
3797    )NKSP_CODE",
3798            .expectBoolExitResult = true
3799        });
3800    
3801        // std unit tests ...
3802    
3803        runScript({
3804            .code = R"NKSP_CODE(
3805    on init
3806      exit(13ms >= 14ms)
3807    end on
3808    )NKSP_CODE",
3809            .expectBoolExitResult = false
3810        });
3811    
3812        runScript({
3813            .code = R"NKSP_CODE(
3814    on init
3815      exit(14ms >= 13ms)
3816    end on
3817    )NKSP_CODE",
3818            .expectBoolExitResult = true
3819        });
3820    
3821        runScript({
3822            .code = R"NKSP_CODE(
3823    on init
3824      exit(1s >= 990ms)
3825    end on
3826    )NKSP_CODE",
3827            .expectBoolExitResult = true
3828        });
3829    
3830        runScript({
3831            .code = R"NKSP_CODE(
3832    on init
3833      exit(990ms >= 1s)
3834    end on
3835    )NKSP_CODE",
3836            .expectBoolExitResult = false
3837        });
3838    
3839        runScript({
3840            .code = R"NKSP_CODE(
3841    on init
3842      exit(1000ms >= 1s)
3843    end on
3844    )NKSP_CODE",
3845            .expectBoolExitResult = true
3846        });
3847    
3848        runScript({
3849            .code = R"NKSP_CODE(
3850    on init
3851      exit(1s >= 1000ms)
3852    end on
3853    )NKSP_CODE",
3854            .expectBoolExitResult = true
3855        });
3856    
3857        runScript({
3858            .code = R"NKSP_CODE(
3859    on init
3860      exit(1s >= 1)
3861    end on
3862    )NKSP_CODE",
3863            .expectParseError = true // units on both sides must match
3864        });
3865    
3866        runScript({
3867            .code = R"NKSP_CODE(
3868    on init
3869      exit(1 >= 1s)
3870    end on
3871    )NKSP_CODE",
3872            .expectParseError = true // units on both sides must match
3873        });
3874    
3875        runScript({
3876            .code = R"NKSP_CODE(
3877    on init
3878      exit(1Hz >= 1B)
3879    end on
3880    )NKSP_CODE",
3881            .expectParseError = true // units on both sides must match
3882        });
3883    
3884        runScript({
3885            .code = R"NKSP_CODE(
3886    on init
3887      exit(13.0ms >= 13.1ms)
3888    end on
3889    )NKSP_CODE",
3890            .expectBoolExitResult = false
3891        });
3892    
3893        runScript({
3894            .code = R"NKSP_CODE(
3895    on init
3896      exit(13.1ms >= 13.0ms)
3897    end on
3898    )NKSP_CODE",
3899            .expectBoolExitResult = true
3900        });
3901    
3902        runScript({
3903            .code = R"NKSP_CODE(
3904    on init
3905      exit(0.9s >= 600.0ms)
3906    end on
3907    )NKSP_CODE",
3908            .expectBoolExitResult = true
3909        });
3910    
3911        runScript({
3912            .code = R"NKSP_CODE(
3913    on init
3914      exit(600.0ms >= 0.9s)
3915    end on
3916    )NKSP_CODE",
3917            .expectBoolExitResult = false
3918        });
3919    
3920        runScript({
3921            .code = R"NKSP_CODE(
3922    on init
3923      exit(5.1kHz >= 5100.0Hz)
3924    end on
3925    )NKSP_CODE",
3926            .expectBoolExitResult = true
3927        });
3928    
3929        runScript({
3930            .code = R"NKSP_CODE(
3931    on init
3932      exit(5100.0Hz >= 5.1kHz)
3933    end on
3934    )NKSP_CODE",
3935            .expectBoolExitResult = true
3936        });
3937    
3938        runScript({
3939            .code = R"NKSP_CODE(
3940    on init
3941      exit(1.0Hz >= 1.1)
3942    end on
3943    )NKSP_CODE",
3944            .expectParseError = true // units on both sides must match
3945        });
3946    
3947        runScript({
3948            .code = R"NKSP_CODE(
3949    on init
3950      exit(1.2 >= 1.34mdB)
3951    end on
3952    )NKSP_CODE",
3953            .expectParseError = true // units on both sides must match
3954        });
3955    
3956        runScript({
3957            .code = R"NKSP_CODE(
3958    on init
3959      exit(9.23us >= 3.14kHz)
3960    end on
3961    )NKSP_CODE",
3962            .expectParseError = true // units on both sides must match
3963        });
3964    
3965        // 'final' ('!') operator tests ...
3966        // (should always yield in false for relation operators)
3967    
3968        runScript({
3969            .code = R"NKSP_CODE(
3970    on init
3971      exit(!-4 >= !3)
3972    end on
3973    )NKSP_CODE",
3974            .expectBoolExitResult = false,
3975            .expectExitResultFinal = false
3976        });
3977    
3978        runScript({
3979            .code = R"NKSP_CODE(
3980    on init
3981      exit(-4 >= 3)
3982    end on
3983    )NKSP_CODE",
3984            .expectBoolExitResult = false,
3985            .expectExitResultFinal = false
3986        });
3987    
3988      #if !SILENT_TEST      #if !SILENT_TEST
3989      std::cout << std::endl;      std::cout << std::endl;
3990      #endif      #endif
# Line 752  static void testEqualOperator() { Line 3995  static void testEqualOperator() {
3995      std::cout << "UNIT TEST: equal (=) operator\n";      std::cout << "UNIT TEST: equal (=) operator\n";
3996      #endif      #endif
3997    
3998        // integer tests ...
3999    
4000      runScript({      runScript({
4001          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
4002  on init  on init
# Line 788  end on Line 4033  end on
4033          .expectBoolExitResult = false          .expectBoolExitResult = false
4034      });      });
4035    
4036        // real number tests ...
4037    
4038        runScript({
4039            .code = R"NKSP_CODE(
4040    on init
4041      exit(3.0 = 3.0)
4042    end on
4043    )NKSP_CODE",
4044            .expectBoolExitResult = true
4045        });
4046    
4047        runScript({
4048            .code = R"NKSP_CODE(
4049    on init
4050      exit(4.33 = 4.33)
4051    end on
4052    )NKSP_CODE",
4053            .expectBoolExitResult = true
4054        });
4055    
4056        runScript({
4057            .code = R"NKSP_CODE(
4058    on init
4059      exit(4.31 = 4.35)
4060    end on
4061    )NKSP_CODE",
4062            .expectBoolExitResult = false
4063        });
4064    
4065        runScript({
4066            .code = R"NKSP_CODE(
4067    on init
4068      exit(3.0 = 4.0)
4069    end on
4070    )NKSP_CODE",
4071            .expectBoolExitResult = false
4072        });
4073    
4074        runScript({
4075            .code = R"NKSP_CODE(
4076    on init
4077      exit(23.0 = -23.0)
4078    end on
4079    )NKSP_CODE",
4080            .expectBoolExitResult = false
4081        });
4082    
4083        // deal with inaccuracy of float point
4084        runScript({
4085            .code = R"NKSP_CODE(
4086    on init
4087      declare ~a := 0.165
4088      declare ~b := 0.185
4089      declare ~x := 0.1
4090      declare ~y := 0.25
4091      exit(~a + ~b = ~x + ~y) { both sides should actually be 0.35, they slightly deviate both though }
4092    end on
4093    )NKSP_CODE",
4094            .expectBoolExitResult = true // our implementation of real number equal comparison should take care about floating point tolerance
4095        });
4096    
4097        // deal with inaccuracy of float point
4098        runScript({
4099            .code = R"NKSP_CODE(
4100    on init
4101      declare ~a := 0.166
4102      declare ~b := 0.185
4103      declare ~x := 0.1
4104      declare ~y := 0.25
4105      exit(~a + ~b = ~x + ~y) { left side approx. 0.351, right side approx. 0.35 }
4106    end on
4107    )NKSP_CODE",
4108            .expectBoolExitResult = false
4109        });
4110    
4111        // mixed type tests ...
4112    
4113        runScript({
4114            .code = R"NKSP_CODE(
4115    on init
4116      exit(23 = 23.0)
4117    end on
4118    )NKSP_CODE",
4119            .expectBoolExitResult = true
4120        });
4121    
4122        runScript({
4123            .code = R"NKSP_CODE(
4124    on init
4125      exit(23.0 = 23)
4126    end on
4127    )NKSP_CODE",
4128            .expectBoolExitResult = true
4129        });
4130    
4131        runScript({
4132            .code = R"NKSP_CODE(
4133    on init
4134      exit(23 = 23.1)
4135    end on
4136    )NKSP_CODE",
4137            .expectBoolExitResult = false
4138        });
4139    
4140        runScript({
4141            .code = R"NKSP_CODE(
4142    on init
4143      exit(23.1 = 23)
4144    end on
4145    )NKSP_CODE",
4146            .expectBoolExitResult = false
4147        });
4148    
4149        // std unit tests ...
4150    
4151        runScript({
4152            .code = R"NKSP_CODE(
4153    on init
4154      exit(13ms = 14ms)
4155    end on
4156    )NKSP_CODE",
4157            .expectBoolExitResult = false
4158        });
4159    
4160        runScript({
4161            .code = R"NKSP_CODE(
4162    on init
4163      exit(14ms = 13ms)
4164    end on
4165    )NKSP_CODE",
4166            .expectBoolExitResult = false
4167        });
4168    
4169        runScript({
4170            .code = R"NKSP_CODE(
4171    on init
4172      exit(1s = 1ms)
4173    end on
4174    )NKSP_CODE",
4175            .expectBoolExitResult = false
4176        });
4177    
4178        runScript({
4179            .code = R"NKSP_CODE(
4180    on init
4181      exit(1ms = 1s)
4182    end on
4183    )NKSP_CODE",
4184            .expectBoolExitResult = false
4185        });
4186    
4187        runScript({
4188            .code = R"NKSP_CODE(
4189    on init
4190      exit(3.14kHz = 3140Hz)
4191    end on
4192    )NKSP_CODE",
4193            .expectBoolExitResult = true
4194        });
4195    
4196        runScript({
4197            .code = R"NKSP_CODE(
4198    on init
4199      exit(3140Hz = 3.14kHz)
4200    end on
4201    )NKSP_CODE",
4202            .expectBoolExitResult = true
4203        });
4204    
4205        runScript({
4206            .code = R"NKSP_CODE(
4207    on init
4208      exit(1s = 1)
4209    end on
4210    )NKSP_CODE",
4211            .expectParseError = true // units on both sides must match
4212        });
4213    
4214        runScript({
4215            .code = R"NKSP_CODE(
4216    on init
4217      exit(1 = 1s)
4218    end on
4219    )NKSP_CODE",
4220            .expectParseError = true // units on both sides must match
4221        });
4222    
4223        runScript({
4224            .code = R"NKSP_CODE(
4225    on init
4226      exit(1Hz = 1B)
4227    end on
4228    )NKSP_CODE",
4229            .expectParseError = true // units on both sides must match
4230        });
4231    
4232        // 'final' ('!') operator tests ...
4233        // (should always yield in false for relation operators)
4234    
4235        runScript({
4236            .code = R"NKSP_CODE(
4237    on init
4238      exit(!-4 = !3)
4239    end on
4240    )NKSP_CODE",
4241            .expectBoolExitResult = false,
4242            .expectExitResultFinal = false
4243        });
4244    
4245        runScript({
4246            .code = R"NKSP_CODE(
4247    on init
4248      exit(-4 = 3)
4249    end on
4250    )NKSP_CODE",
4251            .expectBoolExitResult = false,
4252            .expectExitResultFinal = false
4253        });
4254    
4255      #if !SILENT_TEST      #if !SILENT_TEST
4256      std::cout << std::endl;      std::cout << std::endl;
4257      #endif      #endif
# Line 798  static void testUnequalOperator() { Line 4262  static void testUnequalOperator() {
4262      std::cout << "UNIT TEST: unequal (#) operator\n";      std::cout << "UNIT TEST: unequal (#) operator\n";
4263      #endif      #endif
4264    
4265        // integer tests ...
4266    
4267      runScript({      runScript({
4268          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
4269  on init  on init
# Line 834  end on Line 4300  end on
4300          .expectBoolExitResult = true          .expectBoolExitResult = true
4301      });      });
4302    
4303        // real number tests ...
4304    
4305        runScript({
4306            .code = R"NKSP_CODE(
4307    on init
4308      exit(3.0 # 3.0)
4309    end on
4310    )NKSP_CODE",
4311            .expectBoolExitResult = false
4312        });
4313    
4314        runScript({
4315            .code = R"NKSP_CODE(
4316    on init
4317      exit(3.14 # 3.14)
4318    end on
4319    )NKSP_CODE",
4320            .expectBoolExitResult = false
4321        });
4322    
4323        runScript({
4324            .code = R"NKSP_CODE(
4325    on init
4326      exit(3.19 # 3.12)
4327    end on
4328    )NKSP_CODE",
4329            .expectBoolExitResult = true
4330        });
4331    
4332        runScript({
4333            .code = R"NKSP_CODE(
4334    on init
4335      exit(23.0 # -23.0)
4336    end on
4337    )NKSP_CODE",
4338            .expectBoolExitResult = true
4339        });
4340    
4341        // deal with inaccuracy of float point
4342        runScript({
4343            .code = R"NKSP_CODE(
4344    on init
4345      declare ~a := 0.165
4346      declare ~b := 0.185
4347      declare ~x := 0.1
4348      declare ~y := 0.25
4349            exit(~a + ~b # ~x + ~y) { both sides should actually be 0.35, they slightly deviate both though }
4350    end on
4351    )NKSP_CODE",
4352            .expectBoolExitResult = false // our implementation of real number unequal comparison should take care about floating point tolerance
4353        });
4354    
4355        // deal with inaccuracy of float point
4356        runScript({
4357            .code = R"NKSP_CODE(
4358    on init
4359      declare ~a := 0.166
4360      declare ~b := 0.185
4361      declare ~x := 0.1
4362      declare ~y := 0.25
4363            exit(~a + ~b # ~x + ~y) { left side approx. 0.351, right side approx. 0.35 }
4364    end on
4365    )NKSP_CODE",
4366            .expectBoolExitResult = true
4367        });
4368    
4369        // mixed type tests ...
4370    
4371        runScript({
4372            .code = R"NKSP_CODE(
4373    on init
4374      exit(3 # 3.0)
4375    end on
4376    )NKSP_CODE",
4377            .expectBoolExitResult = false
4378        });
4379    
4380        runScript({
4381            .code = R"NKSP_CODE(
4382    on init
4383      exit(3.0 # 3)
4384    end on
4385    )NKSP_CODE",
4386            .expectBoolExitResult = false
4387        });
4388    
4389        runScript({
4390            .code = R"NKSP_CODE(
4391    on init
4392      exit(3.1 # 3)
4393    end on
4394    )NKSP_CODE",
4395            .expectBoolExitResult = true
4396        });
4397    
4398        runScript({
4399            .code = R"NKSP_CODE(
4400    on init
4401      exit(3 # 3.1)
4402    end on
4403    )NKSP_CODE",
4404            .expectBoolExitResult = true
4405        });
4406    
4407        // std unit tests ...
4408    
4409        runScript({
4410            .code = R"NKSP_CODE(
4411    on init
4412      exit(13ms # 14ms)
4413    end on
4414    )NKSP_CODE",
4415            .expectBoolExitResult = true
4416        });
4417    
4418        runScript({
4419            .code = R"NKSP_CODE(
4420    on init
4421      exit(14ms # 13ms)
4422    end on
4423    )NKSP_CODE",
4424            .expectBoolExitResult = true
4425        });
4426    
4427        runScript({
4428            .code = R"NKSP_CODE(
4429    on init
4430      exit(1s # 1ms)
4431    end on
4432    )NKSP_CODE",
4433            .expectBoolExitResult = true
4434        });
4435    
4436        runScript({
4437            .code = R"NKSP_CODE(
4438    on init
4439      exit(1ms # 1s)
4440    end on
4441    )NKSP_CODE",
4442            .expectBoolExitResult = true
4443        });
4444    
4445        runScript({
4446            .code = R"NKSP_CODE(
4447    on init
4448      exit(3.14kHz # 3140Hz)
4449    end on
4450    )NKSP_CODE",
4451            .expectBoolExitResult = false
4452        });
4453    
4454        runScript({
4455            .code = R"NKSP_CODE(
4456    on init
4457      exit(3140Hz # 3.14kHz)
4458    end on
4459    )NKSP_CODE",
4460            .expectBoolExitResult = false
4461        });
4462    
4463        runScript({
4464            .code = R"NKSP_CODE(
4465    on init
4466      exit(1s # 1)
4467    end on
4468    )NKSP_CODE",
4469            .expectParseError = true // units on both sides must match
4470        });
4471    
4472        runScript({
4473            .code = R"NKSP_CODE(
4474    on init
4475      exit(1 # 1s)
4476    end on
4477    )NKSP_CODE",
4478            .expectParseError = true // units on both sides must match
4479        });
4480    
4481        runScript({
4482            .code = R"NKSP_CODE(
4483    on init
4484      exit(1Hz # 1B)
4485    end on
4486    )NKSP_CODE",
4487            .expectParseError = true // units on both sides must match
4488        });
4489    
4490        // 'final' ('!') operator tests ...
4491        // (should always yield in false for relation operators)
4492    
4493        runScript({
4494            .code = R"NKSP_CODE(
4495    on init
4496      exit(!-4 # !3)
4497    end on
4498    )NKSP_CODE",
4499            .expectBoolExitResult = true,
4500            .expectExitResultFinal = false
4501        });
4502    
4503        runScript({
4504            .code = R"NKSP_CODE(
4505    on init
4506      exit(-4 # 3)
4507    end on
4508    )NKSP_CODE",
4509            .expectBoolExitResult = true,
4510            .expectExitResultFinal = false
4511        });
4512    
4513      #if !SILENT_TEST      #if !SILENT_TEST
4514      std::cout << std::endl;      std::cout << std::endl;
4515      #endif      #endif
# Line 844  static void testLogicalAndOperator() { Line 4520  static void testLogicalAndOperator() {
4520      std::cout << "UNIT TEST: logical and (and) operator\n";      std::cout << "UNIT TEST: logical and (and) operator\n";
4521      #endif      #endif
4522    
4523        // integer tests ...
4524    
4525      runScript({      runScript({
4526          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
4527  on init  on init
# Line 898  end on Line 4576  end on
4576          .expectBoolExitResult = false          .expectBoolExitResult = false
4577      });      });
4578    
4579        // real number tests ...
4580        // (not allowed for this operator)
4581    
4582        runScript({
4583            .code = R"NKSP_CODE(
4584    on init
4585      exit(1.0 and 1.0)
4586    end on
4587    )NKSP_CODE",
4588            .expectParseError = true // real numbers not allowed for this operator
4589        });
4590    
4591        // mixed type tests ...
4592        // (not allowed for this operator)
4593    
4594        runScript({
4595            .code = R"NKSP_CODE(
4596    on init
4597      exit(1.0 and 1)
4598    end on
4599    )NKSP_CODE",
4600            .expectParseError = true // real numbers not allowed for this operator
4601        });
4602    
4603        runScript({
4604            .code = R"NKSP_CODE(
4605    on init
4606      exit(1 and 1.0)
4607    end on
4608    )NKSP_CODE",
4609            .expectParseError = true // real numbers not allowed for this operator
4610        });
4611    
4612        // std unit tests ...
4613        // (not allowed for this operator)
4614    
4615        runScript({
4616            .code = R"NKSP_CODE(
4617    on init
4618      exit(1s and 0)
4619    end on
4620    )NKSP_CODE",
4621            .expectParseError = true // std units not allowed for this operator
4622        });
4623    
4624        runScript({
4625            .code = R"NKSP_CODE(
4626    on init
4627      exit(0 and 1s)
4628    end on
4629    )NKSP_CODE",
4630            .expectParseError = true // std units not allowed for this operator
4631        });
4632    
4633        // 'final' ('!') operator tests ...
4634    
4635        runScript({
4636            .code = R"NKSP_CODE(
4637    on init
4638      exit(!0 and !0)
4639    end on
4640    )NKSP_CODE",
4641            .expectExitResultFinal = true
4642        });
4643    
4644        runScript({
4645            .code = R"NKSP_CODE(
4646    on init
4647      exit(0 and 0)
4648    end on
4649    )NKSP_CODE",
4650            .expectExitResultFinal = false
4651        });
4652    
4653      #if !SILENT_TEST      #if !SILENT_TEST
4654      std::cout << std::endl;      std::cout << std::endl;
4655      #endif      #endif
# Line 908  static void testLogicalOrOperator() { Line 4660  static void testLogicalOrOperator() {
4660      std::cout << "UNIT TEST: logical or (or) operator\n";      std::cout << "UNIT TEST: logical or (or) operator\n";
4661      #endif      #endif
4662    
4663        // integer tests ...
4664    
4665      runScript({      runScript({
4666          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
4667  on init  on init
# Line 962  end on Line 4716  end on
4716          .expectBoolExitResult = false          .expectBoolExitResult = false
4717      });      });
4718    
4719        // real number tests ...
4720        // (not allowed for this operator)
4721    
4722        runScript({
4723            .code = R"NKSP_CODE(
4724    on init
4725      exit(1.0 or 1.0)
4726    end on
4727    )NKSP_CODE",
4728            .expectParseError = true // real numbers not allowed for this operator
4729        });
4730    
4731        // mixed type tests ...
4732        // (not allowed for this operator)
4733    
4734        runScript({
4735            .code = R"NKSP_CODE(
4736    on init
4737      exit(1.0 or 1)
4738    end on
4739    )NKSP_CODE",
4740            .expectParseError = true // real numbers not allowed for this operator
4741        });
4742    
4743        runScript({
4744            .code = R"NKSP_CODE(
4745    on init
4746      exit(1 or 1.0)
4747    end on
4748    )NKSP_CODE",
4749            .expectParseError = true // real numbers not allowed for this operator
4750        });
4751    
4752        // std unit tests ...
4753        // (not allowed for this operator)
4754    
4755        runScript({
4756            .code = R"NKSP_CODE(
4757    on init
4758      exit(1s or 0)
4759    end on
4760    )NKSP_CODE",
4761            .expectParseError = true // std units not allowed for this operator
4762        });
4763    
4764        runScript({
4765            .code = R"NKSP_CODE(
4766    on init
4767      exit(0 or 1s)
4768    end on
4769    )NKSP_CODE",
4770            .expectParseError = true // std units not allowed for this operator
4771        });
4772    
4773        // 'final' ('!') operator tests ...
4774    
4775        runScript({
4776            .code = R"NKSP_CODE(
4777    on init
4778      exit(!0 or !0)
4779    end on
4780    )NKSP_CODE",
4781            .expectExitResultFinal = true
4782        });
4783    
4784        runScript({
4785            .code = R"NKSP_CODE(
4786    on init
4787      exit(0 or 0)
4788    end on
4789    )NKSP_CODE",
4790            .expectExitResultFinal = false
4791        });
4792    
4793      #if !SILENT_TEST      #if !SILENT_TEST
4794      std::cout << std::endl;      std::cout << std::endl;
4795      #endif      #endif
# Line 972  static void testLogicalNotOperator() { Line 4800  static void testLogicalNotOperator() {
4800      std::cout << "UNIT TEST: logical not (not) operator\n";      std::cout << "UNIT TEST: logical not (not) operator\n";
4801      #endif      #endif
4802    
4803        // integer tests ...
4804    
4805      runScript({      runScript({
4806          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
4807  on init  on init
# Line 999  end on Line 4829  end on
4829          .expectBoolExitResult = true          .expectBoolExitResult = true
4830      });      });
4831    
4832        // real number tests ...
4833        // (not allowed for this operator)
4834    
4835        runScript({
4836            .code = R"NKSP_CODE(
4837    on init
4838      exit(not 1.0)
4839    end on
4840    )NKSP_CODE",
4841            .expectParseError = true // real numbers not allowed for this operator
4842        });
4843    
4844        // std unit tests ...
4845        // (not allowed for this operator)
4846    
4847        runScript({
4848            .code = R"NKSP_CODE(
4849    on init
4850      exit(not 1s)
4851    end on
4852    )NKSP_CODE",
4853            .expectParseError = true // std units not allowed for this operator
4854        });
4855    
4856        // 'final' ('!') operator tests ...
4857    
4858        runScript({
4859            .code = R"NKSP_CODE(
4860    on init
4861      exit(not !1)
4862    end on
4863    )NKSP_CODE",
4864            .expectExitResultFinal = true
4865        });
4866    
4867        runScript({
4868            .code = R"NKSP_CODE(
4869    on init
4870      exit(not 1)
4871    end on
4872    )NKSP_CODE",
4873            .expectExitResultFinal = false
4874        });
4875    
4876      #if !SILENT_TEST      #if !SILENT_TEST
4877      std::cout << std::endl;      std::cout << std::endl;
4878      #endif      #endif
# Line 1009  static void testBitwiseAndOperator() { Line 4883  static void testBitwiseAndOperator() {
4883      std::cout << "UNIT TEST: bitwise and (.and.) operator\n";      std::cout << "UNIT TEST: bitwise and (.and.) operator\n";
4884      #endif      #endif
4885    
4886        // integer tests ...
4887    
4888      runScript({      runScript({
4889          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
4890  on init  on init
# Line 1027  end on Line 4903  end on
4903          .expectIntExitResult = 10          .expectIntExitResult = 10
4904      });      });
4905    
4906        // real number tests ...
4907        // (not allowed for this operator)
4908    
4909        runScript({
4910            .code = R"NKSP_CODE(
4911    on init
4912      exit(1.0 .and. 1.0)
4913    end on
4914    )NKSP_CODE",
4915            .expectParseError = true // real numbers not allowed for this operator
4916        });
4917    
4918        // mixed type tests ...
4919        // (not allowed for this operator)
4920    
4921        runScript({
4922            .code = R"NKSP_CODE(
4923    on init
4924      exit(1.0 .and. 1)
4925    end on
4926    )NKSP_CODE",
4927            .expectParseError = true // real numbers not allowed for this operator
4928        });
4929    
4930        runScript({
4931            .code = R"NKSP_CODE(
4932    on init
4933      exit(1 .and. 1.0)
4934    end on
4935    )NKSP_CODE",
4936            .expectParseError = true // real numbers not allowed for this operator
4937        });
4938    
4939        // std unit tests ...
4940        // (not allowed for this operator)
4941    
4942        runScript({
4943            .code = R"NKSP_CODE(
4944    on init
4945      exit(1s .and. 1)
4946    end on
4947    )NKSP_CODE",
4948            .expectParseError = true // std units not allowed for this operator
4949        });
4950    
4951        runScript({
4952            .code = R"NKSP_CODE(
4953    on init
4954      exit(1 .and. 1s)
4955    end on
4956    )NKSP_CODE",
4957            .expectParseError = true // std units not allowed for this operator
4958        });
4959    
4960        // 'final' ('!') operator tests ...
4961    
4962        runScript({
4963            .code = R"NKSP_CODE(
4964    on init
4965      exit(!43 .and. !142)
4966    end on
4967    )NKSP_CODE",
4968            .expectIntExitResult = 10,
4969            .expectExitResultFinal = true
4970        });
4971    
4972        runScript({
4973            .code = R"NKSP_CODE(
4974    on init
4975      exit(43 .and. 142)
4976    end on
4977    )NKSP_CODE",
4978            .expectIntExitResult = 10,
4979            .expectExitResultFinal = false
4980        });
4981    
4982      #if !SILENT_TEST      #if !SILENT_TEST
4983      std::cout << std::endl;      std::cout << std::endl;
4984      #endif      #endif
# Line 1037  static void testBitwiseOrOperator() { Line 4989  static void testBitwiseOrOperator() {
4989      std::cout << "UNIT TEST: bitwise or (.or.) operator\n";      std::cout << "UNIT TEST: bitwise or (.or.) operator\n";
4990      #endif      #endif
4991    
4992        // integer tests ...
4993    
4994      runScript({      runScript({
4995          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
4996  on init  on init
# Line 1064  end on Line 5018  end on
5018          .expectIntExitResult = 175          .expectIntExitResult = 175
5019      });      });
5020    
5021        // real number tests ...
5022        // (not allowed for this operator)
5023    
5024        runScript({
5025            .code = R"NKSP_CODE(
5026    on init
5027      exit(1.0 .or. 1.0)
5028    end on
5029    )NKSP_CODE",
5030            .expectParseError = true // real numbers not allowed for this operator
5031        });
5032    
5033        // mixed type tests ...
5034        // (not allowed for this operator)
5035    
5036        runScript({
5037            .code = R"NKSP_CODE(
5038    on init
5039      exit(1.0 .or. 1)
5040    end on
5041    )NKSP_CODE",
5042            .expectParseError = true // real numbers not allowed for this operator
5043        });
5044    
5045        runScript({
5046            .code = R"NKSP_CODE(
5047    on init
5048      exit(1 .or. 1.0)
5049    end on
5050    )NKSP_CODE",
5051            .expectParseError = true // real numbers not allowed for this operator
5052        });
5053    
5054        // std unit tests ...
5055        // (not allowed for this operator)
5056    
5057        runScript({
5058            .code = R"NKSP_CODE(
5059    on init
5060      exit(1s .or. 1)
5061    end on
5062    )NKSP_CODE",
5063            .expectParseError = true // std units not allowed for this operator
5064        });
5065    
5066        runScript({
5067            .code = R"NKSP_CODE(
5068    on init
5069      exit(1 .or. 1s)
5070    end on
5071    )NKSP_CODE",
5072            .expectParseError = true // std units not allowed for this operator
5073        });
5074    
5075        // 'final' ('!') operator tests ...
5076    
5077        runScript({
5078            .code = R"NKSP_CODE(
5079    on init
5080      exit(!43 .or. !142)
5081    end on
5082    )NKSP_CODE",
5083            .expectIntExitResult = 175,
5084            .expectExitResultFinal = true
5085        });
5086    
5087        runScript({
5088            .code = R"NKSP_CODE(
5089    on init
5090      exit(43 .or. 142)
5091    end on
5092    )NKSP_CODE",
5093            .expectIntExitResult = 175,
5094            .expectExitResultFinal = false
5095        });
5096    
5097      #if !SILENT_TEST      #if !SILENT_TEST
5098      std::cout << std::endl;      std::cout << std::endl;
5099      #endif      #endif
# Line 1074  static void testBitwiseNotOperator() { Line 5104  static void testBitwiseNotOperator() {
5104      std::cout << "UNIT TEST: bitwise not (.not.) operator\n";      std::cout << "UNIT TEST: bitwise not (.not.) operator\n";
5105      #endif      #endif
5106    
5107        // integer tests ...
5108    
5109      runScript({      runScript({
5110          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
5111  on init  on init
# Line 1101  end on Line 5133  end on
5133          .expectIntExitResult = ssize_t(size_t(-1) << 2)          .expectIntExitResult = ssize_t(size_t(-1) << 2)
5134      });      });
5135    
5136        // real number tests ...
5137        // (not allowed for this operator)
5138    
5139        runScript({
5140            .code = R"NKSP_CODE(
5141    on init
5142      exit(.not. 1.0)
5143    end on
5144    )NKSP_CODE",
5145            .expectParseError = true // real numbers not allowed for this operator
5146        });
5147    
5148        runScript({
5149            .code = R"NKSP_CODE(
5150    on init
5151      exit(.not. -1.0)
5152    end on
5153    )NKSP_CODE",
5154            .expectParseError = true // real numbers not allowed for this operator
5155        });
5156    
5157        // std unit tests ...
5158        // (not allowed for this operator)
5159    
5160        runScript({
5161            .code = R"NKSP_CODE(
5162    on init
5163      exit(.not. 1s)
5164    end on
5165    )NKSP_CODE",
5166            .expectParseError = true // std units not allowed for this operator
5167        });
5168    
5169        // 'final' ('!') operator tests ...
5170    
5171        runScript({
5172            .code = R"NKSP_CODE(
5173    on init
5174      exit(.not. !0)
5175    end on
5176    )NKSP_CODE",
5177            .expectIntExitResult = -1,
5178            .expectExitResultFinal = true
5179        });
5180    
5181        runScript({
5182            .code = R"NKSP_CODE(
5183    on init
5184      exit(.not. 0)
5185    end on
5186    )NKSP_CODE",
5187            .expectIntExitResult = -1,
5188            .expectExitResultFinal = false
5189        });
5190    
5191      #if !SILENT_TEST      #if !SILENT_TEST
5192      std::cout << std::endl;      std::cout << std::endl;
5193      #endif      #endif
# Line 1111  static void testPrecedenceOfOperators() Line 5198  static void testPrecedenceOfOperators()
5198      std::cout << "UNIT TEST: precedence of operators\n";      std::cout << "UNIT TEST: precedence of operators\n";
5199      #endif      #endif
5200    
5201        // integer tests ...
5202    
5203      runScript({      runScript({
5204          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
5205  on init  on init
# Line 1147  end on Line 5236  end on
5236          .expectIntExitResult = 20          .expectIntExitResult = 20
5237      });      });
5238    
5239        // real number tests ...
5240    
5241        runScript({
5242            .code = R"NKSP_CODE(
5243    on init
5244      exit(3.2 + 4.0 * 2.0)
5245    end on
5246    )NKSP_CODE",
5247            .expectRealExitResult = 11.2
5248        });
5249    
5250        runScript({
5251            .code = R"NKSP_CODE(
5252    on init
5253      exit(4.0 * 2.0 + 3.2)
5254    end on
5255    )NKSP_CODE",
5256            .expectRealExitResult = 11.2
5257        });
5258    
5259        runScript({
5260            .code = R"NKSP_CODE(
5261    on init
5262      exit((3.2 + 4.0) * 2.0)
5263    end on
5264    )NKSP_CODE",
5265            .expectRealExitResult = 14.4
5266        });
5267    
5268        runScript({
5269            .code = R"NKSP_CODE(
5270    on init
5271      exit(4.0 * (2.0 + 3.2))
5272    end on
5273    )NKSP_CODE",
5274            .expectRealExitResult = 20.8
5275        });
5276    
5277        // std unit tests ...
5278    
5279        runScript({
5280            .code = R"NKSP_CODE(
5281    on init
5282      exit(4 * (2us + 3us) + 7ms)
5283    end on
5284    )NKSP_CODE",
5285            .expectIntExitResult = 7020,
5286            .expectExitResultUnitPrefix = { VM_MICRO },
5287            .expectExitResultUnit = VM_SECOND
5288        });
5289    
5290        runScript({
5291            .code = R"NKSP_CODE(
5292    on init
5293      declare $a := 4
5294      declare $c := 3us
5295      exit($a * (2us + $c) + 7ms)
5296    end on
5297    )NKSP_CODE",
5298            .expectIntExitResult = 7020,
5299            .expectExitResultUnitPrefix = { VM_MICRO },
5300            .expectExitResultUnit = VM_SECOND
5301        });
5302    
5303        runScript({
5304            .code = R"NKSP_CODE(
5305    on init
5306      declare $a := 4
5307      declare $b := 2us
5308      declare $c := 3us
5309      exit($a * ($b + $c) + 7ms)
5310    end on
5311    )NKSP_CODE",
5312            .expectIntExitResult = 7020,
5313            .expectExitResultUnitPrefix = { VM_MICRO },
5314            .expectExitResultUnit = VM_SECOND
5315        });
5316    
5317        runScript({
5318            .code = R"NKSP_CODE(
5319    on init
5320      declare $a := 4
5321      declare $b := 2us
5322      declare $c := 3us
5323      declare $d := 7ms
5324      exit($a * ($b + $c) + 7ms)
5325    end on
5326    )NKSP_CODE",
5327            .expectIntExitResult = 7020,
5328            .expectExitResultUnitPrefix = { VM_MICRO },
5329            .expectExitResultUnit = VM_SECOND
5330        });
5331    
5332        runScript({
5333            .code = R"NKSP_CODE(
5334    on init
5335      declare $c := 3us
5336      declare $a := 4
5337      declare $d := 7ms
5338      declare $b := 2us
5339      exit($a * ($b + $c) + 7ms)
5340    end on
5341    )NKSP_CODE",
5342            .expectIntExitResult = 7020,
5343            .expectExitResultUnitPrefix = { VM_MICRO },
5344            .expectExitResultUnit = VM_SECOND
5345        });
5346    
5347        runScript({
5348            .code = R"NKSP_CODE(
5349    on init
5350      exit(4.0 * (2.0mdB + 3.2mdB) / 2.0)
5351    end on
5352    )NKSP_CODE",
5353            .expectRealExitResult = 10.4,
5354            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
5355            .expectExitResultUnit = VM_BEL
5356        });
5357    
5358        runScript({
5359            .code = R"NKSP_CODE(
5360    on init
5361      declare ~a := 2.0mdB
5362      declare ~b := 3.2mdB
5363      exit(4.0 * (~a + ~b) / 2.0)
5364    end on
5365    )NKSP_CODE",
5366            .expectRealExitResult = 10.4,
5367            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
5368            .expectExitResultUnit = VM_BEL
5369        });
5370    
5371        runScript({
5372            .code = R"NKSP_CODE(
5373    on init
5374      declare ~b := 3.2mdB
5375      declare ~a := 2.0mdB
5376      exit(4.0 * (~a + ~b) / 2.0)
5377    end on
5378    )NKSP_CODE",
5379            .expectRealExitResult = 10.4,
5380            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
5381            .expectExitResultUnit = VM_BEL
5382        });
5383    
5384        runScript({
5385            .code = R"NKSP_CODE(
5386    on init
5387      declare ~a := 4.0
5388      declare ~b := 2.0mdB
5389      declare ~c := 3.2mdB
5390      declare ~d := 2.0
5391      exit((~a * (~b + ~c) / ~d) + 1.1mdB)
5392    end on
5393    )NKSP_CODE",
5394            .expectRealExitResult = 11.5,
5395            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
5396            .expectExitResultUnit = VM_BEL
5397        });
5398    
5399        runScript({
5400            .code = R"NKSP_CODE(
5401    on init
5402      declare ~c := 3.2mdB
5403      declare ~a := 4.0
5404      declare ~d := 2.0
5405      declare ~b := 2.0mdB
5406      exit(~a * (~b + ~c) / ~d + 1.1mdB)
5407    end on
5408    )NKSP_CODE",
5409            .expectRealExitResult = 11.5,
5410            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
5411            .expectExitResultUnit = VM_BEL
5412        });
5413    
5414        // 'final' ('!') operator tests ...
5415    
5416        runScript({
5417            .code = R"NKSP_CODE(
5418    on init
5419      declare $a := 4
5420      declare $b := !2us
5421      declare $c := 3us
5422      declare $d := 7ms
5423      exit($a * ($b + $c) + 7ms)
5424    end on
5425    )NKSP_CODE",
5426            .expectIntExitResult = 7020,
5427            .expectExitResultUnitPrefix = { VM_MICRO },
5428            .expectExitResultUnit = VM_SECOND,
5429            .expectExitResultFinal = true,
5430            .expectParseWarning = true // only one operand is defined as 'final', result will be final though
5431        });
5432    
5433        runScript({
5434            .code = R"NKSP_CODE(
5435    on init
5436      declare $a := 4
5437      declare $b := 2us
5438      declare $c := !3us
5439      declare $d := 7ms
5440      exit($a * ($b + $c) + 7ms)
5441    end on
5442    )NKSP_CODE",
5443            .expectIntExitResult = 7020,
5444            .expectExitResultUnitPrefix = { VM_MICRO },
5445            .expectExitResultUnit = VM_SECOND,
5446            .expectExitResultFinal = true,
5447            .expectParseWarning = true // only one operand is defined as 'final', result will be final though
5448        });
5449    
5450        #if !SILENT_TEST
5451        std::cout << std::endl;
5452        #endif
5453    }
5454    
5455    static void testIntVarDeclaration() {
5456        #if !SILENT_TEST
5457        std::cout << "UNIT TEST: int var declaration\n";
5458        #endif
5459    
5460        runScript({
5461            .code = R"NKSP_CODE(
5462    on init
5463      declare $a
5464      exit($a)
5465    end on
5466    )NKSP_CODE",
5467            .expectIntExitResult = 0
5468        });
5469    
5470        runScript({
5471            .code = R"NKSP_CODE(
5472    on init
5473      declare $a := 24
5474      exit($a)
5475    end on
5476    )NKSP_CODE",
5477            .expectIntExitResult = 24
5478        });
5479    
5480        runScript({
5481            .code = R"NKSP_CODE(
5482    on init
5483      declare $a := 24
5484      $a := 8
5485      exit($a)
5486    end on
5487    )NKSP_CODE",
5488            .expectIntExitResult = 8
5489        });
5490    
5491        runScript({
5492            .code = R"NKSP_CODE(
5493    on init
5494      declare $a
5495      declare $a
5496    end on
5497    )NKSP_CODE",
5498            .expectParseError = true // variable re-declaration
5499        });
5500    
5501        runScript({
5502            .code = R"NKSP_CODE(
5503    on init
5504      declare const $a
5505    end on
5506    )NKSP_CODE",
5507            .expectParseError = true // const variable declaration without assignment
5508        });
5509    
5510        runScript({
5511            .code = R"NKSP_CODE(
5512    on init
5513      declare const $a := 24
5514      exit($a)
5515    end on
5516    )NKSP_CODE",
5517            .expectIntExitResult = 24
5518        });
5519    
5520        runScript({
5521            .code = R"NKSP_CODE(
5522    on init
5523      declare const $a := 24
5524      $a := 8
5525    end on
5526    )NKSP_CODE",
5527            .expectParseError = true // attempt to modify const variable
5528        });
5529    
5530        runScript({
5531            .code = R"NKSP_CODE(
5532    on init
5533      declare const $a := 24
5534      declare const $b := $a
5535      exit($b)
5536    end on
5537    )NKSP_CODE",
5538            .expectIntExitResult = 24
5539        });
5540    
5541        runScript({
5542            .code = R"NKSP_CODE(
5543    on init
5544      declare $a := 24
5545      declare const $b := $a
5546    end on
5547    )NKSP_CODE",
5548            .expectParseError = true // const variable defined with non-const assignment
5549        });
5550    
5551        runScript({
5552            .code = R"NKSP_CODE(
5553    on init
5554      declare polyphonic $a
5555      exit($a)
5556    end on
5557    )NKSP_CODE",
5558            .expectIntExitResult = 0
5559        });
5560    
5561        runScript({
5562            .code = R"NKSP_CODE(
5563    on init
5564      declare const polyphonic $a
5565    end on
5566    )NKSP_CODE",
5567            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
5568        });
5569    
5570        runScript({
5571            .code = R"NKSP_CODE(
5572    on init
5573      declare polyphonic const $a
5574    end on
5575    )NKSP_CODE",
5576            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
5577        });
5578    
5579        runScript({
5580            .code = R"NKSP_CODE(
5581    on init
5582      declare const polyphonic $a := 3
5583    end on
5584    )NKSP_CODE",
5585            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
5586        });
5587    
5588        runScript({
5589            .code = R"NKSP_CODE(
5590    on init
5591      declare polyphonic const $a := 3
5592    end on
5593    )NKSP_CODE",
5594            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
5595        });
5596    
5597        runScript({
5598            .code = R"NKSP_CODE(
5599    on init
5600      declare ~a := 24
5601      exit(~a)
5602    end on
5603    )NKSP_CODE",
5604            .expectParseWarning = true, // real type declaration vs. int value assignment
5605            .expectIntExitResult = 24
5606        });
5607    
5608        runScript({
5609            .code = R"NKSP_CODE(
5610    on init
5611      declare %a := 24
5612      exit(%a)
5613    end on
5614    )NKSP_CODE",
5615            .expectParseWarning = true, // int array type declaration vs. int scalar value assignment
5616            .expectIntExitResult = 24
5617        });
5618    
5619        runScript({
5620            .code = R"NKSP_CODE(
5621    on init
5622      declare const %a := 24
5623      exit(%a)
5624    end on
5625    )NKSP_CODE",
5626            .expectParseWarning = true, // int array type declaration vs. int scalar value assignment
5627            .expectIntExitResult = 24
5628        });
5629    
5630        runScript({
5631            .code = R"NKSP_CODE(
5632    on init
5633      declare ?a := 24
5634      exit(?a)
5635    end on
5636    )NKSP_CODE",
5637            .expectParseWarning = true, // real array type declaration vs. int scalar value assignment
5638            .expectIntExitResult = 24
5639        });
5640    
5641        runScript({
5642            .code = R"NKSP_CODE(
5643    on init
5644      declare const ?a := 24
5645      exit(?a)
5646    end on
5647    )NKSP_CODE",
5648            .expectParseWarning = true, // real array type declaration vs. int scalar value assignment
5649            .expectIntExitResult = 24
5650        });
5651    
5652        runScript({
5653            .code = R"NKSP_CODE(
5654    on init
5655      declare @a := 24
5656      exit(@a)
5657    end on
5658    )NKSP_CODE",
5659            .expectParseWarning = true, // string type declaration vs. int scalar value assignment
5660            .expectIntExitResult = 24
5661        });
5662    
5663        runScript({
5664            .code = R"NKSP_CODE(
5665    on init
5666      declare const @a := 24
5667      exit(@a)
5668    end on
5669    )NKSP_CODE",
5670            .expectParseWarning = true, // string type declaration vs. int scalar value assignment
5671            .expectIntExitResult = 24
5672        });
5673    
5674        runScript({
5675            .code = R"NKSP_CODE(
5676    on init
5677      declare $a := ( 0, 1, 2 )
5678    end on
5679    )NKSP_CODE",
5680            .expectParseError = true // int scalar type declaration vs. int array value assignment
5681        });
5682    
5683        runScript({
5684            .code = R"NKSP_CODE(
5685    on init
5686      declare const $a := ( 0, 1, 2 )
5687    end on
5688    )NKSP_CODE",
5689            .expectParseError = true // int scalar type declaration vs. int array value assignment
5690        });
5691    
5692        runScript({
5693            .code = R"NKSP_CODE(
5694    on init
5695      declare a
5696    end on
5697    )NKSP_CODE",
5698            .expectParseError = true // missing type prefix character in variable name
5699        });
5700    
5701        runScript({
5702            .code = R"NKSP_CODE(
5703    on init
5704      declare a := 24
5705    end on
5706    )NKSP_CODE",
5707            .expectParseError = true // missing type prefix character in variable name
5708        });
5709    
5710        runScript({
5711            .code = R"NKSP_CODE(
5712    on init
5713      declare const a := 24
5714    end on
5715    )NKSP_CODE",
5716            .expectParseError = true // missing type prefix character in variable name
5717        });
5718    
5719        runScript({
5720            .code = R"NKSP_CODE(
5721    on init
5722      declare polyphonic a
5723    end on
5724    )NKSP_CODE",
5725            .expectParseError = true // missing type prefix character in variable name
5726        });
5727    
5728        runScript({
5729            .code = R"NKSP_CODE(
5730    on init
5731      declare $a := max(8,24)
5732      exit($a)
5733    end on
5734    )NKSP_CODE",
5735            .expectIntExitResult = 24
5736        });
5737    
5738        runScript({
5739            .code = R"NKSP_CODE(
5740    on init
5741      declare $a := abort($NI_CALLBACK_ID)
5742    end on
5743    )NKSP_CODE",
5744            .expectParseError = true // assigned expression does not result in a value
5745        });
5746    
5747        runScript({
5748            .code = R"NKSP_CODE(
5749    on init
5750      declare const $a := abort($NI_CALLBACK_ID)
5751    end on
5752    )NKSP_CODE",
5753            .expectParseError = true // assigned expression does not result in a value
5754        });
5755    
5756        #if !SILENT_TEST
5757        std::cout << std::endl;
5758        #endif
5759    }
5760    
5761    static void testIntArrayVarDeclaration() {
5762        #if !SILENT_TEST
5763        std::cout << "UNIT TEST: int array var declaration\n";
5764        #endif
5765    
5766        runScript({
5767            .code = R"NKSP_CODE(
5768    on init
5769      declare %a[3]
5770      exit( %a[0] + %a[1] + %a[2] )
5771    end on
5772    )NKSP_CODE",
5773            .expectIntExitResult = 0
5774        });
5775    
5776        runScript({
5777            .code = R"NKSP_CODE(
5778    on init
5779      declare %a[0]
5780    end on
5781    )NKSP_CODE",
5782            .expectParseWarning = true // unusable array size
5783        });
5784    
5785        runScript({
5786            .code = R"NKSP_CODE(
5787    on init
5788      declare %a[-1]
5789    end on
5790    )NKSP_CODE",
5791            .expectParseError = true // illegal array size
5792        });
5793    
5794        runScript({
5795            .code = R"NKSP_CODE(
5796    on init
5797      declare %a[3] := ( 1, 2, 3 )
5798      exit( %a[0] + %a[1] + %a[2] )
5799    end on
5800    )NKSP_CODE",
5801            .expectIntExitResult = (1 + 2 + 3)
5802        });
5803    
5804        runScript({
5805            .code = R"NKSP_CODE(
5806    on init
5807      declare %a[] := ( 1, 2, 3 )
5808      exit( %a[0] + %a[1] + %a[2] )
5809    end on
5810    )NKSP_CODE",
5811            .expectIntExitResult = (1 + 2 + 3)
5812        });
5813    
5814        runScript({
5815            .code = R"NKSP_CODE(
5816    on init
5817      declare %a[]
5818    end on
5819    )NKSP_CODE",
5820            .expectParseWarning = true // unusable array size (zero)
5821        });
5822    
5823        runScript({
5824            .code = R"NKSP_CODE(
5825    on init
5826      declare const $sz := 3
5827      declare %a[$sz] := ( 1, 2, 3 )
5828      exit( %a[0] + %a[1] + %a[2] )
5829    end on
5830    )NKSP_CODE",
5831            .expectIntExitResult = (1 + 2 + 3)
5832        });
5833    
5834        runScript({
5835            .code = R"NKSP_CODE(
5836    on init
5837      declare const $sz := 3
5838      declare const %a[$sz] := ( 1, 2, 3 )
5839      exit( %a[0] + %a[1] + %a[2] )
5840    end on
5841    )NKSP_CODE",
5842            .expectIntExitResult = (1 + 2 + 3)
5843        });
5844    
5845        runScript({
5846            .code = R"NKSP_CODE(
5847    on init
5848      declare $sz := 3
5849      declare %a[$sz] := ( 1, 2, 3 )
5850    end on
5851    )NKSP_CODE",
5852            .expectParseError = true // array size must be constant expression
5853        });
5854    
5855        runScript({
5856            .code = R"NKSP_CODE(
5857    on init
5858      declare $sz := 3
5859      declare const %a[$sz] := ( 1, 2, 3 )
5860    end on
5861    )NKSP_CODE",
5862            .expectParseError = true // array size must be constant expression
5863        });
5864    
5865        runScript({
5866            .code = R"NKSP_CODE(
5867    on init
5868      declare const ~sz := 3.0
5869      declare const %a[~sz] := ( 1, 2, 3 )
5870    end on
5871    )NKSP_CODE",
5872            .expectParseError = true // array size must be integer type
5873        });
5874    
5875        runScript({
5876            .code = R"NKSP_CODE(
5877    on init
5878      declare %a[3s] := ( 1, 2, 3 )
5879    end on
5880    )NKSP_CODE",
5881            .expectParseError = true // units not allowed for array size
5882        });
5883    
5884        runScript({
5885            .code = R"NKSP_CODE(
5886    on init
5887      declare %a[3m] := ( 1, 2, 3 )
5888    end on
5889    )NKSP_CODE",
5890            .expectParseError = true // units not allowed for array size
5891        });
5892    
5893        runScript({
5894            .code = R"NKSP_CODE(
5895    on init
5896      declare const %a[!3] := ( 1, 2, 3 )
5897      exit( %a[0] + %a[1] + %a[2] )
5898    end on
5899    )NKSP_CODE",
5900            .expectIntExitResult = (1 + 2 + 3),
5901            .expectParseWarning = true // 'final' operator is meaningless for array size
5902        });
5903    
5904        runScript({
5905            .code = R"NKSP_CODE(
5906    on init
5907      declare %a[3] := ( 1, 2, 3 )
5908      %a[0] := 4
5909      %a[1] := 5
5910      %a[2] := 6
5911      exit( %a[0] + %a[1] + %a[2] )
5912    end on
5913    )NKSP_CODE",
5914            .expectIntExitResult = (4 + 5 + 6)
5915        });
5916    
5917        runScript({
5918            .code = R"NKSP_CODE(
5919    on init
5920      declare %a[3]
5921      declare %a[3]
5922    end on
5923    )NKSP_CODE",
5924            .expectParseError = true // variable re-declaration
5925        });
5926    
5927        runScript({
5928            .code = R"NKSP_CODE(
5929    on init
5930      declare const %a[3]
5931    end on
5932    )NKSP_CODE",
5933            .expectParseError = true // const variable declaration without assignment
5934        });
5935    
5936        runScript({
5937            .code = R"NKSP_CODE(
5938    on init
5939      declare const %a[3] := ( 1, 2, 3 )
5940      exit( %a[0] + %a[1] + %a[2] )
5941    end on
5942    )NKSP_CODE",
5943            .expectIntExitResult = (1 + 2 + 3)
5944        });
5945    
5946        runScript({
5947            .code = R"NKSP_CODE(
5948    on init
5949      declare const %a[3] := ( 1, 2, 3, 4 )
5950    end on
5951    )NKSP_CODE",
5952            .expectParseError = true // incompatible array sizes
5953        });
5954    
5955        runScript({
5956            .code = R"NKSP_CODE(
5957    on init
5958      declare const %a[3] := ( 1, 2, 3 )
5959      %a[0] := 8
5960    end on
5961    )NKSP_CODE",
5962            .expectParseError = true // attempt to modify const variable
5963        });
5964    
5965        runScript({
5966            .code = R"NKSP_CODE(
5967    on init
5968      declare const %a[3] := ( 1, 2, 3 )
5969      declare const %b[3] := ( %a[0], %a[1], %a[2] )
5970      exit( %b[0] + %b[1] + %b[2] )
5971    end on
5972    )NKSP_CODE",
5973            .expectIntExitResult = (1 + 2 + 3)
5974        });
5975    
5976        runScript({
5977            .code = R"NKSP_CODE(
5978    on init
5979      declare %a[3] := ( 1, 2, 3 )
5980      declare const %b[3] := ( %a[0], %a[1], %a[2] )
5981    end on
5982    )NKSP_CODE",
5983            .expectParseError = true // const array defined with non-const assignment
5984        });
5985    
5986        runScript({
5987            .code = R"NKSP_CODE(
5988    on init
5989      declare polyphonic %a[3]
5990    end on
5991    )NKSP_CODE",
5992            .expectParseError = true // polyphonic not allowed for array types
5993        });
5994    
5995        runScript({
5996            .code = R"NKSP_CODE(
5997    on init
5998      declare polyphonic %a[3] := ( 1, 2, 3 )
5999    end on
6000    )NKSP_CODE",
6001            .expectParseError = true // polyphonic not allowed for array types
6002        });
6003    
6004        runScript({
6005            .code = R"NKSP_CODE(
6006    on init
6007      declare const polyphonic %a[3]
6008    end on
6009    )NKSP_CODE",
6010            .expectParseError = true // polyphonic not allowed for array types
6011        });
6012    
6013        runScript({
6014            .code = R"NKSP_CODE(
6015    on init
6016      declare const polyphonic %a[3] := ( 1, 2, 3 )
6017    end on
6018    )NKSP_CODE",
6019            .expectParseError = true // polyphonic not allowed for array types
6020        });
6021    
6022        runScript({
6023            .code = R"NKSP_CODE(
6024    on init
6025      declare polyphonic const %a[3]
6026    end on
6027    )NKSP_CODE",
6028            .expectParseError = true // polyphonic not allowed for array types
6029        });
6030    
6031        runScript({
6032            .code = R"NKSP_CODE(
6033    on init
6034      declare polyphonic const %a[3] := ( 1, 2, 3 )
6035    end on
6036    )NKSP_CODE",
6037            .expectParseError = true // polyphonic not allowed for array types
6038        });
6039    
6040        runScript({
6041            .code = R"NKSP_CODE(
6042    on init
6043      declare %a[3] := ( 1, max(8,24), 3 )
6044      exit( %a[0] + %a[1] + %a[2] )
6045    end on
6046    )NKSP_CODE",
6047            .expectIntExitResult = ( 1 + 24 + 3 )
6048        });
6049    
6050        runScript({
6051            .code = R"NKSP_CODE(
6052    on init
6053      declare %a[3] := ( 1, abort($NI_CALLBACK_ID), 3 )
6054    end on
6055    )NKSP_CODE",
6056            .expectParseError = true // assigned expression does not result in a value
6057        });
6058    
6059        runScript({
6060            .code = R"NKSP_CODE(
6061    on init
6062      declare const %a[3] := ( 1, abort($NI_CALLBACK_ID), 3 )
6063    end on
6064    )NKSP_CODE",
6065            .expectParseError = true // assigned expression does not result in a value
6066        });
6067    
6068        runScript({
6069            .code = R"NKSP_CODE(
6070    on init
6071      declare %a[3] := ( 1.0, 2.0, 3.0 )
6072    end on
6073    )NKSP_CODE",
6074            .expectParseError = true // int array declaration vs. real array assignment
6075        });
6076    
6077        runScript({
6078            .code = R"NKSP_CODE(
6079    on init
6080      declare %a[3] := ( 1, 2, 3.0 )
6081    end on
6082    )NKSP_CODE",
6083            .expectParseError = true // 3rd element not an integer
6084        });
6085    
6086        runScript({
6087            .code = R"NKSP_CODE(
6088    on init
6089      declare %a[3] := ( "x", "y", "z" )
6090    end on
6091    )NKSP_CODE",
6092            .expectParseError = true // int array declaration vs. string array assignment
6093        });
6094    
6095        runScript({
6096            .code = R"NKSP_CODE(
6097    on init
6098      declare a[3] := ( 1, 2, 3 )
6099    end on
6100    )NKSP_CODE",
6101            .expectParseError = true // missing type prefix character in variable name
6102        });
6103    
6104        runScript({
6105            .code = R"NKSP_CODE(
6106    on init
6107      declare a[3]
6108    end on
6109    )NKSP_CODE",
6110            .expectParseError = true // missing type prefix character in variable name
6111        });
6112    
6113        runScript({
6114            .code = R"NKSP_CODE(
6115    on init
6116      declare const %a[3] := ( 1, 2s, 3 )
6117    end on
6118    )NKSP_CODE",
6119            .expectParseError = true // unit types not allowed for arrays
6120        });
6121    
6122        runScript({
6123            .code = R"NKSP_CODE(
6124    on init
6125      declare const %a[3] := ( 1, !2, 3 )
6126    end on
6127    )NKSP_CODE",
6128            .expectParseError = true // 'final' not allowed for arrays
6129        });
6130    
6131        #if !SILENT_TEST
6132        std::cout << std::endl;
6133        #endif
6134    }
6135    
6136    static void testRealVarDeclaration() {
6137        #if !SILENT_TEST
6138        std::cout << "UNIT TEST: real var declaration\n";
6139        #endif
6140    
6141        runScript({
6142            .code = R"NKSP_CODE(
6143    on init
6144      declare ~a
6145      exit(~a)
6146    end on
6147    )NKSP_CODE",
6148            .expectRealExitResult = 0.0
6149        });
6150    
6151        runScript({
6152            .code = R"NKSP_CODE(
6153    on init
6154      declare ~a := 24.8
6155      exit(~a)
6156    end on
6157    )NKSP_CODE",
6158            .expectRealExitResult = 24.8
6159        });
6160    
6161        runScript({
6162            .code = R"NKSP_CODE(
6163    on init
6164      declare ~a := 8.24
6165      ~a := 24.8
6166      exit(~a)
6167    end on
6168    )NKSP_CODE",
6169            .expectRealExitResult = 24.8
6170        });
6171    
6172        runScript({
6173            .code = R"NKSP_CODE(
6174    on init
6175      declare ~a
6176      declare ~a
6177    end on
6178    )NKSP_CODE",
6179            .expectParseError = true // variable re-declaration
6180        });
6181    
6182        runScript({
6183            .code = R"NKSP_CODE(
6184    on init
6185      declare const ~a
6186    end on
6187    )NKSP_CODE",
6188            .expectParseError = true // const variable declaration without assignment
6189        });
6190    
6191        runScript({
6192            .code = R"NKSP_CODE(
6193    on init
6194      declare const ~a := 8.24
6195      exit(~a)
6196    end on
6197    )NKSP_CODE",
6198            .expectRealExitResult = 8.24
6199        });
6200    
6201        runScript({
6202            .code = R"NKSP_CODE(
6203    on init
6204      declare const ~a := 28.0
6205      ~a := 8.0
6206    end on
6207    )NKSP_CODE",
6208            .expectParseError = true // attempt to modify const variable
6209        });
6210    
6211        runScript({
6212            .code = R"NKSP_CODE(
6213    on init
6214      declare const ~a := 24.8
6215      declare const ~b := ~a
6216      exit(~b)
6217    end on
6218    )NKSP_CODE",
6219            .expectRealExitResult = 24.8
6220        });
6221    
6222        runScript({
6223            .code = R"NKSP_CODE(
6224    on init
6225      declare ~a := 24.0
6226      declare const ~b := ~a
6227    end on
6228    )NKSP_CODE",
6229            .expectParseError = true // const variable defined with non-const assignment
6230        });
6231    
6232        runScript({
6233            .code = R"NKSP_CODE(
6234    on init
6235      declare polyphonic ~a
6236      exit(~a)
6237    end on
6238    )NKSP_CODE",
6239            .expectRealExitResult = 0.0
6240        });
6241    
6242        runScript({
6243            .code = R"NKSP_CODE(
6244    on init
6245      declare const polyphonic ~a
6246    end on
6247    )NKSP_CODE",
6248            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6249        });
6250    
6251        runScript({
6252            .code = R"NKSP_CODE(
6253    on init
6254      declare polyphonic const ~a
6255    end on
6256    )NKSP_CODE",
6257            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6258        });
6259    
6260        runScript({
6261            .code = R"NKSP_CODE(
6262    on init
6263      declare const polyphonic ~a := 3.0
6264    end on
6265    )NKSP_CODE",
6266            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6267        });
6268    
6269        runScript({
6270            .code = R"NKSP_CODE(
6271    on init
6272      declare polyphonic const ~a := 3.0
6273    end on
6274    )NKSP_CODE",
6275            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6276        });
6277    
6278        runScript({
6279            .code = R"NKSP_CODE(
6280    on init
6281      declare $a := 24.8
6282      exit($a)
6283    end on
6284    )NKSP_CODE",
6285            .expectParseWarning = true, // int type declaration vs. real value assignment
6286            .expectRealExitResult = 24.8
6287        });
6288    
6289        runScript({
6290            .code = R"NKSP_CODE(
6291    on init
6292      declare %a := 24.8
6293      exit(%a)
6294    end on
6295    )NKSP_CODE",
6296            .expectParseWarning = true, // int array type declaration vs. real scalar value assignment
6297            .expectRealExitResult = 24.8
6298        });
6299    
6300        runScript({
6301            .code = R"NKSP_CODE(
6302    on init
6303      declare const %a := 24.8
6304      exit(%a)
6305    end on
6306    )NKSP_CODE",
6307            .expectParseWarning = true, // int array type declaration vs. real scalar value assignment
6308            .expectRealExitResult = 24.8
6309        });
6310    
6311        runScript({
6312            .code = R"NKSP_CODE(
6313    on init
6314      declare ?a := 24.8
6315      exit(?a)
6316    end on
6317    )NKSP_CODE",
6318            .expectParseWarning = true, // real array type declaration vs. real scalar value assignment
6319            .expectRealExitResult = 24.8
6320        });
6321    
6322        runScript({
6323            .code = R"NKSP_CODE(
6324    on init
6325      declare const ?a := 24.8
6326      exit(?a)
6327    end on
6328    )NKSP_CODE",
6329            .expectParseWarning = true, // real array type declaration vs. real scalar value assignment
6330            .expectRealExitResult = 24.8
6331        });
6332    
6333        runScript({
6334            .code = R"NKSP_CODE(
6335    on init
6336      declare @a := 24.8
6337      exit(@a)
6338    end on
6339    )NKSP_CODE",
6340            .expectParseWarning = true, // string type declaration vs. real scalar value assignment
6341            .expectRealExitResult = 24.8
6342        });
6343    
6344        runScript({
6345            .code = R"NKSP_CODE(
6346    on init
6347      declare const @a := 24.8
6348      exit(@a)
6349    end on
6350    )NKSP_CODE",
6351            .expectParseWarning = true, // string type declaration vs. real scalar value assignment
6352            .expectRealExitResult = 24.8
6353        });
6354    
6355        runScript({
6356            .code = R"NKSP_CODE(
6357    on init
6358      declare ~a := ( 0, 1, 2 )
6359    end on
6360    )NKSP_CODE",
6361            .expectParseError = true // real scalar type declaration vs. int array value assignment
6362        });
6363    
6364        runScript({
6365            .code = R"NKSP_CODE(
6366    on init
6367      declare const ~a := ( 0, 1, 2 )
6368    end on
6369    )NKSP_CODE",
6370            .expectParseError = true // real scalar type declaration vs. int array value assignment
6371        });
6372    
6373        runScript({
6374            .code = R"NKSP_CODE(
6375    on init
6376      declare a := 24.8
6377    end on
6378    )NKSP_CODE",
6379            .expectParseError = true // missing type prefix character in variable name
6380        });
6381    
6382        runScript({
6383            .code = R"NKSP_CODE(
6384    on init
6385      declare const a := 24.8
6386    end on
6387    )NKSP_CODE",
6388            .expectParseError = true // missing type prefix character in variable name
6389        });
6390    
6391        runScript({
6392            .code = R"NKSP_CODE(
6393    on init
6394      declare ~a := max(8.1,24.2)
6395      exit(~a)
6396    end on
6397    )NKSP_CODE",
6398            .expectRealExitResult = 24.2
6399        });
6400    
6401        runScript({
6402            .code = R"NKSP_CODE(
6403    on init
6404      declare ~a := abort($NI_CALLBACK_ID)
6405    end on
6406    )NKSP_CODE",
6407            .expectParseError = true // assigned expression does not result in a value
6408        });
6409    
6410        runScript({
6411            .code = R"NKSP_CODE(
6412    on init
6413      declare const ~a := abort($NI_CALLBACK_ID)
6414    end on
6415    )NKSP_CODE",
6416            .expectParseError = true // assigned expression does not result in a value
6417        });
6418    
6419        #if !SILENT_TEST
6420        std::cout << std::endl;
6421        #endif
6422    }
6423    
6424    static void testRealArrayVarDeclaration() {
6425        #if !SILENT_TEST
6426        std::cout << "UNIT TEST: real array var declaration\n";
6427        #endif
6428    
6429        runScript({
6430            .code = R"NKSP_CODE(
6431    on init
6432      declare ?a[3]
6433      exit( ?a[0] + ?a[1] + ?a[2] )
6434    end on
6435    )NKSP_CODE",
6436            .expectRealExitResult = 0.0
6437        });
6438    
6439        runScript({
6440            .code = R"NKSP_CODE(
6441    on init
6442      declare ?a[0]
6443    end on
6444    )NKSP_CODE",
6445            .expectParseWarning = true // unusable array size
6446        });
6447    
6448        runScript({
6449            .code = R"NKSP_CODE(
6450    on init
6451      declare ?a[-1]
6452    end on
6453    )NKSP_CODE",
6454            .expectParseError = true // illegal array size
6455        });
6456    
6457        runScript({
6458            .code = R"NKSP_CODE(
6459    on init
6460      declare ?a[3] := ( 1.1, 2.2, 3.3 )
6461      exit( ?a[0] + ?a[1] + ?a[2] )
6462    end on
6463    )NKSP_CODE",
6464            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6465        });
6466    
6467        runScript({
6468            .code = R"NKSP_CODE(
6469    on init
6470      declare ?a[] := ( 1.1, 2.2, 3.3 )
6471      exit( ?a[0] + ?a[1] + ?a[2] )
6472    end on
6473    )NKSP_CODE",
6474            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6475        });
6476    
6477        runScript({
6478            .code = R"NKSP_CODE(
6479    on init
6480      declare ?a[]
6481    end on
6482    )NKSP_CODE",
6483            .expectParseWarning = true // unusable array size (zero)
6484        });
6485    
6486        runScript({
6487            .code = R"NKSP_CODE(
6488    on init
6489      declare const $sz := 3
6490      declare ?a[$sz] := ( 1.1, 2.2, 3.3 )
6491      exit( ?a[0] + ?a[1] + ?a[2] )
6492    end on
6493    )NKSP_CODE",
6494            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6495        });
6496    
6497        runScript({
6498            .code = R"NKSP_CODE(
6499    on init
6500      declare const $sz := 3
6501      declare const ?a[$sz] := ( 1.1, 2.2, 3.3 )
6502      exit( ?a[0] + ?a[1] + ?a[2] )
6503    end on
6504    )NKSP_CODE",
6505            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6506        });
6507    
6508        runScript({
6509            .code = R"NKSP_CODE(
6510    on init
6511      declare $sz := 3
6512      declare ?a[$sz] := ( 1.1, 2.2, 3.3 )
6513    end on
6514    )NKSP_CODE",
6515            .expectParseError = true // array size must be constant expression
6516        });
6517    
6518        runScript({
6519            .code = R"NKSP_CODE(
6520    on init
6521      declare $sz := 3
6522      declare const ?a[$sz] := ( 1.1, 2.2, 3.3 )
6523    end on
6524    )NKSP_CODE",
6525            .expectParseError = true // array size must be constant expression
6526        });
6527    
6528        runScript({
6529            .code = R"NKSP_CODE(
6530    on init
6531      declare const ~sz := 3.0
6532      declare const ?a[~sz] := ( 1.1, 2.2, 3.3 )
6533    end on
6534    )NKSP_CODE",
6535            .expectParseError = true // array size must be integer type
6536        });
6537    
6538        runScript({
6539            .code = R"NKSP_CODE(
6540    on init
6541      declare ?a[3s] := ( 1.1, 2.2, 3.3 )
6542    end on
6543    )NKSP_CODE",
6544            .expectParseError = true // units not allowed for array size
6545        });
6546    
6547        runScript({
6548            .code = R"NKSP_CODE(
6549    on init
6550      declare ?a[3m] := ( 1.1, 2.2, 3.3 )
6551    end on
6552    )NKSP_CODE",
6553            .expectParseError = true // units not allowed for array size
6554        });
6555    
6556        runScript({
6557            .code = R"NKSP_CODE(
6558    on init
6559      declare const ?a[!3] := ( 1.1, 2.2, 3.3 )
6560      exit( ?a[0] + ?a[1] + ?a[2] )
6561    end on
6562    )NKSP_CODE",
6563            .expectRealExitResult = (1.1 + 2.2 + 3.3),
6564            .expectParseWarning = true // 'final' operator is meaningless for array size
6565        });
6566    
6567        runScript({
6568            .code = R"NKSP_CODE(
6569    on init
6570      declare ?a[3] := ( 1.0, 2.0, 3.0 )
6571      ?a[0] := 4.5
6572      ?a[1] := 5.5
6573      ?a[2] := 6.5
6574      exit( ?a[0] + ?a[1] + ?a[2] )
6575    end on
6576    )NKSP_CODE",
6577            .expectRealExitResult = (4.5 + 5.5 + 6.5)
6578        });
6579    
6580        runScript({
6581            .code = R"NKSP_CODE(
6582    on init
6583      declare ?a[3]
6584      declare ?a[3]
6585    end on
6586    )NKSP_CODE",
6587            .expectParseError = true // variable re-declaration
6588        });
6589    
6590        runScript({
6591            .code = R"NKSP_CODE(
6592    on init
6593      declare const ?a[3]
6594    end on
6595    )NKSP_CODE",
6596            .expectParseError = true // const variable declaration without assignment
6597        });
6598    
6599        runScript({
6600            .code = R"NKSP_CODE(
6601    on init
6602      declare const ?a[3] := ( 1.1, 2.2, 3.3 )
6603      exit( ?a[0] + ?a[1] + ?a[2] )
6604    end on
6605    )NKSP_CODE",
6606            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6607        });
6608    
6609        runScript({
6610            .code = R"NKSP_CODE(
6611    on init
6612      declare const ?a[3] := ( 1.1, 2.2, 3.3, 4.4 )
6613    end on
6614    )NKSP_CODE",
6615            .expectParseError = true // incompatible array sizes
6616        });
6617    
6618        runScript({
6619            .code = R"NKSP_CODE(
6620    on init
6621      declare const ?a[3] := ( 1.0, 2.0, 3.0 )
6622      ?a[0] := 8.0
6623    end on
6624    )NKSP_CODE",
6625            .expectParseError = true // attempt to modify const variable
6626        });
6627    
6628        runScript({
6629            .code = R"NKSP_CODE(
6630    on init
6631      declare const ?a[3] := ( 1.1, 2.2, 3.3 )
6632      declare const ?b[3] := ( ?a[0], ?a[1], ?a[2] )
6633      exit( ?b[0] + ?b[1] + ?b[2] )
6634    end on
6635    )NKSP_CODE",
6636            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6637        });
6638    
6639        runScript({
6640            .code = R"NKSP_CODE(
6641    on init
6642      declare ?a[3] := ( 1.1, 2.2, 3.3 )
6643      declare const ?b[3] := ( ?a[0], ?a[1], ?a[2] )
6644    end on
6645    )NKSP_CODE",
6646            .expectParseError = true // const array defined with non-const assignment
6647        });
6648    
6649        runScript({
6650            .code = R"NKSP_CODE(
6651    on init
6652      declare polyphonic ?a[3]
6653    end on
6654    )NKSP_CODE",
6655            .expectParseError = true // polyphonic not allowed for array types
6656        });
6657    
6658        runScript({
6659            .code = R"NKSP_CODE(
6660    on init
6661      declare polyphonic ?a[3] := ( 1.0, 2.0, 3.0 )
6662    end on
6663    )NKSP_CODE",
6664            .expectParseError = true // polyphonic not allowed for array types
6665        });
6666    
6667        runScript({
6668            .code = R"NKSP_CODE(
6669    on init
6670      declare const polyphonic ?a[3]
6671    end on
6672    )NKSP_CODE",
6673            .expectParseError = true // polyphonic not allowed for array types
6674        });
6675    
6676        runScript({
6677            .code = R"NKSP_CODE(
6678    on init
6679      declare const polyphonic ?a[3] := ( 1.0, 2.0, 3.0 )
6680    end on
6681    )NKSP_CODE",
6682            .expectParseError = true // polyphonic not allowed for array types
6683        });
6684    
6685        runScript({
6686            .code = R"NKSP_CODE(
6687    on init
6688      declare polyphonic const ?a[3]
6689    end on
6690    )NKSP_CODE",
6691            .expectParseError = true // polyphonic not allowed for array types
6692        });
6693    
6694        runScript({
6695            .code = R"NKSP_CODE(
6696    on init
6697      declare polyphonic const ?a[3] := ( 1.0, 2.0, 3.0 )
6698    end on
6699    )NKSP_CODE",
6700            .expectParseError = true // polyphonic not allowed for array types
6701        });
6702    
6703        runScript({
6704            .code = R"NKSP_CODE(
6705    on init
6706      declare ?a[3] := ( 1.0, max(8.3,24.6), 3.0 )
6707      exit( ?a[0] + ?a[1] + ?a[2] )
6708    end on
6709    )NKSP_CODE",
6710            .expectRealExitResult = ( 1.0 + 24.6 + 3.0 )
6711        });
6712    
6713        runScript({
6714            .code = R"NKSP_CODE(
6715    on init
6716      declare ?a[3] := ( 1.0, abort($NI_CALLBACK_ID), 3.0 )
6717    end on
6718    )NKSP_CODE",
6719            .expectParseError = true // assigned expression does not result in a value
6720        });
6721    
6722        runScript({
6723            .code = R"NKSP_CODE(
6724    on init
6725      declare const ?a[3] := ( 1.0, abort($NI_CALLBACK_ID), 3.0 )
6726    end on
6727    )NKSP_CODE",
6728            .expectParseError = true // assigned expression does not result in a value
6729        });
6730    
6731        runScript({
6732            .code = R"NKSP_CODE(
6733    on init
6734      declare ?a[3] := ( 1, 2, 3 )
6735    end on
6736    )NKSP_CODE",
6737            .expectParseError = true // real array declaration vs. int array assignment
6738        });
6739    
6740        runScript({
6741            .code = R"NKSP_CODE(
6742    on init
6743      declare ?a[3] := ( 1.0, 2.0, 3 )
6744    end on
6745    )NKSP_CODE",
6746            .expectParseError = true // 3rd element not a real value
6747        });
6748    
6749        runScript({
6750            .code = R"NKSP_CODE(
6751    on init
6752      declare ?a[3] := ( "x", "y", "z" )
6753    end on
6754    )NKSP_CODE",
6755            .expectParseError = true // real array declaration vs. string array assignment
6756        });
6757    
6758        runScript({
6759            .code = R"NKSP_CODE(
6760    on init
6761      declare a[3] := ( 1.0, 2.0, 3.0 )
6762    end on
6763    )NKSP_CODE",
6764            .expectParseError = true // missing type prefix character in variable name
6765        });
6766    
6767        runScript({
6768            .code = R"NKSP_CODE(
6769    on init
6770      declare const ?a[3] := ( 1.0, 2.0s, 3.0 )
6771    end on
6772    )NKSP_CODE",
6773            .expectParseError = true // unit types not allowed for arrays
6774        });
6775    
6776        runScript({
6777            .code = R"NKSP_CODE(
6778    on init
6779      declare const ?a[3] := ( 1.0, !2.0, 3.0 )
6780    end on
6781    )NKSP_CODE",
6782            .expectParseError = true // 'final' not allowed for arrays
6783        });
6784    
6785        #if !SILENT_TEST
6786        std::cout << std::endl;
6787        #endif
6788    }
6789    
6790    static void testStringVarDeclaration() {
6791        #if !SILENT_TEST
6792        std::cout << "UNIT TEST: string var declaration\n";
6793        #endif
6794    
6795    runScript({
6796            .code = R"NKSP_CODE(
6797    on init
6798      declare @a
6799      exit(@a)
6800    end on
6801    )NKSP_CODE",
6802            .expectStringExitResult = ""
6803        });
6804    
6805        runScript({
6806            .code = R"NKSP_CODE(
6807    on init
6808      declare @a := "foo"
6809      exit(@a)
6810    end on
6811    )NKSP_CODE",
6812            .expectStringExitResult = "foo"
6813        });
6814    
6815        runScript({
6816            .code = R"NKSP_CODE(
6817    on init
6818      declare @a := "foo"
6819      @a := "bar"
6820      exit(@a)
6821    end on
6822    )NKSP_CODE",
6823            .expectStringExitResult = "bar"
6824        });
6825    
6826        runScript({
6827            .code = R"NKSP_CODE(
6828    on init
6829      declare @a
6830      declare @a
6831    end on
6832    )NKSP_CODE",
6833            .expectParseError = true // variable re-declaration
6834        });
6835    
6836        runScript({
6837            .code = R"NKSP_CODE(
6838    on init
6839      declare const @a
6840    end on
6841    )NKSP_CODE",
6842            .expectParseError = true // const variable declaration without assignment
6843        });
6844    
6845        runScript({
6846            .code = R"NKSP_CODE(
6847    on init
6848      declare const @a := "foo"
6849      exit(@a)
6850    end on
6851    )NKSP_CODE",
6852            .expectStringExitResult = "foo"
6853        });
6854    
6855        runScript({
6856            .code = R"NKSP_CODE(
6857    on init
6858      declare const @a := "foo"
6859      @a := "bar"
6860    end on
6861    )NKSP_CODE",
6862            .expectParseError = true // attempt to modify const variable
6863        });
6864    
6865        runScript({
6866            .code = R"NKSP_CODE(
6867    on init
6868      declare const @a := "foo"
6869      declare const @b := @a
6870      exit(@b)
6871    end on
6872    )NKSP_CODE",
6873            .expectStringExitResult = "foo"
6874        });
6875    
6876        runScript({
6877            .code = R"NKSP_CODE(
6878    on init
6879      declare @a := "foo"
6880      declare const @b := @a
6881    end on
6882    )NKSP_CODE",
6883            .expectParseError = true // const variable defined with non-const assignment
6884        });
6885    
6886        runScript({
6887            .code = R"NKSP_CODE(
6888    on init
6889      declare polyphonic @a
6890    end on
6891    )NKSP_CODE",
6892            .expectParseError = true // 'polyphonic' not allowed for string type
6893        });
6894    
6895        runScript({
6896            .code = R"NKSP_CODE(
6897    on init
6898      declare const polyphonic @a
6899    end on
6900    )NKSP_CODE",
6901            .expectParseError = true // 'polyphonic' not allowed for string type
6902        });
6903    
6904        runScript({
6905            .code = R"NKSP_CODE(
6906    on init
6907      declare polyphonic const @a
6908    end on
6909    )NKSP_CODE",
6910            .expectParseError = true // 'polyphonic' not allowed for string type
6911        });
6912    
6913        runScript({
6914            .code = R"NKSP_CODE(
6915    on init
6916      declare polyphonic @a = "foo"
6917    end on
6918    )NKSP_CODE",
6919            .expectParseError = true // 'polyphonic' not allowed for string type
6920        });
6921    
6922        runScript({
6923            .code = R"NKSP_CODE(
6924    on init
6925      declare polyphonic const @a = "foo"
6926    end on
6927    )NKSP_CODE",
6928            .expectParseError = true // 'polyphonic' not allowed for string type
6929        });
6930    
6931        runScript({
6932            .code = R"NKSP_CODE(
6933    on init
6934      declare const polyphonic @a = "foo"
6935    end on
6936    )NKSP_CODE",
6937            .expectParseError = true // 'polyphonic' not allowed for string type
6938        });
6939    
6940        runScript({
6941            .code = R"NKSP_CODE(
6942    on init
6943      declare $a := "foo"
6944      exit($a)
6945    end on
6946    )NKSP_CODE",
6947            .expectParseWarning = true, // int type declaration vs. string assignment
6948            .expectStringExitResult = "foo"
6949        });
6950    
6951        runScript({
6952            .code = R"NKSP_CODE(
6953    on init
6954      declare ~a := "foo"
6955      exit(~a)
6956    end on
6957    )NKSP_CODE",
6958            .expectParseWarning = true, // real type declaration vs. string assignment
6959            .expectStringExitResult = "foo"
6960        });
6961    
6962        runScript({
6963            .code = R"NKSP_CODE(
6964    on init
6965      declare %a := "foo"
6966      exit(%a)
6967    end on
6968    )NKSP_CODE",
6969            .expectParseWarning = true, // int array type declaration vs. string assignment
6970            .expectStringExitResult = "foo"
6971        });
6972    
6973        runScript({
6974            .code = R"NKSP_CODE(
6975    on init
6976      declare const $a := "foo"
6977      exit($a)
6978    end on
6979    )NKSP_CODE",
6980            .expectParseWarning = true, // int type declaration vs. string assignment
6981            .expectStringExitResult = "foo"
6982        });
6983    
6984        runScript({
6985            .code = R"NKSP_CODE(
6986    on init
6987      declare const ~a := "foo"
6988      exit(~a)
6989    end on
6990    )NKSP_CODE",
6991            .expectParseWarning = true, // real type declaration vs. string assignment
6992            .expectStringExitResult = "foo"
6993        });
6994    
6995        runScript({
6996            .code = R"NKSP_CODE(
6997    on init
6998      declare const %a := "foo"
6999      exit(%a)
7000    end on
7001    )NKSP_CODE",
7002            .expectParseWarning = true, // int array type declaration vs. string assignment
7003            .expectStringExitResult = "foo"
7004        });
7005    
7006        runScript({
7007            .code = R"NKSP_CODE(
7008    on init
7009      declare a := "foo"
7010    end on
7011    )NKSP_CODE",
7012            .expectParseError = true // missing type prefix character in variable name
7013        });
7014    
7015        runScript({
7016            .code = R"NKSP_CODE(
7017    on init
7018      declare const a := "foo"
7019    end on
7020    )NKSP_CODE",
7021            .expectParseError = true // missing type prefix character in variable name
7022        });
7023    
7024        runScript({
7025            .code = R"NKSP_CODE(
7026    on init
7027      declare @a := abort($NI_CALLBACK_ID)
7028    end on
7029    )NKSP_CODE",
7030            .expectParseError = true // assigned expression does not result in a value
7031        });
7032    
7033        runScript({
7034            .code = R"NKSP_CODE(
7035    on init
7036      declare const @a := abort($NI_CALLBACK_ID)
7037    end on
7038    )NKSP_CODE",
7039            .expectParseError = true // assigned expression does not result in a value
7040        });
7041    
7042      #if !SILENT_TEST      #if !SILENT_TEST
7043      std::cout << std::endl;      std::cout << std::endl;
7044      #endif      #endif
# Line 1184  end on Line 7076  end on
7076          .expectParseError = true // because min() function requires 2 arguments          .expectParseError = true // because min() function requires 2 arguments
7077      });      });
7078    
7079        // integer tests ...
7080    
7081      runScript({      runScript({
7082          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7083  on init  on init
# Line 1204  end on Line 7098  end on
7098          .expectIntExitResult = -30          .expectIntExitResult = -30
7099      });      });
7100    
7101        // real number tests ...
7102    
7103        runScript({
7104            .code = R"NKSP_CODE(
7105    on init
7106      declare ~foo := min(1.0, 2.0)
7107      exit(~foo)
7108    end on
7109    )NKSP_CODE",
7110            .expectRealExitResult = 1.0
7111        });
7112    
7113        runScript({
7114            .code = R"NKSP_CODE(
7115    on init
7116      declare ~foo := min(-30.0, 4.0)
7117      exit(~foo)
7118    end on
7119    )NKSP_CODE",
7120            .expectRealExitResult = -30.0
7121        });
7122    
7123        runScript({
7124            .code = R"NKSP_CODE(
7125    on init
7126      declare ~foo := min(1.1, 1.13)
7127      exit(~foo)
7128    end on
7129    )NKSP_CODE",
7130            .expectRealExitResult = 1.1
7131        });
7132    
7133        runScript({
7134            .code = R"NKSP_CODE(
7135    on init
7136      declare ~foo := min(1.13, 1.1)
7137      exit(~foo)
7138    end on
7139    )NKSP_CODE",
7140            .expectRealExitResult = 1.1
7141        });
7142    
7143        // mixed type tests ...
7144    
7145        runScript({
7146            .code = R"NKSP_CODE(
7147    on init
7148      declare ~foo := min(1, 1.16)
7149      exit(~foo)
7150    end on
7151    )NKSP_CODE",
7152            .expectRealExitResult = 1.0,
7153            .expectParseWarning = true // min() warns if data types of arguments not matching
7154        });
7155    
7156        runScript({
7157            .code = R"NKSP_CODE(
7158    on init
7159      declare ~foo := min(-3.92, 9)
7160      exit(~foo)
7161    end on
7162    )NKSP_CODE",
7163            .expectRealExitResult = -3.92,
7164            .expectParseWarning = true // min() warns if data types of arguments not matching
7165        });
7166    
7167        // std unit tests ...
7168    
7169        runScript({
7170            .code = R"NKSP_CODE(
7171    on init
7172      declare $foo := min(30ms,4s)
7173      exit($foo)
7174    end on
7175    )NKSP_CODE",
7176            .expectIntExitResult = 30,
7177            .expectExitResultUnitPrefix = { VM_MILLI },
7178            .expectExitResultUnit = VM_SECOND,
7179        });
7180    
7181        runScript({
7182            .code = R"NKSP_CODE(
7183    on init
7184      declare $foo := min(4s,30ms)
7185      exit($foo)
7186    end on
7187    )NKSP_CODE",
7188            .expectIntExitResult = 30,
7189            .expectExitResultUnitPrefix = { VM_MILLI },
7190            .expectExitResultUnit = VM_SECOND,
7191        });
7192    
7193        runScript({
7194            .code = R"NKSP_CODE(
7195    on init
7196      declare $foo := min(-30mdB,-4dB)
7197      exit($foo)
7198    end on
7199    )NKSP_CODE",
7200            .expectIntExitResult = -4,
7201            .expectExitResultUnitPrefix = { VM_DECI },
7202            .expectExitResultUnit = VM_BEL,
7203        });
7204    
7205        runScript({
7206            .code = R"NKSP_CODE(
7207    on init
7208      declare $foo := min(-4dB,-30mdB)
7209      exit($foo)
7210    end on
7211    )NKSP_CODE",
7212            .expectIntExitResult = -4,
7213            .expectExitResultUnitPrefix = { VM_DECI },
7214            .expectExitResultUnit = VM_BEL,
7215        });
7216    
7217        runScript({
7218            .code = R"NKSP_CODE(
7219    on init
7220      declare $foo := min(-4s,-30Hz)
7221      exit($foo)
7222    end on
7223    )NKSP_CODE",
7224            .expectParseError = true // min() requires arguments to have same unit type
7225        });
7226    
7227        runScript({
7228            .code = R"NKSP_CODE(
7229    on init
7230      declare $foo := min(-4s,-30)
7231      exit($foo)
7232    end on
7233    )NKSP_CODE",
7234            .expectParseError = true // min() requires arguments to have same unit type
7235        });
7236    
7237        runScript({
7238            .code = R"NKSP_CODE(
7239    on init
7240      declare $foo := min(-4,-30s)
7241      exit($foo)
7242    end on
7243    )NKSP_CODE",
7244            .expectParseError = true // min() requires arguments to have same unit type
7245        });
7246    
7247        runScript({
7248            .code = R"NKSP_CODE(
7249    on init
7250      declare ~foo := min(0.9s,1.0s)
7251      exit(~foo)
7252    end on
7253    )NKSP_CODE",
7254            .expectRealExitResult = 0.9,
7255            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7256            .expectExitResultUnit = VM_SECOND,
7257        });
7258    
7259        // 'final' ('!') operator tests ...
7260    
7261        runScript({
7262            .code = R"NKSP_CODE(
7263    on init
7264      declare $foo := min(!30,!4)
7265      exit($foo)
7266    end on
7267    )NKSP_CODE",
7268            .expectIntExitResult = 4,
7269            .expectExitResultFinal = true
7270        });
7271    
7272        runScript({
7273            .code = R"NKSP_CODE(
7274    on init
7275      declare $foo := min(30,4)
7276      exit($foo)
7277    end on
7278    )NKSP_CODE",
7279            .expectIntExitResult = 4,
7280            .expectExitResultFinal = false
7281        });
7282    
7283        runScript({
7284            .code = R"NKSP_CODE(
7285    on init
7286      declare $foo := min(30,!4)
7287      exit($foo)
7288    end on
7289    )NKSP_CODE",
7290            .expectIntExitResult = 4,
7291            .expectExitResultFinal = true,
7292            .expectParseWarning = true // min() warns if only one argument is 'final'
7293        });
7294    
7295        runScript({
7296            .code = R"NKSP_CODE(
7297    on init
7298      declare $foo := min(!30,4)
7299      exit($foo)
7300    end on
7301    )NKSP_CODE",
7302            .expectIntExitResult = 4,
7303            .expectExitResultFinal = true,
7304            .expectParseWarning = true // min() warns if only one argument is 'final'
7305        });
7306    
7307        runScript({
7308            .code = R"NKSP_CODE(
7309    on init
7310      declare ~foo := min(!12.1,!12.2)
7311      exit(~foo)
7312    end on
7313    )NKSP_CODE",
7314            .expectRealExitResult = 12.1,
7315            .expectExitResultFinal = true
7316        });
7317    
7318        runScript({
7319            .code = R"NKSP_CODE(
7320    on init
7321      declare ~foo := min(12.1,12.2)
7322      exit(~foo)
7323    end on
7324    )NKSP_CODE",
7325            .expectRealExitResult = 12.1,
7326            .expectExitResultFinal = false
7327        });
7328    
7329        runScript({
7330            .code = R"NKSP_CODE(
7331    on init
7332      declare ~foo := min(!12.1,12.2)
7333      exit(~foo)
7334    end on
7335    )NKSP_CODE",
7336            .expectRealExitResult = 12.1,
7337            .expectExitResultFinal = true,
7338            .expectParseWarning = true // min() warns if only one argument is 'final'
7339        });
7340    
7341        runScript({
7342            .code = R"NKSP_CODE(
7343    on init
7344      declare ~foo := min(12.1,!12.2)
7345      exit(~foo)
7346    end on
7347    )NKSP_CODE",
7348            .expectRealExitResult = 12.1,
7349            .expectExitResultFinal = true,
7350            .expectParseWarning = true // min() warns if only one argument is 'final'
7351        });
7352    
7353      #if !SILENT_TEST      #if !SILENT_TEST
7354      std::cout << std::endl;      std::cout << std::endl;
7355      #endif      #endif
# Line 1214  static void testBuiltInMaxFunction() { Line 7360  static void testBuiltInMaxFunction() {
7360      std::cout << "UNIT TEST: built-in max() function\n";      std::cout << "UNIT TEST: built-in max() function\n";
7361      #endif      #endif
7362    
7363        // integer tests ...
7364    
7365      runScript({      runScript({
7366          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7367  on init  on init
# Line 1261  end on Line 7409  end on
7409          .expectIntExitResult = 4          .expectIntExitResult = 4
7410      });      });
7411    
7412        // real number tests ...
7413    
7414        runScript({
7415            .code = R"NKSP_CODE(
7416    on init
7417      declare ~foo := max(1.0, 2.0)
7418      exit(~foo)
7419    end on
7420    )NKSP_CODE",
7421            .expectRealExitResult = 2.0
7422        });
7423    
7424        runScript({
7425            .code = R"NKSP_CODE(
7426    on init
7427      declare ~foo := max(-30.0, 4.0)
7428      exit(~foo)
7429    end on
7430    )NKSP_CODE",
7431            .expectRealExitResult = 4.0
7432        });
7433    
7434        runScript({
7435            .code = R"NKSP_CODE(
7436    on init
7437      declare ~foo := max(1.1, 1.13)
7438      exit(~foo)
7439    end on
7440    )NKSP_CODE",
7441            .expectRealExitResult = 1.13
7442        });
7443    
7444        runScript({
7445            .code = R"NKSP_CODE(
7446    on init
7447      declare ~foo := max(1.13, 1.1)
7448      exit(~foo)
7449    end on
7450    )NKSP_CODE",
7451            .expectRealExitResult = 1.13
7452        });
7453    
7454        // mixed type tests ...
7455    
7456        runScript({
7457            .code = R"NKSP_CODE(
7458    on init
7459      declare ~foo := max(1, 1.16)
7460      exit(~foo)
7461    end on
7462    )NKSP_CODE",
7463            .expectRealExitResult = 1.16,
7464            .expectParseWarning = true // max() warns if data types of arguments not matching
7465        });
7466    
7467        runScript({
7468            .code = R"NKSP_CODE(
7469    on init
7470      declare ~foo := max(-3.92, 9)
7471      exit(~foo)
7472    end on
7473    )NKSP_CODE",
7474            .expectRealExitResult = 9.0,
7475            .expectParseWarning = true // max() warns if data types of arguments not matching
7476        });
7477    
7478        // std unit tests ...
7479    
7480        runScript({
7481            .code = R"NKSP_CODE(
7482    on init
7483      declare $foo := max(30ms,4s)
7484      exit($foo)
7485    end on
7486    )NKSP_CODE",
7487            .expectIntExitResult = 4,
7488            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7489            .expectExitResultUnit = VM_SECOND,
7490        });
7491    
7492        runScript({
7493            .code = R"NKSP_CODE(
7494    on init
7495      declare $foo := max(4s,30ms)
7496      exit($foo)
7497    end on
7498    )NKSP_CODE",
7499            .expectIntExitResult = 4,
7500            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7501            .expectExitResultUnit = VM_SECOND,
7502        });
7503    
7504        runScript({
7505            .code = R"NKSP_CODE(
7506    on init
7507      declare $foo := max(-30mdB,-4dB)
7508      exit($foo)
7509    end on
7510    )NKSP_CODE",
7511            .expectIntExitResult = -30,
7512            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7513            .expectExitResultUnit = VM_BEL,
7514        });
7515    
7516        runScript({
7517            .code = R"NKSP_CODE(
7518    on init
7519      declare $foo := max(-4dB,-30mdB)
7520      exit($foo)
7521    end on
7522    )NKSP_CODE",
7523            .expectIntExitResult = -30,
7524            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7525            .expectExitResultUnit = VM_BEL,
7526        });
7527    
7528        runScript({
7529            .code = R"NKSP_CODE(
7530    on init
7531      declare $foo := max(-4s,-30Hz)
7532      exit($foo)
7533    end on
7534    )NKSP_CODE",
7535            .expectParseError = true // max() requires arguments to have same unit type
7536        });
7537    
7538        runScript({
7539            .code = R"NKSP_CODE(
7540    on init
7541      declare $foo := max(-4s,-30)
7542      exit($foo)
7543    end on
7544    )NKSP_CODE",
7545            .expectParseError = true // max() requires arguments to have same unit type
7546        });
7547    
7548        runScript({
7549            .code = R"NKSP_CODE(
7550    on init
7551      declare $foo := max(-4,-30s)
7552      exit($foo)
7553    end on
7554    )NKSP_CODE",
7555            .expectParseError = true // max() requires arguments to have same unit type
7556        });
7557    
7558        runScript({
7559            .code = R"NKSP_CODE(
7560    on init
7561      declare ~foo := max(0.9s,1.0s)
7562      exit(~foo)
7563    end on
7564    )NKSP_CODE",
7565            .expectRealExitResult = 1.0,
7566            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7567            .expectExitResultUnit = VM_SECOND,
7568        });
7569    
7570        // 'final' ('!') operator tests ...
7571    
7572        runScript({
7573            .code = R"NKSP_CODE(
7574    on init
7575      declare $foo := max(!30,!4)
7576      exit($foo)
7577    end on
7578    )NKSP_CODE",
7579            .expectIntExitResult = 30,
7580            .expectExitResultFinal = true
7581        });
7582    
7583        runScript({
7584            .code = R"NKSP_CODE(
7585    on init
7586      declare $foo := max(30,4)
7587      exit($foo)
7588    end on
7589    )NKSP_CODE",
7590            .expectIntExitResult = 30,
7591            .expectExitResultFinal = false
7592        });
7593    
7594        runScript({
7595            .code = R"NKSP_CODE(
7596    on init
7597      declare $foo := max(30,!4)
7598      exit($foo)
7599    end on
7600    )NKSP_CODE",
7601            .expectIntExitResult = 30,
7602            .expectExitResultFinal = true,
7603            .expectParseWarning = true // max() warns if only one argument is 'final'
7604        });
7605    
7606        runScript({
7607            .code = R"NKSP_CODE(
7608    on init
7609      declare $foo := max(!30,4)
7610      exit($foo)
7611    end on
7612    )NKSP_CODE",
7613            .expectIntExitResult = 30,
7614            .expectExitResultFinal = true,
7615            .expectParseWarning = true // max() warns if only one argument is 'final'
7616        });
7617    
7618        runScript({
7619            .code = R"NKSP_CODE(
7620    on init
7621      declare ~foo := max(!12.1,!12.2)
7622      exit(~foo)
7623    end on
7624    )NKSP_CODE",
7625            .expectRealExitResult = 12.2,
7626            .expectExitResultFinal = true
7627        });
7628    
7629        runScript({
7630            .code = R"NKSP_CODE(
7631    on init
7632      declare ~foo := max(12.1,12.2)
7633      exit(~foo)
7634    end on
7635    )NKSP_CODE",
7636            .expectRealExitResult = 12.2,
7637            .expectExitResultFinal = false
7638        });
7639    
7640        runScript({
7641            .code = R"NKSP_CODE(
7642    on init
7643      declare ~foo := max(!12.1,12.2)
7644      exit(~foo)
7645    end on
7646    )NKSP_CODE",
7647            .expectRealExitResult = 12.2,
7648            .expectExitResultFinal = true,
7649            .expectParseWarning = true // max() warns if only one argument is 'final'
7650        });
7651    
7652        runScript({
7653            .code = R"NKSP_CODE(
7654    on init
7655      declare ~foo := max(12.1,!12.2)
7656      exit(~foo)
7657    end on
7658    )NKSP_CODE",
7659            .expectRealExitResult = 12.2,
7660            .expectExitResultFinal = true,
7661            .expectParseWarning = true // max() warns if only one argument is 'final'
7662        });
7663    
7664      #if !SILENT_TEST      #if !SILENT_TEST
7665      std::cout << std::endl;      std::cout << std::endl;
7666      #endif      #endif
# Line 1289  end on Line 7689  end on
7689          .expectParseError = true // because abs() function requires 1 argument          .expectParseError = true // because abs() function requires 1 argument
7690      });      });
7691    
7692        // integer tests ...
7693    
7694      runScript({      runScript({
7695          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7696  on init  on init
# Line 1309  end on Line 7711  end on
7711          .expectIntExitResult = 23          .expectIntExitResult = 23
7712      });      });
7713    
7714        // real number tests ...
7715    
7716        runScript({
7717            .code = R"NKSP_CODE(
7718    on init
7719      declare ~foo := abs(23.0)
7720      exit(~foo)
7721    end on
7722    )NKSP_CODE",
7723            .expectRealExitResult = 23.0
7724        });
7725    
7726        runScript({
7727            .code = R"NKSP_CODE(
7728    on init
7729      declare ~foo := abs(23.11)
7730      exit(~foo)
7731    end on
7732    )NKSP_CODE",
7733            .expectRealExitResult = 23.11
7734        });
7735    
7736        runScript({
7737            .code = R"NKSP_CODE(
7738    on init
7739      declare ~foo := abs(-23.11)
7740      exit(~foo)
7741    end on
7742    )NKSP_CODE",
7743            .expectRealExitResult = 23.11
7744        });
7745    
7746        runScript({
7747            .code = R"NKSP_CODE(
7748    on init
7749      declare ~bar := -23.11
7750      declare ~foo := abs(~bar)
7751      exit(~foo)
7752    end on
7753    )NKSP_CODE",
7754            .expectRealExitResult = 23.11
7755        });
7756    
7757        // std unit tests ...
7758    
7759        runScript({
7760            .code = R"NKSP_CODE(
7761    on init
7762      declare $foo := abs(-23kHz)
7763      exit($foo)
7764    end on
7765    )NKSP_CODE",
7766            .expectIntExitResult = 23,
7767            .expectExitResultUnitPrefix = { VM_KILO },
7768            .expectExitResultUnit = VM_HERTZ
7769        });
7770    
7771        runScript({
7772            .code = R"NKSP_CODE(
7773    on init
7774      declare ~foo := abs(-23.4kHz)
7775      exit(~foo)
7776    end on
7777    )NKSP_CODE",
7778            .expectRealExitResult = 23.4,
7779            .expectExitResultUnitPrefix = { VM_KILO },
7780            .expectExitResultUnit = VM_HERTZ
7781        });
7782    
7783        // 'final' ('!') operator tests ...
7784    
7785        runScript({
7786            .code = R"NKSP_CODE(
7787    on init
7788      declare $foo := abs(!-23)
7789      exit($foo)
7790    end on
7791    )NKSP_CODE",
7792            .expectIntExitResult = 23,
7793            .expectExitResultFinal = true
7794        });
7795    
7796        runScript({
7797            .code = R"NKSP_CODE(
7798    on init
7799      declare $foo := abs(-23)
7800      exit($foo)
7801    end on
7802    )NKSP_CODE",
7803            .expectIntExitResult = 23,
7804            .expectExitResultFinal = false
7805        });
7806    
7807        runScript({
7808            .code = R"NKSP_CODE(
7809    on init
7810      declare ~foo := abs(!-23.2)
7811      exit(~foo)
7812    end on
7813    )NKSP_CODE",
7814            .expectRealExitResult = 23.2,
7815            .expectExitResultFinal = true
7816        });
7817    
7818        runScript({
7819            .code = R"NKSP_CODE(
7820    on init
7821      declare ~foo := abs(-23.9)
7822      exit(~foo)
7823    end on
7824    )NKSP_CODE",
7825            .expectRealExitResult = 23.9,
7826            .expectExitResultFinal = false
7827        });
7828    
7829      #if !SILENT_TEST      #if !SILENT_TEST
7830      std::cout << std::endl;      std::cout << std::endl;
7831      #endif      #endif
# Line 1319  static void testBuiltInIncFunction() { Line 7836  static void testBuiltInIncFunction() {
7836      std::cout << "UNIT TEST: built-in inc() function\n";      std::cout << "UNIT TEST: built-in inc() function\n";
7837      #endif      #endif
7838    
7839        // integer tests ...
7840    
7841      runScript({      runScript({
7842          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7843  on init  on init
# Line 1354  end on Line 7873  end on
7873          .expectIntExitResult = 7          .expectIntExitResult = 7
7874      });      });
7875    
7876        // std unit tests ...
7877    
7878        runScript({
7879            .code = R"NKSP_CODE(
7880    on init
7881      declare $foo := 53mdB
7882      inc($foo)
7883      exit( inc($foo) )
7884    end on
7885    )NKSP_CODE",
7886            .expectIntExitResult = 55,
7887            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7888            .expectExitResultUnit = VM_BEL,
7889            .expectParseWarning = true // inc() warns if argument has a unit
7890        });
7891    
7892        // 'final' ('!') operator tests ...
7893    
7894        runScript({
7895            .code = R"NKSP_CODE(
7896    on init
7897      declare $foo := !53
7898      inc($foo)
7899      exit( inc($foo) )
7900    end on
7901    )NKSP_CODE",
7902            .expectIntExitResult = 55,
7903            .expectExitResultFinal = true
7904        });
7905    
7906        runScript({
7907            .code = R"NKSP_CODE(
7908    on init
7909      declare $foo := 53
7910      inc($foo)
7911      exit( inc($foo) )
7912    end on
7913    )NKSP_CODE",
7914            .expectIntExitResult = 55,
7915            .expectExitResultFinal = false
7916        });
7917    
7918        runScript({
7919            .code = R"NKSP_CODE(
7920    on init
7921      declare $foo := 53
7922      inc($foo)
7923      exit( !inc($foo) )
7924    end on
7925    )NKSP_CODE",
7926            .expectIntExitResult = 55,
7927            .expectExitResultFinal = true
7928        });
7929    
7930      #if !SILENT_TEST      #if !SILENT_TEST
7931      std::cout << std::endl;      std::cout << std::endl;
7932      #endif      #endif
# Line 1364  static void testBuiltInDecFunction() { Line 7937  static void testBuiltInDecFunction() {
7937      std::cout << "UNIT TEST: built-in dec() function\n";      std::cout << "UNIT TEST: built-in dec() function\n";
7938      #endif      #endif
7939    
7940        // integer tests ...
7941    
7942      runScript({      runScript({
7943          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7944  on init  on init
# Line 1399  end on Line 7974  end on
7974          .expectIntExitResult = 3          .expectIntExitResult = 3
7975      });      });
7976    
7977        // std unit tests ...
7978    
7979        runScript({
7980            .code = R"NKSP_CODE(
7981    on init
7982      declare $foo := 53mdB
7983      dec($foo)
7984      exit( dec($foo) )
7985    end on
7986    )NKSP_CODE",
7987            .expectIntExitResult = 51,
7988            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7989            .expectExitResultUnit = VM_BEL,
7990            .expectParseWarning = true // dec() warns if argument has a unit
7991        });
7992    
7993        // 'final' ('!') operator tests ...
7994    
7995        runScript({
7996            .code = R"NKSP_CODE(
7997    on init
7998      declare $foo := !53
7999      dec($foo)
8000      exit( dec($foo) )
8001    end on
8002    )NKSP_CODE",
8003            .expectIntExitResult = 51,
8004            .expectExitResultFinal = true
8005        });
8006    
8007        runScript({
8008            .code = R"NKSP_CODE(
8009    on init
8010      declare $foo := 53
8011      dec($foo)
8012      exit( dec($foo) )
8013    end on
8014    )NKSP_CODE",
8015            .expectIntExitResult = 51,
8016            .expectExitResultFinal = false
8017        });
8018    
8019        runScript({
8020            .code = R"NKSP_CODE(
8021    on init
8022      declare $foo := 53
8023      dec($foo)
8024      exit( !dec($foo) )
8025    end on
8026    )NKSP_CODE",
8027            .expectIntExitResult = 51,
8028            .expectExitResultFinal = true
8029        });
8030    
8031      #if !SILENT_TEST      #if !SILENT_TEST
8032      std::cout << std::endl;      std::cout << std::endl;
8033      #endif      #endif
# Line 1409  static void testBuiltInInRangeFunction() Line 8038  static void testBuiltInInRangeFunction()
8038      std::cout << "UNIT TEST: built-in in_range() function\n";      std::cout << "UNIT TEST: built-in in_range() function\n";
8039      #endif      #endif
8040    
8041        // integer tests ...
8042    
8043      runScript({      runScript({
8044          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
8045  on init  on init
# Line 1490  end on Line 8121  end on
8121          .expectBoolExitResult = false          .expectBoolExitResult = false
8122      });      });
8123    
8124        // real number tests ...
8125    
8126        runScript({
8127            .code = R"NKSP_CODE(
8128    on init
8129      exit( in_range(12.2,12.1,12.9) )
8130    end on
8131    )NKSP_CODE",
8132            .expectBoolExitResult = true
8133        });
8134    
8135        runScript({
8136            .code = R"NKSP_CODE(
8137    on init
8138      exit( in_range(12.2,12.9,12.1) )
8139    end on
8140    )NKSP_CODE",
8141            .expectBoolExitResult = true
8142        });
8143    
8144        runScript({
8145            .code = R"NKSP_CODE(
8146    on init
8147      exit( in_range(12.0,12.1,12.9) )
8148    end on
8149    )NKSP_CODE",
8150            .expectBoolExitResult = false
8151        });
8152    
8153        runScript({
8154            .code = R"NKSP_CODE(
8155    on init
8156      exit( in_range(12.0,12.9,12.1) )
8157    end on
8158    )NKSP_CODE",
8159            .expectBoolExitResult = false
8160        });
8161    
8162        runScript({
8163            .code = R"NKSP_CODE(
8164    on init
8165      exit( in_range(0.0,-0.3,0.3) )
8166    end on
8167    )NKSP_CODE",
8168            .expectBoolExitResult = true
8169        });
8170    
8171        runScript({
8172            .code = R"NKSP_CODE(
8173    on init
8174      exit( in_range(-0.34,-0.3,0.3) )
8175    end on
8176    )NKSP_CODE",
8177            .expectBoolExitResult = false
8178        });
8179    
8180        runScript({
8181            .code = R"NKSP_CODE(
8182    on init
8183      exit( in_range(0.34,-0.3,0.3) )
8184    end on
8185    )NKSP_CODE",
8186            .expectBoolExitResult = false
8187        });
8188    
8189        runScript({
8190            .code = R"NKSP_CODE(
8191    on init
8192      exit( in_range(-0.3,-0.3,0.3) )
8193    end on
8194    )NKSP_CODE",
8195            .expectBoolExitResult = true
8196        });
8197    
8198        runScript({
8199            .code = R"NKSP_CODE(
8200    on init
8201      exit( in_range(0.3,-0.3,0.3) )
8202    end on
8203    )NKSP_CODE",
8204            .expectBoolExitResult = true
8205        });
8206    
8207        // mixed type tests ...
8208    
8209        runScript({
8210            .code = R"NKSP_CODE(
8211    on init
8212      exit( in_range(4.0,-5,5) )
8213    end on
8214    )NKSP_CODE",
8215            .expectBoolExitResult = true,
8216            .expectParseWarning = true // in_range() warns if not all arguments are of same type
8217        });
8218    
8219        runScript({
8220            .code = R"NKSP_CODE(
8221    on init
8222      exit( in_range(5,-5,5.0) )
8223    end on
8224    )NKSP_CODE",
8225            .expectBoolExitResult = true,
8226            .expectParseWarning = true // in_range() warns if not all arguments are of same type
8227        });
8228    
8229        runScript({
8230            .code = R"NKSP_CODE(
8231    on init
8232      exit( in_range(-5,-5.0,5) )
8233    end on
8234    )NKSP_CODE",
8235            .expectBoolExitResult = true,
8236            .expectParseWarning = true // in_range() warns if not all arguments are of same type
8237        });
8238    
8239        // std unit tests ...
8240    
8241        runScript({
8242            .code = R"NKSP_CODE(
8243    on init
8244      exit( in_range(4000Hz,3kHz,5kHz) )
8245    end on
8246    )NKSP_CODE",
8247            .expectBoolExitResult = true,
8248            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8249            .expectExitResultUnit = VM_NO_UNIT
8250        });
8251    
8252        runScript({
8253            .code = R"NKSP_CODE(
8254    on init
8255      exit( in_range(5000Hz,3kHz,5kHz) )
8256    end on
8257    )NKSP_CODE",
8258            .expectBoolExitResult = true,
8259            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8260            .expectExitResultUnit = VM_NO_UNIT
8261        });
8262    
8263        runScript({
8264            .code = R"NKSP_CODE(
8265    on init
8266      exit( in_range(5001Hz,3kHz,5kHz) )
8267    end on
8268    )NKSP_CODE",
8269            .expectBoolExitResult = false,
8270            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8271            .expectExitResultUnit = VM_NO_UNIT
8272        });
8273    
8274        runScript({
8275            .code = R"NKSP_CODE(
8276    on init
8277      exit( in_range(3000Hz,3kHz,5kHz) )
8278    end on
8279    )NKSP_CODE",
8280            .expectBoolExitResult = true,
8281            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8282            .expectExitResultUnit = VM_NO_UNIT
8283        });
8284    
8285        runScript({
8286            .code = R"NKSP_CODE(
8287    on init
8288      exit( in_range(2999Hz,3kHz,5kHz) )
8289    end on
8290    )NKSP_CODE",
8291            .expectBoolExitResult = false,
8292            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8293            .expectExitResultUnit = VM_NO_UNIT
8294        });
8295    
8296        runScript({
8297            .code = R"NKSP_CODE(
8298    on init
8299      exit( in_range(0.003s,3000.0us,5ms) )
8300    end on
8301    )NKSP_CODE",
8302            .expectBoolExitResult = true,
8303            .expectParseWarning = true, // in_range() warns if not all arguments are of same type
8304            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8305            .expectExitResultUnit = VM_NO_UNIT
8306        });
8307    
8308        runScript({
8309            .code = R"NKSP_CODE(
8310    on init
8311      exit( in_range(0.005s,3000.0us,5ms) )
8312    end on
8313    )NKSP_CODE",
8314            .expectBoolExitResult = true,
8315            .expectParseWarning = true, // in_range() warns if not all arguments are of same type,
8316            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8317            .expectExitResultUnit = VM_NO_UNIT
8318        });
8319    
8320        runScript({
8321            .code = R"NKSP_CODE(
8322    on init
8323      exit( in_range(0.0051s,3000.0us,5ms) )
8324    end on
8325    )NKSP_CODE",
8326            .expectBoolExitResult = false,
8327            .expectParseWarning = true, // in_range() warns if not all arguments are of same type
8328            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8329            .expectExitResultUnit = VM_NO_UNIT
8330        });
8331    
8332        runScript({
8333            .code = R"NKSP_CODE(
8334    on init
8335      exit( in_range(3s,2Hz,5Hz) )
8336    end on
8337    )NKSP_CODE",
8338            .expectParseError = true // in_range() throws error if not all arguments' unit types equal,
8339        });
8340    
8341        runScript({
8342            .code = R"NKSP_CODE(
8343    on init
8344      exit( in_range(3Hz,2s,5Hz) )
8345    end on
8346    )NKSP_CODE",
8347            .expectParseError = true // in_range() throws error if not all arguments' unit types equal
8348        });
8349    
8350        runScript({
8351            .code = R"NKSP_CODE(
8352    on init
8353      exit( in_range(3Hz,2Hz,5s) )
8354    end on
8355    )NKSP_CODE",
8356            .expectParseError = true // in_range() throws error if not all arguments' unit types equal
8357        });
8358    
8359        // 'final' ('!') operator tests ...
8360        // (result should always be NOT final)
8361    
8362        runScript({
8363            .code = R"NKSP_CODE(
8364    on init
8365      exit( in_range(!9,!4,!9) )
8366    end on
8367    )NKSP_CODE",
8368            .expectBoolExitResult = true,
8369            .expectExitResultFinal = false
8370        });
8371    
8372      #if !SILENT_TEST      #if !SILENT_TEST
8373      std::cout << std::endl;      std::cout << std::endl;
8374      #endif      #endif
# Line 1500  static void testBuiltInRandomFunction() Line 8379  static void testBuiltInRandomFunction()
8379      std::cout << "UNIT TEST: built-in random() function\n";      std::cout << "UNIT TEST: built-in random() function\n";
8380      #endif      #endif
8381    
8382        // integer tests ...
8383    
8384        runScript({
8385            .code = R"NKSP_CODE(
8386    on init
8387      exit( random(-5,5) )
8388    end on
8389    )NKSP_CODE",
8390            .expectExitResultIsInt = true // only check type, exact value is irrelevant here
8391        });
8392    
8393      for (int run = 0; run < 20; ++run) {      for (int run = 0; run < 20; ++run) {
8394          runScript({          runScript({
8395              .code = R"NKSP_CODE(              .code = R"NKSP_CODE(
# Line 1512  end on Line 8402  end on
8402          });          });
8403      }      }
8404    
8405        // real number tests ...
8406    
8407        runScript({
8408            .code = R"NKSP_CODE(
8409    on init
8410      exit( random(-0.5,0.5) )
8411    end on
8412    )NKSP_CODE",
8413            .expectExitResultIsReal = true // only check type, exact value is irrelevant here
8414        });
8415    
8416        runScript({
8417            .code = R"NKSP_CODE(
8418    on init
8419      declare ~foo := random(-5.0,5.0)
8420      exit(~foo)
8421    end on
8422    )NKSP_CODE",
8423            .expectExitResultIsReal = true // only check type, exact value is irrelevant here
8424        });
8425    
8426        for (int run = 0; run < 20; ++run) {
8427            runScript({
8428                .code = R"NKSP_CODE(
8429    on init
8430      declare ~foo := random(-0.5,0.5)
8431      exit( in_range(~foo,-0.5,0.5) )
8432    end on
8433    )NKSP_CODE",
8434                .expectBoolExitResult = true
8435            });
8436        }
8437    
8438        for (int run = 0; run < 20; ++run) {
8439            runScript({
8440                .code = R"NKSP_CODE(
8441    on init
8442      declare ~foo := random(-5.0,12.0)
8443      exit( in_range(~foo,-5.0,12.0) )
8444    end on
8445    )NKSP_CODE",
8446                .expectBoolExitResult = true
8447            });
8448        }
8449    
8450        for (int run = 0; run < 20; ++run) {
8451            runScript({
8452                .code = R"NKSP_CODE(
8453    on init
8454      declare ~foo := random(23.3,98.4)
8455      exit( in_range(~foo,23.3,98.4) )
8456    end on
8457    )NKSP_CODE",
8458                .expectBoolExitResult = true
8459            });
8460        }
8461    
8462        // std unit tests ...
8463    
8464        runScript({
8465            .code = R"NKSP_CODE(
8466    on init
8467      exit( random(-5Hz,5Hz) )
8468    end on
8469    )NKSP_CODE",
8470            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8471            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8472            .expectExitResultUnit = VM_HERTZ
8473        });
8474    
8475        for (int run = 0; run < 20; ++run) {
8476            runScript({
8477                .code = R"NKSP_CODE(
8478    on init
8479      declare $foo := random(-5Hz,5Hz)
8480      exit( in_range($foo,-5Hz,5Hz) )
8481    end on
8482    )NKSP_CODE",
8483                .expectBoolExitResult = true
8484            });
8485        }
8486    
8487        runScript({
8488            .code = R"NKSP_CODE(
8489    on init
8490      exit( random(5us,1ms) )
8491    end on
8492    )NKSP_CODE",
8493            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8494            .expectExitResultUnitPrefix = { VM_MICRO },
8495            .expectExitResultUnit = VM_SECOND
8496        });
8497    
8498        for (int run = 0; run < 20; ++run) {
8499            runScript({
8500                .code = R"NKSP_CODE(
8501    on init
8502      declare $foo := random(5us,1ms)
8503      exit( in_range($foo,5us,1ms) )
8504    end on
8505    )NKSP_CODE",
8506                .expectBoolExitResult = true
8507            });
8508        }
8509    
8510        runScript({
8511            .code = R"NKSP_CODE(
8512    on init
8513      exit( random(1ms,5000us) )
8514    end on
8515    )NKSP_CODE",
8516            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8517            .expectExitResultUnitPrefix = { VM_MICRO },
8518            .expectExitResultUnit = VM_SECOND
8519        });
8520    
8521        for (int run = 0; run < 20; ++run) {
8522            runScript({
8523                .code = R"NKSP_CODE(
8524    on init
8525      declare $foo := random(1ms,5000us)
8526      exit( in_range($foo,1ms,5000us) )
8527    end on
8528    )NKSP_CODE",
8529                .expectBoolExitResult = true
8530            });
8531        }
8532    
8533        runScript({
8534            .code = R"NKSP_CODE(
8535    on init
8536      exit( random(1kHz,20kHz) )
8537    end on
8538    )NKSP_CODE",
8539            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8540            .expectExitResultUnitPrefix = { VM_KILO },
8541            .expectExitResultUnit = VM_HERTZ
8542        });
8543    
8544        for (int run = 0; run < 20; ++run) {
8545            runScript({
8546                .code = R"NKSP_CODE(
8547    on init
8548      declare $foo := random(1kHz,20kHz)
8549      exit( in_range($foo,1kHz,20kHz) )
8550    end on
8551    )NKSP_CODE",
8552                .expectBoolExitResult = true
8553            });
8554        }
8555    
8556        runScript({
8557            .code = R"NKSP_CODE(
8558    on init
8559      exit( random(1.2us,3.5us) )
8560    end on
8561    )NKSP_CODE",
8562            .expectExitResultIsReal = true, // only check type, exact value is irrelevant here
8563            .expectExitResultUnitPrefix = { VM_MICRO },
8564            .expectExitResultUnit = VM_SECOND
8565        });
8566    
8567        for (int run = 0; run < 20; ++run) {
8568            runScript({
8569                .code = R"NKSP_CODE(
8570    on init
8571      declare ~foo := random(1.2us,3.5us)
8572      exit( in_range(~foo,1.2us,3.5us) )
8573    end on
8574    )NKSP_CODE",
8575                .expectBoolExitResult = true
8576            });
8577        }
8578    
8579        runScript({
8580            .code = R"NKSP_CODE(
8581    on init
8582      exit( random(5.2us,1.1ms) )
8583    end on
8584    )NKSP_CODE",
8585            .expectExitResultIsReal = true, // only check type, exact value is irrelevant here
8586            .expectExitResultUnitPrefix = { VM_MICRO },
8587            .expectExitResultUnit = VM_SECOND
8588        });
8589    
8590        for (int run = 0; run < 20; ++run) {
8591            runScript({
8592                .code = R"NKSP_CODE(
8593    on init
8594      declare ~foo := random(5.2us,1.1ms)
8595      exit( in_range(~foo,5.2us,1.1ms) )
8596    end on
8597    )NKSP_CODE",
8598                .expectBoolExitResult = true
8599            });
8600        }
8601    
8602        runScript({
8603            .code = R"NKSP_CODE(
8604    on init
8605      exit( random(1Hz,12s) )
8606    end on
8607    )NKSP_CODE",
8608            .expectParseError = true // random() throws error if arguments' unit types don't match
8609        });
8610    
8611        runScript({
8612            .code = R"NKSP_CODE(
8613    on init
8614      exit( random(1,12s) )
8615    end on
8616    )NKSP_CODE",
8617            .expectParseError = true // random() throws error if arguments' unit types don't match
8618        });
8619    
8620        runScript({
8621            .code = R"NKSP_CODE(
8622    on init
8623      exit( random(1s,12) )
8624    end on
8625    )NKSP_CODE",
8626            .expectParseError = true // random() throws error if arguments' unit types don't match
8627        });
8628    
8629        // 'final' ('!') operator tests ...
8630    
8631        runScript({
8632            .code = R"NKSP_CODE(
8633    on init
8634      exit( random(!1,!12) )
8635    end on
8636    )NKSP_CODE",
8637            .expectExitResultFinal = true
8638        });
8639    
8640        runScript({
8641            .code = R"NKSP_CODE(
8642    on init
8643      exit( random(1,12) )
8644    end on
8645    )NKSP_CODE",
8646            .expectExitResultFinal = false
8647        });
8648    
8649        runScript({
8650            .code = R"NKSP_CODE(
8651    on init
8652      exit( random(!1,12) )
8653    end on
8654    )NKSP_CODE",
8655            .expectExitResultFinal = true,
8656            .expectParseWarning = true // random() warns if only one argument is 'final'
8657        });
8658    
8659        runScript({
8660            .code = R"NKSP_CODE(
8661    on init
8662      exit( random(1,!12) )
8663    end on
8664    )NKSP_CODE",
8665            .expectExitResultFinal = true,
8666            .expectParseWarning = true // random() warns if only one argument is 'final'
8667        });
8668    
8669      #if !SILENT_TEST      #if !SILENT_TEST
8670      std::cout << std::endl;      std::cout << std::endl;
8671      #endif      #endif
# Line 1618  end on Line 8772  end on
8772      #endif      #endif
8773  }  }
8774    
8775    static void testBuiltInMsbFunction() {
8776        #if !SILENT_TEST
8777        std::cout << "UNIT TEST: built-in msb() function\n";
8778        #endif
8779    
8780        runScript({
8781            .code = R"NKSP_CODE(
8782    on init
8783      exit( msb(0) )
8784    end on
8785    )NKSP_CODE",
8786            .expectIntExitResult = 0
8787        });
8788    
8789        runScript({
8790            .code = R"NKSP_CODE(
8791    on init
8792      exit( msb(127) )
8793    end on
8794    )NKSP_CODE",
8795            .expectIntExitResult = 0
8796        });
8797    
8798        runScript({
8799            .code = R"NKSP_CODE(
8800    on init
8801      exit( msb(128) )
8802    end on
8803    )NKSP_CODE",
8804            .expectIntExitResult = 1
8805        });
8806    
8807        runScript({
8808            .code = R"NKSP_CODE(
8809    on init
8810      exit( msb(16255) )
8811    end on
8812    )NKSP_CODE",
8813            .expectIntExitResult = 126
8814        });
8815    
8816        runScript({
8817            .code = R"NKSP_CODE(
8818    on init
8819      exit( msb(16256) )
8820    end on
8821    )NKSP_CODE",
8822            .expectIntExitResult = 127
8823        });
8824    
8825        runScript({
8826            .code = R"NKSP_CODE(
8827    on init
8828      exit( msb(16383) )
8829    end on
8830    )NKSP_CODE",
8831            .expectIntExitResult = 127
8832        });
8833    
8834        #if !SILENT_TEST
8835        std::cout << std::endl;
8836        #endif
8837    }
8838    
8839    static void testBuiltInLsbFunction() {
8840        #if !SILENT_TEST
8841        std::cout << "UNIT TEST: built-in lsb() function\n";
8842        #endif
8843    
8844        runScript({
8845            .code = R"NKSP_CODE(
8846    on init
8847      exit( lsb(0) )
8848    end on
8849    )NKSP_CODE",
8850            .expectIntExitResult = 0
8851        });
8852    
8853        runScript({
8854            .code = R"NKSP_CODE(
8855    on init
8856      exit( lsb(1) )
8857    end on
8858    )NKSP_CODE",
8859            .expectIntExitResult = 1
8860        });
8861    
8862        runScript({
8863            .code = R"NKSP_CODE(
8864    on init
8865      exit( lsb(126) )
8866    end on
8867    )NKSP_CODE",
8868            .expectIntExitResult = 126
8869        });
8870    
8871        runScript({
8872            .code = R"NKSP_CODE(
8873    on init
8874      exit( lsb(127) )
8875    end on
8876    )NKSP_CODE",
8877            .expectIntExitResult = 127
8878        });
8879    
8880        runScript({
8881            .code = R"NKSP_CODE(
8882    on init
8883      exit( lsb(128) )
8884    end on
8885    )NKSP_CODE",
8886            .expectIntExitResult = 0
8887        });
8888    
8889        runScript({
8890            .code = R"NKSP_CODE(
8891    on init
8892      exit( lsb(16255) )
8893    end on
8894    )NKSP_CODE",
8895            .expectIntExitResult = 127
8896        });
8897    
8898        runScript({
8899            .code = R"NKSP_CODE(
8900    on init
8901      exit( lsb(16256) )
8902    end on
8903    )NKSP_CODE",
8904            .expectIntExitResult = 0
8905        });
8906    
8907        #if !SILENT_TEST
8908        std::cout << std::endl;
8909        #endif
8910    }
8911    
8912    static void testBuiltInIntToRealFunction() {
8913        #if !SILENT_TEST
8914        std::cout << "UNIT TEST: built-in int_to_real() function\n";
8915        #endif
8916    
8917        runScript({
8918            .code = R"NKSP_CODE(
8919    on init
8920      exit( int_to_real(8) )
8921    end on
8922    )NKSP_CODE",
8923            .expectRealExitResult = 8.0
8924        });
8925    
8926        runScript({
8927            .code = R"NKSP_CODE(
8928    on init
8929      declare $foo := 23
8930      exit( int_to_real($foo) )
8931    end on
8932    )NKSP_CODE",
8933            .expectRealExitResult = 23.0
8934        });
8935    
8936        // std unit tests ...
8937    
8938        runScript({
8939            .code = R"NKSP_CODE(
8940    on init
8941      exit( int_to_real(-58mdB) )
8942    end on
8943    )NKSP_CODE",
8944            .expectRealExitResult = -58.0,
8945            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
8946            .expectExitResultUnit = VM_BEL
8947        });
8948    
8949        runScript({
8950            .code = R"NKSP_CODE(
8951    on init
8952      declare $foo := -58mdB
8953      exit( int_to_real($foo) )
8954    end on
8955    )NKSP_CODE",
8956            .expectRealExitResult = -58.0,
8957            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
8958            .expectExitResultUnit = VM_BEL
8959        });
8960    
8961        runScript({
8962            .code = R"NKSP_CODE(
8963    on init
8964      declare $foo := 7000ms
8965      exit( int_to_real($foo) )
8966    end on
8967    )NKSP_CODE",
8968            .expectRealExitResult = 7000.0,
8969            .expectExitResultUnitPrefix = { VM_MILLI },
8970            .expectExitResultUnit = VM_SECOND
8971        });
8972    
8973        runScript({
8974            .code = R"NKSP_CODE(
8975    on init
8976      declare $foo := 7000ms
8977      declare @s := "" & int_to_real($foo)
8978      exit( @s )
8979    end on
8980    )NKSP_CODE",
8981            .expectStringExitResult = "7000ms",
8982        });
8983    
8984        runScript({
8985            .code = R"NKSP_CODE(
8986    on init
8987      declare $foo := 700ms
8988      exit( int_to_real($foo) / 7.0 )
8989    end on
8990    )NKSP_CODE",
8991            .expectRealExitResult = 100.0,
8992            .expectExitResultUnitPrefix = { VM_MILLI },
8993            .expectExitResultUnit = VM_SECOND
8994        });
8995    
8996        runScript({
8997            .code = R"NKSP_CODE(
8998    on init
8999      declare $foo := 700ms
9000      exit( int_to_real($foo) / 7.0 & "" )
9001    end on
9002    )NKSP_CODE",
9003            .expectStringExitResult = "100ms"
9004        });
9005    
9006        // 'final' ('!') operator tests ...
9007    
9008        runScript({
9009            .code = R"NKSP_CODE(
9010    on init
9011      declare $foo := !-58
9012      exit( int_to_real($foo) )
9013    end on
9014    )NKSP_CODE",
9015            .expectRealExitResult = -58.0,
9016            .expectExitResultFinal = true
9017        });
9018    
9019        runScript({
9020            .code = R"NKSP_CODE(
9021    on init
9022      declare $foo := -58
9023      exit( int_to_real($foo) )
9024    end on
9025    )NKSP_CODE",
9026            .expectRealExitResult = -58.0,
9027            .expectExitResultFinal = false
9028        });
9029    
9030        #if !SILENT_TEST
9031        std::cout << std::endl;
9032        #endif
9033    }
9034    
9035    static void testBuiltInRealFunction() {
9036        #if !SILENT_TEST
9037        std::cout << "UNIT TEST: built-in real() function\n";
9038        #endif
9039    
9040        runScript({
9041            .code = R"NKSP_CODE(
9042    on init
9043      exit( real(8) )
9044    end on
9045    )NKSP_CODE",
9046            .expectRealExitResult = 8.0
9047        });
9048    
9049        runScript({
9050            .code = R"NKSP_CODE(
9051    on init
9052      declare $foo := 23
9053      exit( real($foo) )
9054    end on
9055    )NKSP_CODE",
9056            .expectRealExitResult = 23.0
9057        });
9058    
9059        // std unit tests ...
9060    
9061        runScript({
9062            .code = R"NKSP_CODE(
9063    on init
9064      exit( real(-58mdB) )
9065    end on
9066    )NKSP_CODE",
9067            .expectRealExitResult = -58.0,
9068            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9069            .expectExitResultUnit = VM_BEL
9070        });
9071    
9072        runScript({
9073            .code = R"NKSP_CODE(
9074    on init
9075      declare $foo := -58mdB
9076      exit( real($foo) )
9077    end on
9078    )NKSP_CODE",
9079            .expectRealExitResult = -58.0,
9080            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9081            .expectExitResultUnit = VM_BEL
9082        });
9083    
9084        runScript({
9085            .code = R"NKSP_CODE(
9086    on init
9087      declare $foo := 7000ms
9088      exit( real($foo) )
9089    end on
9090    )NKSP_CODE",
9091            .expectRealExitResult = 7000.0,
9092            .expectExitResultUnitPrefix = { VM_MILLI },
9093            .expectExitResultUnit = VM_SECOND
9094        });
9095    
9096        runScript({
9097            .code = R"NKSP_CODE(
9098    on init
9099      declare $foo := 7000ms
9100      declare @s := "" & real($foo)
9101      exit( @s )
9102    end on
9103    )NKSP_CODE",
9104            .expectStringExitResult = "7000ms",
9105        });
9106    
9107        runScript({
9108            .code = R"NKSP_CODE(
9109    on init
9110      declare $foo := 700ms
9111      exit( real($foo) / 7.0 )
9112    end on
9113    )NKSP_CODE",
9114            .expectRealExitResult = 100.0,
9115            .expectExitResultUnitPrefix = { VM_MILLI },
9116            .expectExitResultUnit = VM_SECOND
9117        });
9118    
9119        runScript({
9120            .code = R"NKSP_CODE(
9121    on init
9122      declare $foo := 700ms
9123      exit( real($foo) / 7.0 & "" )
9124    end on
9125    )NKSP_CODE",
9126            .expectStringExitResult = "100ms"
9127        });
9128    
9129        // 'final' ('!') operator tests ...
9130    
9131        runScript({
9132            .code = R"NKSP_CODE(
9133    on init
9134      declare $foo := !-58
9135      exit( real($foo) )
9136    end on
9137    )NKSP_CODE",
9138            .expectRealExitResult = -58.0,
9139            .expectExitResultFinal = true
9140        });
9141    
9142        runScript({
9143            .code = R"NKSP_CODE(
9144    on init
9145      declare $foo := -58
9146      exit( real($foo) )
9147    end on
9148    )NKSP_CODE",
9149            .expectRealExitResult = -58.0,
9150            .expectExitResultFinal = false
9151        });
9152    
9153        #if !SILENT_TEST
9154        std::cout << std::endl;
9155        #endif
9156    }
9157    
9158    static void testBuiltInRealToIntFunction() {
9159        #if !SILENT_TEST
9160        std::cout << "UNIT TEST: built-in real_to_int() function\n";
9161        #endif
9162    
9163        runScript({
9164            .code = R"NKSP_CODE(
9165    on init
9166      exit( real_to_int(8.9) )
9167    end on
9168    )NKSP_CODE",
9169            .expectIntExitResult = 8
9170        });
9171    
9172        runScript({
9173            .code = R"NKSP_CODE(
9174    on init
9175      declare ~foo := 8.9
9176      exit( real_to_int(~foo) )
9177    end on
9178    )NKSP_CODE",
9179            .expectIntExitResult = 8
9180        });
9181    
9182        // std unit tests ...
9183    
9184        runScript({
9185            .code = R"NKSP_CODE(
9186    on init
9187      declare ~foo := 8.9mdB
9188      exit( real_to_int(~foo) )
9189    end on
9190    )NKSP_CODE",
9191            .expectIntExitResult = 8,
9192            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9193            .expectExitResultUnit = VM_BEL
9194        });
9195    
9196        runScript({
9197            .code = R"NKSP_CODE(
9198    on init
9199      declare ~foo := 9000.0us
9200      exit( real_to_int(~foo) )
9201    end on
9202    )NKSP_CODE",
9203            .expectIntExitResult = 9000.0,
9204            .expectExitResultUnitPrefix = { VM_MICRO },
9205            .expectExitResultUnit = VM_SECOND
9206        });
9207    
9208        runScript({
9209            .code = R"NKSP_CODE(
9210    on init
9211      declare ~foo := 9000.0us
9212      declare @s := "" & real_to_int(~foo)
9213      exit( @s )
9214    end on
9215    )NKSP_CODE",
9216            .expectStringExitResult = "9000us",
9217        });
9218    
9219        runScript({
9220            .code = R"NKSP_CODE(
9221    on init
9222      declare ~foo := 700.0ms
9223      exit( real_to_int(~foo) / 7 )
9224    end on
9225    )NKSP_CODE",
9226            .expectIntExitResult = 100,
9227            .expectExitResultUnitPrefix = { VM_MILLI },
9228            .expectExitResultUnit = VM_SECOND
9229        });
9230    
9231        runScript({
9232            .code = R"NKSP_CODE(
9233    on init
9234      declare ~foo := 700.0ms
9235      exit( real_to_int(~foo) / 7 & "" )
9236    end on
9237    )NKSP_CODE",
9238            .expectStringExitResult = "100ms"
9239        });
9240    
9241        // 'final' ('!') operator tests ...
9242    
9243        runScript({
9244            .code = R"NKSP_CODE(
9245    on init
9246      declare ~foo := !8.9
9247      exit( real_to_int(~foo) )
9248    end on
9249    )NKSP_CODE",
9250            .expectIntExitResult = 8,
9251            .expectExitResultFinal = true
9252        });
9253    
9254        runScript({
9255            .code = R"NKSP_CODE(
9256    on init
9257      declare ~foo := 8.9
9258      exit( real_to_int(~foo) )
9259    end on
9260    )NKSP_CODE",
9261            .expectIntExitResult = 8,
9262            .expectExitResultFinal = false
9263        });
9264    
9265        #if !SILENT_TEST
9266        std::cout << std::endl;
9267        #endif
9268    }
9269    
9270    static void testBuiltInIntFunction() {
9271        #if !SILENT_TEST
9272        std::cout << "UNIT TEST: built-in int() function\n";
9273        #endif
9274    
9275        runScript({
9276            .code = R"NKSP_CODE(
9277    on init
9278      exit( int(8.9) )
9279    end on
9280    )NKSP_CODE",
9281            .expectIntExitResult = 8
9282        });
9283    
9284        runScript({
9285            .code = R"NKSP_CODE(
9286    on init
9287      declare ~foo := 8.9
9288      exit( int(~foo) )
9289    end on
9290    )NKSP_CODE",
9291            .expectIntExitResult = 8
9292        });
9293    
9294        // std unit tests ...
9295    
9296        runScript({
9297            .code = R"NKSP_CODE(
9298    on init
9299      declare ~foo := 8.9mdB
9300      exit( int(~foo) )
9301    end on
9302    )NKSP_CODE",
9303            .expectIntExitResult = 8,
9304            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9305            .expectExitResultUnit = VM_BEL
9306        });
9307    
9308        runScript({
9309            .code = R"NKSP_CODE(
9310    on init
9311      declare ~foo := 9000.0us
9312      exit( int(~foo) )
9313    end on
9314    )NKSP_CODE",
9315            .expectIntExitResult = 9000.0,
9316            .expectExitResultUnitPrefix = { VM_MICRO },
9317            .expectExitResultUnit = VM_SECOND
9318        });
9319    
9320        runScript({
9321            .code = R"NKSP_CODE(
9322    on init
9323      declare ~foo := 9000.0us
9324      declare @s := "" & int(~foo)
9325      exit( @s )
9326    end on
9327    )NKSP_CODE",
9328            .expectStringExitResult = "9000us",
9329        });
9330    
9331        runScript({
9332            .code = R"NKSP_CODE(
9333    on init
9334      declare ~foo := 700.0ms
9335      exit( int(~foo) / 7 )
9336    end on
9337    )NKSP_CODE",
9338            .expectIntExitResult = 100,
9339            .expectExitResultUnitPrefix = { VM_MILLI },
9340            .expectExitResultUnit = VM_SECOND
9341        });
9342    
9343        runScript({
9344            .code = R"NKSP_CODE(
9345    on init
9346      declare ~foo := 700.0ms
9347      exit( int(~foo) / 7 & "" )
9348    end on
9349    )NKSP_CODE",
9350            .expectStringExitResult = "100ms"
9351        });
9352    
9353        // 'final' ('!') operator tests ...
9354    
9355        runScript({
9356            .code = R"NKSP_CODE(
9357    on init
9358      declare ~foo := !8.9
9359      exit( int(~foo) )
9360    end on
9361    )NKSP_CODE",
9362            .expectIntExitResult = 8,
9363            .expectExitResultFinal = true
9364        });
9365    
9366        runScript({
9367            .code = R"NKSP_CODE(
9368    on init
9369      declare ~foo := 8.9
9370      exit( int(~foo) )
9371    end on
9372    )NKSP_CODE",
9373            .expectIntExitResult = 8,
9374            .expectExitResultFinal = false
9375        });
9376    
9377        #if !SILENT_TEST
9378        std::cout << std::endl;
9379        #endif
9380    }
9381    
9382  static void testBuiltInArrayEqualFunction() {  static void testBuiltInArrayEqualFunction() {
9383      #if !SILENT_TEST      #if !SILENT_TEST
9384      std::cout << "UNIT TEST: built-in array_equal() function\n";      std::cout << "UNIT TEST: built-in array_equal() function\n";
9385      #endif      #endif
9386    
9387        // integer array tests ...
9388    
9389      runScript({      runScript({
9390          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
9391  on init  on init
# Line 1675  on init Line 9438  on init
9438    exit( array_equal(%foo, %bar) )    exit( array_equal(%foo, %bar) )
9439  end on  end on
9440  )NKSP_CODE",  )NKSP_CODE",
9441            .expectBoolExitResult = false,
9442            .expectParseWarning = true // array_equal() warns if array sizes do not match
9443        });
9444    
9445        // real number array tests ...
9446    
9447        runScript({
9448            .code = R"NKSP_CODE(
9449    on init
9450      declare ?foo[3] := ( 1.0, 2.0, 3.0 )
9451      declare ?bar[3] := ( 1.0, 2.0, 3.0 )
9452      exit( array_equal(?foo, ?bar) )
9453    end on
9454    )NKSP_CODE",
9455            .expectBoolExitResult = true
9456        });
9457    
9458        runScript({
9459            .code = R"NKSP_CODE(
9460    on init
9461      declare ?foo[3] := ( 1.0, 1.1, 3.4 )
9462      declare ?bar[3] := ( 1.0, 1.1, 3.4 )
9463      exit( array_equal(?foo, ?bar) )
9464    end on
9465    )NKSP_CODE",
9466            .expectBoolExitResult = true
9467        });
9468    
9469        runScript({
9470            .code = R"NKSP_CODE(
9471    on init
9472      declare ?foo[3] := ( 1.0, 1.1, 3.4 )
9473      declare ?bar[3] := ( 1.0, 1.2, 3.4 )
9474      exit( array_equal(?foo, ?bar) )
9475    end on
9476    )NKSP_CODE",
9477            .expectBoolExitResult = false
9478        });
9479    
9480        runScript({
9481            .code = R"NKSP_CODE(
9482    on init
9483      declare ?foo[3] := ( 1.0, 1.1, 3.4 )
9484      declare ?bar[2] := ( 1.0, 1.1 )
9485      exit( array_equal(?foo, ?bar) )
9486    end on
9487    )NKSP_CODE",
9488            .expectBoolExitResult = false,
9489            .expectParseWarning = true // array_equal() warns if array sizes do not match
9490        });
9491    
9492        // std unit tests ...
9493        // (only metric prefixes allowed, unit types are prohibited for arrays ATM)
9494    
9495        runScript({
9496            .code = R"NKSP_CODE(
9497    on init
9498      declare %foo[3] := ( 1, 1s, 1 )
9499      declare %bar[3] := ( 1, 1,  1 )
9500      exit( array_equal(%foo, %bar) )
9501    end on
9502    )NKSP_CODE",
9503            .expectParseError = true // see comment above
9504        });
9505    
9506        runScript({
9507            .code = R"NKSP_CODE(
9508    on init
9509      declare %foo[3] := ( 1k, 1, 1m )
9510      declare %bar[3] := ( 1k, 1, 1m )
9511      exit( array_equal(%foo, %bar) )
9512    end on
9513    )NKSP_CODE",
9514            .expectBoolExitResult = true
9515        });
9516    
9517        runScript({
9518            .code = R"NKSP_CODE(
9519    on init
9520      declare %foo[3] := ( 1m, 1, 1k )
9521      declare %bar[3] := ( 1k, 1, 1m )
9522      exit( array_equal(%foo, %bar) )
9523    end on
9524    )NKSP_CODE",
9525            .expectBoolExitResult = false
9526        });
9527    
9528        runScript({
9529            .code = R"NKSP_CODE(
9530    on init
9531      declare %foo[3] := ( 1, 1k, 1 )
9532      declare %bar[3] := ( 1, 1,  1 )
9533      exit( array_equal(%foo, %bar) )
9534    end on
9535    )NKSP_CODE",
9536            .expectBoolExitResult = false
9537        });
9538    
9539        runScript({
9540            .code = R"NKSP_CODE(
9541    on init
9542      declare %foo[3] := ( 1, 1k, 1 )
9543      declare %bar[3] := ( 1, 1000, 1 )
9544      exit( array_equal(%foo, %bar) )
9545    end on
9546    )NKSP_CODE",
9547            .expectBoolExitResult = true
9548        });
9549    
9550        runScript({
9551            .code = R"NKSP_CODE(
9552    on init
9553      declare %foo[3] := ( 1, 2, 3000 )
9554      declare %bar[3] := ( 1, 2, 3k )
9555      exit( array_equal(%foo, %bar) )
9556    end on
9557    )NKSP_CODE",
9558            .expectBoolExitResult = true
9559        });
9560    
9561        runScript({
9562            .code = R"NKSP_CODE(
9563    on init
9564      declare %foo[3] := ( 1, 2, 3m )
9565      declare %bar[3] := ( 1, 2, 3k )
9566      exit( array_equal(%foo, %bar) )
9567    end on
9568    )NKSP_CODE",
9569            .expectBoolExitResult = false
9570        });
9571    
9572        runScript({
9573            .code = R"NKSP_CODE(
9574    on init
9575      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9576      declare ?bar[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9577      exit( array_equal(?foo, ?bar) )
9578    end on
9579    )NKSP_CODE",
9580            .expectBoolExitResult = true
9581        });
9582    
9583        runScript({
9584            .code = R"NKSP_CODE(
9585    on init
9586      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9587      declare ?bar[4] := ( 1.0, 1.0 , 1.1m, 3.4k )
9588      exit( array_equal(?foo, ?bar) )
9589    end on
9590    )NKSP_CODE",
9591          .expectBoolExitResult = false          .expectBoolExitResult = false
9592      });      });
9593    
9594        runScript({
9595            .code = R"NKSP_CODE(
9596    on init
9597      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9598      declare ?bar[4] := ( 1.0, 1.0m, 1.1k, 3.4k )
9599      exit( array_equal(?foo, ?bar) )
9600    end on
9601    )NKSP_CODE",
9602            .expectBoolExitResult = false
9603        });
9604    
9605        runScript({
9606            .code = R"NKSP_CODE(
9607    on init
9608      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9609      declare ?bar[4] := ( 1.0, 1.0m, 1.1m, 3.4u )
9610      exit( array_equal(?foo, ?bar) )
9611    end on
9612    )NKSP_CODE",
9613            .expectBoolExitResult = false
9614        });
9615    
9616        runScript({
9617            .code = R"NKSP_CODE(
9618    on init
9619      declare ?foo[3] := ( 1.0, 1.0k, 1.1m )
9620      declare ?bar[3] := ( 1.0, 1000.0, 1.1m )
9621      exit( array_equal(?foo, ?bar) )
9622    end on
9623    )NKSP_CODE",
9624            .expectBoolExitResult = true
9625        });
9626    
9627        runScript({
9628            .code = R"NKSP_CODE(
9629    on init
9630      declare ?foo[3] := ( 1.0, 1.0k, 1.1u )
9631      declare ?bar[3] := ( 1.0, 1000.0, 0.0011m )
9632      exit( array_equal(?foo, ?bar) )
9633    end on
9634    )NKSP_CODE",
9635            .expectBoolExitResult = true
9636        });
9637    
9638        runScript({
9639            .code = R"NKSP_CODE(
9640    on init
9641      declare ?foo[3] := ( 1.0, 1.0k, 1.1u )
9642      declare ?bar[3] := ( 1.0, 1000.0, 0.0016m )
9643      exit( array_equal(?foo, ?bar) )
9644    end on
9645    )NKSP_CODE",
9646            .expectBoolExitResult = false
9647        });
9648    
9649        // 'final' ('!') operator tests ...
9650        // (currently prohibited for arrays)
9651    
9652        runScript({
9653            .code = R"NKSP_CODE(
9654    on init
9655      declare %foo[3] := ( !1, !1, !1 )
9656      declare %bar[3] := ( !1, !1, !1 )
9657      exit( array_equal(%foo, %bar) )
9658    end on
9659    )NKSP_CODE",
9660            .expectParseError = true // see comment above
9661        });
9662    
9663        runScript({
9664            .code = R"NKSP_CODE(
9665    on init
9666      declare ?foo[3] := ( !1.0, !1.0, !1.0 )
9667      declare ?bar[3] := ( !1.0, !1.0, !1.0 )
9668      exit( array_equal(?foo, ?bar) )
9669    end on
9670    )NKSP_CODE",
9671            .expectParseError = true // see comment above
9672        });
9673    
9674      #if !SILENT_TEST      #if !SILENT_TEST
9675      std::cout << std::endl;      std::cout << std::endl;
9676      #endif      #endif
# Line 1688  static void testBuiltInSortFunction() { Line 9681  static void testBuiltInSortFunction() {
9681      std::cout << "UNIT TEST: built-in sort() function\n";      std::cout << "UNIT TEST: built-in sort() function\n";
9682      #endif      #endif
9683    
9684        // integer array tests ...
9685    
9686      runScript({      runScript({
9687          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
9688  on init  on init
# Line 1712  end on Line 9707  end on
9707          .expectBoolExitResult = true          .expectBoolExitResult = true
9708      });      });
9709    
9710        runScript({
9711            .code = R"NKSP_CODE(
9712    on init
9713      declare %input[6] := ( 1, 80, 120, 40, 3000, 20 )
9714      declare %expected[6] := ( 1, 20, 40, 80, 120, 3000  )
9715      sort(%input, 0)
9716      exit( array_equal(%input, %expected) )
9717    end on
9718    )NKSP_CODE",
9719            .expectBoolExitResult = true
9720        });
9721    
9722        // real number array tests ...
9723    
9724        runScript({
9725            .code = R"NKSP_CODE(
9726    on init
9727      declare ?input[4] := ( 1.4, 1.0, 13.4, 2.7 )
9728      declare ?expected[4] := ( 1.0, 1.4, 2.7, 13.4 )
9729      sort(?input, 0)
9730      exit( array_equal(?input, ?expected) )
9731    end on
9732    )NKSP_CODE",
9733            .expectBoolExitResult = true
9734        });
9735    
9736        runScript({
9737            .code = R"NKSP_CODE(
9738    on init
9739      declare ?input[4] := ( 1.4, 1.0, 13.4, 2.7 )
9740      declare ?expected[4] := ( 13.4, 2.7, 1.4, 1.0 )
9741      sort(?input, 1)
9742      exit( array_equal(?input, ?expected) )
9743    end on
9744    )NKSP_CODE",
9745            .expectBoolExitResult = true
9746        });
9747    
9748        // std unit tests ...
9749        // (only metric prefixes are allowed for arrays ATM)
9750    
9751        runScript({
9752            .code = R"NKSP_CODE(
9753    on init
9754      declare %input[3] := ( 1k, 6, 900 )
9755      declare %expected[3] := ( 6, 900, 1k )
9756      sort(%input, 0)
9757      exit( array_equal(%input, %expected) )
9758    end on
9759    )NKSP_CODE",
9760            .expectBoolExitResult = true
9761        });
9762    
9763        runScript({
9764            .code = R"NKSP_CODE(
9765    on init
9766      declare %input[3] := ( 900, 1k, 6 )
9767      declare %expected[3] := ( 1k, 900, 6 )
9768      sort(%input, 1)
9769      exit( array_equal(%input, %expected) )
9770    end on
9771    )NKSP_CODE",
9772            .expectBoolExitResult = true
9773        });
9774    
9775        runScript({
9776            .code = R"NKSP_CODE(
9777    on init
9778      declare %input[6] := ( 1k, 8m, 4k, 12000u, 3000u, 1000u )
9779      declare %expected[6] := ( 1000u, 3000u, 8m, 12000u, 1k, 4k )
9780      sort(%input, 0)
9781      exit( array_equal(%input, %expected) )
9782    end on
9783    )NKSP_CODE",
9784            .expectBoolExitResult = true
9785        });
9786    
9787        runScript({
9788            .code = R"NKSP_CODE(
9789    on init
9790      declare ?input[3] := ( 1.0k, 6.0, 900.0 )
9791      declare ?expected[3] := ( 6.0, 900.0, 1.0k )
9792      sort(?input, 0)
9793      exit( array_equal(?input, ?expected) )
9794    end on
9795    )NKSP_CODE",
9796            .expectBoolExitResult = true
9797        });
9798    
9799        runScript({
9800            .code = R"NKSP_CODE(
9801    on init
9802      declare ?input[3] := ( 900.0, 1.0k, 6.0 )
9803      declare ?expected[3] := ( 1.0k, 900.0, 6.0 )
9804      sort(?input, 1)
9805      exit( array_equal(?input, ?expected) )
9806    end on
9807    )NKSP_CODE",
9808            .expectBoolExitResult = true
9809        });
9810    
9811        runScript({
9812            .code = R"NKSP_CODE(
9813    on init
9814      declare ?input[3] := ( 1.0k, 0.9k, 1.1k )
9815      declare ?expected[3] := ( 0.9k, 1.0k, 1.1k )
9816      sort(?input, 0)
9817      exit( array_equal(?input, ?expected) )
9818    end on
9819    )NKSP_CODE",
9820            .expectBoolExitResult = true
9821        });
9822    
9823        runScript({
9824            .code = R"NKSP_CODE(
9825    on init
9826      declare ?input[3] := ( 2.0m, 1000.1u, 1.0 )
9827      declare ?expected[3] := ( 1000.1u, 2.0m, 1.0 )
9828      sort(?input, 0)
9829      exit( array_equal(?input, ?expected) )
9830    end on
9831    )NKSP_CODE",
9832            .expectBoolExitResult = true
9833        });
9834    
9835        runScript({
9836            .code = R"NKSP_CODE(
9837    on init
9838      declare ?input[4] := ( 2.0m, 1000.1u, 1.0, 1400.0u )
9839      declare ?expected[4] := ( 1000.1u, 1400.0u, 2.0m, 1.0 )
9840      sort(?input, 0)
9841      exit( array_equal(?input, ?expected) )
9842    end on
9843    )NKSP_CODE",
9844            .expectBoolExitResult = true
9845        });
9846    
9847        runScript({
9848            .code = R"NKSP_CODE(
9849    on init
9850      declare ?input[4] := ( 2.0m, 1000.1u, 1.0, 1400.0u )
9851      declare ?expected[4] := ( 1.0, 2.0m, 1400.0u, 1000.1u )
9852      sort(?input, 1)
9853      exit( array_equal(?input, ?expected) )
9854    end on
9855    )NKSP_CODE",
9856            .expectBoolExitResult = true
9857        });
9858    
9859        runScript({
9860            .code = R"NKSP_CODE(
9861    on init
9862      declare ?input[6] := ( 0.9k, 8.0m, 1.1k, 12000.0u, 3000.0u, 1000.0u )
9863      declare ?expected[6] := ( 1000.0u, 3000.0u, 8.0m, 12000.0u, 0.9k, 1.1k )
9864      sort(?input, 0)
9865      exit( array_equal(?input, ?expected) )
9866    end on
9867    )NKSP_CODE",
9868            .expectBoolExitResult = true
9869        });
9870    
9871        runScript({
9872            .code = R"NKSP_CODE(
9873    on init
9874      declare ?input[6] := ( 0.9k, 8.0m, 1.1k, 12000.0u, 3000.0u, 1000.0u )
9875      declare ?expected[6] := ( 1.1k, 0.9k, 12000.0u, 8.0m, 3000.0u, 1000.0u )
9876      sort(?input, 1)
9877      exit( array_equal(?input, ?expected) )
9878    end on
9879    )NKSP_CODE",
9880            .expectBoolExitResult = true
9881        });
9882    
9883        #if !SILENT_TEST
9884        std::cout << std::endl;
9885        #endif
9886    }
9887    
9888    static void testBuiltInRoundFunction() {
9889        #if !SILENT_TEST
9890        std::cout << "UNIT TEST: built-in round() function\n";
9891        #endif
9892    
9893        // integer tests ...
9894        // (ATM not allowed for this function)
9895    
9896        runScript({
9897            .code = R"NKSP_CODE(
9898    on init
9899      declare $foo := 1
9900      exit( round($foo) )
9901    end on
9902    )NKSP_CODE",
9903            .expectParseError = true // integer not allowed for this function ATM
9904        });
9905    
9906        // real number tests ...
9907    
9908        runScript({
9909            .code = R"NKSP_CODE(
9910    on init
9911      exit( round(99.4) )
9912    end on
9913    )NKSP_CODE",
9914            .expectRealExitResult = 99.0
9915        });
9916    
9917        runScript({
9918            .code = R"NKSP_CODE(
9919    on init
9920      exit( round(99.5) )
9921    end on
9922    )NKSP_CODE",
9923            .expectRealExitResult = 100.0
9924        });
9925    
9926        // std unit tests ...
9927    
9928        runScript({
9929            .code = R"NKSP_CODE(
9930    on init
9931      exit( round(2.4ms) )
9932    end on
9933    )NKSP_CODE",
9934            .expectRealExitResult = 2.0,
9935            .expectExitResultUnitPrefix = { VM_MILLI },
9936            .expectExitResultUnit = VM_SECOND
9937        });
9938    
9939        runScript({
9940            .code = R"NKSP_CODE(
9941    on init
9942      exit( round(2.6kHz) )
9943    end on
9944    )NKSP_CODE",
9945            .expectRealExitResult = 3.0,
9946            .expectExitResultUnitPrefix = { VM_KILO },
9947            .expectExitResultUnit = VM_HERTZ
9948        });
9949    
9950        // 'final' ('!') operator tests ...
9951    
9952        runScript({
9953            .code = R"NKSP_CODE(
9954    on init
9955      exit( round(123.8) )
9956    end on
9957    )NKSP_CODE",
9958            .expectRealExitResult = 124.0,
9959            .expectExitResultFinal = false
9960        });
9961    
9962        runScript({
9963            .code = R"NKSP_CODE(
9964    on init
9965      exit( round(!123.8) )
9966    end on
9967    )NKSP_CODE",
9968            .expectRealExitResult = 124.0,
9969            .expectExitResultFinal = true
9970        });
9971    
9972        #if !SILENT_TEST
9973        std::cout << std::endl;
9974        #endif
9975    }
9976    
9977    static void testBuiltInCeilFunction() {
9978        #if !SILENT_TEST
9979        std::cout << "UNIT TEST: built-in ceil() function\n";
9980        #endif
9981    
9982        // integer tests ...
9983        // (ATM not allowed for this function)
9984    
9985        runScript({
9986            .code = R"NKSP_CODE(
9987    on init
9988      declare $foo := 1
9989      exit( ceil($foo) )
9990    end on
9991    )NKSP_CODE",
9992            .expectParseError = true // integer not allowed for this function ATM
9993        });
9994    
9995        // real number tests ...
9996    
9997        runScript({
9998            .code = R"NKSP_CODE(
9999    on init
10000      exit( ceil(99.0) )
10001    end on
10002    )NKSP_CODE",
10003            .expectRealExitResult = 99.0
10004        });
10005    
10006        runScript({
10007            .code = R"NKSP_CODE(
10008    on init
10009      exit( ceil(99.1) )
10010    end on
10011    )NKSP_CODE",
10012            .expectRealExitResult = 100.0
10013        });
10014    
10015        runScript({
10016            .code = R"NKSP_CODE(
10017    on init
10018      exit( ceil(99.9) )
10019    end on
10020    )NKSP_CODE",
10021            .expectRealExitResult = 100.0
10022        });
10023    
10024        // std unit tests ...
10025    
10026        runScript({
10027            .code = R"NKSP_CODE(
10028    on init
10029      exit( ceil(2.4ms) )
10030    end on
10031    )NKSP_CODE",
10032            .expectRealExitResult = 3.0,
10033            .expectExitResultUnitPrefix = { VM_MILLI },
10034            .expectExitResultUnit = VM_SECOND
10035        });
10036    
10037        runScript({
10038            .code = R"NKSP_CODE(
10039    on init
10040      exit( ceil(2.6kHz) )
10041    end on
10042    )NKSP_CODE",
10043            .expectRealExitResult = 3.0,
10044            .expectExitResultUnitPrefix = { VM_KILO },
10045            .expectExitResultUnit = VM_HERTZ
10046        });
10047    
10048        runScript({
10049            .code = R"NKSP_CODE(
10050    on init
10051      exit( ceil(9.4ms / 2.0) )
10052    end on
10053    )NKSP_CODE",
10054            .expectRealExitResult = 5.0,
10055            .expectExitResultUnitPrefix = { VM_MILLI },
10056            .expectExitResultUnit = VM_SECOND
10057        });
10058    
10059        runScript({
10060            .code = R"NKSP_CODE(
10061    on init
10062      exit( ceil( ceil(8.4us) / 2.0) )
10063    end on
10064    )NKSP_CODE",
10065            .expectRealExitResult = 5.0,
10066            .expectExitResultUnitPrefix = { VM_MICRO },
10067            .expectExitResultUnit = VM_SECOND
10068        });
10069    
10070        // 'final' ('!') operator tests ...
10071    
10072        runScript({
10073            .code = R"NKSP_CODE(
10074    on init
10075      exit( ceil(123.1) )
10076    end on
10077    )NKSP_CODE",
10078            .expectRealExitResult = 124.0,
10079            .expectExitResultFinal = false
10080        });
10081    
10082        runScript({
10083            .code = R"NKSP_CODE(
10084    on init
10085      exit( ceil(!123.8) )
10086    end on
10087    )NKSP_CODE",
10088            .expectRealExitResult = 124.0,
10089            .expectExitResultFinal = true
10090        });
10091    
10092        #if !SILENT_TEST
10093        std::cout << std::endl;
10094        #endif
10095    }
10096    
10097    static void testBuiltInFloorFunction() {
10098        #if !SILENT_TEST
10099        std::cout << "UNIT TEST: built-in floor() function\n";
10100        #endif
10101    
10102        // integer tests ...
10103        // (ATM not allowed for this function)
10104    
10105        runScript({
10106            .code = R"NKSP_CODE(
10107    on init
10108      declare $foo := 1
10109      exit( floor($foo) )
10110    end on
10111    )NKSP_CODE",
10112            .expectParseError = true // integer not allowed for this function ATM
10113        });
10114    
10115        // real number tests ...
10116    
10117        runScript({
10118            .code = R"NKSP_CODE(
10119    on init
10120      exit( floor(99.0) )
10121    end on
10122    )NKSP_CODE",
10123            .expectRealExitResult = 99.0
10124        });
10125    
10126        runScript({
10127            .code = R"NKSP_CODE(
10128    on init
10129      exit( floor(99.1) )
10130    end on
10131    )NKSP_CODE",
10132            .expectRealExitResult = 99.0
10133        });
10134    
10135        runScript({
10136            .code = R"NKSP_CODE(
10137    on init
10138      exit( floor(99.9) )
10139    end on
10140    )NKSP_CODE",
10141            .expectRealExitResult = 99.0
10142        });
10143    
10144        // std unit tests ...
10145    
10146        runScript({
10147            .code = R"NKSP_CODE(
10148    on init
10149      exit( floor(2.4ms) )
10150    end on
10151    )NKSP_CODE",
10152            .expectRealExitResult = 2.0,
10153            .expectExitResultUnitPrefix = { VM_MILLI },
10154            .expectExitResultUnit = VM_SECOND
10155        });
10156    
10157        runScript({
10158            .code = R"NKSP_CODE(
10159    on init
10160      exit( floor(2.6kHz) )
10161    end on
10162    )NKSP_CODE",
10163            .expectRealExitResult = 2.0,
10164            .expectExitResultUnitPrefix = { VM_KILO },
10165            .expectExitResultUnit = VM_HERTZ
10166        });
10167    
10168        runScript({
10169            .code = R"NKSP_CODE(
10170    on init
10171      exit( floor(4.4ms / 2.0) )
10172    end on
10173    )NKSP_CODE",
10174            .expectRealExitResult = 2.0,
10175            .expectExitResultUnitPrefix = { VM_MILLI },
10176            .expectExitResultUnit = VM_SECOND
10177        });
10178    
10179        runScript({
10180            .code = R"NKSP_CODE(
10181    on init
10182      exit( floor( floor(8.4us) / 4.0) )
10183    end on
10184    )NKSP_CODE",
10185            .expectRealExitResult = 2.0,
10186            .expectExitResultUnitPrefix = { VM_MICRO },
10187            .expectExitResultUnit = VM_SECOND
10188        });
10189    
10190        // 'final' ('!') operator tests ...
10191    
10192        runScript({
10193            .code = R"NKSP_CODE(
10194    on init
10195      exit( floor(123.1) )
10196    end on
10197    )NKSP_CODE",
10198            .expectRealExitResult = 123.0,
10199            .expectExitResultFinal = false
10200        });
10201    
10202        runScript({
10203            .code = R"NKSP_CODE(
10204    on init
10205      exit( floor(!123.8) )
10206    end on
10207    )NKSP_CODE",
10208            .expectRealExitResult = 123.0,
10209            .expectExitResultFinal = true
10210        });
10211    
10212        #if !SILENT_TEST
10213        std::cout << std::endl;
10214        #endif
10215    }
10216    
10217    static void testBuiltInSqrtFunction() {
10218        #if !SILENT_TEST
10219        std::cout << "UNIT TEST: built-in sqrt() function\n";
10220        #endif
10221    
10222        // integer tests ...
10223        // (ATM not allowed for this function)
10224    
10225        runScript({
10226            .code = R"NKSP_CODE(
10227    on init
10228      declare $foo := 1
10229      exit( sqrt($foo) )
10230    end on
10231    )NKSP_CODE",
10232            .expectParseError = true // integer not allowed for this function ATM
10233        });
10234    
10235        // real number tests ...
10236    
10237        runScript({
10238            .code = R"NKSP_CODE(
10239    on init
10240      exit( sqrt(36.0) )
10241    end on
10242    )NKSP_CODE",
10243            .expectRealExitResult = 6.0
10244        });
10245    
10246        // std unit tests ...
10247    
10248        runScript({
10249            .code = R"NKSP_CODE(
10250    on init
10251      exit( sqrt(100.0ms) )
10252    end on
10253    )NKSP_CODE",
10254            .expectRealExitResult = 10.0,
10255            .expectExitResultUnitPrefix = { VM_MILLI },
10256            .expectExitResultUnit = VM_SECOND
10257        });
10258    
10259        runScript({
10260            .code = R"NKSP_CODE(
10261    on init
10262      exit( sqrt(5.76kHz) )
10263    end on
10264    )NKSP_CODE",
10265            .expectRealExitResult = 2.4,
10266            .expectExitResultUnitPrefix = { VM_KILO },
10267            .expectExitResultUnit = VM_HERTZ
10268        });
10269    
10270        // 'final' ('!') operator tests ...
10271    
10272        runScript({
10273            .code = R"NKSP_CODE(
10274    on init
10275      exit( sqrt(25.0) )
10276    end on
10277    )NKSP_CODE",
10278            .expectRealExitResult = 5.0,
10279            .expectExitResultFinal = false
10280        });
10281    
10282        runScript({
10283            .code = R"NKSP_CODE(
10284    on init
10285      exit( sqrt(!25.0) )
10286    end on
10287    )NKSP_CODE",
10288            .expectRealExitResult = 5.0,
10289            .expectExitResultFinal = true
10290        });
10291    
10292        #if !SILENT_TEST
10293        std::cout << std::endl;
10294        #endif
10295    }
10296    
10297    static void testBuiltInLogFunction() {
10298        #if !SILENT_TEST
10299        std::cout << "UNIT TEST: built-in log() function\n";
10300        #endif
10301    
10302        // integer tests ...
10303        // (ATM not allowed for this function)
10304    
10305        runScript({
10306            .code = R"NKSP_CODE(
10307    on init
10308      declare $foo := 1
10309      exit( log($foo) )
10310    end on
10311    )NKSP_CODE",
10312            .expectParseError = true // integer not allowed for this function ATM
10313        });
10314    
10315        // real number tests ...
10316    
10317        runScript({
10318            .code = R"NKSP_CODE(
10319    on init
10320      exit( log(1.0) )
10321    end on
10322    )NKSP_CODE",
10323            .expectRealExitResult = 0.0
10324        });
10325    
10326        runScript({
10327            .code = R"NKSP_CODE(
10328    on init
10329      exit( log(~NI_MATH_E) )
10330    end on
10331    )NKSP_CODE",
10332            .expectRealExitResult = 1.0
10333        });
10334    
10335        // std unit tests ...
10336    
10337        runScript({
10338            .code = R"NKSP_CODE(
10339    on init
10340      exit( log(~NI_MATH_E * 1.0ms) )
10341    end on
10342    )NKSP_CODE",
10343            .expectRealExitResult = 1.0,
10344            .expectExitResultUnitPrefix = { VM_MILLI },
10345            .expectExitResultUnit = VM_SECOND
10346        });
10347    
10348        runScript({
10349            .code = R"NKSP_CODE(
10350    on init
10351      exit( log(~NI_MATH_E * 1.0kHz) )
10352    end on
10353    )NKSP_CODE",
10354            .expectRealExitResult = 1.0,
10355            .expectExitResultUnitPrefix = { VM_KILO },
10356            .expectExitResultUnit = VM_HERTZ
10357        });
10358    
10359        // 'final' ('!') operator tests ...
10360    
10361        runScript({
10362            .code = R"NKSP_CODE(
10363    on init
10364      exit( log(~NI_MATH_E * 1.0) )
10365    end on
10366    )NKSP_CODE",
10367            .expectRealExitResult = 1.0,
10368            .expectExitResultFinal = false
10369        });
10370    
10371        runScript({
10372            .code = R"NKSP_CODE(
10373    on init
10374      exit( log(!(~NI_MATH_E * 1.0)) )
10375    end on
10376    )NKSP_CODE",
10377            .expectRealExitResult = 1.0,
10378            .expectExitResultFinal = true
10379        });
10380    
10381        #if !SILENT_TEST
10382        std::cout << std::endl;
10383        #endif
10384    }
10385    
10386    static void testBuiltInLog2Function() {
10387        #if !SILENT_TEST
10388        std::cout << "UNIT TEST: built-in log2() function\n";
10389        #endif
10390    
10391        // integer tests ...
10392        // (ATM not allowed for this function)
10393    
10394        runScript({
10395            .code = R"NKSP_CODE(
10396    on init
10397      declare $foo := 1
10398      exit( log2($foo) )
10399    end on
10400    )NKSP_CODE",
10401            .expectParseError = true // integer not allowed for this function ATM
10402        });
10403    
10404        // real number tests ...
10405    
10406        runScript({
10407            .code = R"NKSP_CODE(
10408    on init
10409      exit( log2(1.0) )
10410    end on
10411    )NKSP_CODE",
10412            .expectRealExitResult = 0.0
10413        });
10414    
10415        runScript({
10416            .code = R"NKSP_CODE(
10417    on init
10418      exit( log2(32.0) )
10419    end on
10420    )NKSP_CODE",
10421            .expectRealExitResult = 5.0
10422        });
10423    
10424        // std unit tests ...
10425    
10426        runScript({
10427            .code = R"NKSP_CODE(
10428    on init
10429      exit( log2(32.0ms) )
10430    end on
10431    )NKSP_CODE",
10432            .expectRealExitResult = 5.0,
10433            .expectExitResultUnitPrefix = { VM_MILLI },
10434            .expectExitResultUnit = VM_SECOND
10435        });
10436    
10437        runScript({
10438            .code = R"NKSP_CODE(
10439    on init
10440      exit( log2(32.0kHz) )
10441    end on
10442    )NKSP_CODE",
10443            .expectRealExitResult = 5.0,
10444            .expectExitResultUnitPrefix = { VM_KILO },
10445            .expectExitResultUnit = VM_HERTZ
10446        });
10447    
10448        // 'final' ('!') operator tests ...
10449    
10450        runScript({
10451            .code = R"NKSP_CODE(
10452    on init
10453      exit( log2(32.0) )
10454    end on
10455    )NKSP_CODE",
10456            .expectRealExitResult = 5.0,
10457            .expectExitResultFinal = false
10458        });
10459    
10460        runScript({
10461            .code = R"NKSP_CODE(
10462    on init
10463      exit( log2(!32.0) )
10464    end on
10465    )NKSP_CODE",
10466            .expectRealExitResult = 5.0,
10467            .expectExitResultFinal = true
10468        });
10469    
10470        #if !SILENT_TEST
10471        std::cout << std::endl;
10472        #endif
10473    }
10474    
10475    static void testBuiltInLog10Function() {
10476        #if !SILENT_TEST
10477        std::cout << "UNIT TEST: built-in log10() function\n";
10478        #endif
10479    
10480        // integer tests ...
10481        // (ATM not allowed for this function)
10482    
10483        runScript({
10484            .code = R"NKSP_CODE(
10485    on init
10486      declare $foo := 1
10487      exit( log10($foo) )
10488    end on
10489    )NKSP_CODE",
10490            .expectParseError = true // integer not allowed for this function ATM
10491        });
10492    
10493        // real number tests ...
10494    
10495        runScript({
10496            .code = R"NKSP_CODE(
10497    on init
10498      exit( log10(1000.0) )
10499    end on
10500    )NKSP_CODE",
10501            .expectRealExitResult = 3.0
10502        });
10503    
10504        runScript({
10505            .code = R"NKSP_CODE(
10506    on init
10507      exit( log10(1000.0) )
10508    end on
10509    )NKSP_CODE",
10510            .expectRealExitResult = 3.0
10511        });
10512    
10513        // std unit tests ...
10514    
10515        runScript({
10516            .code = R"NKSP_CODE(
10517    on init
10518      exit( log10(1000.0ms) )
10519    end on
10520    )NKSP_CODE",
10521            .expectRealExitResult = 3.0,
10522            .expectExitResultUnitPrefix = { VM_MILLI },
10523            .expectExitResultUnit = VM_SECOND
10524        });
10525    
10526        runScript({
10527            .code = R"NKSP_CODE(
10528    on init
10529      exit( log10(1000.0kHz) )
10530    end on
10531    )NKSP_CODE",
10532            .expectRealExitResult = 3.0,
10533            .expectExitResultUnitPrefix = { VM_KILO },
10534            .expectExitResultUnit = VM_HERTZ
10535        });
10536    
10537        // 'final' ('!') operator tests ...
10538    
10539        runScript({
10540            .code = R"NKSP_CODE(
10541    on init
10542      exit( log10(1000.0) )
10543    end on
10544    )NKSP_CODE",
10545            .expectRealExitResult = 3.0,
10546            .expectExitResultFinal = false
10547        });
10548    
10549        runScript({
10550            .code = R"NKSP_CODE(
10551    on init
10552      exit( log10(!1000.0) )
10553    end on
10554    )NKSP_CODE",
10555            .expectRealExitResult = 3.0,
10556            .expectExitResultFinal = true
10557        });
10558    
10559        #if !SILENT_TEST
10560        std::cout << std::endl;
10561        #endif
10562    }
10563    
10564    static void testBuiltInExpFunction() {
10565        #if !SILENT_TEST
10566        std::cout << "UNIT TEST: built-in exp() function\n";
10567        #endif
10568    
10569        // integer tests ...
10570        // (ATM not allowed for this function)
10571    
10572        runScript({
10573            .code = R"NKSP_CODE(
10574    on init
10575      declare $foo := 1
10576      exit( exp($foo) )
10577    end on
10578    )NKSP_CODE",
10579            .expectParseError = true // integer not allowed for this function ATM
10580        });
10581    
10582        // real number tests ...
10583    
10584        runScript({
10585            .code = R"NKSP_CODE(
10586    on init
10587      exit( exp(0.0) )
10588    end on
10589    )NKSP_CODE",
10590            .expectRealExitResult = 1.0
10591        });
10592    
10593        runScript({
10594            .code = R"NKSP_CODE(
10595    on init
10596      exit( exp(1.0) )
10597    end on
10598    )NKSP_CODE",
10599            .expectRealExitResult = M_E
10600        });
10601    
10602        // std unit tests ...
10603    
10604        runScript({
10605            .code = R"NKSP_CODE(
10606    on init
10607      exit( exp(0.0ms) )
10608    end on
10609    )NKSP_CODE",
10610            .expectRealExitResult = 1.0,
10611            .expectExitResultUnitPrefix = { VM_MILLI },
10612            .expectExitResultUnit = VM_SECOND
10613        });
10614    
10615        runScript({
10616            .code = R"NKSP_CODE(
10617    on init
10618      exit( exp(0.0kHz) )
10619    end on
10620    )NKSP_CODE",
10621            .expectRealExitResult = 1.0,
10622            .expectExitResultUnitPrefix = { VM_KILO },
10623            .expectExitResultUnit = VM_HERTZ
10624        });
10625    
10626        // 'final' ('!') operator tests ...
10627    
10628        runScript({
10629            .code = R"NKSP_CODE(
10630    on init
10631      exit( exp(0.0) )
10632    end on
10633    )NKSP_CODE",
10634            .expectRealExitResult = 1.0,
10635            .expectExitResultFinal = false
10636        });
10637    
10638        runScript({
10639            .code = R"NKSP_CODE(
10640    on init
10641      exit( exp(!0.0) )
10642    end on
10643    )NKSP_CODE",
10644            .expectRealExitResult = 1.0,
10645            .expectExitResultFinal = true
10646        });
10647    
10648        #if !SILENT_TEST
10649        std::cout << std::endl;
10650        #endif
10651    }
10652    
10653    static void testBuiltInPowFunction() {
10654        #if !SILENT_TEST
10655        std::cout << "UNIT TEST: built-in pow() function\n";
10656        #endif
10657    
10658        // integer tests ...
10659        // (ATM not allowed for this function)
10660    
10661        runScript({
10662            .code = R"NKSP_CODE(
10663    on init
10664      declare $foo := 1
10665      exit( pow($foo,$foo) )
10666    end on
10667    )NKSP_CODE",
10668            .expectParseError = true // integer not allowed for this function ATM
10669        });
10670    
10671        // real number tests ...
10672    
10673        runScript({
10674            .code = R"NKSP_CODE(
10675    on init
10676      exit( pow(1.0) )
10677    end on
10678    )NKSP_CODE",
10679            .expectParseError = true // because pow() requires exactly 2 arguments
10680        });
10681    
10682        runScript({
10683            .code = R"NKSP_CODE(
10684    on init
10685      exit( pow(3.0,4.0) )
10686    end on
10687    )NKSP_CODE",
10688            .expectRealExitResult = 81.0
10689        });
10690    
10691        // std unit tests ...
10692    
10693        runScript({
10694            .code = R"NKSP_CODE(
10695    on init
10696      exit( pow(3.0ms,4.0ms) )
10697    end on
10698    )NKSP_CODE",
10699            .expectParseError = true // because units are prohibited for 2nd argument
10700        });
10701    
10702        runScript({
10703            .code = R"NKSP_CODE(
10704    on init
10705      exit( pow(3.0,4.0ms) )
10706    end on
10707    )NKSP_CODE",
10708            .expectParseError = true // because units are prohibited for 2nd argument
10709        });
10710    
10711        runScript({
10712            .code = R"NKSP_CODE(
10713    on init
10714      exit( pow(3.0ms,4.0) )
10715    end on
10716    )NKSP_CODE",
10717            .expectRealExitResult = 81.0,
10718            .expectExitResultUnitPrefix = { VM_MILLI },
10719            .expectExitResultUnit = VM_SECOND
10720        });
10721    
10722        runScript({
10723            .code = R"NKSP_CODE(
10724    on init
10725      exit( pow(3.0kHz,4.0) )
10726    end on
10727    )NKSP_CODE",
10728            .expectRealExitResult = 81.0,
10729            .expectExitResultUnitPrefix = { VM_KILO },
10730            .expectExitResultUnit = VM_HERTZ
10731        });
10732    
10733        // 'final' ('!') operator tests ...
10734    
10735        runScript({
10736            .code = R"NKSP_CODE(
10737    on init
10738      exit( pow(3.0,4.0) )
10739    end on
10740    )NKSP_CODE",
10741            .expectRealExitResult = 81.0,
10742            .expectExitResultFinal = false
10743        });
10744    
10745        runScript({
10746            .code = R"NKSP_CODE(
10747    on init
10748      exit( pow(!3.0,4.0) )
10749    end on
10750    )NKSP_CODE",
10751            .expectRealExitResult = 81.0,
10752            .expectExitResultFinal = true
10753        });
10754    
10755        runScript({
10756            .code = R"NKSP_CODE(
10757    on init
10758      exit( pow(3.0,!4.0) )
10759    end on
10760    )NKSP_CODE",
10761            .expectParseError = true // because 'final' is meaningless for 2nd argument
10762        });
10763    
10764        #if !SILENT_TEST
10765        std::cout << std::endl;
10766        #endif
10767    }
10768    
10769    static void testBuiltInSinFunction() {
10770        #if !SILENT_TEST
10771        std::cout << "UNIT TEST: built-in sin() function\n";
10772        #endif
10773    
10774        // integer tests ...
10775        // (ATM not allowed for this function)
10776    
10777        runScript({
10778            .code = R"NKSP_CODE(
10779    on init
10780      declare $foo := 1
10781      exit( sin($foo) )
10782    end on
10783    )NKSP_CODE",
10784            .expectParseError = true // integer not allowed for this function ATM
10785        });
10786    
10787        // real number tests ...
10788    
10789        runScript({
10790            .code = R"NKSP_CODE(
10791    on init
10792      exit( sin(0.0) )
10793    end on
10794    )NKSP_CODE",
10795            .expectRealExitResult = 0.0
10796        });
10797    
10798        runScript({
10799            .code = R"NKSP_CODE(
10800    on init
10801      exit( sin(0.5 * ~NI_MATH_PI) )
10802    end on
10803    )NKSP_CODE",
10804            .expectRealExitResult = 1.0
10805        });
10806    
10807        runScript({
10808            .code = R"NKSP_CODE(
10809    on init
10810      exit( sin(~NI_MATH_PI) )
10811    end on
10812    )NKSP_CODE",
10813            .expectRealExitResult = 0.0
10814        });
10815    
10816        runScript({
10817            .code = R"NKSP_CODE(
10818    on init
10819      exit( sin(1.5 * ~NI_MATH_PI) )
10820    end on
10821    )NKSP_CODE",
10822            .expectRealExitResult = -1.0
10823        });
10824    
10825        // std unit tests ...
10826    
10827        runScript({
10828            .code = R"NKSP_CODE(
10829    on init
10830      exit( sin(0.0ms) )
10831    end on
10832    )NKSP_CODE",
10833            .expectRealExitResult = 0.0,
10834            .expectExitResultUnitPrefix = { VM_MILLI },
10835            .expectExitResultUnit = VM_SECOND
10836        });
10837    
10838        runScript({
10839            .code = R"NKSP_CODE(
10840    on init
10841      exit( sin(0.0kHz) )
10842    end on
10843    )NKSP_CODE",
10844            .expectRealExitResult = 0.0,
10845            .expectExitResultUnitPrefix = { VM_KILO },
10846            .expectExitResultUnit = VM_HERTZ
10847        });
10848    
10849        // 'final' ('!') operator tests ...
10850    
10851        runScript({
10852            .code = R"NKSP_CODE(
10853    on init
10854      exit( sin(0.0) )
10855    end on
10856    )NKSP_CODE",
10857            .expectRealExitResult = 0.0,
10858            .expectExitResultFinal = false
10859        });
10860    
10861        runScript({
10862            .code = R"NKSP_CODE(
10863    on init
10864      exit( sin(!0.0) )
10865    end on
10866    )NKSP_CODE",
10867            .expectRealExitResult = 0.0,
10868            .expectExitResultFinal = true
10869        });
10870    
10871        #if !SILENT_TEST
10872        std::cout << std::endl;
10873        #endif
10874    }
10875    
10876    static void testBuiltInCosFunction() {
10877        #if !SILENT_TEST
10878        std::cout << "UNIT TEST: built-in cos() function\n";
10879        #endif
10880    
10881        // integer tests ...
10882        // (ATM not allowed for this function)
10883    
10884        runScript({
10885            .code = R"NKSP_CODE(
10886    on init
10887      declare $foo := 1
10888      exit( cos($foo) )
10889    end on
10890    )NKSP_CODE",
10891            .expectParseError = true // integer not allowed for this function ATM
10892        });
10893    
10894        // real number tests ...
10895    
10896        runScript({
10897            .code = R"NKSP_CODE(
10898    on init
10899      exit( cos(0.0) )
10900    end on
10901    )NKSP_CODE",
10902            .expectRealExitResult = 1.0
10903        });
10904    
10905        runScript({
10906            .code = R"NKSP_CODE(
10907    on init
10908      exit( cos(0.5 * ~NI_MATH_PI) )
10909    end on
10910    )NKSP_CODE",
10911            .expectRealExitResult = 0.0
10912        });
10913    
10914        runScript({
10915            .code = R"NKSP_CODE(
10916    on init
10917      exit( cos(~NI_MATH_PI) )
10918    end on
10919    )NKSP_CODE",
10920            .expectRealExitResult = -1.0
10921        });
10922    
10923        runScript({
10924            .code = R"NKSP_CODE(
10925    on init
10926      exit( cos(1.5 * ~NI_MATH_PI) )
10927    end on
10928    )NKSP_CODE",
10929            .expectRealExitResult = 0.0
10930        });
10931    
10932        // std unit tests ...
10933    
10934        runScript({
10935            .code = R"NKSP_CODE(
10936    on init
10937      exit( cos(0.0ms) )
10938    end on
10939    )NKSP_CODE",
10940            .expectRealExitResult = 1.0,
10941            .expectExitResultUnitPrefix = { VM_MILLI },
10942            .expectExitResultUnit = VM_SECOND
10943        });
10944    
10945        runScript({
10946            .code = R"NKSP_CODE(
10947    on init
10948      exit( cos(0.0kHz) )
10949    end on
10950    )NKSP_CODE",
10951            .expectRealExitResult = 1.0,
10952            .expectExitResultUnitPrefix = { VM_KILO },
10953            .expectExitResultUnit = VM_HERTZ
10954        });
10955    
10956        // 'final' ('!') operator tests ...
10957    
10958        runScript({
10959            .code = R"NKSP_CODE(
10960    on init
10961      exit( cos(0.0) )
10962    end on
10963    )NKSP_CODE",
10964            .expectRealExitResult = 1.0,
10965            .expectExitResultFinal = false
10966        });
10967    
10968        runScript({
10969            .code = R"NKSP_CODE(
10970    on init
10971      exit( cos(!0.0) )
10972    end on
10973    )NKSP_CODE",
10974            .expectRealExitResult = 1.0,
10975            .expectExitResultFinal = true
10976        });
10977    
10978        #if !SILENT_TEST
10979        std::cout << std::endl;
10980        #endif
10981    }
10982    
10983    static void testBuiltInTanFunction() {
10984        #if !SILENT_TEST
10985        std::cout << "UNIT TEST: built-in tan() function\n";
10986        #endif
10987    
10988        // integer tests ...
10989        // (ATM not allowed for this function)
10990    
10991        runScript({
10992            .code = R"NKSP_CODE(
10993    on init
10994      declare $foo := 1
10995      exit( tan($foo) )
10996    end on
10997    )NKSP_CODE",
10998            .expectParseError = true // integer not allowed for this function ATM
10999        });
11000    
11001        // real number tests ...
11002    
11003        runScript({
11004            .code = R"NKSP_CODE(
11005    on init
11006      exit( tan(0.0) )
11007    end on
11008    )NKSP_CODE",
11009            .expectRealExitResult = 0.0
11010        });
11011    
11012        runScript({
11013            .code = R"NKSP_CODE(
11014    on init
11015      exit( tan(0.25 * ~NI_MATH_PI) )
11016    end on
11017    )NKSP_CODE",
11018            .expectRealExitResult = 1.0
11019        });
11020    
11021        // std unit tests ...
11022    
11023        runScript({
11024            .code = R"NKSP_CODE(
11025    on init
11026      exit( tan(0.0ms) )
11027    end on
11028    )NKSP_CODE",
11029            .expectRealExitResult = 0.0,
11030            .expectExitResultUnitPrefix = { VM_MILLI },
11031            .expectExitResultUnit = VM_SECOND
11032        });
11033    
11034        runScript({
11035            .code = R"NKSP_CODE(
11036    on init
11037      exit( tan(0.0kHz) )
11038    end on
11039    )NKSP_CODE",
11040            .expectRealExitResult = 0.0,
11041            .expectExitResultUnitPrefix = { VM_KILO },
11042            .expectExitResultUnit = VM_HERTZ
11043        });
11044    
11045        // 'final' ('!') operator tests ...
11046    
11047        runScript({
11048            .code = R"NKSP_CODE(
11049    on init
11050      exit( tan(0.0) )
11051    end on
11052    )NKSP_CODE",
11053            .expectRealExitResult = 0.0,
11054            .expectExitResultFinal = false
11055        });
11056    
11057        runScript({
11058            .code = R"NKSP_CODE(
11059    on init
11060      exit( tan(!0.0) )
11061    end on
11062    )NKSP_CODE",
11063            .expectRealExitResult = 0.0,
11064            .expectExitResultFinal = true
11065        });
11066    
11067        #if !SILENT_TEST
11068        std::cout << std::endl;
11069        #endif
11070    }
11071    
11072    static void testBuiltInAsinFunction() {
11073        #if !SILENT_TEST
11074        std::cout << "UNIT TEST: built-in asin() function\n";
11075        #endif
11076    
11077        // integer tests ...
11078        // (ATM not allowed for this function)
11079    
11080        runScript({
11081            .code = R"NKSP_CODE(
11082    on init
11083      declare $foo := 1
11084      exit( asin($foo) )
11085    end on
11086    )NKSP_CODE",
11087            .expectParseError = true // integer not allowed for this function ATM
11088        });
11089    
11090        // real number tests ...
11091    
11092        runScript({
11093            .code = R"NKSP_CODE(
11094    on init
11095      exit( asin(0.0) )
11096    end on
11097    )NKSP_CODE",
11098            .expectRealExitResult = 0.0
11099        });
11100    
11101        runScript({
11102            .code = R"NKSP_CODE(
11103    on init
11104      exit( asin(1.0) )
11105    end on
11106    )NKSP_CODE",
11107            .expectRealExitResult = 0.5 * M_PI
11108        });
11109    
11110        runScript({
11111            .code = R"NKSP_CODE(
11112    on init
11113      exit( asin(-1.0) )
11114    end on
11115    )NKSP_CODE",
11116            .expectRealExitResult = -0.5 * M_PI
11117        });
11118    
11119        // std unit tests ...
11120    
11121        runScript({
11122            .code = R"NKSP_CODE(
11123    on init
11124      exit( asin(0.0ms) )
11125    end on
11126    )NKSP_CODE",
11127            .expectRealExitResult = 0.0,
11128            .expectExitResultUnitPrefix = { VM_MILLI },
11129            .expectExitResultUnit = VM_SECOND
11130        });
11131    
11132        runScript({
11133            .code = R"NKSP_CODE(
11134    on init
11135      exit( asin(0.0kHz) )
11136    end on
11137    )NKSP_CODE",
11138            .expectRealExitResult = 0.0,
11139            .expectExitResultUnitPrefix = { VM_KILO },
11140            .expectExitResultUnit = VM_HERTZ
11141        });
11142    
11143        // 'final' ('!') operator tests ...
11144    
11145        runScript({
11146            .code = R"NKSP_CODE(
11147    on init
11148      exit( asin(0.0) )
11149    end on
11150    )NKSP_CODE",
11151            .expectRealExitResult = 0.0,
11152            .expectExitResultFinal = false
11153        });
11154    
11155        runScript({
11156            .code = R"NKSP_CODE(
11157    on init
11158      exit( asin(!0.0) )
11159    end on
11160    )NKSP_CODE",
11161            .expectRealExitResult = 0.0,
11162            .expectExitResultFinal = true
11163        });
11164    
11165        #if !SILENT_TEST
11166        std::cout << std::endl;
11167        #endif
11168    }
11169    
11170    static void testBuiltInAcosFunction() {
11171        #if !SILENT_TEST
11172        std::cout << "UNIT TEST: built-in acos() function\n";
11173        #endif
11174    
11175        // integer tests ...
11176        // (ATM not allowed for this function)
11177    
11178        runScript({
11179            .code = R"NKSP_CODE(
11180    on init
11181      declare $foo := 1
11182      exit( acos($foo) )
11183    end on
11184    )NKSP_CODE",
11185            .expectParseError = true // integer not allowed for this function ATM
11186        });
11187    
11188        // real number tests ...
11189    
11190        runScript({
11191            .code = R"NKSP_CODE(
11192    on init
11193      exit( acos(1.0) )
11194    end on
11195    )NKSP_CODE",
11196            .expectRealExitResult = 0.0
11197        });
11198    
11199        runScript({
11200            .code = R"NKSP_CODE(
11201    on init
11202      exit( acos(0.0) )
11203    end on
11204    )NKSP_CODE",
11205            .expectRealExitResult = 0.5 * M_PI
11206        });
11207    
11208        runScript({
11209            .code = R"NKSP_CODE(
11210    on init
11211      exit( acos(-1.0) )
11212    end on
11213    )NKSP_CODE",
11214            .expectRealExitResult = M_PI
11215        });
11216    
11217        // std unit tests ...
11218    
11219        runScript({
11220            .code = R"NKSP_CODE(
11221    on init
11222      exit( acos(1.0ms) )
11223    end on
11224    )NKSP_CODE",
11225            .expectRealExitResult = 0.0,
11226            .expectExitResultUnitPrefix = { VM_MILLI },
11227            .expectExitResultUnit = VM_SECOND
11228        });
11229    
11230        runScript({
11231            .code = R"NKSP_CODE(
11232    on init
11233      exit( acos(1.0kHz) )
11234    end on
11235    )NKSP_CODE",
11236            .expectRealExitResult = 0.0,
11237            .expectExitResultUnitPrefix = { VM_KILO },
11238            .expectExitResultUnit = VM_HERTZ
11239        });
11240    
11241        // 'final' ('!') operator tests ...
11242    
11243        runScript({
11244            .code = R"NKSP_CODE(
11245    on init
11246      exit( acos(1.0) )
11247    end on
11248    )NKSP_CODE",
11249            .expectRealExitResult = 0.0,
11250            .expectExitResultFinal = false
11251        });
11252    
11253        runScript({
11254            .code = R"NKSP_CODE(
11255    on init
11256      exit( acos(!1.0) )
11257    end on
11258    )NKSP_CODE",
11259            .expectRealExitResult = 0.0,
11260            .expectExitResultFinal = true
11261        });
11262    
11263        #if !SILENT_TEST
11264        std::cout << std::endl;
11265        #endif
11266    }
11267    
11268    static void testBuiltInAtanFunction() {
11269        #if !SILENT_TEST
11270        std::cout << "UNIT TEST: built-in atan() function\n";
11271        #endif
11272    
11273        // integer tests ...
11274        // (ATM not allowed for this function)
11275    
11276        runScript({
11277            .code = R"NKSP_CODE(
11278    on init
11279      declare $foo := 1
11280      exit( atan($foo) )
11281    end on
11282    )NKSP_CODE",
11283            .expectParseError = true // integer not allowed for this function ATM
11284        });
11285    
11286        // real number tests ...
11287    
11288        runScript({
11289            .code = R"NKSP_CODE(
11290    on init
11291      exit( atan(0.0) )
11292    end on
11293    )NKSP_CODE",
11294            .expectRealExitResult = 0.0
11295        });
11296    
11297        runScript({
11298            .code = R"NKSP_CODE(
11299    on init
11300      exit( atan(1.0) )
11301    end on
11302    )NKSP_CODE",
11303            .expectRealExitResult = 0.25 * M_PI
11304        });
11305    
11306        // std unit tests ...
11307    
11308        runScript({
11309            .code = R"NKSP_CODE(
11310    on init
11311      exit( atan(0.0ms) )
11312    end on
11313    )NKSP_CODE",
11314            .expectRealExitResult = 0.0,
11315            .expectExitResultUnitPrefix = { VM_MILLI },
11316            .expectExitResultUnit = VM_SECOND
11317        });
11318    
11319        runScript({
11320            .code = R"NKSP_CODE(
11321    on init
11322      exit( atan(0.0kHz) )
11323    end on
11324    )NKSP_CODE",
11325            .expectRealExitResult = 0.0,
11326            .expectExitResultUnitPrefix = { VM_KILO },
11327            .expectExitResultUnit = VM_HERTZ
11328        });
11329    
11330        // 'final' ('!') operator tests ...
11331    
11332        runScript({
11333            .code = R"NKSP_CODE(
11334    on init
11335      exit( atan(0.0) )
11336    end on
11337    )NKSP_CODE",
11338            .expectRealExitResult = 0.0,
11339            .expectExitResultFinal = false
11340        });
11341    
11342        runScript({
11343            .code = R"NKSP_CODE(
11344    on init
11345      exit( atan(!0.0) )
11346    end on
11347    )NKSP_CODE",
11348            .expectRealExitResult = 0.0,
11349            .expectExitResultFinal = true
11350        });
11351    
11352      #if !SILENT_TEST      #if !SILENT_TEST
11353      std::cout << std::endl;      std::cout << std::endl;
11354      #endif      #endif
# Line 1722  static void testBuiltInNumElementsFuncti Line 11359  static void testBuiltInNumElementsFuncti
11359      std::cout << "UNIT TEST: built-in num_elements() function\n";      std::cout << "UNIT TEST: built-in num_elements() function\n";
11360      #endif      #endif
11361    
11362        // integer array tests ...
11363    
11364      runScript({      runScript({
11365          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
11366  on init  on init
# Line 1752  end on Line 11391  end on
11391          .expectIntExitResult = 5          .expectIntExitResult = 5
11392      });      });
11393    
11394        // real array tests ...
11395    
11396        runScript({
11397            .code = R"NKSP_CODE(
11398    on init
11399      declare ?foo[3] := ( 19.0, 3.2, 6.5 )
11400      exit( num_elements(?foo) )
11401    end on
11402    )NKSP_CODE",
11403            .expectIntExitResult = 3
11404        });
11405    
11406        runScript({
11407            .code = R"NKSP_CODE(
11408    on init
11409      declare ?foo[1] := ( 19.0 )
11410      exit( num_elements(?foo) )
11411    end on
11412    )NKSP_CODE",
11413            .expectIntExitResult = 1
11414        });
11415    
11416        runScript({
11417            .code = R"NKSP_CODE(
11418    on init
11419      declare ?foo[5] := ( 1.1, 2.2, 3.3, 4.4, 5.5 )
11420      exit( num_elements(?foo) )
11421    end on
11422    )NKSP_CODE",
11423            .expectIntExitResult = 5
11424        });
11425    
11426      #if !SILENT_TEST      #if !SILENT_TEST
11427      std::cout << std::endl;      std::cout << std::endl;
11428      #endif      #endif
# Line 1762  static void testBuiltInSearchFunction() Line 11433  static void testBuiltInSearchFunction()
11433      std::cout << "UNIT TEST: built-in search() function\n";      std::cout << "UNIT TEST: built-in search() function\n";
11434      #endif      #endif
11435    
11436        // integer array tests ...
11437    
11438      runScript({      runScript({
11439          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
11440  on init  on init
# Line 1802  end on Line 11475  end on
11475          .expectIntExitResult = -1          .expectIntExitResult = -1
11476      });      });
11477    
11478        // real array tests ...
11479    
11480        runScript({
11481            .code = R"NKSP_CODE(
11482    on init
11483      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11484      exit( search(?foo, 19.12) )
11485    end on
11486    )NKSP_CODE",
11487            .expectIntExitResult = 0
11488        });
11489    
11490        runScript({
11491            .code = R"NKSP_CODE(
11492    on init
11493      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11494      exit( search(?foo, 3.45) )
11495    end on
11496    )NKSP_CODE",
11497            .expectIntExitResult = 1
11498        });
11499    
11500        runScript({
11501            .code = R"NKSP_CODE(
11502    on init
11503      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11504      exit( search(?foo, 6.89) )
11505    end on
11506    )NKSP_CODE",
11507            .expectIntExitResult = 2
11508        });
11509    
11510        runScript({
11511            .code = R"NKSP_CODE(
11512    on init
11513      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11514      exit( search(?foo, 6.99) )
11515    end on
11516    )NKSP_CODE",
11517            .expectIntExitResult = -1
11518        });
11519    
11520      #if !SILENT_TEST      #if !SILENT_TEST
11521      std::cout << std::endl;      std::cout << std::endl;
11522      #endif      #endif
# Line 1895  end on Line 11610  end on
11610      #endif      #endif
11611  }  }
11612    
11613    static void testBuiltInVars() {
11614        #if !SILENT_TEST
11615        std::cout << "UNIT TEST: built-in variables\n";
11616        #endif
11617    
11618        runScript({
11619            .code = R"NKSP_CODE(
11620    on init
11621      exit($NKSP_PERF_TIMER)
11622    end on
11623    )NKSP_CODE",
11624            .expectExitResultIsInt = true,
11625            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11626            .expectExitResultUnit = VM_NO_UNIT
11627        });
11628    
11629        runScript({
11630            .code = R"NKSP_CODE(
11631    on init
11632      exit($NKSP_REAL_TIMER)
11633    end on
11634    )NKSP_CODE",
11635            .expectExitResultIsInt = true,
11636            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11637            .expectExitResultUnit = VM_NO_UNIT
11638        });
11639    
11640        runScript({
11641            .code = R"NKSP_CODE(
11642    on init
11643      exit($KSP_TIMER)
11644    end on
11645    )NKSP_CODE",
11646            .expectExitResultIsInt = true,
11647            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11648            .expectExitResultUnit = VM_NO_UNIT
11649        });
11650    
11651        runScript({
11652            .code = R"NKSP_CODE(
11653    on init
11654      exit(~NI_MATH_PI)
11655    end on
11656    )NKSP_CODE",
11657            .expectExitResultIsReal = true,
11658            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11659            .expectExitResultUnit = VM_NO_UNIT
11660        });
11661    
11662        runScript({
11663            .code = R"NKSP_CODE(
11664    on init
11665      exit(~NI_MATH_E)
11666    end on
11667    )NKSP_CODE",
11668            .expectExitResultIsReal = true,
11669            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11670            .expectExitResultUnit = VM_NO_UNIT
11671        });
11672    
11673        runScript({
11674            .code = R"NKSP_CODE(
11675    on init
11676      exit($NI_CB_TYPE_INIT)
11677    end on
11678    )NKSP_CODE",
11679            .expectIntExitResult = VM_EVENT_HANDLER_INIT,
11680            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11681            .expectExitResultUnit = VM_NO_UNIT
11682        });
11683    
11684        runScript({
11685            .code = R"NKSP_CODE(
11686    on init
11687      exit($NI_CB_TYPE_NOTE)
11688    end on
11689    )NKSP_CODE",
11690            .expectIntExitResult = VM_EVENT_HANDLER_NOTE,
11691            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11692            .expectExitResultUnit = VM_NO_UNIT
11693        });
11694    
11695        runScript({
11696            .code = R"NKSP_CODE(
11697    on init
11698      exit($NI_CB_TYPE_RELEASE)
11699    end on
11700    )NKSP_CODE",
11701            .expectIntExitResult = VM_EVENT_HANDLER_RELEASE,
11702            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11703            .expectExitResultUnit = VM_NO_UNIT
11704        });
11705    
11706        runScript({
11707            .code = R"NKSP_CODE(
11708    on init
11709      exit($NI_CB_TYPE_CONTROLLER)
11710    end on
11711    )NKSP_CODE",
11712            .expectIntExitResult = VM_EVENT_HANDLER_CONTROLLER,
11713            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11714            .expectExitResultUnit = VM_NO_UNIT
11715        });
11716    
11717        runScript({
11718            .code = R"NKSP_CODE(
11719    on init
11720      exit($NI_CB_TYPE_RPN)
11721    end on
11722    )NKSP_CODE",
11723            .expectIntExitResult = VM_EVENT_HANDLER_RPN,
11724            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11725            .expectExitResultUnit = VM_NO_UNIT
11726        });
11727    
11728        runScript({
11729            .code = R"NKSP_CODE(
11730    on init
11731      exit($NI_CB_TYPE_NRPN)
11732    end on
11733    )NKSP_CODE",
11734            .expectIntExitResult = VM_EVENT_HANDLER_NRPN,
11735            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11736            .expectExitResultUnit = VM_NO_UNIT
11737        });
11738    
11739        #if !SILENT_TEST
11740        std::cout << std::endl;
11741        #endif
11742    }
11743    
11744  #if !NO_MAIN  #if !NO_MAIN
11745    
11746  int main() {  int main() {
11747      testBuiltInExitFunction();      testBuiltInExitFunction();
11748      testStringConcatOperator();      testStringConcatOperator();
11749        testNegOperator();
11750      testPlusOperator();      testPlusOperator();
11751      testMinusOperator();      testMinusOperator();
11752      testModuloOperator();      testModuloOperator();
# Line 1918  int main() { Line 11765  int main() {
11765      testBitwiseOrOperator();      testBitwiseOrOperator();
11766      testBitwiseNotOperator();      testBitwiseNotOperator();
11767      testPrecedenceOfOperators();      testPrecedenceOfOperators();
11768        testIntVarDeclaration();
11769        testIntArrayVarDeclaration();
11770        testRealVarDeclaration();
11771        testRealArrayVarDeclaration();
11772        testStringVarDeclaration();
11773      testBuiltInMinFunction();      testBuiltInMinFunction();
11774      testBuiltInMaxFunction();      testBuiltInMaxFunction();
11775      testBuiltInAbsFunction();      testBuiltInAbsFunction();
# Line 1927  int main() { Line 11779  int main() {
11779      testBuiltInRandomFunction();      testBuiltInRandomFunction();
11780      testBuiltInShiftLeftFunction();      testBuiltInShiftLeftFunction();
11781      testBuiltInShiftRightFunction();      testBuiltInShiftRightFunction();
11782        testBuiltInMsbFunction();
11783        testBuiltInLsbFunction();
11784        testBuiltInIntToRealFunction();
11785        testBuiltInRealFunction();
11786        testBuiltInRealToIntFunction();
11787        testBuiltInIntFunction();
11788        testBuiltInRoundFunction();
11789        testBuiltInCeilFunction();
11790        testBuiltInFloorFunction();
11791        testBuiltInSqrtFunction();
11792        testBuiltInLogFunction();
11793        testBuiltInLog2Function();
11794        testBuiltInLog10Function();
11795        testBuiltInExpFunction();
11796        testBuiltInPowFunction();
11797        testBuiltInSinFunction();
11798        testBuiltInCosFunction();
11799        testBuiltInTanFunction();
11800        testBuiltInAsinFunction();
11801        testBuiltInAcosFunction();
11802        testBuiltInAtanFunction();
11803      testBuiltInArrayEqualFunction();      testBuiltInArrayEqualFunction();
11804      testBuiltInSortFunction();      testBuiltInSortFunction();
11805      testBuiltInNumElementsFunction();      testBuiltInNumElementsFunction();
11806      testBuiltInSearchFunction();      testBuiltInSearchFunction();
11807      testIfStatement();      testIfStatement();
11808      testWhileStatement();      testWhileStatement();
11809        testBuiltInVars();
11810      std::cout << "\nAll tests passed successfully. :-)\n";      std::cout << "\nAll tests passed successfully. :-)\n";
11811      return 0;      return 0;
11812  }  }

Legend:
Removed from v.3551  
changed lines
  Added in v.3790

  ViewVC Help
Powered by ViewVC