logicaffeine-compile 0.10.1

LOGOS compilation pipeline - codegen and interpreter
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258

## To isNothing (v: CVal) -> Bool:
    Inspect v:
        When VNothing:
            Return true.
        Otherwise:
            Return false.

## To valToText (v: CVal) -> Text:
    Inspect v:
        When VInt (n):
            Return "{n}".
        When VFloat (f):
            Return "{f}".
        When VBool (b):
            If b:
                Return "true".
            Otherwise:
                Return "false".
        When VText (s):
            Return s.
        When VSeq (items):
            Return "[seq]".
        When VMap (m):
            Return "[map]".
        When VSet (setItems):
            Return "[set]".
        When VOption (optInner, optPresent):
            If optPresent:
                Let innerText be valToText(optInner).
                Return "Some({innerText})".
            Otherwise:
                Return "None".
        When VTuple (tupItems):
            Let tupParts be a new Seq of Text.
            Repeat for ti in tupItems:
                Push valToText(ti) to tupParts.
            Let mutable tupResult be "(".
            Let mutable tupIdx be 1.
            Let tupLen be length of tupParts.
            Repeat for tp in tupParts:
                Set tupResult to "{tupResult}{tp}".
                If tupIdx is less than tupLen:
                    Set tupResult to "{tupResult}, ".
                Set tupIdx to tupIdx + 1.
            Set tupResult to "{tupResult})".
            Return tupResult.
        When VStruct (sTypeName, sFields):
            Return "{sTypeName}(...)".
        When VVariant (vTypeName, vVarName, vFields):
            Return "{vVarName}".
        When VClosure (clParams, clBody, clEnv):
            Return "<closure>".
        When VDuration (durMs):
            If durMs is less than 1000:
                Return "{durMs}ms".
            Let durSec be durMs / 1000.
            If durSec is less than 60:
                Return "{durSec}s".
            Let durMin be durSec / 60.
            Return "{durMin}m".
        When VDate (dYear, dMonth, dDay):
            Return "{dYear}-{dMonth}-{dDay}".
        When VMoment (mMs):
            Return "moment({mMs})".
        When VSpan (spanStart, spanEnd):
            Return "span({spanStart}..{spanEnd})".
        When VTime (tHour, tMin, tSec):
            Return "{tHour}:{tMin}:{tSec}".
        When VCrdt (crdtKind, crdtState):
            Return "<crdt:{crdtKind}>".
        When VError (msg):
            Return "Error: {msg}".
        When VNothing:
            Return "nothing".

## To applyBinOp (op: Text) and (lv: CVal) and (rv: CVal) -> CVal:
    Inspect lv:
        When VError (msg):
            Return a new VError with msg msg.
        When VInt (a):
            Inspect rv:
                When VError (msg):
                    Return a new VError with msg msg.
                When VInt (b):
                    If op equals "+":
                        Return a new VInt with value (a + b).
                    If op equals "-":
                        Return a new VInt with value (a - b).
                    If op equals "*":
                        Return a new VInt with value (a * b).
                    If op equals "/":
                        If b equals 0:
                            Return a new VError with msg "division by zero".
                        Return a new VInt with value (a / b).
                    If op equals "%":
                        If b equals 0:
                            Return a new VError with msg "modulo by zero".
                        Return a new VInt with value (a % b).
                    If op equals "<":
                        Return a new VBool with value (a is less than b).
                    If op equals ">":
                        Return a new VBool with value (a is greater than b).
                    If op equals "<=":
                        Return a new VBool with value (a is at most b).
                    If op equals ">=":
                        Return a new VBool with value (a is at least b).
                    If op equals "==":
                        Return a new VBool with value (a equals b).
                    If op equals "!=":
                        Return a new VBool with value (a is not b).
                    If op equals "^":
                        Return a new VInt with value (a xor b).
                    If op equals "<<":
                        Return a new VInt with value (a shifted left by b).
                    If op equals ">>":
                        Return a new VInt with value (a shifted right by b).
                    Return a new VNothing.
                When VFloat (b):
                    If op equals "+":
                        Return a new VFloat with value (a + b).
                    If op equals "-":
                        Return a new VFloat with value (a - b).
                    If op equals "*":
                        Return a new VFloat with value (a * b).
                    If op equals "/":
                        If b equals 0.0:
                            Return a new VError with msg "division by zero".
                        Return a new VFloat with value (a / b).
                    If op equals "<":
                        Return a new VBool with value (a is less than b).
                    If op equals ">":
                        Return a new VBool with value (a is greater than b).
                    If op equals "<=":
                        Return a new VBool with value (a is at most b).
                    If op equals ">=":
                        Return a new VBool with value (a is at least b).
                    If op equals "==":
                        Return a new VBool with value (a equals b).
                    If op equals "!=":
                        Return a new VBool with value (a is not b).
                    Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When VFloat (a):
            Inspect rv:
                When VError (msg):
                    Return a new VError with msg msg.
                When VFloat (b):
                    If op equals "+":
                        Return a new VFloat with value (a + b).
                    If op equals "-":
                        Return a new VFloat with value (a - b).
                    If op equals "*":
                        Return a new VFloat with value (a * b).
                    If op equals "/":
                        If b equals 0.0:
                            Return a new VError with msg "division by zero".
                        Return a new VFloat with value (a / b).
                    If op equals "<":
                        Return a new VBool with value (a is less than b).
                    If op equals ">":
                        Return a new VBool with value (a is greater than b).
                    If op equals "<=":
                        Return a new VBool with value (a is at most b).
                    If op equals ">=":
                        Return a new VBool with value (a is at least b).
                    If op equals "==":
                        Return a new VBool with value (a equals b).
                    If op equals "!=":
                        Return a new VBool with value (a is not b).
                    Return a new VNothing.
                When VInt (b):
                    If op equals "+":
                        Return a new VFloat with value (a + b).
                    If op equals "-":
                        Return a new VFloat with value (a - b).
                    If op equals "*":
                        Return a new VFloat with value (a * b).
                    If op equals "/":
                        If b equals 0:
                            Return a new VError with msg "division by zero".
                        Return a new VFloat with value (a / b).
                    If op equals "<":
                        Return a new VBool with value (a is less than b).
                    If op equals ">":
                        Return a new VBool with value (a is greater than b).
                    If op equals "<=":
                        Return a new VBool with value (a is at most b).
                    If op equals ">=":
                        Return a new VBool with value (a is at least b).
                    If op equals "==":
                        Return a new VBool with value (a equals b).
                    If op equals "!=":
                        Return a new VBool with value (a is not b).
                    Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When VBool (a):
            Inspect rv:
                When VError (msg):
                    Return a new VError with msg msg.
                When VBool (b):
                    If op equals "&&":
                        Return a new VBool with value (a and b).
                    If op equals "||":
                        Return a new VBool with value (a or b).
                    If op equals "==":
                        Return a new VBool with value (a equals b).
                    If op equals "!=":
                        Return a new VBool with value (a is not b).
                    Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When VText (a):
            Inspect rv:
                When VError (msg):
                    Return a new VError with msg msg.
                When VText (b):
                    If op equals "+":
                        Let joined be "{a}{b}".
                        Return a new VText with value joined.
                    If op equals "==":
                        Return a new VBool with value (a equals b).
                    If op equals "!=":
                        Return a new VBool with value (a is not b).
                    Return a new VNothing.
                When VInt (b):
                    If op equals "+":
                        Let joined be "{a}{b}".
                        Return a new VText with value joined.
                    Return a new VNothing.
                When VBool (b):
                    If op equals "+":
                        If b:
                            Let joined be "{a}true".
                            Return a new VText with value joined.
                        Otherwise:
                            Let joined be "{a}false".
                            Return a new VText with value joined.
                    Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When VDuration (durA):
            Inspect rv:
                When VDuration (durB):
                    If op equals "+":
                        Return a new VDuration with millis (durA + durB).
                    If op equals "-":
                        Return a new VDuration with millis (durA - durB).
                    If op equals "==":
                        Return a new VBool with value (durA equals durB).
                    If op equals "!=":
                        Return a new VBool with value (durA is not durB).
                    If op equals "<":
                        Return a new VBool with value (durA is less than durB).
                    If op equals ">":
                        Return a new VBool with value (durA is greater than durB).
                    Return a new VNothing.
                When VInt (durB):
                    If op equals "*":
                        Return a new VDuration with millis (durA * durB).
                    Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When VDate (dateYA, dateMA, dateDA):
            Inspect rv:
                When VDuration (durB):
                    If op equals "+":
                        Let shiftedDay be dateDA + (durB / 86400000).
                        Return a new VDate with year dateYA and month dateMA and day shiftedDay.
                    Return a new VNothing.
                When VDate (dateYB, dateMB, dateDB):
                    If op equals "-":
                        Let dayDiff be dateDA - dateDB.
                        Return a new VDuration with millis (dayDiff * 86400000).
                    If op equals "==":
                        Let yEq be dateYA equals dateYB.
                        Let mEq be dateMA equals dateMB.
                        Let dEq be dateDA equals dateDB.
                        Return a new VBool with value (yEq and mEq and dEq).
                    If op equals "<":
                        If dateYA is less than dateYB:
                            Return a new VBool with value true.
                        If dateYA is greater than dateYB:
                            Return a new VBool with value false.
                        If dateMA is less than dateMB:
                            Return a new VBool with value true.
                        If dateMA is greater than dateMB:
                            Return a new VBool with value false.
                        Return a new VBool with value (dateDA is less than dateDB).
                    Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When VMoment (momA):
            Inspect rv:
                When VMoment (momB):
                    If op equals "<":
                        Return a new VBool with value (momA is less than momB).
                    If op equals ">":
                        Return a new VBool with value (momA is greater than momB).
                    If op equals "==":
                        Return a new VBool with value (momA equals momB).
                    If op equals "<=":
                        Return a new VBool with value (momA is at most momB).
                    If op equals ">=":
                        Return a new VBool with value (momA is at least momB).
                    Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        Otherwise:
            Return a new VNothing.

## To valEquals (a: CVal) and (b: CVal) -> Bool:
    Let ta be valToText(a).
    Let tb be valToText(b).
    Return ta equals tb.

## To coreEval (expr: CExpr) and (env: Map of Text to CVal) and (funcs: Map of Text to CFunc) -> CVal:
    Inspect expr:
        When CInt (n):
            Return a new VInt with value n.
        When CFloat (f):
            Return a new VFloat with value f.
        When CBool (b):
            Return a new VBool with value b.
        When CText (s):
            Return a new VText with value s.
        When CVar (name):
            Return item name of env.
        When CBinOp (op, left, right):
            Let lv be coreEval(left, env, funcs).
            Let rv be coreEval(right, env, funcs).
            Return applyBinOp(op, lv, rv).
        When CNot (inner):
            Let v be coreEval(inner, env, funcs).
            Inspect v:
                When VBool (b):
                    Return a new VBool with value (not b).
                Otherwise:
                    Return a new VNothing.
        When CCall (name, argExprs):
            Let argVals be a new Seq of CVal.
            Repeat for a in argExprs:
                Push coreEval(a, env, funcs) to argVals.
            Let callInFuncs be (funcs contains name).
            If callInFuncs:
                Let func be item name of funcs.
                Inspect func:
                    When CFuncDef (fname, params, fnParamTypes, fnReturnType, body):
                        Let callEnv be a new Map of Text to CVal.
                        Let mutable idx be 1.
                        Repeat for p in params:
                            Set item p of callEnv to item idx of argVals.
                            Set idx to idx + 1.
                        Let callBodyOut be coreExecBlock(body, callEnv, funcs).
                        Return coreOutResult(callBodyOut).
                    Otherwise:
                        Return a new VNothing.
            Otherwise:
                Let callInEnv be (env contains name).
                If callInEnv:
                    Let envVal be item name of env.
                    Inspect envVal:
                        When VClosure (ceParams, ceBody, ceCapturedEnv):
                            Let mutable ceCallEnv be ceCapturedEnv.
                            Let mutable ceCopyIdx be 1.
                            While ceCopyIdx is at most (length of ceParams):
                                If ceCopyIdx is at most (length of argVals):
                                    Set item (item ceCopyIdx of ceParams) of ceCallEnv to item ceCopyIdx of argVals.
                                Set ceCopyIdx to ceCopyIdx + 1.
                            Let ceBodyOut be coreExecBlock(ceBody, ceCallEnv, funcs).
                            Return coreOutResult(ceBodyOut).
                        Otherwise:
                            Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When CIndex (collExpr, idxExpr):
            Let cv be coreEval(collExpr, env, funcs).
            Let iv be coreEval(idxExpr, env, funcs).
            Inspect cv:
                When VError (msg):
                    Return a new VError with msg msg.
                When VSeq (items):
                    Inspect iv:
                        When VError (msg):
                            Return a new VError with msg msg.
                        When VInt (i):
                            If i is less than 1:
                                Return a new VError with msg "index out of bounds".
                            If i is greater than (length of items):
                                Return a new VError with msg "index out of bounds".
                            Return item i of items.
                        Otherwise:
                            Return a new VNothing.
                When VTuple (tupItems):
                    Inspect iv:
                        When VInt (i):
                            If i is less than 1:
                                Return a new VError with msg "index out of bounds".
                            If i is greater than (length of tupItems):
                                Return a new VError with msg "index out of bounds".
                            Return item i of tupItems.
                        Otherwise:
                            Return a new VNothing.
                When VMap (mapData):
                    Inspect iv:
                        When VText (mapKey):
                            Return item mapKey of mapData.
                        Otherwise:
                            Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When CLen (collExpr):
            Let cv be coreEval(collExpr, env, funcs).
            Inspect cv:
                When VSeq (items):
                    Return a new VInt with value (length of items).
                When VSet (setItems):
                    Return a new VInt with value (length of setItems).
                When VTuple (tupItems):
                    Return a new VInt with value (length of tupItems).
                When VText (textVal):
                    Return a new VInt with value (length of textVal).
                Otherwise:
                    Return a new VNothing.
        When CMapGet (mapExpr, keyExpr):
            Let mv be coreEval(mapExpr, env, funcs).
            Let kv be coreEval(keyExpr, env, funcs).
            Inspect mv:
                When VMap (mapData):
                    Inspect kv:
                        When VText (key):
                            Return item key of mapData.
                        Otherwise:
                            Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When CNewSeq:
            Return a new VSeq with items a new Seq of CVal.
        When CNewVariant (nvTag, nvNames, nvVals):
            Let nvMap be a new Map of Text to CVal.
            Set item "__tag" of nvMap to a new VText with value nvTag.
            Let nvFnSeq be a new Seq of CVal.
            Let mutable nvi be 1.
            While nvi is at most (length of nvNames):
                Let nvn be item nvi of nvNames.
                Let nvv be coreEval(item nvi of nvVals, env, funcs).
                Set item nvn of nvMap to nvv.
                Let nvn2 be item nvi of nvNames.
                Push a new VText with value nvn2 to nvFnSeq.
                Set nvi to nvi + 1.
            Set item "__fnames__" of nvMap to a new VSeq with items nvFnSeq.
            Return a new VMap with entries nvMap.
        When CList (listItems):
            Let result be a new Seq of CVal.
            Repeat for listItem in listItems:
                Push coreEval(listItem, env, funcs) to result.
            Return a new VSeq with items result.
        When CRange (rangeStart, rangeEnd):
            Let sv be coreEval(rangeStart, env, funcs).
            Let ev be coreEval(rangeEnd, env, funcs).
            Let result be a new Seq of CVal.
            Inspect sv:
                When VInt (s):
                    Inspect ev:
                        When VInt (e):
                            Let mutable ri be s.
                            While ri is at most e:
                                Push a new VInt with value ri to result.
                                Set ri to ri + 1.
                        Otherwise:
                            Let skip be true.
                Otherwise:
                    Let skip be true.
            Return a new VSeq with items result.
        When CSlice (sliceColl, sliceStart, sliceEnd):
            Let cv be coreEval(sliceColl, env, funcs).
            Let siv be coreEval(sliceStart, env, funcs).
            Let eiv be coreEval(sliceEnd, env, funcs).
            Inspect cv:
                When VSeq (srcItems):
                    Inspect siv:
                        When VInt (si):
                            Inspect eiv:
                                When VInt (ei):
                                    Let sliceResult be a new Seq of CVal.
                                    Let mutable sIdx be si.
                                    While sIdx is at most ei:
                                        If sIdx is at least 1:
                                            If sIdx is at most (length of srcItems):
                                                Push item sIdx of srcItems to sliceResult.
                                        Set sIdx to sIdx + 1.
                                    Return a new VSeq with items sliceResult.
                                Otherwise:
                                    Return a new VNothing.
                        Otherwise:
                            Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When CCopy (copyTarget):
            Let cv be coreEval(copyTarget, env, funcs).
            Inspect cv:
                When VSeq (srcItems):
                    Let copiedItems be a new Seq of CVal.
                    Repeat for ci in srcItems:
                        Push ci to copiedItems.
                    Return a new VSeq with items copiedItems.
                When VMap (mapData):
                    Let copiedMap be copy of mapData.
                    Return a new VMap with entries copiedMap.
                When VStruct (stn, stf):
                    Let copiedFields be copy of stf.
                    Return a new VStruct with typeName stn and fields copiedFields.
                Otherwise:
                    Return cv.
        When CNewSet:
            Return a new VSet with items a new Seq of CVal.
        When CContains (containsColl, containsElem):
            Let ccv be coreEval(containsColl, env, funcs).
            Let cev be coreEval(containsElem, env, funcs).
            Let cevText be valToText(cev).
            Inspect ccv:
                When VSet (setItems):
                    Repeat for si in setItems:
                        Let siText be valToText(si).
                        If siText equals cevText:
                            Return a new VBool with value true.
                    Return a new VBool with value false.
                When VSeq (seqItems):
                    Repeat for si in seqItems:
                        Let siText be valToText(si).
                        If siText equals cevText:
                            Return a new VBool with value true.
                    Return a new VBool with value false.
                When VText (haystack):
                    Inspect cev:
                        When VText (needle):
                            If haystack contains needle:
                                Return a new VBool with value true.
                            Otherwise:
                                Return a new VBool with value false.
                        Otherwise:
                            Return a new VBool with value false.
                Otherwise:
                    Return a new VBool with value false.
        When CUnion (unionLeft, unionRight):
            Let ulv be coreEval(unionLeft, env, funcs).
            Let urv be coreEval(unionRight, env, funcs).
            Inspect ulv:
                When VSet (leftItems):
                    Inspect urv:
                        When VSet (rightItems):
                            Let unionResult be a new Seq of CVal.
                            Let unionTexts be a new Seq of Text.
                            Let mutable uliIdx be 1.
                            While uliIdx is at most (length of leftItems):
                                Push item uliIdx of leftItems to unionResult.
                                Push valToText(item uliIdx of leftItems) to unionTexts.
                                Set uliIdx to uliIdx + 1.
                            Let mutable uriIdx be 1.
                            While uriIdx is at most (length of rightItems):
                                Let uriTxt be valToText(item uriIdx of rightItems).
                                Let mutable uriFound be false.
                                Repeat for ut in unionTexts:
                                    If ut equals uriTxt:
                                        Set uriFound to true.
                                If not uriFound:
                                    Push item uriIdx of rightItems to unionResult.
                                    Push uriTxt to unionTexts.
                                Set uriIdx to uriIdx + 1.
                            Return a new VSet with items unionResult.
                        Otherwise:
                            Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When CIntersection (interLeft, interRight):
            Let ilv be coreEval(interLeft, env, funcs).
            Let irv be coreEval(interRight, env, funcs).
            Inspect ilv:
                When VSet (leftItems):
                    Inspect irv:
                        When VSet (rightItems):
                            Let interResult be a new Seq of CVal.
                            Let rightTexts be a new Seq of Text.
                            Repeat for iri in rightItems:
                                Push valToText(iri) to rightTexts.
                            Let mutable iliIdx be 1.
                            While iliIdx is at most (length of leftItems):
                                Let iliTxt be valToText(item iliIdx of leftItems).
                                Let mutable iliFound be false.
                                Repeat for irt in rightTexts:
                                    If irt equals iliTxt:
                                        Set iliFound to true.
                                If iliFound:
                                    Push item iliIdx of leftItems to interResult.
                                Set iliIdx to iliIdx + 1.
                            Return a new VSet with items interResult.
                        Otherwise:
                            Return a new VNothing.
                Otherwise:
                    Return a new VNothing.
        When COptionSome (optInner):
            Let optVal be coreEval(optInner, env, funcs).
            Return a new VOption with inner optVal and present true.
        When COptionNone:
            Return a new VOption with inner (a new VNothing) and present false.
        When CTuple (tupleItems):
            Let tupleResult be a new Seq of CVal.
            Repeat for ti in tupleItems:
                Push coreEval(ti, env, funcs) to tupleResult.
            Return a new VTuple with items tupleResult.
        When CNew (newTypeName, newFieldNames, newFields):
            If newTypeName equals "Map":
                Return a new VMap with entries a new Map of Text to CVal.
            Let newFieldMap be a new Map of Text to CVal.
            Let mutable nfIdx be 1.
            Repeat for nfn in newFieldNames:
                If nfIdx is at most (length of newFields):
                    Set item nfn of newFieldMap to coreEval(item nfIdx of newFields, env, funcs).
                Set nfIdx to nfIdx + 1.
            Return a new VStruct with typeName newTypeName and fields newFieldMap.
        When CFieldAccess (faTarget, faField):
            Let faVal be coreEval(faTarget, env, funcs).
            Inspect faVal:
                When VStruct (faTypeName, faFields):
                    Return item faField of faFields.
                When VMap (faMapData):
                    Return item faField of faMapData.
                Otherwise:
                    Return a new VNothing.
        When CClosure (clParams, clBody, clCaptured):
            Let clEnv be a new Map of Text to CVal.
            Let mutable clCapIdx be 1.
            While clCapIdx is at most (length of clCaptured):
                Let clCapName be item clCapIdx of clCaptured.
                Let clCapVal be item clCapName of env.
                Let clCapName2 be item clCapIdx of clCaptured.
                Set item clCapName2 of clEnv to clCapVal.
                Set clCapIdx to clCapIdx + 1.
            Return a new VClosure with params clParams and body clBody and capturedEnv clEnv.
        When CCallExpr (ceTarget, ceArgs):
            Let ceVal be coreEval(ceTarget, env, funcs).
            Inspect ceVal:
                When VClosure (ceParams, ceBody, ceCapturedEnv):
                    Let mutable ceCallEnv be ceCapturedEnv.
                    Let mutable ceCopyIdx be 1.
                    While ceCopyIdx is at most (length of ceParams):
                        If ceCopyIdx is at most (length of ceArgs):
                            Let ceArgVal be coreEval(item ceCopyIdx of ceArgs, env, funcs).
                            Set item (item ceCopyIdx of ceParams) of ceCallEnv to ceArgVal.
                        Set ceCopyIdx to ceCopyIdx + 1.
                    Let ceOut be coreExecBlock(ceBody, ceCallEnv, funcs).
                    Let ceResult be coreOutResult(ceOut).
                    Return ceResult.
                Otherwise:
                    Return a new VNothing.
        When CInterpolatedString (isParts):
            Let mutable isResult be "".
            Repeat for isPart in isParts:
                Inspect isPart:
                    When CLiteralPart (litVal):
                        Set isResult to "{isResult}{litVal}".
                    When CExprPart (epExpr):
                        Let epVal be coreEval(epExpr, env, funcs).
                        Let epText be valToText(epVal).
                        Set isResult to "{isResult}{epText}".
            Return a new VText with value isResult.
        When CDuration (durAmountExpr, durUnit):
            Let durAmountVal be coreEval(durAmountExpr, env, funcs).
            Inspect durAmountVal:
                When VInt (durAmt):
                    If durUnit equals "seconds":
                        Return a new VDuration with millis (durAmt * 1000).
                    If durUnit equals "minutes":
                        Return a new VDuration with millis (durAmt * 60000).
                    If durUnit equals "hours":
                        Return a new VDuration with millis (durAmt * 3600000).
                    If durUnit equals "milliseconds":
                        Return a new VDuration with millis durAmt.
                    Return a new VDuration with millis (durAmt * 1000).
                Otherwise:
                    Return a new VNothing.
        When CTimeNow:
            Return a new VMoment with millis 0.
        When CDateToday:
            Return a new VDate with year 2026 and month 1 and day 1.
        When CEscExpr (escCode):
            Return a new VNothing.
        When CManifestOf (zn):
            Return a new VNothing.
        When CChunkAt (idx, zn):
            Return a new VNothing.

## A CoreOut is one of:
    A CoreOutR with result CVal and env Map of Text to CVal.

## To coreOutResult (o: CoreOut) -> CVal:
    Inspect o:
        When CoreOutR (corR, coeR):
            Return corR.

## To coreOutEnv (o: CoreOut) -> Map of Text to CVal:
    Inspect o:
        When CoreOutR (corE, coeE):
            Return coeE.

## To coreExecBlock (stmts: Seq of CStmt) and (env0: Map of Text to CVal) and (funcs: Map of Text to CFunc) -> CoreOut:
    Let mutable env be env0.
    Repeat for s in stmts:
        Inspect s:
            When CLet (name, expr):
                Set item name of env to coreEval(expr, env, funcs).
            When CSet (name, expr):
                Set item name of env to coreEval(expr, env, funcs).
            When CIf (cond, thenBlock, elseBlock):
                Let cv be coreEval(cond, env, funcs).
                Inspect cv:
                    When VBool (b):
                        If b:
                            Let ifOut be coreExecBlock(thenBlock, env, funcs).
                            Set env to coreOutEnv(ifOut).
                            Let ifResult be coreOutResult(ifOut).
                            Let ifNoth be isNothing(ifResult).
                            If not ifNoth:
                                Return a new CoreOutR with result ifResult and env env.
                        Otherwise:
                            Let elseOut be coreExecBlock(elseBlock, env, funcs).
                            Set env to coreOutEnv(elseOut).
                            Let elseResult be coreOutResult(elseOut).
                            Let elseNoth be isNothing(elseResult).
                            If not elseNoth:
                                Return a new CoreOutR with result elseResult and env env.
                    Otherwise:
                        Let skip be true.
            When CWhile (whileCond, whileBody):
                Let mutable loopDone be false.
                While not loopDone:
                    Let wcv be coreEval(whileCond, env, funcs).
                    Inspect wcv:
                        When VBool (wb):
                            If not wb:
                                Set loopDone to true.
                            Otherwise:
                                Let whileIterOut be coreExecBlock(whileBody, env, funcs).
                                Set env to coreOutEnv(whileIterOut).
                                Let whileIterResult be coreOutResult(whileIterOut).
                                Let whileIterNoth be isNothing(whileIterResult).
                                If not whileIterNoth:
                                    Let whileIterTxt be valToText(whileIterResult).
                                    If whileIterTxt equals "__break__":
                                        Set loopDone to true.
                                    Otherwise:
                                        Return a new CoreOutR with result whileIterResult and env env.
                        Otherwise:
                            Set loopDone to true.
            When CReturn (expr):
                Let retVal be coreEval(expr, env, funcs).
                Return a new CoreOutR with result retVal and env env.
            When CShow (expr):
                Let v be coreEval(expr, env, funcs).
                Show valToText(v).
            When CCallS (name, argExprs):
                Let argVals be a new Seq of CVal.
                Repeat for a in argExprs:
                    Push coreEval(a, env, funcs) to argVals.
                Let csInFuncs be (funcs contains name).
                If csInFuncs:
                    Let func be item name of funcs.
                    Inspect func:
                        When CFuncDef (fname, params, fnParamTypes, fnReturnType, body):
                            Let callEnv be a new Map of Text to CVal.
                            Let mutable cidx be 1.
                            Repeat for p in params:
                                Set item p of callEnv to item cidx of argVals.
                                Set cidx to cidx + 1.
                            Let callOut be coreExecBlock(body, callEnv, funcs).
                            Let skip be true.
                        Otherwise:
                            Let skip be true.
                Otherwise:
                    Let csInEnv be (env contains name).
                    If csInEnv:
                        Let envVal be item name of env.
                        Inspect envVal:
                            When VClosure (csParams, csBody, csCapturedEnv):
                                Let mutable csCallEnv be csCapturedEnv.
                                Let mutable csCopyIdx be 1.
                                While csCopyIdx is at most (length of csParams):
                                    If csCopyIdx is at most (length of argVals):
                                        Set item (item csCopyIdx of csParams) of csCallEnv to item csCopyIdx of argVals.
                                    Set csCopyIdx to csCopyIdx + 1.
                                Let csOut be coreExecBlock(csBody, csCallEnv, funcs).
                                Let skip be true.
                            Otherwise:
                                Let skip be true.
            When CPush (valExpr, collName):
                Let v be coreEval(valExpr, env, funcs).
                Let seq be item collName of env.
                Inspect seq:
                    When VSeq (items):
                        Let mutable mutItems be items.
                        Push v to mutItems.
                        Set item collName of env to a new VSeq with items mutItems.
                    Otherwise:
                        Let skip be true.
            When CSetIdx (collName, idxExpr, valExpr):
                Let iv be coreEval(idxExpr, env, funcs).
                Let v be coreEval(valExpr, env, funcs).
                Let seq be item collName of env.
                Inspect seq:
                    When VSeq (items):
                        Inspect iv:
                            When VInt (i):
                                Let mutable mutItems be items.
                                Set item i of mutItems to v.
                                Set item collName of env to a new VSeq with items mutItems.
                            Otherwise:
                                Let skip be true.
                    When VMap (mapData):
                        Inspect iv:
                            When VText (key):
                                Let mutable mutMap be mapData.
                                Set item key of mutMap to v.
                                Set item collName of env to a new VMap with entries mutMap.
                            Otherwise:
                                Let skip be true.
                    Otherwise:
                        Let skip be true.
            When CMapSet (mapName, keyExpr, valExpr):
                Let kv be coreEval(keyExpr, env, funcs).
                Let v be coreEval(valExpr, env, funcs).
                Let mv be item mapName of env.
                Inspect mv:
                    When VMap (mapData):
                        Inspect kv:
                            When VText (key):
                                Let mutable mutMap be mapData.
                                Set item key of mutMap to v.
                                Set item mapName of env to a new VMap with entries mutMap.
                            Otherwise:
                                Let skip be true.
                    Otherwise:
                        Let skip be true.
            When CPop (popTarget):
                Let seq be item popTarget of env.
                Inspect seq:
                    When VSeq (seqItems):
                        Let seqLen be length of seqItems.
                        If seqLen is greater than 0:
                            Let mutable newItems be a new Seq of CVal.
                            Let mutable pi be 1.
                            While pi is less than seqLen:
                                Push item pi of seqItems to newItems.
                                Set pi to pi + 1.
                            Set item popTarget of env to a new VSeq with items newItems.
                    Otherwise:
                        Let skip be true.
            When CAdd (addElem, addTarget):
                Let addValHolder be a new Seq of CVal.
                Push coreEval(addElem, env, funcs) to addValHolder.
                Let addValText be valToText(item 1 of addValHolder).
                Let addColl be item addTarget of env.
                Inspect addColl:
                    When VSet (addItems):
                        Let mutable addFound be false.
                        Repeat for ai in addItems:
                            Let aiText be valToText(ai).
                            If aiText equals addValText:
                                Set addFound to true.
                        If not addFound:
                            Let mutable addNew be addItems.
                            Push item 1 of addValHolder to addNew.
                            Set item addTarget of env to a new VSet with items addNew.
                    Otherwise:
                        Let skip be true.
            When CRemove (remElem, remTarget):
                Let remValText be valToText(coreEval(remElem, env, funcs)).
                Let remColl be item remTarget of env.
                Inspect remColl:
                    When VSet (remItems):
                        Let mutable remNew be a new Seq of CVal.
                        Let mutable remIdx be 1.
                        While remIdx is at most (length of remItems):
                            Let remItemText be valToText(item remIdx of remItems).
                            If remItemText is not remValText:
                                Push item remIdx of remItems to remNew.
                            Set remIdx to remIdx + 1.
                        Set item remTarget of env to a new VSet with items remNew.
                    Otherwise:
                        Let skip be true.
            When CSetField (sfTarget, sfField, sfValExpr):
                Let sfVal be coreEval(sfValExpr, env, funcs).
                Let sfObj be item sfTarget of env.
                Inspect sfObj:
                    When VStruct (sfTypeName, sfFields):
                        Let mutable sfMut be copy of sfFields.
                        Set item sfField of sfMut to sfVal.
                        Set item sfTarget of env to a new VStruct with typeName sfTypeName and fields sfMut.
                    When VMap (sfMapData):
                        Let mutable sfMutMap be copy of sfMapData.
                        Set item sfField of sfMutMap to sfVal.
                        Set item sfTarget of env to a new VMap with entries sfMutMap.
                    Otherwise:
                        Let skip be true.
            When CStructDef (sdName, sdFieldNames):
                Let skip be true.
            When CEnumDef (edName, edVariants):
                Let skip be true.
            When CInspect (inspTarget, inspArms):
                Let inspVal be coreEval(inspTarget, env, funcs).
                Let mutable inspTag be "".
                Let mutable inspFields be a new Seq of CVal.
                Let mutable inspNamedFields be a new Map of Text to CVal.
                Let mutable inspIsMap be false.
                Inspect inspVal:
                    When VVariant (ivt, ivn, ivf):
                        Set inspTag to ivn.
                        Set inspFields to ivf.
                    When VMap (mapData):
                        Set inspIsMap to true.
                        Let tagEntry be item "__tag" of mapData.
                        Inspect tagEntry:
                            When VText (tagStr):
                                Set inspTag to tagStr.
                            Otherwise:
                                Let skip be true.
                        Set inspNamedFields to mapData.
                    Otherwise:
                        Let skip be true.
                Let mutable inspMatched be false.
                Repeat for arm in inspArms:
                    If not inspMatched:
                        Inspect arm:
                            When CWhen (armName, armBindings, armBody):
                                If armName equals inspTag:
                                    Set inspMatched to true.
                                    If inspIsMap:
                                        Let fnamesEntry be item "__fnames__" of inspNamedFields.
                                        Let mutable inspFnameSeq be a new Seq of CVal.
                                        Inspect fnamesEntry:
                                            When VSeq (fnameItems):
                                                Set inspFnameSeq to fnameItems.
                                            Otherwise:
                                                Let skip be true.
                                        Let mutable abiM be 1.
                                        While abiM is at most (length of armBindings):
                                            If abiM is at most (length of inspFnameSeq):
                                                Let fnameVal be item abiM of inspFnameSeq.
                                                Let mutable fnameStr be "".
                                                Inspect fnameVal:
                                                    When VText (fns):
                                                        Set fnameStr to fns.
                                                    Otherwise:
                                                        Let skip be true.
                                                Let abLookup be item fnameStr of inspNamedFields.
                                                Set item (item abiM of armBindings) of env to abLookup.
                                            Set abiM to abiM + 1.
                                    Otherwise:
                                        Let mutable abi2 be 1.
                                        While abi2 is at most (length of armBindings):
                                            If abi2 is at most (length of inspFields):
                                                Set item (item abi2 of armBindings) of env to item abi2 of inspFields.
                                            Set abi2 to abi2 + 1.
                                    Let armOut be coreExecBlock(armBody, env, funcs).
                                    Set env to coreOutEnv(armOut).
                                    Let armResult be coreOutResult(armOut).
                                    Let armNoth be isNothing(armResult).
                                    If not armNoth:
                                        Return a new CoreOutR with result armResult and env env.
                            When COtherwise (owBody):
                                If not inspMatched:
                                    Set inspMatched to true.
                                    Let owOut be coreExecBlock(owBody, env, funcs).
                                    Set env to coreOutEnv(owOut).
                                    Let owResult be coreOutResult(owOut).
                                    Let owNoth be isNothing(owResult).
                                    If not owNoth:
                                        Return a new CoreOutR with result owResult and env env.
            When CRepeat (repVar, repCollExpr, repBody):
                Let repCV be coreEval(repCollExpr, env, funcs).
                Inspect repCV:
                    When VSeq (repItems):
                        Let repLen be length of repItems.
                        Let mutable repIdx be 1.
                        Let mutable repDone be false.
                        While (not repDone):
                            If repIdx is greater than repLen:
                                Set repDone to true.
                            Otherwise:
                                Let repKey be "{repVar}".
                                Set item repKey of env to item repIdx of repItems.
                                Let repIterOut be coreExecBlock(repBody, env, funcs).
                                Set env to coreOutEnv(repIterOut).
                                Let repIterResult be coreOutResult(repIterOut).
                                Let repIterNoth be isNothing(repIterResult).
                                If not repIterNoth:
                                    Let repIterTxt be valToText(repIterResult).
                                    If repIterTxt equals "__break__":
                                        Set repDone to true.
                                    Otherwise:
                                        Return a new CoreOutR with result repIterResult and env env.
                                Set repIdx to repIdx + 1.
                    Otherwise:
                        Let skip be true.
            When CRepeatRange (rrVar, rrStartExpr, rrEndExpr, rrBody):
                Let rrSV be coreEval(rrStartExpr, env, funcs).
                Let rrEV be coreEval(rrEndExpr, env, funcs).
                Inspect rrSV:
                    When VInt (rrStart):
                        Inspect rrEV:
                            When VInt (rrEnd):
                                Let mutable rrI be rrStart.
                                Let mutable rrDone be false.
                                While not rrDone:
                                    If rrI is greater than rrEnd:
                                        Set rrDone to true.
                                    Otherwise:
                                        Let rrKey be "{rrVar}".
                                        Set item rrKey of env to a new VInt with value rrI.
                                        Let rrIterOut be coreExecBlock(rrBody, env, funcs).
                                        Set env to coreOutEnv(rrIterOut).
                                        Let rrIterResult be coreOutResult(rrIterOut).
                                        Let rrIterNoth be isNothing(rrIterResult).
                                        If not rrIterNoth:
                                            Let rrIterTxt be valToText(rrIterResult).
                                            If rrIterTxt equals "__break__":
                                                Set rrDone to true.
                                            Otherwise:
                                                Return a new CoreOutR with result rrIterResult and env env.
                                        Set rrI to rrI + 1.
                            Otherwise:
                                Let skip be true.
                    Otherwise:
                        Let skip be true.
            When CBreak:
                Let breakVal be a new VText with value "__break__".
                Return a new CoreOutR with result breakVal and env env.
            When CRuntimeAssert (raCond, raMsg):
                Let raCondVal be coreEval(raCond, env, funcs).
                Inspect raCondVal:
                    When VBool (raB):
                        If raB is not true:
                            Let raMsgVal be coreEval(raMsg, env, funcs).
                            Let raMsgText be valToText(raMsgVal).
                            Show "Assertion failed: {raMsgText}".
                            Let raErr be a new VError with msg raMsgText.
                            Return a new CoreOutR with result raErr and env env.
                    Otherwise:
                        Let skip be true.
            When CGive (giveExpr, giveTarget):
                Let giveVal be coreEval(giveExpr, env, funcs).
                Set item giveTarget of env to giveVal.
            When CEscStmt (escCode):
                Let skip be true.
            When CSleep (sleepDur):
                Let skip be true.
            When CReadConsole (rcTarget):
                Set item rcTarget of env to (a new VText with value "").
            When CReadFile (rfPath, rfTarget):
                Set item rfTarget of env to (a new VText with value "").
            When CWriteFile (wfPath, wfContent):
                Let skip be true.
            When CCheck (chkPred, chkMsg):
                Let chkVal be coreEval(chkPred, env, funcs).
                Inspect chkVal:
                    When VBool (chkB):
                        If chkB is not true:
                            Let chkMsgVal be coreEval(chkMsg, env, funcs).
                            Let chkMsgText be valToText(chkMsgVal).
                            Show "Security violation: {chkMsgText}".
                            Let chkErr be a new VError with msg chkMsgText.
                            Return a new CoreOutR with result chkErr and env env.
                    Otherwise:
                        Let skip be true.
            When CAssert (assertProp):
                Let assertVal be coreEval(assertProp, env, funcs).
                Inspect assertVal:
                    When VBool (assertB):
                        If assertB is not true:
                            Show "Assertion failed".
                            Let assertErr be a new VError with msg "assertion failed".
                            Return a new CoreOutR with result assertErr and env env.
                    Otherwise:
                        Let skip be true.
            When CTrust (trustProp, trustJust):
                Let trustVal be coreEval(trustProp, env, funcs).
                Inspect trustVal:
                    When VBool (trustB):
                        If trustB is not true:
                            Show "Trust violation: {trustJust}".
                            Let trustErr be a new VError with msg trustJust.
                            Return a new CoreOutR with result trustErr and env env.
                    Otherwise:
                        Let skip be true.
            When CRequire (reqDep):
                Let skip be true.
            When CMerge (mergeTarget, mergeOther):
                Let skip be true.
            When CIncrease (incTarget, incAmountExpr):
                Let incAmount be coreEval(incAmountExpr, env, funcs).
                Let incTargetVal be item incTarget of env.
                Inspect incTargetVal:
                    When VInt (incOldVal):
                        Inspect incAmount:
                            When VInt (incAmtVal):
                                Set item incTarget of env to a new VInt with value (incOldVal + incAmtVal).
                            Otherwise:
                                Let skip be true.
                    Otherwise:
                        Let skip be true.
            When CDecrease (decTarget, decAmountExpr):
                Let decAmount be coreEval(decAmountExpr, env, funcs).
                Let decTargetVal be item decTarget of env.
                Inspect decTargetVal:
                    When VInt (decOldVal):
                        Inspect decAmount:
                            When VInt (decAmtVal):
                                Set item decTarget of env to a new VInt with value (decOldVal - decAmtVal).
                            Otherwise:
                                Let skip be true.
                    Otherwise:
                        Let skip be true.
            When CAppendToSeq (asTarget, asValueExpr):
                Let asValue be coreEval(asValueExpr, env, funcs).
                Let asTargetVal be item asTarget of env.
                Inspect asTargetVal:
                    When VSeq (asItems):
                        Let mutable asMutSeq be asItems.
                        Push asValue to asMutSeq.
                        Set item asTarget of env to a new VSeq with items asMutSeq.
                    Otherwise:
                        Let skip be true.
            When CResolve (resTarget):
                Let skip be true.
            When CSync (syncTarget, syncChannel):
                Let skip be true.
            When CMount (mountTarget, mountPath):
                Let skip be true.
            When CConcurrent (concBranches):
                Repeat for concBranch in concBranches:
                    Let concOut be coreExecBlock(concBranch, env, funcs).
                    Set env to coreOutEnv(concOut).
                    Let concResult be coreOutResult(concOut).
                    Let concNoth be isNothing(concResult).
                    If not concNoth:
                        Let skip be true.
            When CParallel (parBranches):
                Repeat for parBranch in parBranches:
                    Let parOut be coreExecBlock(parBranch, env, funcs).
                    Set env to coreOutEnv(parOut).
                    Let parResult be coreOutResult(parOut).
                    Let parNoth be isNothing(parResult).
                    If not parNoth:
                        Let skip be true.
            When CLaunchTask (ltBody, ltHandle):
                Let ltOut be coreExecBlock(ltBody, env, funcs).
                Set env to coreOutEnv(ltOut).
                Set item ltHandle of env to a new VText with value "task_handle".
            When CStopTask (stHandle):
                Let skip be true.
            When CSelect (selBranches):
                Repeat for selBranch in selBranches:
                    Inspect selBranch:
                        When CSelectRecv (selPipe, selVar, selBody):
                            Let selPipeHas be (env contains selPipe).
                            If selPipeHas:
                                Let selPipeVal be item selPipe of env.
                                Inspect selPipeVal:
                                    When VSeq (selPipeItems):
                                        If (length of selPipeItems) is greater than 0:
                                            Set item selVar of env to item 1 of selPipeItems.
                                            Let mutable selNewPipe be a new Seq of CVal.
                                            Let mutable selPi be 2.
                                            While selPi is at most (length of selPipeItems):
                                                Push item selPi of selPipeItems to selNewPipe.
                                                Set selPi to selPi + 1.
                                            Set item selPipe of env to a new VSeq with items selNewPipe.
                                            Let selRecvOut be coreExecBlock(selBody, env, funcs).
                                            Set env to coreOutEnv(selRecvOut).
                                    Otherwise:
                                        Let skip be true.
                        When CSelectTimeout (selDur, selBody):
                            Let selTimeoutOut be coreExecBlock(selBody, env, funcs).
                            Set env to coreOutEnv(selTimeoutOut).
            When CCreatePipe (cpName, cpCapacity):
                Set item cpName of env to a new VSeq with items (a new Seq of CVal).
            When CSendPipe (spPipe, spValueExpr):
                Let spVal be coreEval(spValueExpr, env, funcs).
                Let spPipeVal be item spPipe of env.
                Inspect spPipeVal:
                    When VSeq (spItems):
                        Let mutable spMut be spItems.
                        Push spVal to spMut.
                        Set item spPipe of env to a new VSeq with items spMut.
                    Otherwise:
                        Let skip be true.
            When CReceivePipe (rpPipe, rpTarget):
                Let rpPipeVal be item rpPipe of env.
                Inspect rpPipeVal:
                    When VSeq (rpItems):
                        If (length of rpItems) is greater than 0:
                            Set item rpTarget of env to item 1 of rpItems.
                            Let mutable rpNew be a new Seq of CVal.
                            Let mutable rpI be 2.
                            While rpI is at most (length of rpItems):
                                Push item rpI of rpItems to rpNew.
                                Set rpI to rpI + 1.
                            Set item rpPipe of env to a new VSeq with items rpNew.
                    Otherwise:
                        Let skip be true.
            When CTrySendPipe (tspPipe, tspValueExpr):
                Let tspVal be coreEval(tspValueExpr, env, funcs).
                Let tspPipeVal be item tspPipe of env.
                Inspect tspPipeVal:
                    When VSeq (tspItems):
                        Let mutable tspMut be tspItems.
                        Push tspVal to tspMut.
                        Set item tspPipe of env to a new VSeq with items tspMut.
                    Otherwise:
                        Let skip be true.
            When CTryReceivePipe (trpPipe, trpTarget):
                Let trpPipeVal be item trpPipe of env.
                Inspect trpPipeVal:
                    When VSeq (trpItems):
                        If (length of trpItems) is greater than 0:
                            Set item trpTarget of env to item 1 of trpItems.
                            Let mutable trpNew be a new Seq of CVal.
                            Let mutable trpI be 2.
                            While trpI is at most (length of trpItems):
                                Push item trpI of trpItems to trpNew.
                                Set trpI to trpI + 1.
                            Set item trpPipe of env to a new VSeq with items trpNew.
                        Otherwise:
                            Set item trpTarget of env to a new VNothing.
                    Otherwise:
                        Set item trpTarget of env to a new VNothing.
            When CSpawn (spawnType, spawnTarget):
                Set item spawnTarget of env to a new VText with value "agent_handle".
            When CSendMessage (smTarget, smMsg):
                Let skip be true.
            When CAwaitMessage (amTarget):
                Set item amTarget of env to a new VNothing.
            When CListen (listenAddr, listenHandler):
                Let skip be true.
            When CConnectTo (connAddr, connTarget):
                Set item connTarget of env to a new VText with value "connection".
            When CZone (zoneName, zoneKind, zoneBody):
                Let zoneOut be coreExecBlock(zoneBody, env, funcs).
                Set env to coreOutEnv(zoneOut).
                Let zoneResult be coreOutResult(zoneOut).
                Let zoneNoth be isNothing(zoneResult).
                If not zoneNoth:
                    Return a new CoreOutR with result zoneResult and env env.
            Otherwise:
                Let skip be true.
    Let finalNoth be a new VNothing.
    Return a new CoreOutR with result finalNoth and env env.