/[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 3747 by schoenebeck, Sun Feb 16 11:31:46 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            .expectParseError = true // illegal 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 const $sz := 3
5808      declare %a[$sz] := ( 1, 2, 3 )
5809      exit( %a[0] + %a[1] + %a[2] )
5810    end on
5811    )NKSP_CODE",
5812            .expectIntExitResult = (1 + 2 + 3)
5813        });
5814    
5815        runScript({
5816            .code = R"NKSP_CODE(
5817    on init
5818      declare const $sz := 3
5819      declare const %a[$sz] := ( 1, 2, 3 )
5820      exit( %a[0] + %a[1] + %a[2] )
5821    end on
5822    )NKSP_CODE",
5823            .expectIntExitResult = (1 + 2 + 3)
5824        });
5825    
5826        runScript({
5827            .code = R"NKSP_CODE(
5828    on init
5829      declare $sz := 3
5830      declare %a[$sz] := ( 1, 2, 3 )
5831    end on
5832    )NKSP_CODE",
5833            .expectParseError = true // array size must be constant expression
5834        });
5835    
5836        runScript({
5837            .code = R"NKSP_CODE(
5838    on init
5839      declare $sz := 3
5840      declare const %a[$sz] := ( 1, 2, 3 )
5841    end on
5842    )NKSP_CODE",
5843            .expectParseError = true // array size must be constant expression
5844        });
5845    
5846        runScript({
5847            .code = R"NKSP_CODE(
5848    on init
5849      declare const ~sz := 3.0
5850      declare const %a[~sz] := ( 1, 2, 3 )
5851    end on
5852    )NKSP_CODE",
5853            .expectParseError = true // array size must be integer type
5854        });
5855    
5856        runScript({
5857            .code = R"NKSP_CODE(
5858    on init
5859      declare %a[3s] := ( 1, 2, 3 )
5860    end on
5861    )NKSP_CODE",
5862            .expectParseError = true // units not allowed for array size
5863        });
5864    
5865        runScript({
5866            .code = R"NKSP_CODE(
5867    on init
5868      declare %a[3m] := ( 1, 2, 3 )
5869    end on
5870    )NKSP_CODE",
5871            .expectParseError = true // units not allowed for array size
5872        });
5873    
5874        runScript({
5875            .code = R"NKSP_CODE(
5876    on init
5877      declare const %a[!3] := ( 1, 2, 3 )
5878      exit( %a[0] + %a[1] + %a[2] )
5879    end on
5880    )NKSP_CODE",
5881            .expectIntExitResult = (1 + 2 + 3),
5882            .expectParseWarning = true // 'final' operator is meaningless for array size
5883        });
5884    
5885        runScript({
5886            .code = R"NKSP_CODE(
5887    on init
5888      declare %a[3] := ( 1, 2, 3 )
5889      %a[0] := 4
5890      %a[1] := 5
5891      %a[2] := 6
5892      exit( %a[0] + %a[1] + %a[2] )
5893    end on
5894    )NKSP_CODE",
5895            .expectIntExitResult = (4 + 5 + 6)
5896        });
5897    
5898        runScript({
5899            .code = R"NKSP_CODE(
5900    on init
5901      declare %a[3]
5902      declare %a[3]
5903    end on
5904    )NKSP_CODE",
5905            .expectParseError = true // variable re-declaration
5906        });
5907    
5908        runScript({
5909            .code = R"NKSP_CODE(
5910    on init
5911      declare const %a[3]
5912    end on
5913    )NKSP_CODE",
5914            .expectParseError = true // const variable declaration without assignment
5915        });
5916    
5917        runScript({
5918            .code = R"NKSP_CODE(
5919    on init
5920      declare const %a[3] := ( 1, 2, 3 )
5921      exit( %a[0] + %a[1] + %a[2] )
5922    end on
5923    )NKSP_CODE",
5924            .expectIntExitResult = (1 + 2 + 3)
5925        });
5926    
5927        runScript({
5928            .code = R"NKSP_CODE(
5929    on init
5930      declare const %a[3] := ( 1, 2, 3, 4 )
5931    end on
5932    )NKSP_CODE",
5933            .expectParseError = true // incompatible array sizes
5934        });
5935    
5936        runScript({
5937            .code = R"NKSP_CODE(
5938    on init
5939      declare const %a[3] := ( 1, 2, 3 )
5940      %a[0] := 8
5941    end on
5942    )NKSP_CODE",
5943            .expectParseError = true // attempt to modify const variable
5944        });
5945    
5946        runScript({
5947            .code = R"NKSP_CODE(
5948    on init
5949      declare const %a[3] := ( 1, 2, 3 )
5950      declare const %b[3] := ( %a[0], %a[1], %a[2] )
5951      exit( %b[0] + %b[1] + %b[2] )
5952    end on
5953    )NKSP_CODE",
5954            .expectIntExitResult = (1 + 2 + 3)
5955        });
5956    
5957        runScript({
5958            .code = R"NKSP_CODE(
5959    on init
5960      declare %a[3] := ( 1, 2, 3 )
5961      declare const %b[3] := ( %a[0], %a[1], %a[2] )
5962    end on
5963    )NKSP_CODE",
5964            .expectParseError = true // const array defined with non-const assignment
5965        });
5966    
5967        runScript({
5968            .code = R"NKSP_CODE(
5969    on init
5970      declare polyphonic %a[3]
5971    end on
5972    )NKSP_CODE",
5973            .expectParseError = true // polyphonic not allowed for array types
5974        });
5975    
5976        runScript({
5977            .code = R"NKSP_CODE(
5978    on init
5979      declare polyphonic %a[3] := ( 1, 2, 3 )
5980    end on
5981    )NKSP_CODE",
5982            .expectParseError = true // polyphonic not allowed for array types
5983        });
5984    
5985        runScript({
5986            .code = R"NKSP_CODE(
5987    on init
5988      declare const polyphonic %a[3]
5989    end on
5990    )NKSP_CODE",
5991            .expectParseError = true // polyphonic not allowed for array types
5992        });
5993    
5994        runScript({
5995            .code = R"NKSP_CODE(
5996    on init
5997      declare const polyphonic %a[3] := ( 1, 2, 3 )
5998    end on
5999    )NKSP_CODE",
6000            .expectParseError = true // polyphonic not allowed for array types
6001        });
6002    
6003        runScript({
6004            .code = R"NKSP_CODE(
6005    on init
6006      declare polyphonic const %a[3]
6007    end on
6008    )NKSP_CODE",
6009            .expectParseError = true // polyphonic not allowed for array types
6010        });
6011    
6012        runScript({
6013            .code = R"NKSP_CODE(
6014    on init
6015      declare polyphonic const %a[3] := ( 1, 2, 3 )
6016    end on
6017    )NKSP_CODE",
6018            .expectParseError = true // polyphonic not allowed for array types
6019        });
6020    
6021        runScript({
6022            .code = R"NKSP_CODE(
6023    on init
6024      declare %a[3] := ( 1, max(8,24), 3 )
6025      exit( %a[0] + %a[1] + %a[2] )
6026    end on
6027    )NKSP_CODE",
6028            .expectIntExitResult = ( 1 + 24 + 3 )
6029        });
6030    
6031        runScript({
6032            .code = R"NKSP_CODE(
6033    on init
6034      declare %a[3] := ( 1, abort($NI_CALLBACK_ID), 3 )
6035    end on
6036    )NKSP_CODE",
6037            .expectParseError = true // assigned expression does not result in a value
6038        });
6039    
6040        runScript({
6041            .code = R"NKSP_CODE(
6042    on init
6043      declare const %a[3] := ( 1, abort($NI_CALLBACK_ID), 3 )
6044    end on
6045    )NKSP_CODE",
6046            .expectParseError = true // assigned expression does not result in a value
6047        });
6048    
6049        runScript({
6050            .code = R"NKSP_CODE(
6051    on init
6052      declare %a[3] := ( 1.0, 2.0, 3.0 )
6053    end on
6054    )NKSP_CODE",
6055            .expectParseError = true // int array declaration vs. real array assignment
6056        });
6057    
6058        runScript({
6059            .code = R"NKSP_CODE(
6060    on init
6061      declare %a[3] := ( 1, 2, 3.0 )
6062    end on
6063    )NKSP_CODE",
6064            .expectParseError = true // 3rd element not an integer
6065        });
6066    
6067        runScript({
6068            .code = R"NKSP_CODE(
6069    on init
6070      declare %a[3] := ( "x", "y", "z" )
6071    end on
6072    )NKSP_CODE",
6073            .expectParseError = true // int array declaration vs. string array assignment
6074        });
6075    
6076        runScript({
6077            .code = R"NKSP_CODE(
6078    on init
6079      declare a[3] := ( 1, 2, 3 )
6080    end on
6081    )NKSP_CODE",
6082            .expectParseError = true // missing type prefix character in variable name
6083        });
6084    
6085        runScript({
6086            .code = R"NKSP_CODE(
6087    on init
6088      declare a[3]
6089    end on
6090    )NKSP_CODE",
6091            .expectParseError = true // missing type prefix character in variable name
6092        });
6093    
6094        runScript({
6095            .code = R"NKSP_CODE(
6096    on init
6097      declare const %a[3] := ( 1, 2s, 3 )
6098    end on
6099    )NKSP_CODE",
6100            .expectParseError = true // unit types not allowed for arrays
6101        });
6102    
6103        runScript({
6104            .code = R"NKSP_CODE(
6105    on init
6106      declare const %a[3] := ( 1, !2, 3 )
6107    end on
6108    )NKSP_CODE",
6109            .expectParseError = true // 'final' not allowed for arrays
6110        });
6111    
6112        #if !SILENT_TEST
6113        std::cout << std::endl;
6114        #endif
6115    }
6116    
6117    static void testRealVarDeclaration() {
6118        #if !SILENT_TEST
6119        std::cout << "UNIT TEST: real var declaration\n";
6120        #endif
6121    
6122        runScript({
6123            .code = R"NKSP_CODE(
6124    on init
6125      declare ~a
6126      exit(~a)
6127    end on
6128    )NKSP_CODE",
6129            .expectRealExitResult = 0.0
6130        });
6131    
6132        runScript({
6133            .code = R"NKSP_CODE(
6134    on init
6135      declare ~a := 24.8
6136      exit(~a)
6137    end on
6138    )NKSP_CODE",
6139            .expectRealExitResult = 24.8
6140        });
6141    
6142        runScript({
6143            .code = R"NKSP_CODE(
6144    on init
6145      declare ~a := 8.24
6146      ~a := 24.8
6147      exit(~a)
6148    end on
6149    )NKSP_CODE",
6150            .expectRealExitResult = 24.8
6151        });
6152    
6153        runScript({
6154            .code = R"NKSP_CODE(
6155    on init
6156      declare ~a
6157      declare ~a
6158    end on
6159    )NKSP_CODE",
6160            .expectParseError = true // variable re-declaration
6161        });
6162    
6163        runScript({
6164            .code = R"NKSP_CODE(
6165    on init
6166      declare const ~a
6167    end on
6168    )NKSP_CODE",
6169            .expectParseError = true // const variable declaration without assignment
6170        });
6171    
6172        runScript({
6173            .code = R"NKSP_CODE(
6174    on init
6175      declare const ~a := 8.24
6176      exit(~a)
6177    end on
6178    )NKSP_CODE",
6179            .expectRealExitResult = 8.24
6180        });
6181    
6182        runScript({
6183            .code = R"NKSP_CODE(
6184    on init
6185      declare const ~a := 28.0
6186      ~a := 8.0
6187    end on
6188    )NKSP_CODE",
6189            .expectParseError = true // attempt to modify const variable
6190        });
6191    
6192        runScript({
6193            .code = R"NKSP_CODE(
6194    on init
6195      declare const ~a := 24.8
6196      declare const ~b := ~a
6197      exit(~b)
6198    end on
6199    )NKSP_CODE",
6200            .expectRealExitResult = 24.8
6201        });
6202    
6203        runScript({
6204            .code = R"NKSP_CODE(
6205    on init
6206      declare ~a := 24.0
6207      declare const ~b := ~a
6208    end on
6209    )NKSP_CODE",
6210            .expectParseError = true // const variable defined with non-const assignment
6211        });
6212    
6213        runScript({
6214            .code = R"NKSP_CODE(
6215    on init
6216      declare polyphonic ~a
6217      exit(~a)
6218    end on
6219    )NKSP_CODE",
6220            .expectRealExitResult = 0.0
6221        });
6222    
6223        runScript({
6224            .code = R"NKSP_CODE(
6225    on init
6226      declare const polyphonic ~a
6227    end on
6228    )NKSP_CODE",
6229            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6230        });
6231    
6232        runScript({
6233            .code = R"NKSP_CODE(
6234    on init
6235      declare polyphonic const ~a
6236    end on
6237    )NKSP_CODE",
6238            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6239        });
6240    
6241        runScript({
6242            .code = R"NKSP_CODE(
6243    on init
6244      declare const polyphonic ~a := 3.0
6245    end on
6246    )NKSP_CODE",
6247            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6248        });
6249    
6250        runScript({
6251            .code = R"NKSP_CODE(
6252    on init
6253      declare polyphonic const ~a := 3.0
6254    end on
6255    )NKSP_CODE",
6256            .expectParseError = true // combination of qualifiers 'const' and 'polyphonic' is pointless
6257        });
6258    
6259        runScript({
6260            .code = R"NKSP_CODE(
6261    on init
6262      declare $a := 24.8
6263      exit($a)
6264    end on
6265    )NKSP_CODE",
6266            .expectParseWarning = true, // int type declaration vs. real value assignment
6267            .expectRealExitResult = 24.8
6268        });
6269    
6270        runScript({
6271            .code = R"NKSP_CODE(
6272    on init
6273      declare %a := 24.8
6274      exit(%a)
6275    end on
6276    )NKSP_CODE",
6277            .expectParseWarning = true, // int array type declaration vs. real scalar value assignment
6278            .expectRealExitResult = 24.8
6279        });
6280    
6281        runScript({
6282            .code = R"NKSP_CODE(
6283    on init
6284      declare const %a := 24.8
6285      exit(%a)
6286    end on
6287    )NKSP_CODE",
6288            .expectParseWarning = true, // int array type declaration vs. real scalar value assignment
6289            .expectRealExitResult = 24.8
6290        });
6291    
6292        runScript({
6293            .code = R"NKSP_CODE(
6294    on init
6295      declare ?a := 24.8
6296      exit(?a)
6297    end on
6298    )NKSP_CODE",
6299            .expectParseWarning = true, // real array type declaration vs. real scalar value assignment
6300            .expectRealExitResult = 24.8
6301        });
6302    
6303        runScript({
6304            .code = R"NKSP_CODE(
6305    on init
6306      declare const ?a := 24.8
6307      exit(?a)
6308    end on
6309    )NKSP_CODE",
6310            .expectParseWarning = true, // real array type declaration vs. real scalar value assignment
6311            .expectRealExitResult = 24.8
6312        });
6313    
6314        runScript({
6315            .code = R"NKSP_CODE(
6316    on init
6317      declare @a := 24.8
6318      exit(@a)
6319    end on
6320    )NKSP_CODE",
6321            .expectParseWarning = true, // string type declaration vs. real scalar value assignment
6322            .expectRealExitResult = 24.8
6323        });
6324    
6325        runScript({
6326            .code = R"NKSP_CODE(
6327    on init
6328      declare const @a := 24.8
6329      exit(@a)
6330    end on
6331    )NKSP_CODE",
6332            .expectParseWarning = true, // string type declaration vs. real scalar value assignment
6333            .expectRealExitResult = 24.8
6334        });
6335    
6336        runScript({
6337            .code = R"NKSP_CODE(
6338    on init
6339      declare ~a := ( 0, 1, 2 )
6340    end on
6341    )NKSP_CODE",
6342            .expectParseError = true // real scalar type declaration vs. int array value assignment
6343        });
6344    
6345        runScript({
6346            .code = R"NKSP_CODE(
6347    on init
6348      declare const ~a := ( 0, 1, 2 )
6349    end on
6350    )NKSP_CODE",
6351            .expectParseError = true // real scalar type declaration vs. int array value assignment
6352        });
6353    
6354        runScript({
6355            .code = R"NKSP_CODE(
6356    on init
6357      declare a := 24.8
6358    end on
6359    )NKSP_CODE",
6360            .expectParseError = true // missing type prefix character in variable name
6361        });
6362    
6363        runScript({
6364            .code = R"NKSP_CODE(
6365    on init
6366      declare const a := 24.8
6367    end on
6368    )NKSP_CODE",
6369            .expectParseError = true // missing type prefix character in variable name
6370        });
6371    
6372        runScript({
6373            .code = R"NKSP_CODE(
6374    on init
6375      declare ~a := max(8.1,24.2)
6376      exit(~a)
6377    end on
6378    )NKSP_CODE",
6379            .expectRealExitResult = 24.2
6380        });
6381    
6382        runScript({
6383            .code = R"NKSP_CODE(
6384    on init
6385      declare ~a := abort($NI_CALLBACK_ID)
6386    end on
6387    )NKSP_CODE",
6388            .expectParseError = true // assigned expression does not result in a value
6389        });
6390    
6391        runScript({
6392            .code = R"NKSP_CODE(
6393    on init
6394      declare const ~a := abort($NI_CALLBACK_ID)
6395    end on
6396    )NKSP_CODE",
6397            .expectParseError = true // assigned expression does not result in a value
6398        });
6399    
6400        #if !SILENT_TEST
6401        std::cout << std::endl;
6402        #endif
6403    }
6404    
6405    static void testRealArrayVarDeclaration() {
6406        #if !SILENT_TEST
6407        std::cout << "UNIT TEST: real array var declaration\n";
6408        #endif
6409    
6410        runScript({
6411            .code = R"NKSP_CODE(
6412    on init
6413      declare ?a[3]
6414      exit( ?a[0] + ?a[1] + ?a[2] )
6415    end on
6416    )NKSP_CODE",
6417            .expectRealExitResult = 0.0
6418        });
6419    
6420        runScript({
6421            .code = R"NKSP_CODE(
6422    on init
6423      declare ?a[0]
6424    end on
6425    )NKSP_CODE",
6426            .expectParseError = true // illegal array size
6427        });
6428    
6429        runScript({
6430            .code = R"NKSP_CODE(
6431    on init
6432      declare ?a[-1]
6433    end on
6434    )NKSP_CODE",
6435            .expectParseError = true // illegal array size
6436        });
6437    
6438        runScript({
6439            .code = R"NKSP_CODE(
6440    on init
6441      declare ?a[3] := ( 1.1, 2.2, 3.3 )
6442      exit( ?a[0] + ?a[1] + ?a[2] )
6443    end on
6444    )NKSP_CODE",
6445            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6446        });
6447    
6448        runScript({
6449            .code = R"NKSP_CODE(
6450    on init
6451      declare const $sz := 3
6452      declare ?a[$sz] := ( 1.1, 2.2, 3.3 )
6453      exit( ?a[0] + ?a[1] + ?a[2] )
6454    end on
6455    )NKSP_CODE",
6456            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6457        });
6458    
6459        runScript({
6460            .code = R"NKSP_CODE(
6461    on init
6462      declare const $sz := 3
6463      declare const ?a[$sz] := ( 1.1, 2.2, 3.3 )
6464      exit( ?a[0] + ?a[1] + ?a[2] )
6465    end on
6466    )NKSP_CODE",
6467            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6468        });
6469    
6470        runScript({
6471            .code = R"NKSP_CODE(
6472    on init
6473      declare $sz := 3
6474      declare ?a[$sz] := ( 1.1, 2.2, 3.3 )
6475    end on
6476    )NKSP_CODE",
6477            .expectParseError = true // array size must be constant expression
6478        });
6479    
6480        runScript({
6481            .code = R"NKSP_CODE(
6482    on init
6483      declare $sz := 3
6484      declare const ?a[$sz] := ( 1.1, 2.2, 3.3 )
6485    end on
6486    )NKSP_CODE",
6487            .expectParseError = true // array size must be constant expression
6488        });
6489    
6490        runScript({
6491            .code = R"NKSP_CODE(
6492    on init
6493      declare const ~sz := 3.0
6494      declare const ?a[~sz] := ( 1.1, 2.2, 3.3 )
6495    end on
6496    )NKSP_CODE",
6497            .expectParseError = true // array size must be integer type
6498        });
6499    
6500        runScript({
6501            .code = R"NKSP_CODE(
6502    on init
6503      declare ?a[3s] := ( 1.1, 2.2, 3.3 )
6504    end on
6505    )NKSP_CODE",
6506            .expectParseError = true // units not allowed for array size
6507        });
6508    
6509        runScript({
6510            .code = R"NKSP_CODE(
6511    on init
6512      declare ?a[3m] := ( 1.1, 2.2, 3.3 )
6513    end on
6514    )NKSP_CODE",
6515            .expectParseError = true // units not allowed for array size
6516        });
6517    
6518        runScript({
6519            .code = R"NKSP_CODE(
6520    on init
6521      declare const ?a[!3] := ( 1.1, 2.2, 3.3 )
6522      exit( ?a[0] + ?a[1] + ?a[2] )
6523    end on
6524    )NKSP_CODE",
6525            .expectRealExitResult = (1.1 + 2.2 + 3.3),
6526            .expectParseWarning = true // 'final' operator is meaningless for array size
6527        });
6528    
6529        runScript({
6530            .code = R"NKSP_CODE(
6531    on init
6532      declare ?a[3] := ( 1.0, 2.0, 3.0 )
6533      ?a[0] := 4.5
6534      ?a[1] := 5.5
6535      ?a[2] := 6.5
6536      exit( ?a[0] + ?a[1] + ?a[2] )
6537    end on
6538    )NKSP_CODE",
6539            .expectRealExitResult = (4.5 + 5.5 + 6.5)
6540        });
6541    
6542        runScript({
6543            .code = R"NKSP_CODE(
6544    on init
6545      declare ?a[3]
6546      declare ?a[3]
6547    end on
6548    )NKSP_CODE",
6549            .expectParseError = true // variable re-declaration
6550        });
6551    
6552        runScript({
6553            .code = R"NKSP_CODE(
6554    on init
6555      declare const ?a[3]
6556    end on
6557    )NKSP_CODE",
6558            .expectParseError = true // const variable declaration without assignment
6559        });
6560    
6561        runScript({
6562            .code = R"NKSP_CODE(
6563    on init
6564      declare const ?a[3] := ( 1.1, 2.2, 3.3 )
6565      exit( ?a[0] + ?a[1] + ?a[2] )
6566    end on
6567    )NKSP_CODE",
6568            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6569        });
6570    
6571        runScript({
6572            .code = R"NKSP_CODE(
6573    on init
6574      declare const ?a[3] := ( 1.1, 2.2, 3.3, 4.4 )
6575    end on
6576    )NKSP_CODE",
6577            .expectParseError = true // incompatible array sizes
6578        });
6579    
6580        runScript({
6581            .code = R"NKSP_CODE(
6582    on init
6583      declare const ?a[3] := ( 1.0, 2.0, 3.0 )
6584      ?a[0] := 8.0
6585    end on
6586    )NKSP_CODE",
6587            .expectParseError = true // attempt to modify const variable
6588        });
6589    
6590        runScript({
6591            .code = R"NKSP_CODE(
6592    on init
6593      declare const ?a[3] := ( 1.1, 2.2, 3.3 )
6594      declare const ?b[3] := ( ?a[0], ?a[1], ?a[2] )
6595      exit( ?b[0] + ?b[1] + ?b[2] )
6596    end on
6597    )NKSP_CODE",
6598            .expectRealExitResult = (1.1 + 2.2 + 3.3)
6599        });
6600    
6601        runScript({
6602            .code = R"NKSP_CODE(
6603    on init
6604      declare ?a[3] := ( 1.1, 2.2, 3.3 )
6605      declare const ?b[3] := ( ?a[0], ?a[1], ?a[2] )
6606    end on
6607    )NKSP_CODE",
6608            .expectParseError = true // const array defined with non-const assignment
6609        });
6610    
6611        runScript({
6612            .code = R"NKSP_CODE(
6613    on init
6614      declare polyphonic ?a[3]
6615    end on
6616    )NKSP_CODE",
6617            .expectParseError = true // polyphonic not allowed for array types
6618        });
6619    
6620        runScript({
6621            .code = R"NKSP_CODE(
6622    on init
6623      declare polyphonic ?a[3] := ( 1.0, 2.0, 3.0 )
6624    end on
6625    )NKSP_CODE",
6626            .expectParseError = true // polyphonic not allowed for array types
6627        });
6628    
6629        runScript({
6630            .code = R"NKSP_CODE(
6631    on init
6632      declare const polyphonic ?a[3]
6633    end on
6634    )NKSP_CODE",
6635            .expectParseError = true // polyphonic not allowed for array types
6636        });
6637    
6638        runScript({
6639            .code = R"NKSP_CODE(
6640    on init
6641      declare const polyphonic ?a[3] := ( 1.0, 2.0, 3.0 )
6642    end on
6643    )NKSP_CODE",
6644            .expectParseError = true // polyphonic not allowed for array types
6645        });
6646    
6647        runScript({
6648            .code = R"NKSP_CODE(
6649    on init
6650      declare polyphonic const ?a[3]
6651    end on
6652    )NKSP_CODE",
6653            .expectParseError = true // polyphonic not allowed for array types
6654        });
6655    
6656        runScript({
6657            .code = R"NKSP_CODE(
6658    on init
6659      declare polyphonic const ?a[3] := ( 1.0, 2.0, 3.0 )
6660    end on
6661    )NKSP_CODE",
6662            .expectParseError = true // polyphonic not allowed for array types
6663        });
6664    
6665        runScript({
6666            .code = R"NKSP_CODE(
6667    on init
6668      declare ?a[3] := ( 1.0, max(8.3,24.6), 3.0 )
6669      exit( ?a[0] + ?a[1] + ?a[2] )
6670    end on
6671    )NKSP_CODE",
6672            .expectRealExitResult = ( 1.0 + 24.6 + 3.0 )
6673        });
6674    
6675        runScript({
6676            .code = R"NKSP_CODE(
6677    on init
6678      declare ?a[3] := ( 1.0, abort($NI_CALLBACK_ID), 3.0 )
6679    end on
6680    )NKSP_CODE",
6681            .expectParseError = true // assigned expression does not result in a value
6682        });
6683    
6684        runScript({
6685            .code = R"NKSP_CODE(
6686    on init
6687      declare const ?a[3] := ( 1.0, abort($NI_CALLBACK_ID), 3.0 )
6688    end on
6689    )NKSP_CODE",
6690            .expectParseError = true // assigned expression does not result in a value
6691        });
6692    
6693        runScript({
6694            .code = R"NKSP_CODE(
6695    on init
6696      declare ?a[3] := ( 1, 2, 3 )
6697    end on
6698    )NKSP_CODE",
6699            .expectParseError = true // real array declaration vs. int array assignment
6700        });
6701    
6702        runScript({
6703            .code = R"NKSP_CODE(
6704    on init
6705      declare ?a[3] := ( 1.0, 2.0, 3 )
6706    end on
6707    )NKSP_CODE",
6708            .expectParseError = true // 3rd element not a real value
6709        });
6710    
6711        runScript({
6712            .code = R"NKSP_CODE(
6713    on init
6714      declare ?a[3] := ( "x", "y", "z" )
6715    end on
6716    )NKSP_CODE",
6717            .expectParseError = true // real array declaration vs. string array assignment
6718        });
6719    
6720        runScript({
6721            .code = R"NKSP_CODE(
6722    on init
6723      declare a[3] := ( 1.0, 2.0, 3.0 )
6724    end on
6725    )NKSP_CODE",
6726            .expectParseError = true // missing type prefix character in variable name
6727        });
6728    
6729        runScript({
6730            .code = R"NKSP_CODE(
6731    on init
6732      declare const ?a[3] := ( 1.0, 2.0s, 3.0 )
6733    end on
6734    )NKSP_CODE",
6735            .expectParseError = true // unit types not allowed for arrays
6736        });
6737    
6738        runScript({
6739            .code = R"NKSP_CODE(
6740    on init
6741      declare const ?a[3] := ( 1.0, !2.0, 3.0 )
6742    end on
6743    )NKSP_CODE",
6744            .expectParseError = true // 'final' not allowed for arrays
6745        });
6746    
6747        #if !SILENT_TEST
6748        std::cout << std::endl;
6749        #endif
6750    }
6751    
6752    static void testStringVarDeclaration() {
6753        #if !SILENT_TEST
6754        std::cout << "UNIT TEST: string var declaration\n";
6755        #endif
6756    
6757    runScript({
6758            .code = R"NKSP_CODE(
6759    on init
6760      declare @a
6761      exit(@a)
6762    end on
6763    )NKSP_CODE",
6764            .expectStringExitResult = ""
6765        });
6766    
6767        runScript({
6768            .code = R"NKSP_CODE(
6769    on init
6770      declare @a := "foo"
6771      exit(@a)
6772    end on
6773    )NKSP_CODE",
6774            .expectStringExitResult = "foo"
6775        });
6776    
6777        runScript({
6778            .code = R"NKSP_CODE(
6779    on init
6780      declare @a := "foo"
6781      @a := "bar"
6782      exit(@a)
6783    end on
6784    )NKSP_CODE",
6785            .expectStringExitResult = "bar"
6786        });
6787    
6788        runScript({
6789            .code = R"NKSP_CODE(
6790    on init
6791      declare @a
6792      declare @a
6793    end on
6794    )NKSP_CODE",
6795            .expectParseError = true // variable re-declaration
6796        });
6797    
6798        runScript({
6799            .code = R"NKSP_CODE(
6800    on init
6801      declare const @a
6802    end on
6803    )NKSP_CODE",
6804            .expectParseError = true // const variable declaration without assignment
6805        });
6806    
6807        runScript({
6808            .code = R"NKSP_CODE(
6809    on init
6810      declare const @a := "foo"
6811      exit(@a)
6812    end on
6813    )NKSP_CODE",
6814            .expectStringExitResult = "foo"
6815        });
6816    
6817        runScript({
6818            .code = R"NKSP_CODE(
6819    on init
6820      declare const @a := "foo"
6821      @a := "bar"
6822    end on
6823    )NKSP_CODE",
6824            .expectParseError = true // attempt to modify const variable
6825        });
6826    
6827        runScript({
6828            .code = R"NKSP_CODE(
6829    on init
6830      declare const @a := "foo"
6831      declare const @b := @a
6832      exit(@b)
6833    end on
6834    )NKSP_CODE",
6835            .expectStringExitResult = "foo"
6836        });
6837    
6838        runScript({
6839            .code = R"NKSP_CODE(
6840    on init
6841      declare @a := "foo"
6842      declare const @b := @a
6843    end on
6844    )NKSP_CODE",
6845            .expectParseError = true // const variable defined with non-const assignment
6846        });
6847    
6848        runScript({
6849            .code = R"NKSP_CODE(
6850    on init
6851      declare polyphonic @a
6852    end on
6853    )NKSP_CODE",
6854            .expectParseError = true // 'polyphonic' not allowed for string type
6855        });
6856    
6857        runScript({
6858            .code = R"NKSP_CODE(
6859    on init
6860      declare const polyphonic @a
6861    end on
6862    )NKSP_CODE",
6863            .expectParseError = true // 'polyphonic' not allowed for string type
6864        });
6865    
6866        runScript({
6867            .code = R"NKSP_CODE(
6868    on init
6869      declare polyphonic const @a
6870    end on
6871    )NKSP_CODE",
6872            .expectParseError = true // 'polyphonic' not allowed for string type
6873        });
6874    
6875        runScript({
6876            .code = R"NKSP_CODE(
6877    on init
6878      declare polyphonic @a = "foo"
6879    end on
6880    )NKSP_CODE",
6881            .expectParseError = true // 'polyphonic' not allowed for string type
6882        });
6883    
6884        runScript({
6885            .code = R"NKSP_CODE(
6886    on init
6887      declare polyphonic const @a = "foo"
6888    end on
6889    )NKSP_CODE",
6890            .expectParseError = true // 'polyphonic' not allowed for string type
6891        });
6892    
6893        runScript({
6894            .code = R"NKSP_CODE(
6895    on init
6896      declare const polyphonic @a = "foo"
6897    end on
6898    )NKSP_CODE",
6899            .expectParseError = true // 'polyphonic' not allowed for string type
6900        });
6901    
6902        runScript({
6903            .code = R"NKSP_CODE(
6904    on init
6905      declare $a := "foo"
6906      exit($a)
6907    end on
6908    )NKSP_CODE",
6909            .expectParseWarning = true, // int type declaration vs. string assignment
6910            .expectStringExitResult = "foo"
6911        });
6912    
6913        runScript({
6914            .code = R"NKSP_CODE(
6915    on init
6916      declare ~a := "foo"
6917      exit(~a)
6918    end on
6919    )NKSP_CODE",
6920            .expectParseWarning = true, // real type declaration vs. string assignment
6921            .expectStringExitResult = "foo"
6922        });
6923    
6924        runScript({
6925            .code = R"NKSP_CODE(
6926    on init
6927      declare %a := "foo"
6928      exit(%a)
6929    end on
6930    )NKSP_CODE",
6931            .expectParseWarning = true, // int array type declaration vs. string assignment
6932            .expectStringExitResult = "foo"
6933        });
6934    
6935        runScript({
6936            .code = R"NKSP_CODE(
6937    on init
6938      declare const $a := "foo"
6939      exit($a)
6940    end on
6941    )NKSP_CODE",
6942            .expectParseWarning = true, // int type declaration vs. string assignment
6943            .expectStringExitResult = "foo"
6944        });
6945    
6946        runScript({
6947            .code = R"NKSP_CODE(
6948    on init
6949      declare const ~a := "foo"
6950      exit(~a)
6951    end on
6952    )NKSP_CODE",
6953            .expectParseWarning = true, // real type declaration vs. string assignment
6954            .expectStringExitResult = "foo"
6955        });
6956    
6957        runScript({
6958            .code = R"NKSP_CODE(
6959    on init
6960      declare const %a := "foo"
6961      exit(%a)
6962    end on
6963    )NKSP_CODE",
6964            .expectParseWarning = true, // int array type declaration vs. string assignment
6965            .expectStringExitResult = "foo"
6966        });
6967    
6968        runScript({
6969            .code = R"NKSP_CODE(
6970    on init
6971      declare a := "foo"
6972    end on
6973    )NKSP_CODE",
6974            .expectParseError = true // missing type prefix character in variable name
6975        });
6976    
6977        runScript({
6978            .code = R"NKSP_CODE(
6979    on init
6980      declare const a := "foo"
6981    end on
6982    )NKSP_CODE",
6983            .expectParseError = true // missing type prefix character in variable name
6984        });
6985    
6986        runScript({
6987            .code = R"NKSP_CODE(
6988    on init
6989      declare @a := abort($NI_CALLBACK_ID)
6990    end on
6991    )NKSP_CODE",
6992            .expectParseError = true // assigned expression does not result in a value
6993        });
6994    
6995        runScript({
6996            .code = R"NKSP_CODE(
6997    on init
6998      declare const @a := abort($NI_CALLBACK_ID)
6999    end on
7000    )NKSP_CODE",
7001            .expectParseError = true // assigned expression does not result in a value
7002        });
7003    
7004      #if !SILENT_TEST      #if !SILENT_TEST
7005      std::cout << std::endl;      std::cout << std::endl;
7006      #endif      #endif
# Line 1184  end on Line 7038  end on
7038          .expectParseError = true // because min() function requires 2 arguments          .expectParseError = true // because min() function requires 2 arguments
7039      });      });
7040    
7041        // integer tests ...
7042    
7043      runScript({      runScript({
7044          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7045  on init  on init
# Line 1204  end on Line 7060  end on
7060          .expectIntExitResult = -30          .expectIntExitResult = -30
7061      });      });
7062    
7063        // real number tests ...
7064    
7065        runScript({
7066            .code = R"NKSP_CODE(
7067    on init
7068      declare ~foo := min(1.0, 2.0)
7069      exit(~foo)
7070    end on
7071    )NKSP_CODE",
7072            .expectRealExitResult = 1.0
7073        });
7074    
7075        runScript({
7076            .code = R"NKSP_CODE(
7077    on init
7078      declare ~foo := min(-30.0, 4.0)
7079      exit(~foo)
7080    end on
7081    )NKSP_CODE",
7082            .expectRealExitResult = -30.0
7083        });
7084    
7085        runScript({
7086            .code = R"NKSP_CODE(
7087    on init
7088      declare ~foo := min(1.1, 1.13)
7089      exit(~foo)
7090    end on
7091    )NKSP_CODE",
7092            .expectRealExitResult = 1.1
7093        });
7094    
7095        runScript({
7096            .code = R"NKSP_CODE(
7097    on init
7098      declare ~foo := min(1.13, 1.1)
7099      exit(~foo)
7100    end on
7101    )NKSP_CODE",
7102            .expectRealExitResult = 1.1
7103        });
7104    
7105        // mixed type tests ...
7106    
7107        runScript({
7108            .code = R"NKSP_CODE(
7109    on init
7110      declare ~foo := min(1, 1.16)
7111      exit(~foo)
7112    end on
7113    )NKSP_CODE",
7114            .expectRealExitResult = 1.0,
7115            .expectParseWarning = true // min() warns if data types of arguments not matching
7116        });
7117    
7118        runScript({
7119            .code = R"NKSP_CODE(
7120    on init
7121      declare ~foo := min(-3.92, 9)
7122      exit(~foo)
7123    end on
7124    )NKSP_CODE",
7125            .expectRealExitResult = -3.92,
7126            .expectParseWarning = true // min() warns if data types of arguments not matching
7127        });
7128    
7129        // std unit tests ...
7130    
7131        runScript({
7132            .code = R"NKSP_CODE(
7133    on init
7134      declare $foo := min(30ms,4s)
7135      exit($foo)
7136    end on
7137    )NKSP_CODE",
7138            .expectIntExitResult = 30,
7139            .expectExitResultUnitPrefix = { VM_MILLI },
7140            .expectExitResultUnit = VM_SECOND,
7141        });
7142    
7143        runScript({
7144            .code = R"NKSP_CODE(
7145    on init
7146      declare $foo := min(4s,30ms)
7147      exit($foo)
7148    end on
7149    )NKSP_CODE",
7150            .expectIntExitResult = 30,
7151            .expectExitResultUnitPrefix = { VM_MILLI },
7152            .expectExitResultUnit = VM_SECOND,
7153        });
7154    
7155        runScript({
7156            .code = R"NKSP_CODE(
7157    on init
7158      declare $foo := min(-30mdB,-4dB)
7159      exit($foo)
7160    end on
7161    )NKSP_CODE",
7162            .expectIntExitResult = -4,
7163            .expectExitResultUnitPrefix = { VM_DECI },
7164            .expectExitResultUnit = VM_BEL,
7165        });
7166    
7167        runScript({
7168            .code = R"NKSP_CODE(
7169    on init
7170      declare $foo := min(-4dB,-30mdB)
7171      exit($foo)
7172    end on
7173    )NKSP_CODE",
7174            .expectIntExitResult = -4,
7175            .expectExitResultUnitPrefix = { VM_DECI },
7176            .expectExitResultUnit = VM_BEL,
7177        });
7178    
7179        runScript({
7180            .code = R"NKSP_CODE(
7181    on init
7182      declare $foo := min(-4s,-30Hz)
7183      exit($foo)
7184    end on
7185    )NKSP_CODE",
7186            .expectParseError = true // min() requires arguments to have same unit type
7187        });
7188    
7189        runScript({
7190            .code = R"NKSP_CODE(
7191    on init
7192      declare $foo := min(-4s,-30)
7193      exit($foo)
7194    end on
7195    )NKSP_CODE",
7196            .expectParseError = true // min() requires arguments to have same unit type
7197        });
7198    
7199        runScript({
7200            .code = R"NKSP_CODE(
7201    on init
7202      declare $foo := min(-4,-30s)
7203      exit($foo)
7204    end on
7205    )NKSP_CODE",
7206            .expectParseError = true // min() requires arguments to have same unit type
7207        });
7208    
7209        runScript({
7210            .code = R"NKSP_CODE(
7211    on init
7212      declare ~foo := min(0.9s,1.0s)
7213      exit(~foo)
7214    end on
7215    )NKSP_CODE",
7216            .expectRealExitResult = 0.9,
7217            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7218            .expectExitResultUnit = VM_SECOND,
7219        });
7220    
7221        // 'final' ('!') operator tests ...
7222    
7223        runScript({
7224            .code = R"NKSP_CODE(
7225    on init
7226      declare $foo := min(!30,!4)
7227      exit($foo)
7228    end on
7229    )NKSP_CODE",
7230            .expectIntExitResult = 4,
7231            .expectExitResultFinal = true
7232        });
7233    
7234        runScript({
7235            .code = R"NKSP_CODE(
7236    on init
7237      declare $foo := min(30,4)
7238      exit($foo)
7239    end on
7240    )NKSP_CODE",
7241            .expectIntExitResult = 4,
7242            .expectExitResultFinal = false
7243        });
7244    
7245        runScript({
7246            .code = R"NKSP_CODE(
7247    on init
7248      declare $foo := min(30,!4)
7249      exit($foo)
7250    end on
7251    )NKSP_CODE",
7252            .expectIntExitResult = 4,
7253            .expectExitResultFinal = true,
7254            .expectParseWarning = true // min() warns if only one argument is 'final'
7255        });
7256    
7257        runScript({
7258            .code = R"NKSP_CODE(
7259    on init
7260      declare $foo := min(!30,4)
7261      exit($foo)
7262    end on
7263    )NKSP_CODE",
7264            .expectIntExitResult = 4,
7265            .expectExitResultFinal = true,
7266            .expectParseWarning = true // min() warns if only one argument is 'final'
7267        });
7268    
7269        runScript({
7270            .code = R"NKSP_CODE(
7271    on init
7272      declare ~foo := min(!12.1,!12.2)
7273      exit(~foo)
7274    end on
7275    )NKSP_CODE",
7276            .expectRealExitResult = 12.1,
7277            .expectExitResultFinal = true
7278        });
7279    
7280        runScript({
7281            .code = R"NKSP_CODE(
7282    on init
7283      declare ~foo := min(12.1,12.2)
7284      exit(~foo)
7285    end on
7286    )NKSP_CODE",
7287            .expectRealExitResult = 12.1,
7288            .expectExitResultFinal = false
7289        });
7290    
7291        runScript({
7292            .code = R"NKSP_CODE(
7293    on init
7294      declare ~foo := min(!12.1,12.2)
7295      exit(~foo)
7296    end on
7297    )NKSP_CODE",
7298            .expectRealExitResult = 12.1,
7299            .expectExitResultFinal = true,
7300            .expectParseWarning = true // min() warns if only one argument is 'final'
7301        });
7302    
7303        runScript({
7304            .code = R"NKSP_CODE(
7305    on init
7306      declare ~foo := min(12.1,!12.2)
7307      exit(~foo)
7308    end on
7309    )NKSP_CODE",
7310            .expectRealExitResult = 12.1,
7311            .expectExitResultFinal = true,
7312            .expectParseWarning = true // min() warns if only one argument is 'final'
7313        });
7314    
7315      #if !SILENT_TEST      #if !SILENT_TEST
7316      std::cout << std::endl;      std::cout << std::endl;
7317      #endif      #endif
# Line 1214  static void testBuiltInMaxFunction() { Line 7322  static void testBuiltInMaxFunction() {
7322      std::cout << "UNIT TEST: built-in max() function\n";      std::cout << "UNIT TEST: built-in max() function\n";
7323      #endif      #endif
7324    
7325        // integer tests ...
7326    
7327      runScript({      runScript({
7328          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7329  on init  on init
# Line 1261  end on Line 7371  end on
7371          .expectIntExitResult = 4          .expectIntExitResult = 4
7372      });      });
7373    
7374        // real number tests ...
7375    
7376        runScript({
7377            .code = R"NKSP_CODE(
7378    on init
7379      declare ~foo := max(1.0, 2.0)
7380      exit(~foo)
7381    end on
7382    )NKSP_CODE",
7383            .expectRealExitResult = 2.0
7384        });
7385    
7386        runScript({
7387            .code = R"NKSP_CODE(
7388    on init
7389      declare ~foo := max(-30.0, 4.0)
7390      exit(~foo)
7391    end on
7392    )NKSP_CODE",
7393            .expectRealExitResult = 4.0
7394        });
7395    
7396        runScript({
7397            .code = R"NKSP_CODE(
7398    on init
7399      declare ~foo := max(1.1, 1.13)
7400      exit(~foo)
7401    end on
7402    )NKSP_CODE",
7403            .expectRealExitResult = 1.13
7404        });
7405    
7406        runScript({
7407            .code = R"NKSP_CODE(
7408    on init
7409      declare ~foo := max(1.13, 1.1)
7410      exit(~foo)
7411    end on
7412    )NKSP_CODE",
7413            .expectRealExitResult = 1.13
7414        });
7415    
7416        // mixed type tests ...
7417    
7418        runScript({
7419            .code = R"NKSP_CODE(
7420    on init
7421      declare ~foo := max(1, 1.16)
7422      exit(~foo)
7423    end on
7424    )NKSP_CODE",
7425            .expectRealExitResult = 1.16,
7426            .expectParseWarning = true // max() warns if data types of arguments not matching
7427        });
7428    
7429        runScript({
7430            .code = R"NKSP_CODE(
7431    on init
7432      declare ~foo := max(-3.92, 9)
7433      exit(~foo)
7434    end on
7435    )NKSP_CODE",
7436            .expectRealExitResult = 9.0,
7437            .expectParseWarning = true // max() warns if data types of arguments not matching
7438        });
7439    
7440        // std unit tests ...
7441    
7442        runScript({
7443            .code = R"NKSP_CODE(
7444    on init
7445      declare $foo := max(30ms,4s)
7446      exit($foo)
7447    end on
7448    )NKSP_CODE",
7449            .expectIntExitResult = 4,
7450            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7451            .expectExitResultUnit = VM_SECOND,
7452        });
7453    
7454        runScript({
7455            .code = R"NKSP_CODE(
7456    on init
7457      declare $foo := max(4s,30ms)
7458      exit($foo)
7459    end on
7460    )NKSP_CODE",
7461            .expectIntExitResult = 4,
7462            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7463            .expectExitResultUnit = VM_SECOND,
7464        });
7465    
7466        runScript({
7467            .code = R"NKSP_CODE(
7468    on init
7469      declare $foo := max(-30mdB,-4dB)
7470      exit($foo)
7471    end on
7472    )NKSP_CODE",
7473            .expectIntExitResult = -30,
7474            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7475            .expectExitResultUnit = VM_BEL,
7476        });
7477    
7478        runScript({
7479            .code = R"NKSP_CODE(
7480    on init
7481      declare $foo := max(-4dB,-30mdB)
7482      exit($foo)
7483    end on
7484    )NKSP_CODE",
7485            .expectIntExitResult = -30,
7486            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7487            .expectExitResultUnit = VM_BEL,
7488        });
7489    
7490        runScript({
7491            .code = R"NKSP_CODE(
7492    on init
7493      declare $foo := max(-4s,-30Hz)
7494      exit($foo)
7495    end on
7496    )NKSP_CODE",
7497            .expectParseError = true // max() requires arguments to have same unit type
7498        });
7499    
7500        runScript({
7501            .code = R"NKSP_CODE(
7502    on init
7503      declare $foo := max(-4s,-30)
7504      exit($foo)
7505    end on
7506    )NKSP_CODE",
7507            .expectParseError = true // max() requires arguments to have same unit type
7508        });
7509    
7510        runScript({
7511            .code = R"NKSP_CODE(
7512    on init
7513      declare $foo := max(-4,-30s)
7514      exit($foo)
7515    end on
7516    )NKSP_CODE",
7517            .expectParseError = true // max() requires arguments to have same unit type
7518        });
7519    
7520        runScript({
7521            .code = R"NKSP_CODE(
7522    on init
7523      declare ~foo := max(0.9s,1.0s)
7524      exit(~foo)
7525    end on
7526    )NKSP_CODE",
7527            .expectRealExitResult = 1.0,
7528            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
7529            .expectExitResultUnit = VM_SECOND,
7530        });
7531    
7532        // 'final' ('!') operator tests ...
7533    
7534        runScript({
7535            .code = R"NKSP_CODE(
7536    on init
7537      declare $foo := max(!30,!4)
7538      exit($foo)
7539    end on
7540    )NKSP_CODE",
7541            .expectIntExitResult = 30,
7542            .expectExitResultFinal = true
7543        });
7544    
7545        runScript({
7546            .code = R"NKSP_CODE(
7547    on init
7548      declare $foo := max(30,4)
7549      exit($foo)
7550    end on
7551    )NKSP_CODE",
7552            .expectIntExitResult = 30,
7553            .expectExitResultFinal = false
7554        });
7555    
7556        runScript({
7557            .code = R"NKSP_CODE(
7558    on init
7559      declare $foo := max(30,!4)
7560      exit($foo)
7561    end on
7562    )NKSP_CODE",
7563            .expectIntExitResult = 30,
7564            .expectExitResultFinal = true,
7565            .expectParseWarning = true // max() warns if only one argument is 'final'
7566        });
7567    
7568        runScript({
7569            .code = R"NKSP_CODE(
7570    on init
7571      declare $foo := max(!30,4)
7572      exit($foo)
7573    end on
7574    )NKSP_CODE",
7575            .expectIntExitResult = 30,
7576            .expectExitResultFinal = true,
7577            .expectParseWarning = true // max() warns if only one argument is 'final'
7578        });
7579    
7580        runScript({
7581            .code = R"NKSP_CODE(
7582    on init
7583      declare ~foo := max(!12.1,!12.2)
7584      exit(~foo)
7585    end on
7586    )NKSP_CODE",
7587            .expectRealExitResult = 12.2,
7588            .expectExitResultFinal = true
7589        });
7590    
7591        runScript({
7592            .code = R"NKSP_CODE(
7593    on init
7594      declare ~foo := max(12.1,12.2)
7595      exit(~foo)
7596    end on
7597    )NKSP_CODE",
7598            .expectRealExitResult = 12.2,
7599            .expectExitResultFinal = false
7600        });
7601    
7602        runScript({
7603            .code = R"NKSP_CODE(
7604    on init
7605      declare ~foo := max(!12.1,12.2)
7606      exit(~foo)
7607    end on
7608    )NKSP_CODE",
7609            .expectRealExitResult = 12.2,
7610            .expectExitResultFinal = true,
7611            .expectParseWarning = true // max() warns if only one argument is 'final'
7612        });
7613    
7614        runScript({
7615            .code = R"NKSP_CODE(
7616    on init
7617      declare ~foo := max(12.1,!12.2)
7618      exit(~foo)
7619    end on
7620    )NKSP_CODE",
7621            .expectRealExitResult = 12.2,
7622            .expectExitResultFinal = true,
7623            .expectParseWarning = true // max() warns if only one argument is 'final'
7624        });
7625    
7626      #if !SILENT_TEST      #if !SILENT_TEST
7627      std::cout << std::endl;      std::cout << std::endl;
7628      #endif      #endif
# Line 1289  end on Line 7651  end on
7651          .expectParseError = true // because abs() function requires 1 argument          .expectParseError = true // because abs() function requires 1 argument
7652      });      });
7653    
7654        // integer tests ...
7655    
7656      runScript({      runScript({
7657          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7658  on init  on init
# Line 1309  end on Line 7673  end on
7673          .expectIntExitResult = 23          .expectIntExitResult = 23
7674      });      });
7675    
7676        // real number tests ...
7677    
7678        runScript({
7679            .code = R"NKSP_CODE(
7680    on init
7681      declare ~foo := abs(23.0)
7682      exit(~foo)
7683    end on
7684    )NKSP_CODE",
7685            .expectRealExitResult = 23.0
7686        });
7687    
7688        runScript({
7689            .code = R"NKSP_CODE(
7690    on init
7691      declare ~foo := abs(23.11)
7692      exit(~foo)
7693    end on
7694    )NKSP_CODE",
7695            .expectRealExitResult = 23.11
7696        });
7697    
7698        runScript({
7699            .code = R"NKSP_CODE(
7700    on init
7701      declare ~foo := abs(-23.11)
7702      exit(~foo)
7703    end on
7704    )NKSP_CODE",
7705            .expectRealExitResult = 23.11
7706        });
7707    
7708        runScript({
7709            .code = R"NKSP_CODE(
7710    on init
7711      declare ~bar := -23.11
7712      declare ~foo := abs(~bar)
7713      exit(~foo)
7714    end on
7715    )NKSP_CODE",
7716            .expectRealExitResult = 23.11
7717        });
7718    
7719        // std unit tests ...
7720    
7721        runScript({
7722            .code = R"NKSP_CODE(
7723    on init
7724      declare $foo := abs(-23kHz)
7725      exit($foo)
7726    end on
7727    )NKSP_CODE",
7728            .expectIntExitResult = 23,
7729            .expectExitResultUnitPrefix = { VM_KILO },
7730            .expectExitResultUnit = VM_HERTZ
7731        });
7732    
7733        runScript({
7734            .code = R"NKSP_CODE(
7735    on init
7736      declare ~foo := abs(-23.4kHz)
7737      exit(~foo)
7738    end on
7739    )NKSP_CODE",
7740            .expectRealExitResult = 23.4,
7741            .expectExitResultUnitPrefix = { VM_KILO },
7742            .expectExitResultUnit = VM_HERTZ
7743        });
7744    
7745        // 'final' ('!') operator tests ...
7746    
7747        runScript({
7748            .code = R"NKSP_CODE(
7749    on init
7750      declare $foo := abs(!-23)
7751      exit($foo)
7752    end on
7753    )NKSP_CODE",
7754            .expectIntExitResult = 23,
7755            .expectExitResultFinal = true
7756        });
7757    
7758        runScript({
7759            .code = R"NKSP_CODE(
7760    on init
7761      declare $foo := abs(-23)
7762      exit($foo)
7763    end on
7764    )NKSP_CODE",
7765            .expectIntExitResult = 23,
7766            .expectExitResultFinal = false
7767        });
7768    
7769        runScript({
7770            .code = R"NKSP_CODE(
7771    on init
7772      declare ~foo := abs(!-23.2)
7773      exit(~foo)
7774    end on
7775    )NKSP_CODE",
7776            .expectRealExitResult = 23.2,
7777            .expectExitResultFinal = true
7778        });
7779    
7780        runScript({
7781            .code = R"NKSP_CODE(
7782    on init
7783      declare ~foo := abs(-23.9)
7784      exit(~foo)
7785    end on
7786    )NKSP_CODE",
7787            .expectRealExitResult = 23.9,
7788            .expectExitResultFinal = false
7789        });
7790    
7791      #if !SILENT_TEST      #if !SILENT_TEST
7792      std::cout << std::endl;      std::cout << std::endl;
7793      #endif      #endif
# Line 1319  static void testBuiltInIncFunction() { Line 7798  static void testBuiltInIncFunction() {
7798      std::cout << "UNIT TEST: built-in inc() function\n";      std::cout << "UNIT TEST: built-in inc() function\n";
7799      #endif      #endif
7800    
7801        // integer tests ...
7802    
7803      runScript({      runScript({
7804          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7805  on init  on init
# Line 1354  end on Line 7835  end on
7835          .expectIntExitResult = 7          .expectIntExitResult = 7
7836      });      });
7837    
7838        // std unit tests ...
7839    
7840        runScript({
7841            .code = R"NKSP_CODE(
7842    on init
7843      declare $foo := 53mdB
7844      inc($foo)
7845      exit( inc($foo) )
7846    end on
7847    )NKSP_CODE",
7848            .expectIntExitResult = 55,
7849            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7850            .expectExitResultUnit = VM_BEL,
7851            .expectParseWarning = true // inc() warns if argument has a unit
7852        });
7853    
7854        // 'final' ('!') operator tests ...
7855    
7856        runScript({
7857            .code = R"NKSP_CODE(
7858    on init
7859      declare $foo := !53
7860      inc($foo)
7861      exit( inc($foo) )
7862    end on
7863    )NKSP_CODE",
7864            .expectIntExitResult = 55,
7865            .expectExitResultFinal = true
7866        });
7867    
7868        runScript({
7869            .code = R"NKSP_CODE(
7870    on init
7871      declare $foo := 53
7872      inc($foo)
7873      exit( inc($foo) )
7874    end on
7875    )NKSP_CODE",
7876            .expectIntExitResult = 55,
7877            .expectExitResultFinal = false
7878        });
7879    
7880        runScript({
7881            .code = R"NKSP_CODE(
7882    on init
7883      declare $foo := 53
7884      inc($foo)
7885      exit( !inc($foo) )
7886    end on
7887    )NKSP_CODE",
7888            .expectIntExitResult = 55,
7889            .expectExitResultFinal = true
7890        });
7891    
7892      #if !SILENT_TEST      #if !SILENT_TEST
7893      std::cout << std::endl;      std::cout << std::endl;
7894      #endif      #endif
# Line 1364  static void testBuiltInDecFunction() { Line 7899  static void testBuiltInDecFunction() {
7899      std::cout << "UNIT TEST: built-in dec() function\n";      std::cout << "UNIT TEST: built-in dec() function\n";
7900      #endif      #endif
7901    
7902        // integer tests ...
7903    
7904      runScript({      runScript({
7905          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
7906  on init  on init
# Line 1399  end on Line 7936  end on
7936          .expectIntExitResult = 3          .expectIntExitResult = 3
7937      });      });
7938    
7939        // std unit tests ...
7940    
7941        runScript({
7942            .code = R"NKSP_CODE(
7943    on init
7944      declare $foo := 53mdB
7945      dec($foo)
7946      exit( dec($foo) )
7947    end on
7948    )NKSP_CODE",
7949            .expectIntExitResult = 51,
7950            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
7951            .expectExitResultUnit = VM_BEL,
7952            .expectParseWarning = true // dec() warns if argument has a unit
7953        });
7954    
7955        // 'final' ('!') operator tests ...
7956    
7957        runScript({
7958            .code = R"NKSP_CODE(
7959    on init
7960      declare $foo := !53
7961      dec($foo)
7962      exit( dec($foo) )
7963    end on
7964    )NKSP_CODE",
7965            .expectIntExitResult = 51,
7966            .expectExitResultFinal = true
7967        });
7968    
7969        runScript({
7970            .code = R"NKSP_CODE(
7971    on init
7972      declare $foo := 53
7973      dec($foo)
7974      exit( dec($foo) )
7975    end on
7976    )NKSP_CODE",
7977            .expectIntExitResult = 51,
7978            .expectExitResultFinal = false
7979        });
7980    
7981        runScript({
7982            .code = R"NKSP_CODE(
7983    on init
7984      declare $foo := 53
7985      dec($foo)
7986      exit( !dec($foo) )
7987    end on
7988    )NKSP_CODE",
7989            .expectIntExitResult = 51,
7990            .expectExitResultFinal = true
7991        });
7992    
7993      #if !SILENT_TEST      #if !SILENT_TEST
7994      std::cout << std::endl;      std::cout << std::endl;
7995      #endif      #endif
# Line 1409  static void testBuiltInInRangeFunction() Line 8000  static void testBuiltInInRangeFunction()
8000      std::cout << "UNIT TEST: built-in in_range() function\n";      std::cout << "UNIT TEST: built-in in_range() function\n";
8001      #endif      #endif
8002    
8003        // integer tests ...
8004    
8005      runScript({      runScript({
8006          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
8007  on init  on init
# Line 1490  end on Line 8083  end on
8083          .expectBoolExitResult = false          .expectBoolExitResult = false
8084      });      });
8085    
8086        // real number tests ...
8087    
8088        runScript({
8089            .code = R"NKSP_CODE(
8090    on init
8091      exit( in_range(12.2,12.1,12.9) )
8092    end on
8093    )NKSP_CODE",
8094            .expectBoolExitResult = true
8095        });
8096    
8097        runScript({
8098            .code = R"NKSP_CODE(
8099    on init
8100      exit( in_range(12.2,12.9,12.1) )
8101    end on
8102    )NKSP_CODE",
8103            .expectBoolExitResult = true
8104        });
8105    
8106        runScript({
8107            .code = R"NKSP_CODE(
8108    on init
8109      exit( in_range(12.0,12.1,12.9) )
8110    end on
8111    )NKSP_CODE",
8112            .expectBoolExitResult = false
8113        });
8114    
8115        runScript({
8116            .code = R"NKSP_CODE(
8117    on init
8118      exit( in_range(12.0,12.9,12.1) )
8119    end on
8120    )NKSP_CODE",
8121            .expectBoolExitResult = false
8122        });
8123    
8124        runScript({
8125            .code = R"NKSP_CODE(
8126    on init
8127      exit( in_range(0.0,-0.3,0.3) )
8128    end on
8129    )NKSP_CODE",
8130            .expectBoolExitResult = true
8131        });
8132    
8133        runScript({
8134            .code = R"NKSP_CODE(
8135    on init
8136      exit( in_range(-0.34,-0.3,0.3) )
8137    end on
8138    )NKSP_CODE",
8139            .expectBoolExitResult = false
8140        });
8141    
8142        runScript({
8143            .code = R"NKSP_CODE(
8144    on init
8145      exit( in_range(0.34,-0.3,0.3) )
8146    end on
8147    )NKSP_CODE",
8148            .expectBoolExitResult = false
8149        });
8150    
8151        runScript({
8152            .code = R"NKSP_CODE(
8153    on init
8154      exit( in_range(-0.3,-0.3,0.3) )
8155    end on
8156    )NKSP_CODE",
8157            .expectBoolExitResult = true
8158        });
8159    
8160        runScript({
8161            .code = R"NKSP_CODE(
8162    on init
8163      exit( in_range(0.3,-0.3,0.3) )
8164    end on
8165    )NKSP_CODE",
8166            .expectBoolExitResult = true
8167        });
8168    
8169        // mixed type tests ...
8170    
8171        runScript({
8172            .code = R"NKSP_CODE(
8173    on init
8174      exit( in_range(4.0,-5,5) )
8175    end on
8176    )NKSP_CODE",
8177            .expectBoolExitResult = true,
8178            .expectParseWarning = true // in_range() warns if not all arguments are of same type
8179        });
8180    
8181        runScript({
8182            .code = R"NKSP_CODE(
8183    on init
8184      exit( in_range(5,-5,5.0) )
8185    end on
8186    )NKSP_CODE",
8187            .expectBoolExitResult = true,
8188            .expectParseWarning = true // in_range() warns if not all arguments are of same type
8189        });
8190    
8191        runScript({
8192            .code = R"NKSP_CODE(
8193    on init
8194      exit( in_range(-5,-5.0,5) )
8195    end on
8196    )NKSP_CODE",
8197            .expectBoolExitResult = true,
8198            .expectParseWarning = true // in_range() warns if not all arguments are of same type
8199        });
8200    
8201        // std unit tests ...
8202    
8203        runScript({
8204            .code = R"NKSP_CODE(
8205    on init
8206      exit( in_range(4000Hz,3kHz,5kHz) )
8207    end on
8208    )NKSP_CODE",
8209            .expectBoolExitResult = true,
8210            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8211            .expectExitResultUnit = VM_NO_UNIT
8212        });
8213    
8214        runScript({
8215            .code = R"NKSP_CODE(
8216    on init
8217      exit( in_range(5000Hz,3kHz,5kHz) )
8218    end on
8219    )NKSP_CODE",
8220            .expectBoolExitResult = true,
8221            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8222            .expectExitResultUnit = VM_NO_UNIT
8223        });
8224    
8225        runScript({
8226            .code = R"NKSP_CODE(
8227    on init
8228      exit( in_range(5001Hz,3kHz,5kHz) )
8229    end on
8230    )NKSP_CODE",
8231            .expectBoolExitResult = false,
8232            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8233            .expectExitResultUnit = VM_NO_UNIT
8234        });
8235    
8236        runScript({
8237            .code = R"NKSP_CODE(
8238    on init
8239      exit( in_range(3000Hz,3kHz,5kHz) )
8240    end on
8241    )NKSP_CODE",
8242            .expectBoolExitResult = true,
8243            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8244            .expectExitResultUnit = VM_NO_UNIT
8245        });
8246    
8247        runScript({
8248            .code = R"NKSP_CODE(
8249    on init
8250      exit( in_range(2999Hz,3kHz,5kHz) )
8251    end on
8252    )NKSP_CODE",
8253            .expectBoolExitResult = false,
8254            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8255            .expectExitResultUnit = VM_NO_UNIT
8256        });
8257    
8258        runScript({
8259            .code = R"NKSP_CODE(
8260    on init
8261      exit( in_range(0.003s,3000.0us,5ms) )
8262    end on
8263    )NKSP_CODE",
8264            .expectBoolExitResult = true,
8265            .expectParseWarning = true, // in_range() warns if not all arguments are of same type
8266            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8267            .expectExitResultUnit = VM_NO_UNIT
8268        });
8269    
8270        runScript({
8271            .code = R"NKSP_CODE(
8272    on init
8273      exit( in_range(0.005s,3000.0us,5ms) )
8274    end on
8275    )NKSP_CODE",
8276            .expectBoolExitResult = true,
8277            .expectParseWarning = true, // in_range() warns if not all arguments are of same type,
8278            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8279            .expectExitResultUnit = VM_NO_UNIT
8280        });
8281    
8282        runScript({
8283            .code = R"NKSP_CODE(
8284    on init
8285      exit( in_range(0.0051s,3000.0us,5ms) )
8286    end on
8287    )NKSP_CODE",
8288            .expectBoolExitResult = false,
8289            .expectParseWarning = true, // in_range() warns if not all arguments are of same type
8290            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8291            .expectExitResultUnit = VM_NO_UNIT
8292        });
8293    
8294        runScript({
8295            .code = R"NKSP_CODE(
8296    on init
8297      exit( in_range(3s,2Hz,5Hz) )
8298    end on
8299    )NKSP_CODE",
8300            .expectParseError = true // in_range() throws error if not all arguments' unit types equal,
8301        });
8302    
8303        runScript({
8304            .code = R"NKSP_CODE(
8305    on init
8306      exit( in_range(3Hz,2s,5Hz) )
8307    end on
8308    )NKSP_CODE",
8309            .expectParseError = true // in_range() throws error if not all arguments' unit types equal
8310        });
8311    
8312        runScript({
8313            .code = R"NKSP_CODE(
8314    on init
8315      exit( in_range(3Hz,2Hz,5s) )
8316    end on
8317    )NKSP_CODE",
8318            .expectParseError = true // in_range() throws error if not all arguments' unit types equal
8319        });
8320    
8321        // 'final' ('!') operator tests ...
8322        // (result should always be NOT final)
8323    
8324        runScript({
8325            .code = R"NKSP_CODE(
8326    on init
8327      exit( in_range(!9,!4,!9) )
8328    end on
8329    )NKSP_CODE",
8330            .expectBoolExitResult = true,
8331            .expectExitResultFinal = false
8332        });
8333    
8334      #if !SILENT_TEST      #if !SILENT_TEST
8335      std::cout << std::endl;      std::cout << std::endl;
8336      #endif      #endif
# Line 1500  static void testBuiltInRandomFunction() Line 8341  static void testBuiltInRandomFunction()
8341      std::cout << "UNIT TEST: built-in random() function\n";      std::cout << "UNIT TEST: built-in random() function\n";
8342      #endif      #endif
8343    
8344        // integer tests ...
8345    
8346        runScript({
8347            .code = R"NKSP_CODE(
8348    on init
8349      exit( random(-5,5) )
8350    end on
8351    )NKSP_CODE",
8352            .expectExitResultIsInt = true // only check type, exact value is irrelevant here
8353        });
8354    
8355      for (int run = 0; run < 20; ++run) {      for (int run = 0; run < 20; ++run) {
8356          runScript({          runScript({
8357              .code = R"NKSP_CODE(              .code = R"NKSP_CODE(
# Line 1512  end on Line 8364  end on
8364          });          });
8365      }      }
8366    
8367        // real number tests ...
8368    
8369        runScript({
8370            .code = R"NKSP_CODE(
8371    on init
8372      exit( random(-0.5,0.5) )
8373    end on
8374    )NKSP_CODE",
8375            .expectExitResultIsReal = true // only check type, exact value is irrelevant here
8376        });
8377    
8378        runScript({
8379            .code = R"NKSP_CODE(
8380    on init
8381      declare ~foo := random(-5.0,5.0)
8382      exit(~foo)
8383    end on
8384    )NKSP_CODE",
8385            .expectExitResultIsReal = true // only check type, exact value is irrelevant here
8386        });
8387    
8388        for (int run = 0; run < 20; ++run) {
8389            runScript({
8390                .code = R"NKSP_CODE(
8391    on init
8392      declare ~foo := random(-0.5,0.5)
8393      exit( in_range(~foo,-0.5,0.5) )
8394    end on
8395    )NKSP_CODE",
8396                .expectBoolExitResult = true
8397            });
8398        }
8399    
8400        for (int run = 0; run < 20; ++run) {
8401            runScript({
8402                .code = R"NKSP_CODE(
8403    on init
8404      declare ~foo := random(-5.0,12.0)
8405      exit( in_range(~foo,-5.0,12.0) )
8406    end on
8407    )NKSP_CODE",
8408                .expectBoolExitResult = true
8409            });
8410        }
8411    
8412        for (int run = 0; run < 20; ++run) {
8413            runScript({
8414                .code = R"NKSP_CODE(
8415    on init
8416      declare ~foo := random(23.3,98.4)
8417      exit( in_range(~foo,23.3,98.4) )
8418    end on
8419    )NKSP_CODE",
8420                .expectBoolExitResult = true
8421            });
8422        }
8423    
8424        // std unit tests ...
8425    
8426        runScript({
8427            .code = R"NKSP_CODE(
8428    on init
8429      exit( random(-5Hz,5Hz) )
8430    end on
8431    )NKSP_CODE",
8432            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8433            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
8434            .expectExitResultUnit = VM_HERTZ
8435        });
8436    
8437        for (int run = 0; run < 20; ++run) {
8438            runScript({
8439                .code = R"NKSP_CODE(
8440    on init
8441      declare $foo := random(-5Hz,5Hz)
8442      exit( in_range($foo,-5Hz,5Hz) )
8443    end on
8444    )NKSP_CODE",
8445                .expectBoolExitResult = true
8446            });
8447        }
8448    
8449        runScript({
8450            .code = R"NKSP_CODE(
8451    on init
8452      exit( random(5us,1ms) )
8453    end on
8454    )NKSP_CODE",
8455            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8456            .expectExitResultUnitPrefix = { VM_MICRO },
8457            .expectExitResultUnit = VM_SECOND
8458        });
8459    
8460        for (int run = 0; run < 20; ++run) {
8461            runScript({
8462                .code = R"NKSP_CODE(
8463    on init
8464      declare $foo := random(5us,1ms)
8465      exit( in_range($foo,5us,1ms) )
8466    end on
8467    )NKSP_CODE",
8468                .expectBoolExitResult = true
8469            });
8470        }
8471    
8472        runScript({
8473            .code = R"NKSP_CODE(
8474    on init
8475      exit( random(1ms,5000us) )
8476    end on
8477    )NKSP_CODE",
8478            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8479            .expectExitResultUnitPrefix = { VM_MICRO },
8480            .expectExitResultUnit = VM_SECOND
8481        });
8482    
8483        for (int run = 0; run < 20; ++run) {
8484            runScript({
8485                .code = R"NKSP_CODE(
8486    on init
8487      declare $foo := random(1ms,5000us)
8488      exit( in_range($foo,1ms,5000us) )
8489    end on
8490    )NKSP_CODE",
8491                .expectBoolExitResult = true
8492            });
8493        }
8494    
8495        runScript({
8496            .code = R"NKSP_CODE(
8497    on init
8498      exit( random(1kHz,20kHz) )
8499    end on
8500    )NKSP_CODE",
8501            .expectExitResultIsInt = true, // only check type, exact value is irrelevant here
8502            .expectExitResultUnitPrefix = { VM_KILO },
8503            .expectExitResultUnit = VM_HERTZ
8504        });
8505    
8506        for (int run = 0; run < 20; ++run) {
8507            runScript({
8508                .code = R"NKSP_CODE(
8509    on init
8510      declare $foo := random(1kHz,20kHz)
8511      exit( in_range($foo,1kHz,20kHz) )
8512    end on
8513    )NKSP_CODE",
8514                .expectBoolExitResult = true
8515            });
8516        }
8517    
8518        runScript({
8519            .code = R"NKSP_CODE(
8520    on init
8521      exit( random(1.2us,3.5us) )
8522    end on
8523    )NKSP_CODE",
8524            .expectExitResultIsReal = true, // only check type, exact value is irrelevant here
8525            .expectExitResultUnitPrefix = { VM_MICRO },
8526            .expectExitResultUnit = VM_SECOND
8527        });
8528    
8529        for (int run = 0; run < 20; ++run) {
8530            runScript({
8531                .code = R"NKSP_CODE(
8532    on init
8533      declare ~foo := random(1.2us,3.5us)
8534      exit( in_range(~foo,1.2us,3.5us) )
8535    end on
8536    )NKSP_CODE",
8537                .expectBoolExitResult = true
8538            });
8539        }
8540    
8541        runScript({
8542            .code = R"NKSP_CODE(
8543    on init
8544      exit( random(5.2us,1.1ms) )
8545    end on
8546    )NKSP_CODE",
8547            .expectExitResultIsReal = true, // only check type, exact value is irrelevant here
8548            .expectExitResultUnitPrefix = { VM_MICRO },
8549            .expectExitResultUnit = VM_SECOND
8550        });
8551    
8552        for (int run = 0; run < 20; ++run) {
8553            runScript({
8554                .code = R"NKSP_CODE(
8555    on init
8556      declare ~foo := random(5.2us,1.1ms)
8557      exit( in_range(~foo,5.2us,1.1ms) )
8558    end on
8559    )NKSP_CODE",
8560                .expectBoolExitResult = true
8561            });
8562        }
8563    
8564        runScript({
8565            .code = R"NKSP_CODE(
8566    on init
8567      exit( random(1Hz,12s) )
8568    end on
8569    )NKSP_CODE",
8570            .expectParseError = true // random() throws error if arguments' unit types don't match
8571        });
8572    
8573        runScript({
8574            .code = R"NKSP_CODE(
8575    on init
8576      exit( random(1,12s) )
8577    end on
8578    )NKSP_CODE",
8579            .expectParseError = true // random() throws error if arguments' unit types don't match
8580        });
8581    
8582        runScript({
8583            .code = R"NKSP_CODE(
8584    on init
8585      exit( random(1s,12) )
8586    end on
8587    )NKSP_CODE",
8588            .expectParseError = true // random() throws error if arguments' unit types don't match
8589        });
8590    
8591        // 'final' ('!') operator tests ...
8592    
8593        runScript({
8594            .code = R"NKSP_CODE(
8595    on init
8596      exit( random(!1,!12) )
8597    end on
8598    )NKSP_CODE",
8599            .expectExitResultFinal = true
8600        });
8601    
8602        runScript({
8603            .code = R"NKSP_CODE(
8604    on init
8605      exit( random(1,12) )
8606    end on
8607    )NKSP_CODE",
8608            .expectExitResultFinal = false
8609        });
8610    
8611        runScript({
8612            .code = R"NKSP_CODE(
8613    on init
8614      exit( random(!1,12) )
8615    end on
8616    )NKSP_CODE",
8617            .expectExitResultFinal = true,
8618            .expectParseWarning = true // random() warns if only one argument is 'final'
8619        });
8620    
8621        runScript({
8622            .code = R"NKSP_CODE(
8623    on init
8624      exit( random(1,!12) )
8625    end on
8626    )NKSP_CODE",
8627            .expectExitResultFinal = true,
8628            .expectParseWarning = true // random() warns if only one argument is 'final'
8629        });
8630    
8631      #if !SILENT_TEST      #if !SILENT_TEST
8632      std::cout << std::endl;      std::cout << std::endl;
8633      #endif      #endif
# Line 1618  end on Line 8734  end on
8734      #endif      #endif
8735  }  }
8736    
8737    static void testBuiltInMsbFunction() {
8738        #if !SILENT_TEST
8739        std::cout << "UNIT TEST: built-in msb() function\n";
8740        #endif
8741    
8742        runScript({
8743            .code = R"NKSP_CODE(
8744    on init
8745      exit( msb(0) )
8746    end on
8747    )NKSP_CODE",
8748            .expectIntExitResult = 0
8749        });
8750    
8751        runScript({
8752            .code = R"NKSP_CODE(
8753    on init
8754      exit( msb(127) )
8755    end on
8756    )NKSP_CODE",
8757            .expectIntExitResult = 0
8758        });
8759    
8760        runScript({
8761            .code = R"NKSP_CODE(
8762    on init
8763      exit( msb(128) )
8764    end on
8765    )NKSP_CODE",
8766            .expectIntExitResult = 1
8767        });
8768    
8769        runScript({
8770            .code = R"NKSP_CODE(
8771    on init
8772      exit( msb(16255) )
8773    end on
8774    )NKSP_CODE",
8775            .expectIntExitResult = 126
8776        });
8777    
8778        runScript({
8779            .code = R"NKSP_CODE(
8780    on init
8781      exit( msb(16256) )
8782    end on
8783    )NKSP_CODE",
8784            .expectIntExitResult = 127
8785        });
8786    
8787        runScript({
8788            .code = R"NKSP_CODE(
8789    on init
8790      exit( msb(16383) )
8791    end on
8792    )NKSP_CODE",
8793            .expectIntExitResult = 127
8794        });
8795    
8796        #if !SILENT_TEST
8797        std::cout << std::endl;
8798        #endif
8799    }
8800    
8801    static void testBuiltInLsbFunction() {
8802        #if !SILENT_TEST
8803        std::cout << "UNIT TEST: built-in lsb() function\n";
8804        #endif
8805    
8806        runScript({
8807            .code = R"NKSP_CODE(
8808    on init
8809      exit( lsb(0) )
8810    end on
8811    )NKSP_CODE",
8812            .expectIntExitResult = 0
8813        });
8814    
8815        runScript({
8816            .code = R"NKSP_CODE(
8817    on init
8818      exit( lsb(1) )
8819    end on
8820    )NKSP_CODE",
8821            .expectIntExitResult = 1
8822        });
8823    
8824        runScript({
8825            .code = R"NKSP_CODE(
8826    on init
8827      exit( lsb(126) )
8828    end on
8829    )NKSP_CODE",
8830            .expectIntExitResult = 126
8831        });
8832    
8833        runScript({
8834            .code = R"NKSP_CODE(
8835    on init
8836      exit( lsb(127) )
8837    end on
8838    )NKSP_CODE",
8839            .expectIntExitResult = 127
8840        });
8841    
8842        runScript({
8843            .code = R"NKSP_CODE(
8844    on init
8845      exit( lsb(128) )
8846    end on
8847    )NKSP_CODE",
8848            .expectIntExitResult = 0
8849        });
8850    
8851        runScript({
8852            .code = R"NKSP_CODE(
8853    on init
8854      exit( lsb(16255) )
8855    end on
8856    )NKSP_CODE",
8857            .expectIntExitResult = 127
8858        });
8859    
8860        runScript({
8861            .code = R"NKSP_CODE(
8862    on init
8863      exit( lsb(16256) )
8864    end on
8865    )NKSP_CODE",
8866            .expectIntExitResult = 0
8867        });
8868    
8869        #if !SILENT_TEST
8870        std::cout << std::endl;
8871        #endif
8872    }
8873    
8874    static void testBuiltInIntToRealFunction() {
8875        #if !SILENT_TEST
8876        std::cout << "UNIT TEST: built-in int_to_real() function\n";
8877        #endif
8878    
8879        runScript({
8880            .code = R"NKSP_CODE(
8881    on init
8882      exit( int_to_real(8) )
8883    end on
8884    )NKSP_CODE",
8885            .expectRealExitResult = 8.0
8886        });
8887    
8888        runScript({
8889            .code = R"NKSP_CODE(
8890    on init
8891      declare $foo := 23
8892      exit( int_to_real($foo) )
8893    end on
8894    )NKSP_CODE",
8895            .expectRealExitResult = 23.0
8896        });
8897    
8898        // std unit tests ...
8899    
8900        runScript({
8901            .code = R"NKSP_CODE(
8902    on init
8903      exit( int_to_real(-58mdB) )
8904    end on
8905    )NKSP_CODE",
8906            .expectRealExitResult = -58.0,
8907            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
8908            .expectExitResultUnit = VM_BEL
8909        });
8910    
8911        runScript({
8912            .code = R"NKSP_CODE(
8913    on init
8914      declare $foo := -58mdB
8915      exit( int_to_real($foo) )
8916    end on
8917    )NKSP_CODE",
8918            .expectRealExitResult = -58.0,
8919            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
8920            .expectExitResultUnit = VM_BEL
8921        });
8922    
8923        runScript({
8924            .code = R"NKSP_CODE(
8925    on init
8926      declare $foo := 7000ms
8927      exit( int_to_real($foo) )
8928    end on
8929    )NKSP_CODE",
8930            .expectRealExitResult = 7000.0,
8931            .expectExitResultUnitPrefix = { VM_MILLI },
8932            .expectExitResultUnit = VM_SECOND
8933        });
8934    
8935        runScript({
8936            .code = R"NKSP_CODE(
8937    on init
8938      declare $foo := 7000ms
8939      declare @s := "" & int_to_real($foo)
8940      exit( @s )
8941    end on
8942    )NKSP_CODE",
8943            .expectStringExitResult = "7000ms",
8944        });
8945    
8946        runScript({
8947            .code = R"NKSP_CODE(
8948    on init
8949      declare $foo := 700ms
8950      exit( int_to_real($foo) / 7.0 )
8951    end on
8952    )NKSP_CODE",
8953            .expectRealExitResult = 100.0,
8954            .expectExitResultUnitPrefix = { VM_MILLI },
8955            .expectExitResultUnit = VM_SECOND
8956        });
8957    
8958        runScript({
8959            .code = R"NKSP_CODE(
8960    on init
8961      declare $foo := 700ms
8962      exit( int_to_real($foo) / 7.0 & "" )
8963    end on
8964    )NKSP_CODE",
8965            .expectStringExitResult = "100ms"
8966        });
8967    
8968        // 'final' ('!') operator tests ...
8969    
8970        runScript({
8971            .code = R"NKSP_CODE(
8972    on init
8973      declare $foo := !-58
8974      exit( int_to_real($foo) )
8975    end on
8976    )NKSP_CODE",
8977            .expectRealExitResult = -58.0,
8978            .expectExitResultFinal = true
8979        });
8980    
8981        runScript({
8982            .code = R"NKSP_CODE(
8983    on init
8984      declare $foo := -58
8985      exit( int_to_real($foo) )
8986    end on
8987    )NKSP_CODE",
8988            .expectRealExitResult = -58.0,
8989            .expectExitResultFinal = false
8990        });
8991    
8992        #if !SILENT_TEST
8993        std::cout << std::endl;
8994        #endif
8995    }
8996    
8997    static void testBuiltInRealFunction() {
8998        #if !SILENT_TEST
8999        std::cout << "UNIT TEST: built-in real() function\n";
9000        #endif
9001    
9002        runScript({
9003            .code = R"NKSP_CODE(
9004    on init
9005      exit( real(8) )
9006    end on
9007    )NKSP_CODE",
9008            .expectRealExitResult = 8.0
9009        });
9010    
9011        runScript({
9012            .code = R"NKSP_CODE(
9013    on init
9014      declare $foo := 23
9015      exit( real($foo) )
9016    end on
9017    )NKSP_CODE",
9018            .expectRealExitResult = 23.0
9019        });
9020    
9021        // std unit tests ...
9022    
9023        runScript({
9024            .code = R"NKSP_CODE(
9025    on init
9026      exit( real(-58mdB) )
9027    end on
9028    )NKSP_CODE",
9029            .expectRealExitResult = -58.0,
9030            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9031            .expectExitResultUnit = VM_BEL
9032        });
9033    
9034        runScript({
9035            .code = R"NKSP_CODE(
9036    on init
9037      declare $foo := -58mdB
9038      exit( real($foo) )
9039    end on
9040    )NKSP_CODE",
9041            .expectRealExitResult = -58.0,
9042            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9043            .expectExitResultUnit = VM_BEL
9044        });
9045    
9046        runScript({
9047            .code = R"NKSP_CODE(
9048    on init
9049      declare $foo := 7000ms
9050      exit( real($foo) )
9051    end on
9052    )NKSP_CODE",
9053            .expectRealExitResult = 7000.0,
9054            .expectExitResultUnitPrefix = { VM_MILLI },
9055            .expectExitResultUnit = VM_SECOND
9056        });
9057    
9058        runScript({
9059            .code = R"NKSP_CODE(
9060    on init
9061      declare $foo := 7000ms
9062      declare @s := "" & real($foo)
9063      exit( @s )
9064    end on
9065    )NKSP_CODE",
9066            .expectStringExitResult = "7000ms",
9067        });
9068    
9069        runScript({
9070            .code = R"NKSP_CODE(
9071    on init
9072      declare $foo := 700ms
9073      exit( real($foo) / 7.0 )
9074    end on
9075    )NKSP_CODE",
9076            .expectRealExitResult = 100.0,
9077            .expectExitResultUnitPrefix = { VM_MILLI },
9078            .expectExitResultUnit = VM_SECOND
9079        });
9080    
9081        runScript({
9082            .code = R"NKSP_CODE(
9083    on init
9084      declare $foo := 700ms
9085      exit( real($foo) / 7.0 & "" )
9086    end on
9087    )NKSP_CODE",
9088            .expectStringExitResult = "100ms"
9089        });
9090    
9091        // 'final' ('!') operator tests ...
9092    
9093        runScript({
9094            .code = R"NKSP_CODE(
9095    on init
9096      declare $foo := !-58
9097      exit( real($foo) )
9098    end on
9099    )NKSP_CODE",
9100            .expectRealExitResult = -58.0,
9101            .expectExitResultFinal = true
9102        });
9103    
9104        runScript({
9105            .code = R"NKSP_CODE(
9106    on init
9107      declare $foo := -58
9108      exit( real($foo) )
9109    end on
9110    )NKSP_CODE",
9111            .expectRealExitResult = -58.0,
9112            .expectExitResultFinal = false
9113        });
9114    
9115        #if !SILENT_TEST
9116        std::cout << std::endl;
9117        #endif
9118    }
9119    
9120    static void testBuiltInRealToIntFunction() {
9121        #if !SILENT_TEST
9122        std::cout << "UNIT TEST: built-in real_to_int() function\n";
9123        #endif
9124    
9125        runScript({
9126            .code = R"NKSP_CODE(
9127    on init
9128      exit( real_to_int(8.9) )
9129    end on
9130    )NKSP_CODE",
9131            .expectIntExitResult = 8
9132        });
9133    
9134        runScript({
9135            .code = R"NKSP_CODE(
9136    on init
9137      declare ~foo := 8.9
9138      exit( real_to_int(~foo) )
9139    end on
9140    )NKSP_CODE",
9141            .expectIntExitResult = 8
9142        });
9143    
9144        // std unit tests ...
9145    
9146        runScript({
9147            .code = R"NKSP_CODE(
9148    on init
9149      declare ~foo := 8.9mdB
9150      exit( real_to_int(~foo) )
9151    end on
9152    )NKSP_CODE",
9153            .expectIntExitResult = 8,
9154            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9155            .expectExitResultUnit = VM_BEL
9156        });
9157    
9158        runScript({
9159            .code = R"NKSP_CODE(
9160    on init
9161      declare ~foo := 9000.0us
9162      exit( real_to_int(~foo) )
9163    end on
9164    )NKSP_CODE",
9165            .expectIntExitResult = 9000.0,
9166            .expectExitResultUnitPrefix = { VM_MICRO },
9167            .expectExitResultUnit = VM_SECOND
9168        });
9169    
9170        runScript({
9171            .code = R"NKSP_CODE(
9172    on init
9173      declare ~foo := 9000.0us
9174      declare @s := "" & real_to_int(~foo)
9175      exit( @s )
9176    end on
9177    )NKSP_CODE",
9178            .expectStringExitResult = "9000us",
9179        });
9180    
9181        runScript({
9182            .code = R"NKSP_CODE(
9183    on init
9184      declare ~foo := 700.0ms
9185      exit( real_to_int(~foo) / 7 )
9186    end on
9187    )NKSP_CODE",
9188            .expectIntExitResult = 100,
9189            .expectExitResultUnitPrefix = { VM_MILLI },
9190            .expectExitResultUnit = VM_SECOND
9191        });
9192    
9193        runScript({
9194            .code = R"NKSP_CODE(
9195    on init
9196      declare ~foo := 700.0ms
9197      exit( real_to_int(~foo) / 7 & "" )
9198    end on
9199    )NKSP_CODE",
9200            .expectStringExitResult = "100ms"
9201        });
9202    
9203        // 'final' ('!') operator tests ...
9204    
9205        runScript({
9206            .code = R"NKSP_CODE(
9207    on init
9208      declare ~foo := !8.9
9209      exit( real_to_int(~foo) )
9210    end on
9211    )NKSP_CODE",
9212            .expectIntExitResult = 8,
9213            .expectExitResultFinal = true
9214        });
9215    
9216        runScript({
9217            .code = R"NKSP_CODE(
9218    on init
9219      declare ~foo := 8.9
9220      exit( real_to_int(~foo) )
9221    end on
9222    )NKSP_CODE",
9223            .expectIntExitResult = 8,
9224            .expectExitResultFinal = false
9225        });
9226    
9227        #if !SILENT_TEST
9228        std::cout << std::endl;
9229        #endif
9230    }
9231    
9232    static void testBuiltInIntFunction() {
9233        #if !SILENT_TEST
9234        std::cout << "UNIT TEST: built-in int() function\n";
9235        #endif
9236    
9237        runScript({
9238            .code = R"NKSP_CODE(
9239    on init
9240      exit( int(8.9) )
9241    end on
9242    )NKSP_CODE",
9243            .expectIntExitResult = 8
9244        });
9245    
9246        runScript({
9247            .code = R"NKSP_CODE(
9248    on init
9249      declare ~foo := 8.9
9250      exit( int(~foo) )
9251    end on
9252    )NKSP_CODE",
9253            .expectIntExitResult = 8
9254        });
9255    
9256        // std unit tests ...
9257    
9258        runScript({
9259            .code = R"NKSP_CODE(
9260    on init
9261      declare ~foo := 8.9mdB
9262      exit( int(~foo) )
9263    end on
9264    )NKSP_CODE",
9265            .expectIntExitResult = 8,
9266            .expectExitResultUnitPrefix = { VM_MILLI, VM_DECI },
9267            .expectExitResultUnit = VM_BEL
9268        });
9269    
9270        runScript({
9271            .code = R"NKSP_CODE(
9272    on init
9273      declare ~foo := 9000.0us
9274      exit( int(~foo) )
9275    end on
9276    )NKSP_CODE",
9277            .expectIntExitResult = 9000.0,
9278            .expectExitResultUnitPrefix = { VM_MICRO },
9279            .expectExitResultUnit = VM_SECOND
9280        });
9281    
9282        runScript({
9283            .code = R"NKSP_CODE(
9284    on init
9285      declare ~foo := 9000.0us
9286      declare @s := "" & int(~foo)
9287      exit( @s )
9288    end on
9289    )NKSP_CODE",
9290            .expectStringExitResult = "9000us",
9291        });
9292    
9293        runScript({
9294            .code = R"NKSP_CODE(
9295    on init
9296      declare ~foo := 700.0ms
9297      exit( int(~foo) / 7 )
9298    end on
9299    )NKSP_CODE",
9300            .expectIntExitResult = 100,
9301            .expectExitResultUnitPrefix = { VM_MILLI },
9302            .expectExitResultUnit = VM_SECOND
9303        });
9304    
9305        runScript({
9306            .code = R"NKSP_CODE(
9307    on init
9308      declare ~foo := 700.0ms
9309      exit( int(~foo) / 7 & "" )
9310    end on
9311    )NKSP_CODE",
9312            .expectStringExitResult = "100ms"
9313        });
9314    
9315        // 'final' ('!') operator tests ...
9316    
9317        runScript({
9318            .code = R"NKSP_CODE(
9319    on init
9320      declare ~foo := !8.9
9321      exit( int(~foo) )
9322    end on
9323    )NKSP_CODE",
9324            .expectIntExitResult = 8,
9325            .expectExitResultFinal = true
9326        });
9327    
9328        runScript({
9329            .code = R"NKSP_CODE(
9330    on init
9331      declare ~foo := 8.9
9332      exit( int(~foo) )
9333    end on
9334    )NKSP_CODE",
9335            .expectIntExitResult = 8,
9336            .expectExitResultFinal = false
9337        });
9338    
9339        #if !SILENT_TEST
9340        std::cout << std::endl;
9341        #endif
9342    }
9343    
9344  static void testBuiltInArrayEqualFunction() {  static void testBuiltInArrayEqualFunction() {
9345      #if !SILENT_TEST      #if !SILENT_TEST
9346      std::cout << "UNIT TEST: built-in array_equal() function\n";      std::cout << "UNIT TEST: built-in array_equal() function\n";
9347      #endif      #endif
9348    
9349        // integer array tests ...
9350    
9351      runScript({      runScript({
9352          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
9353  on init  on init
# Line 1675  on init Line 9400  on init
9400    exit( array_equal(%foo, %bar) )    exit( array_equal(%foo, %bar) )
9401  end on  end on
9402  )NKSP_CODE",  )NKSP_CODE",
9403            .expectBoolExitResult = false,
9404            .expectParseWarning = true // array_equal() warns if array sizes do not match
9405        });
9406    
9407        // real number array tests ...
9408    
9409        runScript({
9410            .code = R"NKSP_CODE(
9411    on init
9412      declare ?foo[3] := ( 1.0, 2.0, 3.0 )
9413      declare ?bar[3] := ( 1.0, 2.0, 3.0 )
9414      exit( array_equal(?foo, ?bar) )
9415    end on
9416    )NKSP_CODE",
9417            .expectBoolExitResult = true
9418        });
9419    
9420        runScript({
9421            .code = R"NKSP_CODE(
9422    on init
9423      declare ?foo[3] := ( 1.0, 1.1, 3.4 )
9424      declare ?bar[3] := ( 1.0, 1.1, 3.4 )
9425      exit( array_equal(?foo, ?bar) )
9426    end on
9427    )NKSP_CODE",
9428            .expectBoolExitResult = true
9429        });
9430    
9431        runScript({
9432            .code = R"NKSP_CODE(
9433    on init
9434      declare ?foo[3] := ( 1.0, 1.1, 3.4 )
9435      declare ?bar[3] := ( 1.0, 1.2, 3.4 )
9436      exit( array_equal(?foo, ?bar) )
9437    end on
9438    )NKSP_CODE",
9439            .expectBoolExitResult = false
9440        });
9441    
9442        runScript({
9443            .code = R"NKSP_CODE(
9444    on init
9445      declare ?foo[3] := ( 1.0, 1.1, 3.4 )
9446      declare ?bar[2] := ( 1.0, 1.1 )
9447      exit( array_equal(?foo, ?bar) )
9448    end on
9449    )NKSP_CODE",
9450            .expectBoolExitResult = false,
9451            .expectParseWarning = true // array_equal() warns if array sizes do not match
9452        });
9453    
9454        // std unit tests ...
9455        // (only metric prefixes allowed, unit types are prohibited for arrays ATM)
9456    
9457        runScript({
9458            .code = R"NKSP_CODE(
9459    on init
9460      declare %foo[3] := ( 1, 1s, 1 )
9461      declare %bar[3] := ( 1, 1,  1 )
9462      exit( array_equal(%foo, %bar) )
9463    end on
9464    )NKSP_CODE",
9465            .expectParseError = true // see comment above
9466        });
9467    
9468        runScript({
9469            .code = R"NKSP_CODE(
9470    on init
9471      declare %foo[3] := ( 1k, 1, 1m )
9472      declare %bar[3] := ( 1k, 1, 1m )
9473      exit( array_equal(%foo, %bar) )
9474    end on
9475    )NKSP_CODE",
9476            .expectBoolExitResult = true
9477        });
9478    
9479        runScript({
9480            .code = R"NKSP_CODE(
9481    on init
9482      declare %foo[3] := ( 1m, 1, 1k )
9483      declare %bar[3] := ( 1k, 1, 1m )
9484      exit( array_equal(%foo, %bar) )
9485    end on
9486    )NKSP_CODE",
9487            .expectBoolExitResult = false
9488        });
9489    
9490        runScript({
9491            .code = R"NKSP_CODE(
9492    on init
9493      declare %foo[3] := ( 1, 1k, 1 )
9494      declare %bar[3] := ( 1, 1,  1 )
9495      exit( array_equal(%foo, %bar) )
9496    end on
9497    )NKSP_CODE",
9498            .expectBoolExitResult = false
9499        });
9500    
9501        runScript({
9502            .code = R"NKSP_CODE(
9503    on init
9504      declare %foo[3] := ( 1, 1k, 1 )
9505      declare %bar[3] := ( 1, 1000, 1 )
9506      exit( array_equal(%foo, %bar) )
9507    end on
9508    )NKSP_CODE",
9509            .expectBoolExitResult = true
9510        });
9511    
9512        runScript({
9513            .code = R"NKSP_CODE(
9514    on init
9515      declare %foo[3] := ( 1, 2, 3000 )
9516      declare %bar[3] := ( 1, 2, 3k )
9517      exit( array_equal(%foo, %bar) )
9518    end on
9519    )NKSP_CODE",
9520            .expectBoolExitResult = true
9521        });
9522    
9523        runScript({
9524            .code = R"NKSP_CODE(
9525    on init
9526      declare %foo[3] := ( 1, 2, 3m )
9527      declare %bar[3] := ( 1, 2, 3k )
9528      exit( array_equal(%foo, %bar) )
9529    end on
9530    )NKSP_CODE",
9531            .expectBoolExitResult = false
9532        });
9533    
9534        runScript({
9535            .code = R"NKSP_CODE(
9536    on init
9537      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9538      declare ?bar[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9539      exit( array_equal(?foo, ?bar) )
9540    end on
9541    )NKSP_CODE",
9542            .expectBoolExitResult = true
9543        });
9544    
9545        runScript({
9546            .code = R"NKSP_CODE(
9547    on init
9548      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9549      declare ?bar[4] := ( 1.0, 1.0 , 1.1m, 3.4k )
9550      exit( array_equal(?foo, ?bar) )
9551    end on
9552    )NKSP_CODE",
9553            .expectBoolExitResult = false
9554        });
9555    
9556        runScript({
9557            .code = R"NKSP_CODE(
9558    on init
9559      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9560      declare ?bar[4] := ( 1.0, 1.0m, 1.1k, 3.4k )
9561      exit( array_equal(?foo, ?bar) )
9562    end on
9563    )NKSP_CODE",
9564            .expectBoolExitResult = false
9565        });
9566    
9567        runScript({
9568            .code = R"NKSP_CODE(
9569    on init
9570      declare ?foo[4] := ( 1.0, 1.0m, 1.1m, 3.4k )
9571      declare ?bar[4] := ( 1.0, 1.0m, 1.1m, 3.4u )
9572      exit( array_equal(?foo, ?bar) )
9573    end on
9574    )NKSP_CODE",
9575            .expectBoolExitResult = false
9576        });
9577    
9578        runScript({
9579            .code = R"NKSP_CODE(
9580    on init
9581      declare ?foo[3] := ( 1.0, 1.0k, 1.1m )
9582      declare ?bar[3] := ( 1.0, 1000.0, 1.1m )
9583      exit( array_equal(?foo, ?bar) )
9584    end on
9585    )NKSP_CODE",
9586            .expectBoolExitResult = true
9587        });
9588    
9589        runScript({
9590            .code = R"NKSP_CODE(
9591    on init
9592      declare ?foo[3] := ( 1.0, 1.0k, 1.1u )
9593      declare ?bar[3] := ( 1.0, 1000.0, 0.0011m )
9594      exit( array_equal(?foo, ?bar) )
9595    end on
9596    )NKSP_CODE",
9597            .expectBoolExitResult = true
9598        });
9599    
9600        runScript({
9601            .code = R"NKSP_CODE(
9602    on init
9603      declare ?foo[3] := ( 1.0, 1.0k, 1.1u )
9604      declare ?bar[3] := ( 1.0, 1000.0, 0.0016m )
9605      exit( array_equal(?foo, ?bar) )
9606    end on
9607    )NKSP_CODE",
9608          .expectBoolExitResult = false          .expectBoolExitResult = false
9609      });      });
9610    
9611        // 'final' ('!') operator tests ...
9612        // (currently prohibited for arrays)
9613    
9614        runScript({
9615            .code = R"NKSP_CODE(
9616    on init
9617      declare %foo[3] := ( !1, !1, !1 )
9618      declare %bar[3] := ( !1, !1, !1 )
9619      exit( array_equal(%foo, %bar) )
9620    end on
9621    )NKSP_CODE",
9622            .expectParseError = true // see comment above
9623        });
9624    
9625        runScript({
9626            .code = R"NKSP_CODE(
9627    on init
9628      declare ?foo[3] := ( !1.0, !1.0, !1.0 )
9629      declare ?bar[3] := ( !1.0, !1.0, !1.0 )
9630      exit( array_equal(?foo, ?bar) )
9631    end on
9632    )NKSP_CODE",
9633            .expectParseError = true // see comment above
9634        });
9635    
9636      #if !SILENT_TEST      #if !SILENT_TEST
9637      std::cout << std::endl;      std::cout << std::endl;
9638      #endif      #endif
# Line 1688  static void testBuiltInSortFunction() { Line 9643  static void testBuiltInSortFunction() {
9643      std::cout << "UNIT TEST: built-in sort() function\n";      std::cout << "UNIT TEST: built-in sort() function\n";
9644      #endif      #endif
9645    
9646        // integer array tests ...
9647    
9648      runScript({      runScript({
9649          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
9650  on init  on init
# Line 1712  end on Line 9669  end on
9669          .expectBoolExitResult = true          .expectBoolExitResult = true
9670      });      });
9671    
9672        runScript({
9673            .code = R"NKSP_CODE(
9674    on init
9675      declare %input[6] := ( 1, 80, 120, 40, 3000, 20 )
9676      declare %expected[6] := ( 1, 20, 40, 80, 120, 3000  )
9677      sort(%input, 0)
9678      exit( array_equal(%input, %expected) )
9679    end on
9680    )NKSP_CODE",
9681            .expectBoolExitResult = true
9682        });
9683    
9684        // real number array tests ...
9685    
9686        runScript({
9687            .code = R"NKSP_CODE(
9688    on init
9689      declare ?input[4] := ( 1.4, 1.0, 13.4, 2.7 )
9690      declare ?expected[4] := ( 1.0, 1.4, 2.7, 13.4 )
9691      sort(?input, 0)
9692      exit( array_equal(?input, ?expected) )
9693    end on
9694    )NKSP_CODE",
9695            .expectBoolExitResult = true
9696        });
9697    
9698        runScript({
9699            .code = R"NKSP_CODE(
9700    on init
9701      declare ?input[4] := ( 1.4, 1.0, 13.4, 2.7 )
9702      declare ?expected[4] := ( 13.4, 2.7, 1.4, 1.0 )
9703      sort(?input, 1)
9704      exit( array_equal(?input, ?expected) )
9705    end on
9706    )NKSP_CODE",
9707            .expectBoolExitResult = true
9708        });
9709    
9710        // std unit tests ...
9711        // (only metric prefixes are allowed for arrays ATM)
9712    
9713        runScript({
9714            .code = R"NKSP_CODE(
9715    on init
9716      declare %input[3] := ( 1k, 6, 900 )
9717      declare %expected[3] := ( 6, 900, 1k )
9718      sort(%input, 0)
9719      exit( array_equal(%input, %expected) )
9720    end on
9721    )NKSP_CODE",
9722            .expectBoolExitResult = true
9723        });
9724    
9725        runScript({
9726            .code = R"NKSP_CODE(
9727    on init
9728      declare %input[3] := ( 900, 1k, 6 )
9729      declare %expected[3] := ( 1k, 900, 6 )
9730      sort(%input, 1)
9731      exit( array_equal(%input, %expected) )
9732    end on
9733    )NKSP_CODE",
9734            .expectBoolExitResult = true
9735        });
9736    
9737        runScript({
9738            .code = R"NKSP_CODE(
9739    on init
9740      declare %input[6] := ( 1k, 8m, 4k, 12000u, 3000u, 1000u )
9741      declare %expected[6] := ( 1000u, 3000u, 8m, 12000u, 1k, 4k )
9742      sort(%input, 0)
9743      exit( array_equal(%input, %expected) )
9744    end on
9745    )NKSP_CODE",
9746            .expectBoolExitResult = true
9747        });
9748    
9749        runScript({
9750            .code = R"NKSP_CODE(
9751    on init
9752      declare ?input[3] := ( 1.0k, 6.0, 900.0 )
9753      declare ?expected[3] := ( 6.0, 900.0, 1.0k )
9754      sort(?input, 0)
9755      exit( array_equal(?input, ?expected) )
9756    end on
9757    )NKSP_CODE",
9758            .expectBoolExitResult = true
9759        });
9760    
9761        runScript({
9762            .code = R"NKSP_CODE(
9763    on init
9764      declare ?input[3] := ( 900.0, 1.0k, 6.0 )
9765      declare ?expected[3] := ( 1.0k, 900.0, 6.0 )
9766      sort(?input, 1)
9767      exit( array_equal(?input, ?expected) )
9768    end on
9769    )NKSP_CODE",
9770            .expectBoolExitResult = true
9771        });
9772    
9773        runScript({
9774            .code = R"NKSP_CODE(
9775    on init
9776      declare ?input[3] := ( 1.0k, 0.9k, 1.1k )
9777      declare ?expected[3] := ( 0.9k, 1.0k, 1.1k )
9778      sort(?input, 0)
9779      exit( array_equal(?input, ?expected) )
9780    end on
9781    )NKSP_CODE",
9782            .expectBoolExitResult = true
9783        });
9784    
9785        runScript({
9786            .code = R"NKSP_CODE(
9787    on init
9788      declare ?input[3] := ( 2.0m, 1000.1u, 1.0 )
9789      declare ?expected[3] := ( 1000.1u, 2.0m, 1.0 )
9790      sort(?input, 0)
9791      exit( array_equal(?input, ?expected) )
9792    end on
9793    )NKSP_CODE",
9794            .expectBoolExitResult = true
9795        });
9796    
9797        runScript({
9798            .code = R"NKSP_CODE(
9799    on init
9800      declare ?input[4] := ( 2.0m, 1000.1u, 1.0, 1400.0u )
9801      declare ?expected[4] := ( 1000.1u, 1400.0u, 2.0m, 1.0 )
9802      sort(?input, 0)
9803      exit( array_equal(?input, ?expected) )
9804    end on
9805    )NKSP_CODE",
9806            .expectBoolExitResult = true
9807        });
9808    
9809        runScript({
9810            .code = R"NKSP_CODE(
9811    on init
9812      declare ?input[4] := ( 2.0m, 1000.1u, 1.0, 1400.0u )
9813      declare ?expected[4] := ( 1.0, 2.0m, 1400.0u, 1000.1u )
9814      sort(?input, 1)
9815      exit( array_equal(?input, ?expected) )
9816    end on
9817    )NKSP_CODE",
9818            .expectBoolExitResult = true
9819        });
9820    
9821        runScript({
9822            .code = R"NKSP_CODE(
9823    on init
9824      declare ?input[6] := ( 0.9k, 8.0m, 1.1k, 12000.0u, 3000.0u, 1000.0u )
9825      declare ?expected[6] := ( 1000.0u, 3000.0u, 8.0m, 12000.0u, 0.9k, 1.1k )
9826      sort(?input, 0)
9827      exit( array_equal(?input, ?expected) )
9828    end on
9829    )NKSP_CODE",
9830            .expectBoolExitResult = true
9831        });
9832    
9833        runScript({
9834            .code = R"NKSP_CODE(
9835    on init
9836      declare ?input[6] := ( 0.9k, 8.0m, 1.1k, 12000.0u, 3000.0u, 1000.0u )
9837      declare ?expected[6] := ( 1.1k, 0.9k, 12000.0u, 8.0m, 3000.0u, 1000.0u )
9838      sort(?input, 1)
9839      exit( array_equal(?input, ?expected) )
9840    end on
9841    )NKSP_CODE",
9842            .expectBoolExitResult = true
9843        });
9844    
9845        #if !SILENT_TEST
9846        std::cout << std::endl;
9847        #endif
9848    }
9849    
9850    static void testBuiltInRoundFunction() {
9851        #if !SILENT_TEST
9852        std::cout << "UNIT TEST: built-in round() function\n";
9853        #endif
9854    
9855        // integer tests ...
9856        // (ATM not allowed for this function)
9857    
9858        runScript({
9859            .code = R"NKSP_CODE(
9860    on init
9861      declare $foo := 1
9862      exit( round($foo) )
9863    end on
9864    )NKSP_CODE",
9865            .expectParseError = true // integer not allowed for this function ATM
9866        });
9867    
9868        // real number tests ...
9869    
9870        runScript({
9871            .code = R"NKSP_CODE(
9872    on init
9873      exit( round(99.4) )
9874    end on
9875    )NKSP_CODE",
9876            .expectRealExitResult = 99.0
9877        });
9878    
9879        runScript({
9880            .code = R"NKSP_CODE(
9881    on init
9882      exit( round(99.5) )
9883    end on
9884    )NKSP_CODE",
9885            .expectRealExitResult = 100.0
9886        });
9887    
9888        // std unit tests ...
9889    
9890        runScript({
9891            .code = R"NKSP_CODE(
9892    on init
9893      exit( round(2.4ms) )
9894    end on
9895    )NKSP_CODE",
9896            .expectRealExitResult = 2.0,
9897            .expectExitResultUnitPrefix = { VM_MILLI },
9898            .expectExitResultUnit = VM_SECOND
9899        });
9900    
9901        runScript({
9902            .code = R"NKSP_CODE(
9903    on init
9904      exit( round(2.6kHz) )
9905    end on
9906    )NKSP_CODE",
9907            .expectRealExitResult = 3.0,
9908            .expectExitResultUnitPrefix = { VM_KILO },
9909            .expectExitResultUnit = VM_HERTZ
9910        });
9911    
9912        // 'final' ('!') operator tests ...
9913    
9914        runScript({
9915            .code = R"NKSP_CODE(
9916    on init
9917      exit( round(123.8) )
9918    end on
9919    )NKSP_CODE",
9920            .expectRealExitResult = 124.0,
9921            .expectExitResultFinal = false
9922        });
9923    
9924        runScript({
9925            .code = R"NKSP_CODE(
9926    on init
9927      exit( round(!123.8) )
9928    end on
9929    )NKSP_CODE",
9930            .expectRealExitResult = 124.0,
9931            .expectExitResultFinal = true
9932        });
9933    
9934        #if !SILENT_TEST
9935        std::cout << std::endl;
9936        #endif
9937    }
9938    
9939    static void testBuiltInCeilFunction() {
9940        #if !SILENT_TEST
9941        std::cout << "UNIT TEST: built-in ceil() function\n";
9942        #endif
9943    
9944        // integer tests ...
9945        // (ATM not allowed for this function)
9946    
9947        runScript({
9948            .code = R"NKSP_CODE(
9949    on init
9950      declare $foo := 1
9951      exit( ceil($foo) )
9952    end on
9953    )NKSP_CODE",
9954            .expectParseError = true // integer not allowed for this function ATM
9955        });
9956    
9957        // real number tests ...
9958    
9959        runScript({
9960            .code = R"NKSP_CODE(
9961    on init
9962      exit( ceil(99.0) )
9963    end on
9964    )NKSP_CODE",
9965            .expectRealExitResult = 99.0
9966        });
9967    
9968        runScript({
9969            .code = R"NKSP_CODE(
9970    on init
9971      exit( ceil(99.1) )
9972    end on
9973    )NKSP_CODE",
9974            .expectRealExitResult = 100.0
9975        });
9976    
9977        runScript({
9978            .code = R"NKSP_CODE(
9979    on init
9980      exit( ceil(99.9) )
9981    end on
9982    )NKSP_CODE",
9983            .expectRealExitResult = 100.0
9984        });
9985    
9986        // std unit tests ...
9987    
9988        runScript({
9989            .code = R"NKSP_CODE(
9990    on init
9991      exit( ceil(2.4ms) )
9992    end on
9993    )NKSP_CODE",
9994            .expectRealExitResult = 3.0,
9995            .expectExitResultUnitPrefix = { VM_MILLI },
9996            .expectExitResultUnit = VM_SECOND
9997        });
9998    
9999        runScript({
10000            .code = R"NKSP_CODE(
10001    on init
10002      exit( ceil(2.6kHz) )
10003    end on
10004    )NKSP_CODE",
10005            .expectRealExitResult = 3.0,
10006            .expectExitResultUnitPrefix = { VM_KILO },
10007            .expectExitResultUnit = VM_HERTZ
10008        });
10009    
10010        runScript({
10011            .code = R"NKSP_CODE(
10012    on init
10013      exit( ceil(9.4ms / 2.0) )
10014    end on
10015    )NKSP_CODE",
10016            .expectRealExitResult = 5.0,
10017            .expectExitResultUnitPrefix = { VM_MILLI },
10018            .expectExitResultUnit = VM_SECOND
10019        });
10020    
10021        runScript({
10022            .code = R"NKSP_CODE(
10023    on init
10024      exit( ceil( ceil(8.4us) / 2.0) )
10025    end on
10026    )NKSP_CODE",
10027            .expectRealExitResult = 5.0,
10028            .expectExitResultUnitPrefix = { VM_MICRO },
10029            .expectExitResultUnit = VM_SECOND
10030        });
10031    
10032        // 'final' ('!') operator tests ...
10033    
10034        runScript({
10035            .code = R"NKSP_CODE(
10036    on init
10037      exit( ceil(123.1) )
10038    end on
10039    )NKSP_CODE",
10040            .expectRealExitResult = 124.0,
10041            .expectExitResultFinal = false
10042        });
10043    
10044        runScript({
10045            .code = R"NKSP_CODE(
10046    on init
10047      exit( ceil(!123.8) )
10048    end on
10049    )NKSP_CODE",
10050            .expectRealExitResult = 124.0,
10051            .expectExitResultFinal = true
10052        });
10053    
10054        #if !SILENT_TEST
10055        std::cout << std::endl;
10056        #endif
10057    }
10058    
10059    static void testBuiltInFloorFunction() {
10060        #if !SILENT_TEST
10061        std::cout << "UNIT TEST: built-in floor() function\n";
10062        #endif
10063    
10064        // integer tests ...
10065        // (ATM not allowed for this function)
10066    
10067        runScript({
10068            .code = R"NKSP_CODE(
10069    on init
10070      declare $foo := 1
10071      exit( floor($foo) )
10072    end on
10073    )NKSP_CODE",
10074            .expectParseError = true // integer not allowed for this function ATM
10075        });
10076    
10077        // real number tests ...
10078    
10079        runScript({
10080            .code = R"NKSP_CODE(
10081    on init
10082      exit( floor(99.0) )
10083    end on
10084    )NKSP_CODE",
10085            .expectRealExitResult = 99.0
10086        });
10087    
10088        runScript({
10089            .code = R"NKSP_CODE(
10090    on init
10091      exit( floor(99.1) )
10092    end on
10093    )NKSP_CODE",
10094            .expectRealExitResult = 99.0
10095        });
10096    
10097        runScript({
10098            .code = R"NKSP_CODE(
10099    on init
10100      exit( floor(99.9) )
10101    end on
10102    )NKSP_CODE",
10103            .expectRealExitResult = 99.0
10104        });
10105    
10106        // std unit tests ...
10107    
10108        runScript({
10109            .code = R"NKSP_CODE(
10110    on init
10111      exit( floor(2.4ms) )
10112    end on
10113    )NKSP_CODE",
10114            .expectRealExitResult = 2.0,
10115            .expectExitResultUnitPrefix = { VM_MILLI },
10116            .expectExitResultUnit = VM_SECOND
10117        });
10118    
10119        runScript({
10120            .code = R"NKSP_CODE(
10121    on init
10122      exit( floor(2.6kHz) )
10123    end on
10124    )NKSP_CODE",
10125            .expectRealExitResult = 2.0,
10126            .expectExitResultUnitPrefix = { VM_KILO },
10127            .expectExitResultUnit = VM_HERTZ
10128        });
10129    
10130        runScript({
10131            .code = R"NKSP_CODE(
10132    on init
10133      exit( floor(4.4ms / 2.0) )
10134    end on
10135    )NKSP_CODE",
10136            .expectRealExitResult = 2.0,
10137            .expectExitResultUnitPrefix = { VM_MILLI },
10138            .expectExitResultUnit = VM_SECOND
10139        });
10140    
10141        runScript({
10142            .code = R"NKSP_CODE(
10143    on init
10144      exit( floor( floor(8.4us) / 4.0) )
10145    end on
10146    )NKSP_CODE",
10147            .expectRealExitResult = 2.0,
10148            .expectExitResultUnitPrefix = { VM_MICRO },
10149            .expectExitResultUnit = VM_SECOND
10150        });
10151    
10152        // 'final' ('!') operator tests ...
10153    
10154        runScript({
10155            .code = R"NKSP_CODE(
10156    on init
10157      exit( floor(123.1) )
10158    end on
10159    )NKSP_CODE",
10160            .expectRealExitResult = 123.0,
10161            .expectExitResultFinal = false
10162        });
10163    
10164        runScript({
10165            .code = R"NKSP_CODE(
10166    on init
10167      exit( floor(!123.8) )
10168    end on
10169    )NKSP_CODE",
10170            .expectRealExitResult = 123.0,
10171            .expectExitResultFinal = true
10172        });
10173    
10174        #if !SILENT_TEST
10175        std::cout << std::endl;
10176        #endif
10177    }
10178    
10179    static void testBuiltInSqrtFunction() {
10180        #if !SILENT_TEST
10181        std::cout << "UNIT TEST: built-in sqrt() function\n";
10182        #endif
10183    
10184        // integer tests ...
10185        // (ATM not allowed for this function)
10186    
10187        runScript({
10188            .code = R"NKSP_CODE(
10189    on init
10190      declare $foo := 1
10191      exit( sqrt($foo) )
10192    end on
10193    )NKSP_CODE",
10194            .expectParseError = true // integer not allowed for this function ATM
10195        });
10196    
10197        // real number tests ...
10198    
10199        runScript({
10200            .code = R"NKSP_CODE(
10201    on init
10202      exit( sqrt(36.0) )
10203    end on
10204    )NKSP_CODE",
10205            .expectRealExitResult = 6.0
10206        });
10207    
10208        // std unit tests ...
10209    
10210        runScript({
10211            .code = R"NKSP_CODE(
10212    on init
10213      exit( sqrt(100.0ms) )
10214    end on
10215    )NKSP_CODE",
10216            .expectRealExitResult = 10.0,
10217            .expectExitResultUnitPrefix = { VM_MILLI },
10218            .expectExitResultUnit = VM_SECOND
10219        });
10220    
10221        runScript({
10222            .code = R"NKSP_CODE(
10223    on init
10224      exit( sqrt(5.76kHz) )
10225    end on
10226    )NKSP_CODE",
10227            .expectRealExitResult = 2.4,
10228            .expectExitResultUnitPrefix = { VM_KILO },
10229            .expectExitResultUnit = VM_HERTZ
10230        });
10231    
10232        // 'final' ('!') operator tests ...
10233    
10234        runScript({
10235            .code = R"NKSP_CODE(
10236    on init
10237      exit( sqrt(25.0) )
10238    end on
10239    )NKSP_CODE",
10240            .expectRealExitResult = 5.0,
10241            .expectExitResultFinal = false
10242        });
10243    
10244        runScript({
10245            .code = R"NKSP_CODE(
10246    on init
10247      exit( sqrt(!25.0) )
10248    end on
10249    )NKSP_CODE",
10250            .expectRealExitResult = 5.0,
10251            .expectExitResultFinal = true
10252        });
10253    
10254        #if !SILENT_TEST
10255        std::cout << std::endl;
10256        #endif
10257    }
10258    
10259    static void testBuiltInLogFunction() {
10260        #if !SILENT_TEST
10261        std::cout << "UNIT TEST: built-in log() function\n";
10262        #endif
10263    
10264        // integer tests ...
10265        // (ATM not allowed for this function)
10266    
10267        runScript({
10268            .code = R"NKSP_CODE(
10269    on init
10270      declare $foo := 1
10271      exit( log($foo) )
10272    end on
10273    )NKSP_CODE",
10274            .expectParseError = true // integer not allowed for this function ATM
10275        });
10276    
10277        // real number tests ...
10278    
10279        runScript({
10280            .code = R"NKSP_CODE(
10281    on init
10282      exit( log(1.0) )
10283    end on
10284    )NKSP_CODE",
10285            .expectRealExitResult = 0.0
10286        });
10287    
10288        runScript({
10289            .code = R"NKSP_CODE(
10290    on init
10291      exit( log(~NI_MATH_E) )
10292    end on
10293    )NKSP_CODE",
10294            .expectRealExitResult = 1.0
10295        });
10296    
10297        // std unit tests ...
10298    
10299        runScript({
10300            .code = R"NKSP_CODE(
10301    on init
10302      exit( log(~NI_MATH_E * 1.0ms) )
10303    end on
10304    )NKSP_CODE",
10305            .expectRealExitResult = 1.0,
10306            .expectExitResultUnitPrefix = { VM_MILLI },
10307            .expectExitResultUnit = VM_SECOND
10308        });
10309    
10310        runScript({
10311            .code = R"NKSP_CODE(
10312    on init
10313      exit( log(~NI_MATH_E * 1.0kHz) )
10314    end on
10315    )NKSP_CODE",
10316            .expectRealExitResult = 1.0,
10317            .expectExitResultUnitPrefix = { VM_KILO },
10318            .expectExitResultUnit = VM_HERTZ
10319        });
10320    
10321        // 'final' ('!') operator tests ...
10322    
10323        runScript({
10324            .code = R"NKSP_CODE(
10325    on init
10326      exit( log(~NI_MATH_E * 1.0) )
10327    end on
10328    )NKSP_CODE",
10329            .expectRealExitResult = 1.0,
10330            .expectExitResultFinal = false
10331        });
10332    
10333        runScript({
10334            .code = R"NKSP_CODE(
10335    on init
10336      exit( log(!(~NI_MATH_E * 1.0)) )
10337    end on
10338    )NKSP_CODE",
10339            .expectRealExitResult = 1.0,
10340            .expectExitResultFinal = true
10341        });
10342    
10343        #if !SILENT_TEST
10344        std::cout << std::endl;
10345        #endif
10346    }
10347    
10348    static void testBuiltInLog2Function() {
10349        #if !SILENT_TEST
10350        std::cout << "UNIT TEST: built-in log2() function\n";
10351        #endif
10352    
10353        // integer tests ...
10354        // (ATM not allowed for this function)
10355    
10356        runScript({
10357            .code = R"NKSP_CODE(
10358    on init
10359      declare $foo := 1
10360      exit( log2($foo) )
10361    end on
10362    )NKSP_CODE",
10363            .expectParseError = true // integer not allowed for this function ATM
10364        });
10365    
10366        // real number tests ...
10367    
10368        runScript({
10369            .code = R"NKSP_CODE(
10370    on init
10371      exit( log2(1.0) )
10372    end on
10373    )NKSP_CODE",
10374            .expectRealExitResult = 0.0
10375        });
10376    
10377        runScript({
10378            .code = R"NKSP_CODE(
10379    on init
10380      exit( log2(32.0) )
10381    end on
10382    )NKSP_CODE",
10383            .expectRealExitResult = 5.0
10384        });
10385    
10386        // std unit tests ...
10387    
10388        runScript({
10389            .code = R"NKSP_CODE(
10390    on init
10391      exit( log2(32.0ms) )
10392    end on
10393    )NKSP_CODE",
10394            .expectRealExitResult = 5.0,
10395            .expectExitResultUnitPrefix = { VM_MILLI },
10396            .expectExitResultUnit = VM_SECOND
10397        });
10398    
10399        runScript({
10400            .code = R"NKSP_CODE(
10401    on init
10402      exit( log2(32.0kHz) )
10403    end on
10404    )NKSP_CODE",
10405            .expectRealExitResult = 5.0,
10406            .expectExitResultUnitPrefix = { VM_KILO },
10407            .expectExitResultUnit = VM_HERTZ
10408        });
10409    
10410        // 'final' ('!') operator tests ...
10411    
10412        runScript({
10413            .code = R"NKSP_CODE(
10414    on init
10415      exit( log2(32.0) )
10416    end on
10417    )NKSP_CODE",
10418            .expectRealExitResult = 5.0,
10419            .expectExitResultFinal = false
10420        });
10421    
10422        runScript({
10423            .code = R"NKSP_CODE(
10424    on init
10425      exit( log2(!32.0) )
10426    end on
10427    )NKSP_CODE",
10428            .expectRealExitResult = 5.0,
10429            .expectExitResultFinal = true
10430        });
10431    
10432        #if !SILENT_TEST
10433        std::cout << std::endl;
10434        #endif
10435    }
10436    
10437    static void testBuiltInLog10Function() {
10438        #if !SILENT_TEST
10439        std::cout << "UNIT TEST: built-in log10() function\n";
10440        #endif
10441    
10442        // integer tests ...
10443        // (ATM not allowed for this function)
10444    
10445        runScript({
10446            .code = R"NKSP_CODE(
10447    on init
10448      declare $foo := 1
10449      exit( log10($foo) )
10450    end on
10451    )NKSP_CODE",
10452            .expectParseError = true // integer not allowed for this function ATM
10453        });
10454    
10455        // real number tests ...
10456    
10457        runScript({
10458            .code = R"NKSP_CODE(
10459    on init
10460      exit( log10(1000.0) )
10461    end on
10462    )NKSP_CODE",
10463            .expectRealExitResult = 3.0
10464        });
10465    
10466        runScript({
10467            .code = R"NKSP_CODE(
10468    on init
10469      exit( log10(1000.0) )
10470    end on
10471    )NKSP_CODE",
10472            .expectRealExitResult = 3.0
10473        });
10474    
10475        // std unit tests ...
10476    
10477        runScript({
10478            .code = R"NKSP_CODE(
10479    on init
10480      exit( log10(1000.0ms) )
10481    end on
10482    )NKSP_CODE",
10483            .expectRealExitResult = 3.0,
10484            .expectExitResultUnitPrefix = { VM_MILLI },
10485            .expectExitResultUnit = VM_SECOND
10486        });
10487    
10488        runScript({
10489            .code = R"NKSP_CODE(
10490    on init
10491      exit( log10(1000.0kHz) )
10492    end on
10493    )NKSP_CODE",
10494            .expectRealExitResult = 3.0,
10495            .expectExitResultUnitPrefix = { VM_KILO },
10496            .expectExitResultUnit = VM_HERTZ
10497        });
10498    
10499        // 'final' ('!') operator tests ...
10500    
10501        runScript({
10502            .code = R"NKSP_CODE(
10503    on init
10504      exit( log10(1000.0) )
10505    end on
10506    )NKSP_CODE",
10507            .expectRealExitResult = 3.0,
10508            .expectExitResultFinal = false
10509        });
10510    
10511        runScript({
10512            .code = R"NKSP_CODE(
10513    on init
10514      exit( log10(!1000.0) )
10515    end on
10516    )NKSP_CODE",
10517            .expectRealExitResult = 3.0,
10518            .expectExitResultFinal = true
10519        });
10520    
10521        #if !SILENT_TEST
10522        std::cout << std::endl;
10523        #endif
10524    }
10525    
10526    static void testBuiltInExpFunction() {
10527        #if !SILENT_TEST
10528        std::cout << "UNIT TEST: built-in exp() function\n";
10529        #endif
10530    
10531        // integer tests ...
10532        // (ATM not allowed for this function)
10533    
10534        runScript({
10535            .code = R"NKSP_CODE(
10536    on init
10537      declare $foo := 1
10538      exit( exp($foo) )
10539    end on
10540    )NKSP_CODE",
10541            .expectParseError = true // integer not allowed for this function ATM
10542        });
10543    
10544        // real number tests ...
10545    
10546        runScript({
10547            .code = R"NKSP_CODE(
10548    on init
10549      exit( exp(0.0) )
10550    end on
10551    )NKSP_CODE",
10552            .expectRealExitResult = 1.0
10553        });
10554    
10555        runScript({
10556            .code = R"NKSP_CODE(
10557    on init
10558      exit( exp(1.0) )
10559    end on
10560    )NKSP_CODE",
10561            .expectRealExitResult = M_E
10562        });
10563    
10564        // std unit tests ...
10565    
10566        runScript({
10567            .code = R"NKSP_CODE(
10568    on init
10569      exit( exp(0.0ms) )
10570    end on
10571    )NKSP_CODE",
10572            .expectRealExitResult = 1.0,
10573            .expectExitResultUnitPrefix = { VM_MILLI },
10574            .expectExitResultUnit = VM_SECOND
10575        });
10576    
10577        runScript({
10578            .code = R"NKSP_CODE(
10579    on init
10580      exit( exp(0.0kHz) )
10581    end on
10582    )NKSP_CODE",
10583            .expectRealExitResult = 1.0,
10584            .expectExitResultUnitPrefix = { VM_KILO },
10585            .expectExitResultUnit = VM_HERTZ
10586        });
10587    
10588        // 'final' ('!') operator tests ...
10589    
10590        runScript({
10591            .code = R"NKSP_CODE(
10592    on init
10593      exit( exp(0.0) )
10594    end on
10595    )NKSP_CODE",
10596            .expectRealExitResult = 1.0,
10597            .expectExitResultFinal = false
10598        });
10599    
10600        runScript({
10601            .code = R"NKSP_CODE(
10602    on init
10603      exit( exp(!0.0) )
10604    end on
10605    )NKSP_CODE",
10606            .expectRealExitResult = 1.0,
10607            .expectExitResultFinal = true
10608        });
10609    
10610        #if !SILENT_TEST
10611        std::cout << std::endl;
10612        #endif
10613    }
10614    
10615    static void testBuiltInPowFunction() {
10616        #if !SILENT_TEST
10617        std::cout << "UNIT TEST: built-in pow() function\n";
10618        #endif
10619    
10620        // integer tests ...
10621        // (ATM not allowed for this function)
10622    
10623        runScript({
10624            .code = R"NKSP_CODE(
10625    on init
10626      declare $foo := 1
10627      exit( pow($foo,$foo) )
10628    end on
10629    )NKSP_CODE",
10630            .expectParseError = true // integer not allowed for this function ATM
10631        });
10632    
10633        // real number tests ...
10634    
10635        runScript({
10636            .code = R"NKSP_CODE(
10637    on init
10638      exit( pow(1.0) )
10639    end on
10640    )NKSP_CODE",
10641            .expectParseError = true // because pow() requires exactly 2 arguments
10642        });
10643    
10644        runScript({
10645            .code = R"NKSP_CODE(
10646    on init
10647      exit( pow(3.0,4.0) )
10648    end on
10649    )NKSP_CODE",
10650            .expectRealExitResult = 81.0
10651        });
10652    
10653        // std unit tests ...
10654    
10655        runScript({
10656            .code = R"NKSP_CODE(
10657    on init
10658      exit( pow(3.0ms,4.0ms) )
10659    end on
10660    )NKSP_CODE",
10661            .expectParseError = true // because units are prohibited for 2nd argument
10662        });
10663    
10664        runScript({
10665            .code = R"NKSP_CODE(
10666    on init
10667      exit( pow(3.0,4.0ms) )
10668    end on
10669    )NKSP_CODE",
10670            .expectParseError = true // because units are prohibited for 2nd argument
10671        });
10672    
10673        runScript({
10674            .code = R"NKSP_CODE(
10675    on init
10676      exit( pow(3.0ms,4.0) )
10677    end on
10678    )NKSP_CODE",
10679            .expectRealExitResult = 81.0,
10680            .expectExitResultUnitPrefix = { VM_MILLI },
10681            .expectExitResultUnit = VM_SECOND
10682        });
10683    
10684        runScript({
10685            .code = R"NKSP_CODE(
10686    on init
10687      exit( pow(3.0kHz,4.0) )
10688    end on
10689    )NKSP_CODE",
10690            .expectRealExitResult = 81.0,
10691            .expectExitResultUnitPrefix = { VM_KILO },
10692            .expectExitResultUnit = VM_HERTZ
10693        });
10694    
10695        // 'final' ('!') operator tests ...
10696    
10697        runScript({
10698            .code = R"NKSP_CODE(
10699    on init
10700      exit( pow(3.0,4.0) )
10701    end on
10702    )NKSP_CODE",
10703            .expectRealExitResult = 81.0,
10704            .expectExitResultFinal = false
10705        });
10706    
10707        runScript({
10708            .code = R"NKSP_CODE(
10709    on init
10710      exit( pow(!3.0,4.0) )
10711    end on
10712    )NKSP_CODE",
10713            .expectRealExitResult = 81.0,
10714            .expectExitResultFinal = true
10715        });
10716    
10717        runScript({
10718            .code = R"NKSP_CODE(
10719    on init
10720      exit( pow(3.0,!4.0) )
10721    end on
10722    )NKSP_CODE",
10723            .expectParseError = true // because 'final' is meaningless for 2nd argument
10724        });
10725    
10726        #if !SILENT_TEST
10727        std::cout << std::endl;
10728        #endif
10729    }
10730    
10731    static void testBuiltInSinFunction() {
10732        #if !SILENT_TEST
10733        std::cout << "UNIT TEST: built-in sin() function\n";
10734        #endif
10735    
10736        // integer tests ...
10737        // (ATM not allowed for this function)
10738    
10739        runScript({
10740            .code = R"NKSP_CODE(
10741    on init
10742      declare $foo := 1
10743      exit( sin($foo) )
10744    end on
10745    )NKSP_CODE",
10746            .expectParseError = true // integer not allowed for this function ATM
10747        });
10748    
10749        // real number tests ...
10750    
10751        runScript({
10752            .code = R"NKSP_CODE(
10753    on init
10754      exit( sin(0.0) )
10755    end on
10756    )NKSP_CODE",
10757            .expectRealExitResult = 0.0
10758        });
10759    
10760        runScript({
10761            .code = R"NKSP_CODE(
10762    on init
10763      exit( sin(0.5 * ~NI_MATH_PI) )
10764    end on
10765    )NKSP_CODE",
10766            .expectRealExitResult = 1.0
10767        });
10768    
10769        runScript({
10770            .code = R"NKSP_CODE(
10771    on init
10772      exit( sin(~NI_MATH_PI) )
10773    end on
10774    )NKSP_CODE",
10775            .expectRealExitResult = 0.0
10776        });
10777    
10778        runScript({
10779            .code = R"NKSP_CODE(
10780    on init
10781      exit( sin(1.5 * ~NI_MATH_PI) )
10782    end on
10783    )NKSP_CODE",
10784            .expectRealExitResult = -1.0
10785        });
10786    
10787        // std unit tests ...
10788    
10789        runScript({
10790            .code = R"NKSP_CODE(
10791    on init
10792      exit( sin(0.0ms) )
10793    end on
10794    )NKSP_CODE",
10795            .expectRealExitResult = 0.0,
10796            .expectExitResultUnitPrefix = { VM_MILLI },
10797            .expectExitResultUnit = VM_SECOND
10798        });
10799    
10800        runScript({
10801            .code = R"NKSP_CODE(
10802    on init
10803      exit( sin(0.0kHz) )
10804    end on
10805    )NKSP_CODE",
10806            .expectRealExitResult = 0.0,
10807            .expectExitResultUnitPrefix = { VM_KILO },
10808            .expectExitResultUnit = VM_HERTZ
10809        });
10810    
10811        // 'final' ('!') operator tests ...
10812    
10813        runScript({
10814            .code = R"NKSP_CODE(
10815    on init
10816      exit( sin(0.0) )
10817    end on
10818    )NKSP_CODE",
10819            .expectRealExitResult = 0.0,
10820            .expectExitResultFinal = false
10821        });
10822    
10823        runScript({
10824            .code = R"NKSP_CODE(
10825    on init
10826      exit( sin(!0.0) )
10827    end on
10828    )NKSP_CODE",
10829            .expectRealExitResult = 0.0,
10830            .expectExitResultFinal = true
10831        });
10832    
10833        #if !SILENT_TEST
10834        std::cout << std::endl;
10835        #endif
10836    }
10837    
10838    static void testBuiltInCosFunction() {
10839        #if !SILENT_TEST
10840        std::cout << "UNIT TEST: built-in cos() function\n";
10841        #endif
10842    
10843        // integer tests ...
10844        // (ATM not allowed for this function)
10845    
10846        runScript({
10847            .code = R"NKSP_CODE(
10848    on init
10849      declare $foo := 1
10850      exit( cos($foo) )
10851    end on
10852    )NKSP_CODE",
10853            .expectParseError = true // integer not allowed for this function ATM
10854        });
10855    
10856        // real number tests ...
10857    
10858        runScript({
10859            .code = R"NKSP_CODE(
10860    on init
10861      exit( cos(0.0) )
10862    end on
10863    )NKSP_CODE",
10864            .expectRealExitResult = 1.0
10865        });
10866    
10867        runScript({
10868            .code = R"NKSP_CODE(
10869    on init
10870      exit( cos(0.5 * ~NI_MATH_PI) )
10871    end on
10872    )NKSP_CODE",
10873            .expectRealExitResult = 0.0
10874        });
10875    
10876        runScript({
10877            .code = R"NKSP_CODE(
10878    on init
10879      exit( cos(~NI_MATH_PI) )
10880    end on
10881    )NKSP_CODE",
10882            .expectRealExitResult = -1.0
10883        });
10884    
10885        runScript({
10886            .code = R"NKSP_CODE(
10887    on init
10888      exit( cos(1.5 * ~NI_MATH_PI) )
10889    end on
10890    )NKSP_CODE",
10891            .expectRealExitResult = 0.0
10892        });
10893    
10894        // std unit tests ...
10895    
10896        runScript({
10897            .code = R"NKSP_CODE(
10898    on init
10899      exit( cos(0.0ms) )
10900    end on
10901    )NKSP_CODE",
10902            .expectRealExitResult = 1.0,
10903            .expectExitResultUnitPrefix = { VM_MILLI },
10904            .expectExitResultUnit = VM_SECOND
10905        });
10906    
10907        runScript({
10908            .code = R"NKSP_CODE(
10909    on init
10910      exit( cos(0.0kHz) )
10911    end on
10912    )NKSP_CODE",
10913            .expectRealExitResult = 1.0,
10914            .expectExitResultUnitPrefix = { VM_KILO },
10915            .expectExitResultUnit = VM_HERTZ
10916        });
10917    
10918        // 'final' ('!') operator tests ...
10919    
10920        runScript({
10921            .code = R"NKSP_CODE(
10922    on init
10923      exit( cos(0.0) )
10924    end on
10925    )NKSP_CODE",
10926            .expectRealExitResult = 1.0,
10927            .expectExitResultFinal = false
10928        });
10929    
10930        runScript({
10931            .code = R"NKSP_CODE(
10932    on init
10933      exit( cos(!0.0) )
10934    end on
10935    )NKSP_CODE",
10936            .expectRealExitResult = 1.0,
10937            .expectExitResultFinal = true
10938        });
10939    
10940        #if !SILENT_TEST
10941        std::cout << std::endl;
10942        #endif
10943    }
10944    
10945    static void testBuiltInTanFunction() {
10946        #if !SILENT_TEST
10947        std::cout << "UNIT TEST: built-in tan() function\n";
10948        #endif
10949    
10950        // integer tests ...
10951        // (ATM not allowed for this function)
10952    
10953        runScript({
10954            .code = R"NKSP_CODE(
10955    on init
10956      declare $foo := 1
10957      exit( tan($foo) )
10958    end on
10959    )NKSP_CODE",
10960            .expectParseError = true // integer not allowed for this function ATM
10961        });
10962    
10963        // real number tests ...
10964    
10965        runScript({
10966            .code = R"NKSP_CODE(
10967    on init
10968      exit( tan(0.0) )
10969    end on
10970    )NKSP_CODE",
10971            .expectRealExitResult = 0.0
10972        });
10973    
10974        runScript({
10975            .code = R"NKSP_CODE(
10976    on init
10977      exit( tan(0.25 * ~NI_MATH_PI) )
10978    end on
10979    )NKSP_CODE",
10980            .expectRealExitResult = 1.0
10981        });
10982    
10983        // std unit tests ...
10984    
10985        runScript({
10986            .code = R"NKSP_CODE(
10987    on init
10988      exit( tan(0.0ms) )
10989    end on
10990    )NKSP_CODE",
10991            .expectRealExitResult = 0.0,
10992            .expectExitResultUnitPrefix = { VM_MILLI },
10993            .expectExitResultUnit = VM_SECOND
10994        });
10995    
10996        runScript({
10997            .code = R"NKSP_CODE(
10998    on init
10999      exit( tan(0.0kHz) )
11000    end on
11001    )NKSP_CODE",
11002            .expectRealExitResult = 0.0,
11003            .expectExitResultUnitPrefix = { VM_KILO },
11004            .expectExitResultUnit = VM_HERTZ
11005        });
11006    
11007        // 'final' ('!') operator tests ...
11008    
11009        runScript({
11010            .code = R"NKSP_CODE(
11011    on init
11012      exit( tan(0.0) )
11013    end on
11014    )NKSP_CODE",
11015            .expectRealExitResult = 0.0,
11016            .expectExitResultFinal = false
11017        });
11018    
11019        runScript({
11020            .code = R"NKSP_CODE(
11021    on init
11022      exit( tan(!0.0) )
11023    end on
11024    )NKSP_CODE",
11025            .expectRealExitResult = 0.0,
11026            .expectExitResultFinal = true
11027        });
11028    
11029        #if !SILENT_TEST
11030        std::cout << std::endl;
11031        #endif
11032    }
11033    
11034    static void testBuiltInAsinFunction() {
11035        #if !SILENT_TEST
11036        std::cout << "UNIT TEST: built-in asin() function\n";
11037        #endif
11038    
11039        // integer tests ...
11040        // (ATM not allowed for this function)
11041    
11042        runScript({
11043            .code = R"NKSP_CODE(
11044    on init
11045      declare $foo := 1
11046      exit( asin($foo) )
11047    end on
11048    )NKSP_CODE",
11049            .expectParseError = true // integer not allowed for this function ATM
11050        });
11051    
11052        // real number tests ...
11053    
11054        runScript({
11055            .code = R"NKSP_CODE(
11056    on init
11057      exit( asin(0.0) )
11058    end on
11059    )NKSP_CODE",
11060            .expectRealExitResult = 0.0
11061        });
11062    
11063        runScript({
11064            .code = R"NKSP_CODE(
11065    on init
11066      exit( asin(1.0) )
11067    end on
11068    )NKSP_CODE",
11069            .expectRealExitResult = 0.5 * M_PI
11070        });
11071    
11072        runScript({
11073            .code = R"NKSP_CODE(
11074    on init
11075      exit( asin(-1.0) )
11076    end on
11077    )NKSP_CODE",
11078            .expectRealExitResult = -0.5 * M_PI
11079        });
11080    
11081        // std unit tests ...
11082    
11083        runScript({
11084            .code = R"NKSP_CODE(
11085    on init
11086      exit( asin(0.0ms) )
11087    end on
11088    )NKSP_CODE",
11089            .expectRealExitResult = 0.0,
11090            .expectExitResultUnitPrefix = { VM_MILLI },
11091            .expectExitResultUnit = VM_SECOND
11092        });
11093    
11094        runScript({
11095            .code = R"NKSP_CODE(
11096    on init
11097      exit( asin(0.0kHz) )
11098    end on
11099    )NKSP_CODE",
11100            .expectRealExitResult = 0.0,
11101            .expectExitResultUnitPrefix = { VM_KILO },
11102            .expectExitResultUnit = VM_HERTZ
11103        });
11104    
11105        // 'final' ('!') operator tests ...
11106    
11107        runScript({
11108            .code = R"NKSP_CODE(
11109    on init
11110      exit( asin(0.0) )
11111    end on
11112    )NKSP_CODE",
11113            .expectRealExitResult = 0.0,
11114            .expectExitResultFinal = false
11115        });
11116    
11117        runScript({
11118            .code = R"NKSP_CODE(
11119    on init
11120      exit( asin(!0.0) )
11121    end on
11122    )NKSP_CODE",
11123            .expectRealExitResult = 0.0,
11124            .expectExitResultFinal = true
11125        });
11126    
11127        #if !SILENT_TEST
11128        std::cout << std::endl;
11129        #endif
11130    }
11131    
11132    static void testBuiltInAcosFunction() {
11133        #if !SILENT_TEST
11134        std::cout << "UNIT TEST: built-in acos() function\n";
11135        #endif
11136    
11137        // integer tests ...
11138        // (ATM not allowed for this function)
11139    
11140        runScript({
11141            .code = R"NKSP_CODE(
11142    on init
11143      declare $foo := 1
11144      exit( acos($foo) )
11145    end on
11146    )NKSP_CODE",
11147            .expectParseError = true // integer not allowed for this function ATM
11148        });
11149    
11150        // real number tests ...
11151    
11152        runScript({
11153            .code = R"NKSP_CODE(
11154    on init
11155      exit( acos(1.0) )
11156    end on
11157    )NKSP_CODE",
11158            .expectRealExitResult = 0.0
11159        });
11160    
11161        runScript({
11162            .code = R"NKSP_CODE(
11163    on init
11164      exit( acos(0.0) )
11165    end on
11166    )NKSP_CODE",
11167            .expectRealExitResult = 0.5 * M_PI
11168        });
11169    
11170        runScript({
11171            .code = R"NKSP_CODE(
11172    on init
11173      exit( acos(-1.0) )
11174    end on
11175    )NKSP_CODE",
11176            .expectRealExitResult = M_PI
11177        });
11178    
11179        // std unit tests ...
11180    
11181        runScript({
11182            .code = R"NKSP_CODE(
11183    on init
11184      exit( acos(1.0ms) )
11185    end on
11186    )NKSP_CODE",
11187            .expectRealExitResult = 0.0,
11188            .expectExitResultUnitPrefix = { VM_MILLI },
11189            .expectExitResultUnit = VM_SECOND
11190        });
11191    
11192        runScript({
11193            .code = R"NKSP_CODE(
11194    on init
11195      exit( acos(1.0kHz) )
11196    end on
11197    )NKSP_CODE",
11198            .expectRealExitResult = 0.0,
11199            .expectExitResultUnitPrefix = { VM_KILO },
11200            .expectExitResultUnit = VM_HERTZ
11201        });
11202    
11203        // 'final' ('!') operator tests ...
11204    
11205        runScript({
11206            .code = R"NKSP_CODE(
11207    on init
11208      exit( acos(1.0) )
11209    end on
11210    )NKSP_CODE",
11211            .expectRealExitResult = 0.0,
11212            .expectExitResultFinal = false
11213        });
11214    
11215        runScript({
11216            .code = R"NKSP_CODE(
11217    on init
11218      exit( acos(!1.0) )
11219    end on
11220    )NKSP_CODE",
11221            .expectRealExitResult = 0.0,
11222            .expectExitResultFinal = true
11223        });
11224    
11225        #if !SILENT_TEST
11226        std::cout << std::endl;
11227        #endif
11228    }
11229    
11230    static void testBuiltInAtanFunction() {
11231        #if !SILENT_TEST
11232        std::cout << "UNIT TEST: built-in atan() function\n";
11233        #endif
11234    
11235        // integer tests ...
11236        // (ATM not allowed for this function)
11237    
11238        runScript({
11239            .code = R"NKSP_CODE(
11240    on init
11241      declare $foo := 1
11242      exit( atan($foo) )
11243    end on
11244    )NKSP_CODE",
11245            .expectParseError = true // integer not allowed for this function ATM
11246        });
11247    
11248        // real number tests ...
11249    
11250        runScript({
11251            .code = R"NKSP_CODE(
11252    on init
11253      exit( atan(0.0) )
11254    end on
11255    )NKSP_CODE",
11256            .expectRealExitResult = 0.0
11257        });
11258    
11259        runScript({
11260            .code = R"NKSP_CODE(
11261    on init
11262      exit( atan(1.0) )
11263    end on
11264    )NKSP_CODE",
11265            .expectRealExitResult = 0.25 * M_PI
11266        });
11267    
11268        // std unit tests ...
11269    
11270        runScript({
11271            .code = R"NKSP_CODE(
11272    on init
11273      exit( atan(0.0ms) )
11274    end on
11275    )NKSP_CODE",
11276            .expectRealExitResult = 0.0,
11277            .expectExitResultUnitPrefix = { VM_MILLI },
11278            .expectExitResultUnit = VM_SECOND
11279        });
11280    
11281        runScript({
11282            .code = R"NKSP_CODE(
11283    on init
11284      exit( atan(0.0kHz) )
11285    end on
11286    )NKSP_CODE",
11287            .expectRealExitResult = 0.0,
11288            .expectExitResultUnitPrefix = { VM_KILO },
11289            .expectExitResultUnit = VM_HERTZ
11290        });
11291    
11292        // 'final' ('!') operator tests ...
11293    
11294        runScript({
11295            .code = R"NKSP_CODE(
11296    on init
11297      exit( atan(0.0) )
11298    end on
11299    )NKSP_CODE",
11300            .expectRealExitResult = 0.0,
11301            .expectExitResultFinal = false
11302        });
11303    
11304        runScript({
11305            .code = R"NKSP_CODE(
11306    on init
11307      exit( atan(!0.0) )
11308    end on
11309    )NKSP_CODE",
11310            .expectRealExitResult = 0.0,
11311            .expectExitResultFinal = true
11312        });
11313    
11314      #if !SILENT_TEST      #if !SILENT_TEST
11315      std::cout << std::endl;      std::cout << std::endl;
11316      #endif      #endif
# Line 1722  static void testBuiltInNumElementsFuncti Line 11321  static void testBuiltInNumElementsFuncti
11321      std::cout << "UNIT TEST: built-in num_elements() function\n";      std::cout << "UNIT TEST: built-in num_elements() function\n";
11322      #endif      #endif
11323    
11324        // integer array tests ...
11325    
11326      runScript({      runScript({
11327          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
11328  on init  on init
# Line 1752  end on Line 11353  end on
11353          .expectIntExitResult = 5          .expectIntExitResult = 5
11354      });      });
11355    
11356        // real array tests ...
11357    
11358        runScript({
11359            .code = R"NKSP_CODE(
11360    on init
11361      declare ?foo[3] := ( 19.0, 3.2, 6.5 )
11362      exit( num_elements(?foo) )
11363    end on
11364    )NKSP_CODE",
11365            .expectIntExitResult = 3
11366        });
11367    
11368        runScript({
11369            .code = R"NKSP_CODE(
11370    on init
11371      declare ?foo[1] := ( 19.0 )
11372      exit( num_elements(?foo) )
11373    end on
11374    )NKSP_CODE",
11375            .expectIntExitResult = 1
11376        });
11377    
11378        runScript({
11379            .code = R"NKSP_CODE(
11380    on init
11381      declare ?foo[5] := ( 1.1, 2.2, 3.3, 4.4, 5.5 )
11382      exit( num_elements(?foo) )
11383    end on
11384    )NKSP_CODE",
11385            .expectIntExitResult = 5
11386        });
11387    
11388      #if !SILENT_TEST      #if !SILENT_TEST
11389      std::cout << std::endl;      std::cout << std::endl;
11390      #endif      #endif
# Line 1762  static void testBuiltInSearchFunction() Line 11395  static void testBuiltInSearchFunction()
11395      std::cout << "UNIT TEST: built-in search() function\n";      std::cout << "UNIT TEST: built-in search() function\n";
11396      #endif      #endif
11397    
11398        // integer array tests ...
11399    
11400      runScript({      runScript({
11401          .code = R"NKSP_CODE(          .code = R"NKSP_CODE(
11402  on init  on init
# Line 1802  end on Line 11437  end on
11437          .expectIntExitResult = -1          .expectIntExitResult = -1
11438      });      });
11439    
11440        // real array tests ...
11441    
11442        runScript({
11443            .code = R"NKSP_CODE(
11444    on init
11445      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11446      exit( search(?foo, 19.12) )
11447    end on
11448    )NKSP_CODE",
11449            .expectIntExitResult = 0
11450        });
11451    
11452        runScript({
11453            .code = R"NKSP_CODE(
11454    on init
11455      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11456      exit( search(?foo, 3.45) )
11457    end on
11458    )NKSP_CODE",
11459            .expectIntExitResult = 1
11460        });
11461    
11462        runScript({
11463            .code = R"NKSP_CODE(
11464    on init
11465      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11466      exit( search(?foo, 6.89) )
11467    end on
11468    )NKSP_CODE",
11469            .expectIntExitResult = 2
11470        });
11471    
11472        runScript({
11473            .code = R"NKSP_CODE(
11474    on init
11475      declare ?foo[3] := ( 19.12, 3.45, 6.89 )
11476      exit( search(?foo, 6.99) )
11477    end on
11478    )NKSP_CODE",
11479            .expectIntExitResult = -1
11480        });
11481    
11482      #if !SILENT_TEST      #if !SILENT_TEST
11483      std::cout << std::endl;      std::cout << std::endl;
11484      #endif      #endif
# Line 1895  end on Line 11572  end on
11572      #endif      #endif
11573  }  }
11574    
11575    static void testBuiltInVars() {
11576        #if !SILENT_TEST
11577        std::cout << "UNIT TEST: built-in variables\n";
11578        #endif
11579    
11580        runScript({
11581            .code = R"NKSP_CODE(
11582    on init
11583      exit($NKSP_PERF_TIMER)
11584    end on
11585    )NKSP_CODE",
11586            .expectExitResultIsInt = true,
11587            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11588            .expectExitResultUnit = VM_NO_UNIT
11589        });
11590    
11591        runScript({
11592            .code = R"NKSP_CODE(
11593    on init
11594      exit($NKSP_REAL_TIMER)
11595    end on
11596    )NKSP_CODE",
11597            .expectExitResultIsInt = true,
11598            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11599            .expectExitResultUnit = VM_NO_UNIT
11600        });
11601    
11602        runScript({
11603            .code = R"NKSP_CODE(
11604    on init
11605      exit($KSP_TIMER)
11606    end on
11607    )NKSP_CODE",
11608            .expectExitResultIsInt = true,
11609            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11610            .expectExitResultUnit = VM_NO_UNIT
11611        });
11612    
11613        runScript({
11614            .code = R"NKSP_CODE(
11615    on init
11616      exit(~NI_MATH_PI)
11617    end on
11618    )NKSP_CODE",
11619            .expectExitResultIsReal = true,
11620            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11621            .expectExitResultUnit = VM_NO_UNIT
11622        });
11623    
11624        runScript({
11625            .code = R"NKSP_CODE(
11626    on init
11627      exit(~NI_MATH_E)
11628    end on
11629    )NKSP_CODE",
11630            .expectExitResultIsReal = true,
11631            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11632            .expectExitResultUnit = VM_NO_UNIT
11633        });
11634    
11635        runScript({
11636            .code = R"NKSP_CODE(
11637    on init
11638      exit($NI_CB_TYPE_INIT)
11639    end on
11640    )NKSP_CODE",
11641            .expectIntExitResult = VM_EVENT_HANDLER_INIT,
11642            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11643            .expectExitResultUnit = VM_NO_UNIT
11644        });
11645    
11646        runScript({
11647            .code = R"NKSP_CODE(
11648    on init
11649      exit($NI_CB_TYPE_NOTE)
11650    end on
11651    )NKSP_CODE",
11652            .expectIntExitResult = VM_EVENT_HANDLER_NOTE,
11653            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11654            .expectExitResultUnit = VM_NO_UNIT
11655        });
11656    
11657        runScript({
11658            .code = R"NKSP_CODE(
11659    on init
11660      exit($NI_CB_TYPE_RELEASE)
11661    end on
11662    )NKSP_CODE",
11663            .expectIntExitResult = VM_EVENT_HANDLER_RELEASE,
11664            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11665            .expectExitResultUnit = VM_NO_UNIT
11666        });
11667    
11668        runScript({
11669            .code = R"NKSP_CODE(
11670    on init
11671      exit($NI_CB_TYPE_CONTROLLER)
11672    end on
11673    )NKSP_CODE",
11674            .expectIntExitResult = VM_EVENT_HANDLER_CONTROLLER,
11675            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11676            .expectExitResultUnit = VM_NO_UNIT
11677        });
11678    
11679        runScript({
11680            .code = R"NKSP_CODE(
11681    on init
11682      exit($NI_CB_TYPE_RPN)
11683    end on
11684    )NKSP_CODE",
11685            .expectIntExitResult = VM_EVENT_HANDLER_RPN,
11686            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11687            .expectExitResultUnit = VM_NO_UNIT
11688        });
11689    
11690        runScript({
11691            .code = R"NKSP_CODE(
11692    on init
11693      exit($NI_CB_TYPE_NRPN)
11694    end on
11695    )NKSP_CODE",
11696            .expectIntExitResult = VM_EVENT_HANDLER_NRPN,
11697            .expectExitResultUnitPrefix = { VM_NO_PREFIX },
11698            .expectExitResultUnit = VM_NO_UNIT
11699        });
11700    
11701        #if !SILENT_TEST
11702        std::cout << std::endl;
11703        #endif
11704    }
11705    
11706  #if !NO_MAIN  #if !NO_MAIN
11707    
11708  int main() {  int main() {
11709      testBuiltInExitFunction();      testBuiltInExitFunction();
11710      testStringConcatOperator();      testStringConcatOperator();
11711        testNegOperator();
11712      testPlusOperator();      testPlusOperator();
11713      testMinusOperator();      testMinusOperator();
11714      testModuloOperator();      testModuloOperator();
# Line 1918  int main() { Line 11727  int main() {
11727      testBitwiseOrOperator();      testBitwiseOrOperator();
11728      testBitwiseNotOperator();      testBitwiseNotOperator();
11729      testPrecedenceOfOperators();      testPrecedenceOfOperators();
11730        testIntVarDeclaration();
11731        testIntArrayVarDeclaration();
11732        testRealVarDeclaration();
11733        testRealArrayVarDeclaration();
11734        testStringVarDeclaration();
11735      testBuiltInMinFunction();      testBuiltInMinFunction();
11736      testBuiltInMaxFunction();      testBuiltInMaxFunction();
11737      testBuiltInAbsFunction();      testBuiltInAbsFunction();
# Line 1927  int main() { Line 11741  int main() {
11741      testBuiltInRandomFunction();      testBuiltInRandomFunction();
11742      testBuiltInShiftLeftFunction();      testBuiltInShiftLeftFunction();
11743      testBuiltInShiftRightFunction();      testBuiltInShiftRightFunction();
11744        testBuiltInMsbFunction();
11745        testBuiltInLsbFunction();
11746        testBuiltInIntToRealFunction();
11747        testBuiltInRealFunction();
11748        testBuiltInRealToIntFunction();
11749        testBuiltInIntFunction();
11750        testBuiltInRoundFunction();
11751        testBuiltInCeilFunction();
11752        testBuiltInFloorFunction();
11753        testBuiltInSqrtFunction();
11754        testBuiltInLogFunction();
11755        testBuiltInLog2Function();
11756        testBuiltInLog10Function();
11757        testBuiltInExpFunction();
11758        testBuiltInPowFunction();
11759        testBuiltInSinFunction();
11760        testBuiltInCosFunction();
11761        testBuiltInTanFunction();
11762        testBuiltInAsinFunction();
11763        testBuiltInAcosFunction();
11764        testBuiltInAtanFunction();
11765      testBuiltInArrayEqualFunction();      testBuiltInArrayEqualFunction();
11766      testBuiltInSortFunction();      testBuiltInSortFunction();
11767      testBuiltInNumElementsFunction();      testBuiltInNumElementsFunction();
11768      testBuiltInSearchFunction();      testBuiltInSearchFunction();
11769      testIfStatement();      testIfStatement();
11770      testWhileStatement();      testWhileStatement();
11771        testBuiltInVars();
11772      std::cout << "\nAll tests passed successfully. :-)\n";      std::cout << "\nAll tests passed successfully. :-)\n";
11773      return 0;      return 0;
11774  }  }

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

  ViewVC Help
Powered by ViewVC