-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathstack.stack
More file actions
5311 lines (4610 loc) · 207 KB
/
stack.stack
File metadata and controls
5311 lines (4610 loc) · 207 KB
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
@import "stdlib"
const STACK_EXT "stack"
-- STACK TOKENIZER
const STACK_TOKEN_EOF 0
const STACK_TOKEN_ILLEGAL 1
const STACK_TOKEN_NUMBER 2
const STACK_TOKEN_BOOLEAN 3
const STACK_TOKEN_STRING 4
const STACK_TOKEN_NAME 5
const STACK_TOKEN_FUNC 6
const STACK_TOKEN_IN 7
const STACK_TOKEN_END 8
const STACK_TOKEN_LPAREN 9
const STACK_TOKEN_RPAREN 10
const STACK_TOKEN_COMMA 11
const STACK_TOKEN_IF 12
const STACK_TOKEN_ELSE 13
const STACK_TOKEN_FI 14
const STACK_TOKEN_DATA 15
const STACK_TOKEN_IMPORT 16
const STACK_TOKEN_CONST 17
const STACK_TOKEN_MATCH 18
const STACK_TOKEN_WHILE 19
const STACK_TOKEN_LOOP 20
const STACK_TOKEN_POOL 21
func stack_token_kind.map (int) (string) in
dup STACK_TOKEN_EOF = if pop "<EOF>"
else dup STACK_TOKEN_ILLEGAL = if pop "ILLEGAL"
else dup STACK_TOKEN_NUMBER = if pop "NUMBER"
else dup STACK_TOKEN_BOOLEAN = if pop "BOOLEAN"
else dup STACK_TOKEN_STRING = if pop "STRING"
else dup STACK_TOKEN_NAME = if pop "NAME"
else dup STACK_TOKEN_FUNC = if pop "FUNC"
else dup STACK_TOKEN_IN = if pop "IN"
else dup STACK_TOKEN_END = if pop "END"
else dup STACK_TOKEN_LPAREN = if pop "("
else dup STACK_TOKEN_RPAREN = if pop ")"
else dup STACK_TOKEN_COMMA = if pop ","
else dup STACK_TOKEN_IF = if pop "IF"
else dup STACK_TOKEN_ELSE = if pop "ELSE"
else dup STACK_TOKEN_FI = if pop "FI"
else dup STACK_TOKEN_DATA = if pop "DATA"
else dup STACK_TOKEN_IMPORT = if pop "IMPORT"
else dup STACK_TOKEN_CONST = if pop "CONST"
else dup STACK_TOKEN_MATCH = if pop "MATCH"
else dup STACK_TOKEN_WHILE = if pop "WHILE"
else dup STACK_TOKEN_LOOP = if pop "LOOP"
else dup STACK_TOKEN_POOL = if pop "POOL"
else panic pop "" fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi -- (string)
end
const STACK_ILLEGAL_NO_ERROR 0
const STACK_ILLEGAL_INVALID 1
const STACK_ILLEGAL_STRING_NULL 2
const STACK_ILLEGAL_STRING_\N 3
const STACK_ILLEGAL_STRING_EOF 4
data stack_token (int kind, string value, int pos, int err)
func stack_token.init.empty () (stack_token) in
0 "" 0 0 stack_token.init
end
func stack_token.init.ok (int, string, int) (stack_token) in -- kind, value, pos
STACK_ILLEGAL_NO_ERROR stack_token.init
end
data stack_lexer (string buffer, int pos, int read_pos, int ch, string filename)
func stack_lexer.init.with_buffer (string, string) (stack_lexer) in -- buffer, filename
0 0 0 rot4 stack_lexer.init dup stack_lexer.read pop -- stack_lexer
end
func stack_lexer.pos.to_lc' (stack_lexer, int) (int, int) in -- lexer, pos
dup 0 >= if -- lexer, pos
swp dup stack_lexer.buffer -- pos, lexer, string
-- lexer, pos
rot dup rot swp string.!! BYTE_\N = if -- lexer, pos
1 - stack_lexer.pos.to_lc' -- line, col
pop 1 + 1 -- line+1, 1
else
1 - stack_lexer.pos.to_lc' -- line, col
1 + -- line, col+1
fi
else
pop2 1 1
fi -- int, int
end
func stack_lexer.pos.to_lc (stack_lexer, int) (int, int) in -- lexer, pos
1 - stack_lexer.pos.to_lc'
end
func stack_lexer.peek (stack_lexer) (int) in
dup stack_lexer.buffer dup2 -- lexer, buffer, lexer, buffer
string.len swp stack_lexer.read_pos <= if -- lexer, buffer
pop2 BYTE_EOF
else
swp stack_lexer.read_pos string.!!
fi -- byte
end
func stack_lexer.read (stack_lexer) (int) in
dup stack_lexer.peek dup2 stack_lexer.ch.set swp -- chr, stack_lexer
dup stack_lexer.read_pos dup2 stack_lexer.pos.set -- chr, stack_lexer, rpos
1 + dup2 stack_lexer.read_pos.set pop2 -- chr
end
func stack_lexer.skip.whitespace (stack_lexer) () in
dup stack_lexer.ch byte.isspace if dup stack_lexer.read pop stack_lexer.skip.whitespace else pop fi
end
func stack_lexer.skip.until_newline (stack_lexer) () in
dup stack_lexer.ch -- stack_lexer, ch
dup BYTE_\N = swp -- stack_lexer, bool, ch
dup BYTE_EOF = swp -- stack_lexer, bool, bool, ch
pop or not if -- stack_lexer
dup stack_lexer.read pop stack_lexer.skip.until_newline -- ()
else pop fi
end
func stack_lexer.next.number' (int, stack_lexer, int, string) (string) in -- pos, stack_lexer, ch, result
swp dup byte.isdigit if -- pos, stack_lexer, string, ch
byte.chr string.concat -- pos, stack_lexer, string
swp dup stack_lexer.read rot stack_lexer.next.number' -- string
else
pop rot' pop2
fi -- string
end
func stack_lexer.next.number (int, stack_lexer, int) (string) in -- pos, stack_lexer, ch
dup BYTE_- = if -- pos, stack_lexer, ch
pop dup stack_lexer.read "-"
else
""
fi -- pos, stack_lexer, ch, string
stack_lexer.next.number' -- string
end
func stack_lexer.next.string (int, stack_lexer, int, string) (stack_token) in -- pos, stack_lexer, ch, result
swp dup BYTE_QUOTE = not if -- pos, stack_lexer, result, ch
dup BYTE_EOF = if -- pos, stack_lexer, result, ch
pop3 STACK_TOKEN_ILLEGAL "" rot STACK_ILLEGAL_STRING_EOF stack_token.init
else dup BYTE_NULL = if
pop3 STACK_TOKEN_ILLEGAL "" rot STACK_ILLEGAL_STRING_NULL stack_token.init
else dup BYTE_\N = if
pop3 STACK_TOKEN_ILLEGAL "" rot STACK_ILLEGAL_STRING_\N stack_token.init
else
dup BYTE_\ = if -- pos, stack_lexer, result, ch
byte.chr string.concat -- pos, stack_lexer, result
swp dup stack_lexer.read rot swp
fi -- pos, stack_lexer, result, ch
byte.chr string.concat -- pos, stack_lexer, result
swp dup stack_lexer.read rot stack_lexer.next.string -- stack_token
fi fi fi -- stack_token
else
pop "\"" string.concat -- pos, stack_lexer, result
swp stack_lexer.read pop swp -- result, pos
STACK_TOKEN_STRING rot' stack_token.init.ok -- stack_token
fi -- stack_token
end
func stack_lexer.next.name' (int, stack_lexer, int, string) (string) in -- pos stack_lexer, ch, result
swp dup byte.isname if -- int, stack_lexer, result, ch
byte.chr string.concat -- int, stack_lexer, result
swp dup stack_lexer.read -- int, result, stack_lexer, ch
rot stack_lexer.next.name' -- string
else
swp rot4' pop3
fi
end
func stack_lexer.next.name (int, stack_lexer, int) (stack_token) in -- pos, stack_lexer, ch
dup3 "" stack_lexer.next.name' -- int, stack_lexer, int, string
dup "import" string.= if -- int, stack_lexer, int, string
pop3 STACK_TOKEN_IMPORT "" rot stack_token.init.ok
else dup "func" string.= if
pop3 STACK_TOKEN_FUNC "" rot stack_token.init.ok
else dup "in" string.= if
pop3 STACK_TOKEN_IN "" rot stack_token.init.ok
else dup "end" string.= if
pop3 STACK_TOKEN_END "" rot stack_token.init.ok
else dup "data" string.= if
pop3 STACK_TOKEN_DATA "" rot stack_token.init.ok
else dup "true" string.= if
pop3 STACK_TOKEN_BOOLEAN "true" rot stack_token.init.ok
else dup "false" string.= if
pop3 STACK_TOKEN_BOOLEAN "false" rot stack_token.init.ok
else dup "if" string.= if
pop3 STACK_TOKEN_IF "" rot stack_token.init.ok
else dup "else" string.= if
pop3 STACK_TOKEN_ELSE "" rot stack_token.init.ok
else dup "fi" string.= if
pop3 STACK_TOKEN_FI "" rot stack_token.init.ok
else dup "const" string.= if
pop3 STACK_TOKEN_CONST "" rot stack_token.init.ok
else dup "@import" string.= if
pop3 STACK_TOKEN_IMPORT "" rot stack_token.init.ok
else dup "match" string.= if
pop3 STACK_TOKEN_MATCH "" rot stack_token.init.ok
else dup "while" string.= if
pop3 STACK_TOKEN_WHILE "" rot stack_token.init.ok
else dup "loop" string.= if
pop3 STACK_TOKEN_LOOP "" rot stack_token.init.ok
else dup "pool" string.= if
pop3 STACK_TOKEN_POOL "" rot stack_token.init.ok
else
rot4' pop2 STACK_TOKEN_NAME rot' stack_token.init.ok
fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi fi -- stack_token
end
func stack_lexer.next (stack_lexer) (stack_token) in
dup stack_lexer.skip.whitespace -- stack_lexer
dup stack_lexer.pos 0 + swp -- pos, stack_lexer
dup stack_lexer.ch -- pos, stack_lexer, ch
dup BYTE_EOF = if -- pos, stack_lexer, ch
pop stack_lexer.read pop STACK_TOKEN_EOF "" rot stack_token.init.ok
else dup BYTE_LPAREN = if
pop stack_lexer.read pop STACK_TOKEN_LPAREN "" rot stack_token.init.ok
else dup BYTE_RPAREN = if
pop stack_lexer.read pop STACK_TOKEN_RPAREN "" rot stack_token.init.ok
else dup BYTE_COMMA = if
pop stack_lexer.read pop STACK_TOKEN_COMMA "" rot stack_token.init.ok
else dup BYTE_- = rot dup stack_lexer.peek BYTE_- = rot and swp rot' if
swp dup stack_lexer.skip.until_newline -- pos, ch, stack_lexer
rot' pop2 stack_lexer.next
else dup byte.isdigit rot' dup BYTE_- = rot dup stack_lexer.peek byte.isdigit rot and swp rot4' rot or if
dup3 stack_lexer.next.number -- pos, stack_lexer, ch, string
rot' pop2 swp STACK_TOKEN_NUMBER rot' stack_token.init.ok
else dup BYTE_QUOTE = if
pop dup stack_lexer.read "\"" stack_lexer.next.string
else dup byte.isname if
stack_lexer.next.name -- stack_token
else
int.show swp stack_lexer.read pop STACK_TOKEN_ILLEGAL swp rot STACK_ILLEGAL_INVALID stack_token.init
fi fi fi fi fi fi fi fi -- stack_token
end
func stack_lexer.dump (stack_lexer) () in
dup stack_lexer.next -- stack_lexer, token
dup stack_token.kind -- stack_lexer, token, kind
stack_token_kind.map -- stack_lexer, token, s
swp dup stack_token.value dup string.len 0 > if -- stack_lexer, s, token, value
rot "(" string.concat swp string.concat ")" string.concat
else
pop swp
fi -- stack_lexer, token, s
"\n" string.concat string.stdout stack_token.kind -- stack_lexer, kind
STACK_TOKEN_EOF = not if stack_lexer.dump else pop fi -- ()
end
-- STACK PARSER
data stack_parser (stack_lexer lexer, stack_token tok, stack_token next_tok)
func stack_parser.init.with_lexer (stack_lexer) (stack_parser) in
stack_token.init.empty stack_token.init.empty stack_parser.init
dup stack_parser.read pop
end
func stack_parser.peek (stack_parser) (stack_token) in stack_parser.next_tok end
func stack_parser.read (stack_parser) (stack_token) in
dup dup stack_parser.peek stack_parser.tok.set
dup dup stack_parser.lexer stack_lexer.next stack_parser.next_tok.set
stack_parser.tok
end
func stack_parser.parse.exprs.until (stack_parser, int, array) (array) in
rot' dup2 swp stack_parser.peek stack_token.kind = if -- arr p kind
pop stack_parser.read pop -- array
else
swp dup stack_parser.parse.expr unwrap -- arr kind p expr
rot4 dup rot stack_ast_expr.& array.append unwrap -- kind parser arr
rot' swp rot stack_parser.parse.exprs.until -- array
fi -- array
end
func stack_parser.parse.exprs.while (stack_parser, array) (array) in -- parser, array<expr>
swp dup stack_parser.parse.expr if -- array, parser, expr
rot dup rot stack_ast_expr.& array.append unwrap -- parser, array
stack_parser.parse.exprs.while -- array
else
pop2
fi -- array
end
func stack_parser.parse.exprs.until2 (stack_parser, int, int, array) (array) in
rot4' dup3 rot dup stack_parser.peek stack_token.kind rot4 =
swp dup stack_parser.peek stack_token.kind rot4 = rot or if -- arr, parser, k1, k2, parser
pop3 stack_parser.read pop -- array
else
pop rot4 rot4 dup stack_parser.parse.expr unwrap -- k1, k2, array, parser, expr
rot dup rot stack_ast_expr.& array.append unwrap -- k1, k2, parser, array
swp rot4' stack_parser.parse.exprs.until2 -- array
fi -- array
end
func stack_parser.parse.names.until' (stack_parser, array) (array) in
swp dup stack_parser.read -- arr, p, tok
dup stack_token.kind STACK_TOKEN_NAME = unwrap -- arr, p, tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init -- arr, p, node
rot dup rot stack_ast_node.& array.append unwrap -- parser arr
swp dup stack_parser.read dup stack_token.kind STACK_TOKEN_RPAREN = if -- arr, parser, tok
pop2
else dup stack_token.kind STACK_TOKEN_COMMA = if
pop swp stack_parser.parse.names.until'
else
panic pop2
fi fi -- array
end
func stack_parser.parse.names.until (stack_parser, array) (array) in
swp dup stack_parser.peek stack_token.kind STACK_TOKEN_RPAREN = if -- arr p
stack_parser.read pop -- array
else
swp stack_parser.parse.names.until'
fi -- array
end
func stack_parser.parse.cond (stack_parser) (stack_ast_cond) in
dup stack_parser.read -- parser, tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init -- parser, node
swp dup STACK_TOKEN_ELSE STACK_TOKEN_FI stack_ast_expr.sizeof array.init.with_sz -- node, parser, parser, k1, k2, array
stack_parser.parse.exprs.until2 -- node, parser, if_
swp -- node, if_, parser
dup stack_parser.tok stack_token.kind STACK_TOKEN_ELSE = if -- node, if_, parser
dup STACK_TOKEN_FI stack_ast_expr.sizeof array.init.with_sz -- node, if_, parser, parser, k, array
stack_parser.parse.exprs.until -- node, if_, parser, else_
swp
else
stack_ast_expr.sizeof array.init.with_sz -- node, if_, parser, array
swp
fi -- node, if_, else_, parser
pop stack_ast_cond.init -- cond
end
func stack_parser.parse.names.until.in (stack_parser, array) (array) in
swp dup stack_parser.read -- arr, p, tok
dup stack_token.kind STACK_TOKEN_NAME = unwrap -- arr, p, tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init -- arr, p, node
rot dup rot stack_ast_node.& array.append unwrap -- parser arr
swp dup stack_parser.peek stack_token.kind -- arr, parser, kind
dup STACK_TOKEN_IN = if -- arr, parser, kind
pop2
else dup STACK_TOKEN_EOF = if -- arr, parser, kind
todo pop2
else
pop swp stack_parser.parse.names.until.in
fi fi -- array
end
func stack_parser.parse.match (stack_parser) (stack_ast_match) in
dup stack_parser.read -- parser, tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init -- parser, match
swp -- match, parser
dup stack_ast_node.sizeof array.init.with_sz -- match, parser, parser, array<node>
stack_parser.parse.names.until.in swp -- match, array<stack_ast_node>, parser
dup stack_parser.read stack_token.kind STACK_TOKEN_IN = unwrap -- match, array<node>, parser
dup STACK_TOKEN_END stack_ast_expr.sizeof array.init.with_sz stack_parser.parse.exprs.until swp pop -- match, binds, exprs
stack_ast_match.init -- match
end
func stack_parser.parse.while (stack_parser) (stack_ast_while) in
dup stack_parser.read -- parser, tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init -- parser, node
swp dup STACK_TOKEN_LOOP stack_ast_expr.sizeof array.init.with_sz -- node, parser, parser, k1, array
stack_parser.parse.exprs.until -- node, parser, while_
swp -- node, while_, parser
dup STACK_TOKEN_POOL stack_ast_expr.sizeof array.init.with_sz -- node, while_, parser, parser, k, array
stack_parser.parse.exprs.until -- node, while_, parser, loop_
swp -- node, whike_, loop_, parser
pop stack_ast_while.init -- while
end
func stack_parser.illegal.showf (stack_parser) () in
dup stack_parser.lexer stack_lexer.filename string.stdout ":" string.stdout
dup dup stack_parser.lexer swp stack_parser.peek stack_token.pos -- parser, lexer, pos
stack_lexer.pos.to_lc -- parser, line, col
swp int.show string.stdout ":" string.stdout int.show string.stdout
", " string.stdout "Lexical Error: " string.stdout
dup stack_parser.peek dup stack_token.err -- parser, tok, err
dup STACK_ILLEGAL_INVALID = if -- parser, tok, err
"Invalid character: " string.stdout pop2
else dup STACK_ILLEGAL_STRING_NULL = if
"String contains null character" string.stdout pop2
else dup STACK_ILLEGAL_STRING_\N = if
"String contains new line character" string.stdout pop2
else dup STACK_ILLEGAL_STRING_EOF = if
"Unterminated string" string.stdout pop2
else
panic pop2
fi fi fi fi -- parser
"\n" string.stdout
pop
end
func stack_parser.parse.expr (stack_parser) (stack_ast_expr, bool) in
dup stack_parser.peek stack_token.kind STACK_TOKEN_NAME = if -- parser
dup stack_parser.read -- parser, tok
dup stack_token.value swp stack_token.pos stack_ast_node.init -- node
STACK_AST_EXPR_NAME swp stack_ast_node.& stack_ast_expr.init -- expr
true
else dup stack_parser.peek stack_token.kind STACK_TOKEN_NUMBER = if
dup stack_parser.read -- parser, tok
dup stack_token.value swp stack_token.pos stack_ast_node.init -- node
STACK_AST_EXPR_NUMBER swp stack_ast_node.& stack_ast_expr.init -- expr
true
else dup stack_parser.peek stack_token.kind STACK_TOKEN_BOOLEAN = if
dup stack_parser.read -- parser, tok
dup stack_token.value swp stack_token.pos stack_ast_node.init -- node
STACK_AST_EXPR_BOOLEAN swp stack_ast_node.& stack_ast_expr.init -- expr
true
else dup stack_parser.peek stack_token.kind STACK_TOKEN_STRING = if
dup stack_parser.read -- parser, tok
dup stack_token.value swp stack_token.pos stack_ast_node.init -- node
STACK_AST_EXPR_STRING swp stack_ast_node.& stack_ast_expr.init -- expr
true
else dup stack_parser.peek stack_token.kind STACK_TOKEN_IF = if
stack_parser.parse.cond -- stack_ast_cond
STACK_AST_EXPR_COND swp stack_ast_cond.& stack_ast_expr.init -- expr
true
else dup stack_parser.peek stack_token.kind STACK_TOKEN_MATCH = if
stack_parser.parse.match -- stack_ast_match
STACK_AST_EXPR_MATCH swp stack_ast_match.& stack_ast_expr.init -- expr
true
else dup stack_parser.peek stack_token.kind STACK_TOKEN_WHILE = if
stack_parser.parse.while -- stack_ast_while
STACK_AST_EXPR_WHILE swp stack_ast_while.& stack_ast_expr.init -- expr
true
else dup stack_parser.peek stack_token.kind STACK_TOKEN_ILLEGAL = if
dup stack_parser.illegal.showf
pop 0 0 int.& stack_ast_expr.init false
else
pop 0 0 int.& stack_ast_expr.init false
fi fi fi fi fi fi fi fi -- expr, ok
end
func stack_parser.parse.func (stack_parser) (stack_ast_func) in -- parser
dup stack_parser.read stack_token.kind STACK_TOKEN_FUNC = unwrap -- parser
dup stack_parser.read dup stack_token.kind STACK_TOKEN_NAME = unwrap -- parser tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init swp -- name, parser
dup stack_parser.read stack_token.kind STACK_TOKEN_LPAREN = unwrap -- name, parser
dup stack_ast_node.sizeof array.init.with_sz stack_parser.parse.names.until swp -- name, array<stack_ast_node>, parser
dup stack_parser.read stack_token.kind STACK_TOKEN_LPAREN = unwrap -- name, args, parser
dup stack_ast_node.sizeof array.init.with_sz stack_parser.parse.names.until swp -- name, args, rets, parser
dup stack_parser.read stack_token.kind STACK_TOKEN_IN = unwrap -- name, parser
dup STACK_TOKEN_END stack_ast_expr.sizeof array.init.with_sz stack_parser.parse.exprs.until swp pop -- name, args, rets, exprs
stack_ast_func.init -- func
end
func stack_parser.parse.data_field.until' (stack_parser, array) (array) in -- p, arr
swp -- arr, p
dup stack_parser.read -- arr, p, tok
dup stack_token.kind STACK_TOKEN_NAME = unwrap -- arr, p, tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init rot' -- type, arr, p
dup stack_parser.read -- type, arr, p, tok
dup stack_token.kind STACK_TOKEN_NAME = unwrap -- type, arr, p, tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init rot' -- type, name, arr, p
rot4' rot4' stack_ast_data_field.init -- arr, p, field
rot dup rot stack_ast_data_field.& array.append unwrap -- parser arr
swp dup stack_parser.read dup stack_token.kind STACK_TOKEN_RPAREN = if -- arr, parser, tok
pop2
else dup stack_token.kind STACK_TOKEN_COMMA = if
pop swp stack_parser.parse.data_field.until'
else
panic pop2
fi fi -- array
end
func stack_parser.parse.data_field.until (stack_parser, array) (array) in
swp dup stack_parser.peek stack_token.kind STACK_TOKEN_RPAREN = if -- arr p
stack_parser.read pop -- array
else
swp stack_parser.parse.data_field.until'
fi -- array
end
func stack_parser.parse.data (stack_parser) (stack_ast_data) in -- parser
dup stack_parser.read stack_token.kind STACK_TOKEN_DATA = unwrap -- parser
dup stack_parser.read dup stack_token.kind STACK_TOKEN_NAME = unwrap -- parser tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init swp -- name, parser
dup stack_parser.read stack_token.kind STACK_TOKEN_LPAREN = unwrap -- name, parser
dup stack_ast_data_field.sizeof array.init.with_sz stack_parser.parse.data_field.until swp -- name, array<stack_ast_data_field>, parser
pop -- name, array
stack_ast_data.init -- data
end
func stack_parser.parse.const (stack_parser) (stack_ast_const) in -- parser
dup stack_parser.read stack_token.kind STACK_TOKEN_CONST = unwrap -- parser
dup stack_parser.read dup stack_token.kind STACK_TOKEN_NAME = unwrap -- parser tok
dup2 stack_token.value rot stack_token.pos stack_ast_node.init swp -- name, parser
dup stack_ast_expr.sizeof array.init.with_sz stack_parser.parse.exprs.while swp -- name, array<stack_ast_data_field>, parser
pop -- name, array
stack_ast_const.init -- const
end
func stack_parser.parse.import (stack_parser) (stack_ast_import) in -- parser
dup stack_parser.read stack_token.kind STACK_TOKEN_IMPORT = unwrap -- parser
dup stack_parser.read dup stack_token.kind STACK_TOKEN_STRING = unwrap -- parser tok
dup2 stack_token.value stack_assembler.emit.string.interpret rot stack_token.pos stack_ast_node.init swp -- name, parser
pop -- name
stack_ast_import.init -- import
end
func stack_parser.parse' (stack_parser, stack_ast) (stack_ast) in -- parser, ast
swp dup stack_parser.peek dup stack_token.kind STACK_TOKEN_EOF = if -- ast, parser, tok
pop2
else
dup stack_token.kind STACK_TOKEN_DATA = if -- ast, parser, tok
pop dup stack_parser.parse.data -- ast, parser, data
rot dup rot stack_ast.features.append.data -- parser, ast
else dup stack_token.kind STACK_TOKEN_FUNC = if
pop dup stack_parser.parse.func -- ast, parser, func
rot dup rot stack_ast.features.append.func -- parser, ast
else dup stack_token.kind STACK_TOKEN_IMPORT = if
pop dup stack_parser.parse.import -- ast, parser, import
rot dup rot stack_ast.features.append.import -- parser, ast
else dup stack_token.kind STACK_TOKEN_CONST = if
pop dup stack_parser.parse.const -- ast, parser, const
rot dup rot stack_ast.features.append.const -- parser, ast
else
panic pop swp
fi fi fi fi -- parser, ast
stack_parser.parse' -- ast
fi -- ast
end
func stack_parser.parse (stack_parser) (stack_ast, bool) in -- ast
stack_ast.init.empty -- stack_parser, ast
stack_parser.parse' true -- ast, ok
end
data stack_ast_node (stack_parser parser, string value, int pos)
data stack_ast_cond (stack_ast_node cond, array if_, array else_) -- array<stack_ast_expr>, array<stack_ast_expr>
data stack_ast_match (stack_ast_node node, array binds, array exprs) -- array<stack_ast_node>, array<stack_ast_expr>
data stack_ast_while (stack_ast_node node, array while_, array exprs) -- array<stack_ast_expr>, array<stack_ast_expr>
const STACK_AST_EXPR_NUMBER 0
const STACK_AST_EXPR_BOOLEAN 1
const STACK_AST_EXPR_STRING 2
const STACK_AST_EXPR_NAME 3
const STACK_AST_EXPR_COND 4
const STACK_AST_EXPR_MATCH 5
const STACK_AST_EXPR_WHILE 6
data stack_ast_expr (int kind, ptr expr)
data stack_ast_data_field (stack_ast_node type, stack_ast_node name)
data stack_ast_data (stack_ast_node name, array fields)
data stack_ast_func (stack_ast_node name, array args, array rets, array exprs)
data stack_ast_const (stack_ast_node name, array exprs)
data stack_ast_import (stack_ast_node name)
const STACK_AST_FEATURE_DATA 0
const STACK_AST_FEATURE_FUNC 1
const STACK_AST_FEATURE_CONST 2
const STACK_AST_FEATURE_IMPORT 3
data stack_ast_feature (int kind, ptr feature)
data stack_ast (array features)
func stack_ast.init.empty () (stack_ast) in
stack_ast_feature.sizeof array.init.with_sz stack_ast.init
end
func stack_ast.append (stack_ast, stack_ast) () in -- ast, ast'
stack_ast.features swp stack_ast.features swp array.extend unwrap
end
func stack_ast.features.append (stack_ast, stack_ast_feature) () in
swp stack_ast.features swp stack_ast_feature.& array.append unwrap
end
func stack_ast.features.append.func (stack_ast, stack_ast_func) () in
stack_ast_func.& STACK_AST_FEATURE_FUNC swp stack_ast_feature.init stack_ast.features.append
end
func stack_ast.features.append.data (stack_ast, stack_ast_data) () in
stack_ast_data.& STACK_AST_FEATURE_DATA swp stack_ast_feature.init stack_ast.features.append
end
func stack_ast.features.append.const (stack_ast, stack_ast_const) () in
stack_ast_const.& STACK_AST_FEATURE_CONST swp stack_ast_feature.init stack_ast.features.append
end
func stack_ast.features.append.import (stack_ast, stack_ast_import) () in
stack_ast_import.& STACK_AST_FEATURE_IMPORT swp stack_ast_feature.init stack_ast.features.append
end
const stack_ast.dump.indent 4
func stack_ast.dump.cond (int, stack_ast_cond) () in -- indent, cond
swp dup " " swp string.repeat string.stdout "IF\n" string.stdout -- cond, indent
dup stack_ast.dump.indent + -- cond, indent, indent+
rot dup stack_ast_cond.if_ rot swp -- indent, cond, indent+, if_
stack_ast.dump.exprs swp -- cond, indent
dup " " swp string.repeat string.stdout "ELSE\n" string.stdout
dup stack_ast.dump.indent + -- cond, indent, indent+
rot dup stack_ast_cond.else_ rot swp -- indent, cond, indent+, else_
stack_ast.dump.exprs swp -- cond, indent
dup " " swp string.repeat string.stdout "FI\n" string.stdout
pop2
end
func stack_ast.dump.binds' (int, array) () in -- i, names
dup2 array.count < if -- i, name
dup2 swp array.get unwrap stack_ast_node.* -- i, names, node
" " string.stdout stack_ast_node.value string.stdout -- i, names
swp 1 + swp stack_ast.dump.binds' -- ()
else
pop2
fi -- ()
end
func stack_ast.dump.binds (array) () in 0 swp stack_ast.dump.binds' end
func stack_ast.dump.match (int, stack_ast_match) () in -- indent, match
swp -- match, indent
dup " " swp string.repeat string.stdout "MATCH" string.stdout -- match, indent
swp dup stack_ast_match.binds stack_ast.dump.binds swp -- match, indent
"\n" string.stdout -- match, indent
dup stack_ast.dump.indent + -- match, indent, indent+
rot dup stack_ast_match.exprs rot swp -- indent, match, indent+, exprs
stack_ast.dump.exprs swp -- match, indent
pop2
end
func stack_ast.dump.while (int, stack_ast_while) () in -- indent, while
swp -- while, indent
dup " " swp string.repeat string.stdout "WHILE\n" string.stdout -- while, indent
dup stack_ast.dump.indent + -- cond, indent, indent+
rot dup stack_ast_while.while_ rot swp -- indent, cond, indent+, while_
stack_ast.dump.exprs swp -- cond, indent
dup " " swp string.repeat string.stdout "LOOP\n" string.stdout
dup stack_ast.dump.indent + -- cond, indent, indent+
rot dup stack_ast_while.exprs rot swp -- indent, cond, indent+, exprs
stack_ast.dump.exprs swp -- cond, indent
dup " " swp string.repeat string.stdout "POOL\n" string.stdout
pop2
end
func stack_ast.dump.exprs' (int, int, array) () in -- indent, i, exprs
dup2 array.count < if -- indent, i, exprs
dup2 swp array.get unwrap stack_ast_expr.* -- indent, i, exprs, expr
rot4 swp -- i, exprs, indent, expr
dup stack_ast_expr.kind dup STACK_AST_EXPR_NUMBER = if -- i, exprs, indent, expr, kind
pop dup2 swp " " swp string.repeat string.stdout
stack_ast_expr.expr stack_ast_node.* stack_ast_node.value string.stdout "\n" string.stdout pop
else dup STACK_AST_EXPR_BOOLEAN = if
pop dup2 swp " " swp string.repeat string.stdout
stack_ast_expr.expr stack_ast_node.* stack_ast_node.value string.stdout "\n" string.stdout pop
else dup STACK_AST_EXPR_STRING = if
pop dup2 swp " " swp string.repeat string.stdout
stack_ast_expr.expr stack_ast_node.* stack_ast_node.value string.stdout "\n" string.stdout pop
else dup STACK_AST_EXPR_NAME = if
pop dup2 swp " " swp string.repeat string.stdout
stack_ast_expr.expr stack_ast_node.* stack_ast_node.value string.stdout "\n" string.stdout pop
else dup STACK_AST_EXPR_COND = if
pop stack_ast_expr.expr stack_ast_cond.* -- i, exprs, indent, cond
swp dup rot -- i, exprs, indent, indent, cond
stack_ast.dump.cond -- i, exprs, indent
else dup STACK_AST_EXPR_MATCH = if
pop stack_ast_expr.expr stack_ast_match.* -- i, exprs, indent, match
swp dup rot -- i, exprs, indent, indent, match
stack_ast.dump.match -- i, exprs, indent
else dup STACK_AST_EXPR_WHILE = if
pop stack_ast_expr.expr stack_ast_while.* -- i, exprs, indent, while
swp dup rot -- i, exprs, indent, indent, while
stack_ast.dump.while -- i, exprs, indent
else
panic pop2
fi fi fi fi fi fi fi -- i, exprs, indent
rot 1 + rot stack_ast.dump.exprs' -- ()
else
pop3
fi -- ()
end
func stack_ast.dump.exprs (int, array) () in 0 swp stack_ast.dump.exprs' end
func stack_ast.dump.args' (int, int, array) () in -- indent, i, names
dup2 array.count < if -- indent, i, name
dup2 swp array.get unwrap stack_ast_node.* -- indent, i, names, node
rot4 dup " " swp string.repeat string.stdout -- i, names, node, indent
rot4 dup int.show "arg" swp string.concat string.stdout ": " string.stdout -- names, node, indent, i
rot stack_ast_node.value string.stdout "\n" string.stdout -- names, indent, i
1 + rot stack_ast.dump.args' -- ()
else
pop3
fi -- ()
end
func stack_ast.dump.args (int, array) () in 0 swp stack_ast.dump.args' end
func stack_ast.dump.rets' (int, int, array) () in -- indent, i, names
dup2 array.count < if -- indent, i, name
dup2 swp array.get unwrap stack_ast_node.* -- indent, i, names, node
rot4 dup " " swp string.repeat string.stdout -- i, names, node, indent
rot4 dup int.show "ret" swp string.concat string.stdout ": " string.stdout -- names, node, indent, i
rot stack_ast_node.value string.stdout "\n" string.stdout -- names, indent, i
1 + rot stack_ast.dump.rets' -- ()
else
pop3
fi -- ()
end
func stack_ast.dump.rets (int, array) () in 0 swp stack_ast.dump.rets' end
func stack_ast.dump.fields' (int, int, array) () in -- indent, i, array<stack_ast_data_field>
dup2 array.count < if -- indent, i, fields
dup2 swp array.get unwrap stack_ast_data_field.* -- indent, i, fields, field
rot4 dup " " swp string.repeat string.stdout -- i, fields, field, indent
swp -- i, fields, indent, field
dup stack_ast_data_field.name stack_ast_node.value string.stdout ": " string.stdout -- i, fields, indent, field
dup stack_ast_data_field.type stack_ast_node.value string.stdout "\n" string.stdout -- i, fields, indent, field
pop rot 1 + rot stack_ast.dump.fields' -- ()
else
pop3
fi -- ()
end
func stack_ast.dump.fields (int, array) () in 0 swp stack_ast.dump.fields' end
func stack_ast.dump' (int, array) () in
dup2 array.count < if -- i, array
dup2 swp array.get unwrap stack_ast_feature.* -- i, array, feat
dup stack_ast_feature.kind STACK_AST_FEATURE_DATA = if -- i, array, feat
"data " string.stdout
stack_ast_feature.feature stack_ast_data.* dup stack_ast_data.name stack_ast_node.value string.stdout -- i, array, data
"\n" string.stdout
dup stack_ast_data.fields -- i, array, data, fields
stack_ast.dump.indent swp stack_ast.dump.fields -- i, array, data
"\n" string.stdout
pop
else dup stack_ast_feature.kind STACK_AST_FEATURE_FUNC = if -- i, array, feat
"func " string.stdout
stack_ast_feature.feature stack_ast_func.* dup stack_ast_func.name stack_ast_node.value string.stdout -- i, array, func
"\n" string.stdout
dup stack_ast_func.args -- i, array, func, args
stack_ast.dump.indent swp stack_ast.dump.args -- i, array, func
dup stack_ast_func.rets -- i, array, func, rets
stack_ast.dump.indent swp stack_ast.dump.rets -- i, array, func
dup stack_ast_func.exprs -- i, array, func, exprs
" " stack_ast.dump.indent string.repeat string.stdout "body:\n" string.stdout
stack_ast.dump.indent stack_ast.dump.indent + swp stack_ast.dump.exprs -- i, array, func
"\n" string.stdout
pop
else dup stack_ast_feature.kind STACK_AST_FEATURE_CONST = if -- i, array, feat
"const " string.stdout
stack_ast_feature.feature stack_ast_const.* dup stack_ast_const.name stack_ast_node.value string.stdout -- i, array, const
"\n" string.stdout
dup stack_ast_const.exprs -- i, array, const, exprs
stack_ast.dump.indent swp stack_ast.dump.exprs -- i, array, const
"\n" string.stdout
pop
else dup stack_ast_feature.kind STACK_AST_FEATURE_IMPORT = if -- i, array, feat
"@import \"" string.stdout
stack_ast_feature.feature stack_ast_const.* dup stack_ast_const.name stack_ast_node.value string.stdout -- i, array, import
"\"\n\n" string.stdout
pop
else
dup stack_ast_feature.kind int.show string.stdout "\n" string.stdout
todo pop
fi fi fi fi -- i, array
swp 1 + swp stack_ast.dump'
else
pop2
fi -- ()
end
func stack_ast.dump (stack_ast) () in stack_ast.features 0 swp stack_ast.dump' end
-- STACK PREPROCESSOR
data stack_preprocessor (array imports) -- array<string>
func stack_preprocessor.init.empty () (stack_preprocessor) in
string.sizeof array.init.with_sz stack_preprocessor.init
end
func stack_preprocessor.imports.contains (stack_preprocessor, string) (bool) in
swp stack_preprocessor.imports -- string, array<string>
match path imports in
false 0 while -- ok, i
dup imports array.count < loop -- ok, i
dup imports swp -- ok, i, arr, i
array.get unwrap string.* -- ok, i, item
path string.= if -- ok, i
swp pop true swp
fi -- ok, i
1 + -- ok, i+1
pool -- ok, i
pop
end
end
func stack_preprocessor.imports.append (stack_preprocessor, string) (bool) in
swp stack_preprocessor.imports -- string, array<string>
swp string.& -- array<string>, ptr
array.append -- bool
end
func stack_home () (string) in
"STACK_HOME" os.env.get not if pop "." fi
end
const STACK_DATA_INT "int"
const STACK_DATA_PTR "ptr"
const STACK_DATA_BOOL "bool"
const STACK_DATA_STRING "string"
const STACK_INIT "init"
const STACK_SIZEOF "sizeof"
const STACK_OFFSET "offset"
const STACK_SPECIAL_FILE "__file__"
const STACK_SPECIAL_LINE "__line__"
const STACK_SPECIAL_COL "__col__"
func stack_preprocessor.run.base.consts (stack_preprocessor, stack_ast) () in -- pre, ast
"" __file__ stack_lexer.init.with_buffer -- lexer
stack_parser.init.with_lexer -- pre, ast, parser
dup dup -- pre, ast, parser, parser, parser
STACK_DATA_INT "." string.concat STACK_SIZEOF string.concat -- parser, parser, value
0 stack_ast_node.init swp -- sizeof_node parser
int.sizeof int.show -- sizeof_node, parser, string
0 stack_ast_node.init -- sizeof_node, 8_node
STACK_AST_EXPR_NUMBER -- sizeof_node, 8_node, kind
swp stack_ast_node.& stack_ast_expr.init -- sizeof_node, 8_expr
stack_ast_expr.sizeof array.init.with_sz -- sizeof_node, expr, array
dup rot stack_ast_expr.& array.append unwrap -- sizeof_node, array
stack_ast_const.init -- pre, ast, parser, int.sizeof
dup3 rot swp stack_ast.features.append.const pop pop -- pre, ast, parser
dup dup -- pre, ast, parser, parser, parser
STACK_DATA_PTR "." string.concat STACK_SIZEOF string.concat -- parser, parser, value
0 stack_ast_node.init swp -- sizeof_node parser
int.sizeof int.show -- sizeof_node, parser, string
0 stack_ast_node.init -- sizeof_node, 8_node
STACK_AST_EXPR_NUMBER -- sizeof_node, 8_node, kind
swp stack_ast_node.& stack_ast_expr.init -- sizeof_node, 8_expr
stack_ast_expr.sizeof array.init.with_sz -- sizeof_node, expr, array
dup rot stack_ast_expr.& array.append unwrap -- sizeof_node, array
stack_ast_const.init -- pre, ast, parser, int.sizeof
dup3 rot swp stack_ast.features.append.const pop pop -- pre, ast, parser
dup dup -- pre, ast, parser, parser, parser
STACK_DATA_BOOL "." string.concat STACK_SIZEOF string.concat -- parser, parser, value
0 stack_ast_node.init swp -- sizeof_node parser
int.sizeof int.show -- sizeof_node, parser, string
0 stack_ast_node.init -- sizeof_node, 8_node
STACK_AST_EXPR_NUMBER -- sizeof_node, 8_node, kind
swp stack_ast_node.& stack_ast_expr.init -- sizeof_node, 8_expr
stack_ast_expr.sizeof array.init.with_sz -- sizeof_node, expr, array
dup rot stack_ast_expr.& array.append unwrap -- sizeof_node, array
stack_ast_const.init -- pre, ast, parser, int.sizeof
dup3 rot swp stack_ast.features.append.const pop pop -- pre, ast, parser
pop3
end
func stack_preprocessor.run.import (int, stack_preprocessor, stack_ast) () in -- i, pre, ast
rot swp -- pre, i, ast
dup stack_ast.features dup array.count rot4 dup rot < if -- pre ast array<feat> i
dup2 array.get unwrap stack_ast_feature.* dup stack_ast_feature.kind rot4 pop -- pre, ast, i, feat, kind
dup STACK_AST_FEATURE_IMPORT = if -- pre, ast, i, feat, kind
pop stack_ast_feature.feature stack_ast_import.* stack_ast_import.name stack_ast_node.value -- pre ast i filename
"." string.concat STACK_EXT string.concat -- filename.stack
dup "r" stdlib.fopen unwrap -- pre ast i filename fd
dup 0 >= if -- pre ast i filename.stack fd
dup stdlib.fread.<eof> unwrap -- pre, ast, i, filename, fd, string
swp stdlib.fclose unwrap -- pre, ast, i, filename, string
match pre ast i path str in
pre path stack_preprocessor.imports.contains not if
str path stack_lexer.init.with_buffer -- stack_lexer
stack_parser.init.with_lexer -- stack_parser
stack_parser.parse unwrap -- ast'
pre dup2 swp -- ast' pre pre ast'
stack_preprocessor.run' pop -- ast'
ast swp stack_ast.append -- ()
pre path stack_preprocessor.imports.append unwrap -- ()
fi
i pre ast
end
else
pop -- pre ast i filename.stack
stack_home "/lib" string.concat "/" string.concat swp string.concat -- pre ast i path
match pre ast i path in
pre path stack_preprocessor.imports.contains not if
path "r" stdlib.fopen unwrap -- fd
dup stdlib.fread.<eof> unwrap -- fd, string
swp stdlib.fclose unwrap -- string
path stack_lexer.init.with_buffer -- stack_lexer
stack_parser.init.with_lexer -- stack_parser
stack_parser.parse unwrap -- ast'
pre dup2 swp -- ast' pre pre ast'
stack_preprocessor.run' pop -- ast'
ast swp stack_ast.append -- ()
pre path stack_preprocessor.imports.append unwrap -- ()
fi
i pre ast
end
fi -- i, pre, ast
else
pop pop rot'
fi -- i, pre, ast
rot 1 + rot' stack_preprocessor.run.import