-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathclasses.lua
More file actions
1179 lines (1019 loc) · 40 KB
/
Copy pathclasses.lua
File metadata and controls
1179 lines (1019 loc) · 40 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
--------------------------------------------------
-- general stuff:
---@class Position
---@field line integer?
---@field column integer?
---@field index nil @ -- TODO: maybe do add the index to all AstTokenNodes
---@class Options
---- tokenizer.lua: should numbers be parsed as signed int32 or doubles?
---- parser.lua: pass it along to the tokenizer
---- optimize/fold_const.lua: throw not supported error, because emulating an int32 machine is difficult
---- il_generator.lua: throw not supported error
---- dump.lua: should the int32 signature be used?
---- binary_serializer: should size_t be uint32 and Lua numbers be signed int32?
---@field use_int32 boolean?
---checked in several different parts during compilation
---@field optimizations Optimizations
--------------------------------------------------
-- tokens stuff:
---@alias TokenType
---| "blank"
---| "comment"
---| "string"
---| "number"
---| "ident" @ identifier
---| "eof" @ not created in the tokenizer, but created and used by the parser
---| "invalid"
---
---| "+"
---| "*"
---| "/"
---| "%"
---| "^"
---| "#"
---| ";"
---| ","
---| "("
---| ")"
---| "{"
---| "}"
---| "]"
---| "["
---| "<"
---| "<="
---| "="
---| "=="
---| ">"
---| ">="
---| "-"
---| "~="
---| "::"
---| ":"
---| "..."
---| ".."
---| "."
---keywords:
---| "and"
---| "break"
---| "do"
---| "else"
---| "elseif"
---| "end"
---| "false"
---| "for"
---| "function"
---| "if"
---| "in"
---| "local"
---| "nil"
---| "not"
---| "or"
---| "repeat"
---| "return"
---| "then"
---| "true"
---| "until"
---| "while"
---| "goto"
---@class AstTokenParams : Position
---@field token_type TokenType
---for `blank`, `comment`, `string`, `number`, `ident` and `invalid` tokens\
---"blank" tokens shall never contain `\n` in the middle of their value\
---"comment" tokens with `not src_is_block_str` do not contain trailing `\n`
---@field value string|number
---@field src_is_block_str boolean @ for `string` and `comment` tokens
---@field src_quote string @ for non block `string` tokens
---@field src_value string @ for non block `string` and `number` tokens
---@field src_has_leading_newline boolean @ for block `string` and `comment` tokens
---@field src_pad string @ the `=` chain for block `string` and `comment` tokens
---@field leading Token[] @ `blank` and `comment` tokens before this token. Set and used by the parser
---for `invalid` tokens
---@field error_code_insts ErrorCodeInstance[]
---@class Token : AstTokenParams
---@field index integer
--------------------------------------------------
-- ast stuff:
---@alias AstNodeType
---special:
---| "env_scope"
---| "functiondef"
---| "token"
---| "invalid"
---statements:
---| "empty"
---| "ifstat"
---| "testblock"
---| "elseblock"
---| "whilestat"
---| "dostat"
---| "fornum"
---| "forlist"
---| "repeatstat"
---| "funcstat"
---| "localstat"
---| "localfunc"
---| "label"
---| "retstat"
---| "breakstat"
---| "gotostat"
---| "call" @ expression or statement
---| "assignment"
---expressions:
---| "local_ref"
---| "upval_ref"
---| "index"
---| "unop"
---| "binop"
---| "concat"
---| "number"
---| "string"
---| "nil"
---| "boolean"
---| "vararg"
---| "func_proto"
---| "constructor"
---optimizer statements:
---| "inline_iife_retstat" @ inline immediately invoked function expression return statement
---| "loopstat"
---optimizer expressions:
---| "inline_iife" @ inline immediately invoked function expression
---line, column and leading is only used for some node types that represent a single token\
---each ose these nodes have a comment noting this\
---however even those those these value are optional,
---them being omitted means stripped/missing debug info\
---it should also be expected that only some of them could be `nil`
---@class AstNode : Position
---@field node_type AstNodeType
---@field leading Token[]|nil @ `"blank"` and `"comment"` tokens
---uses line, column and leading\
---purely describing the syntax
---@class AstTokenNode : AstNode, Token
---@field node_type "token"
---@field index nil @ overridden to `nil`
---the location of the error is defined in the ErrorCodeInstance\
---indicates a syntax error
---@class AstInvalidNode : AstNode
---@field node_type "invalid"
---@field error_code_inst ErrorCodeInstance
---nodes that ended up being unused due to this syntax error\
---99% of the time these are AstTokenNodes, however for unexpected_expression they
---can be any expression
---@field consumed_nodes AstNode[]|nil
---@class AstStatement : AstNode, ILLNode<AstStatement>
---@field list AstStatementList @ (overridden) back reference
---@field prev AstStatement? @ (overridden) `nil` if this is the first node
---@field next AstStatement? @ (overridden) `nil` if this is the last node
---@class AstParenWrapper
---@field open_paren_token AstTokenNode
---@field close_paren_token AstTokenNode
---@class AstExpression : AstNode
---should the expression be forced to evaluate to only one result
---caused by the expression being wrapped in `()`
---@field force_single_result boolean|nil
---similar to index expressions, the last one to close/most right one is
---the first one in the list/first one you encounter when processing the data
---@field src_paren_wrappers AstParenWrapper[]|nil
---@class AstStatementList : IntrusiveIndexedLinkedList<AstStatement>
---@field scope AstScope
---@field first AstStatement? @ (overridden)
---@field last AstStatement? @ (overridden)
---@class AstScope : AstNode
---@field parent_scope AstScope @ `nil` for AstENVScope (very top level)
---@field child_scopes AstScope[]
---@field body AstStatementList
---@field locals AstLocalDef[]
---@field labels AstLabel[]
---@class AstFunctionDef : AstScope, AstNode
---@field node_type "functiondef"
---@field is_main nil @ overridden by AstMain to be `true`
---@field source string
---is it `function foo:bar() end`?\
---`self` does not get added to `params`, but it does get a `whole_block = true` local,
---which is always the first one
---@field is_method boolean
---@field func_protos AstFunctionDef[]
---@field upvals AstUpvalDef[]
---@field is_vararg boolean
---@field vararg_token AstTokenNode|nil @ used when `is_vararg == true`
---all parameters are `whole_block = true` locals, except vararg
---@field params AstLocalReference[]
---@field param_comma_tokens AstTokenNode[] @ max length is `#params - 1`, min `0`
---@field open_paren_token AstTokenNode
---@field close_paren_token AstTokenNode
---@field function_token AstTokenNode @ position for any `closure` instructions
---@field end_token AstTokenNode
---@field eof_token nil @ overridden by AstMain to be an AstTokenNode
---@class AstFuncBase : AstNode
---@field func_def AstFunctionDef
---@class AstEmpty : AstStatement
---@field node_type "empty"
---@field semi_colon_token AstTokenNode
---@class AstIfStat : AstStatement
---@field node_type "ifstat"
---@field ifs AstTestBlock[]
---@field elseblock AstElseBlock|nil
---@field end_token AstTokenNode
---@class AstTestBlock : AstScope
---@field node_type "testblock"
---@field condition AstExpression
---@field if_token AstTokenNode @ for the first test block this is an `if` node_type, otherwise `elseif`
---@field then_token AstTokenNode @ position for the failure `jup` instruction
---@class AstElseBlock : AstScope
---@field node_type "elseblock"
---@field else_token AstTokenNode
---@class AstLoop
---evaluated by the jump linker. not `nil` after successful linking,
---**but only if there are any `break`s that linked to this loop**
---@field linked_breaks AstBreakStat[]|nil
---@class AstWhileStat : AstStatement, AstScope, AstLoop
---@field node_type "whilestat"
---@field condition AstExpression
---@field while_token AstTokenNode
---@field do_token AstTokenNode @ position for the failure `jmp` instruction
---@field end_token AstTokenNode @ position for the loop `jmp` instruction
---@class AstDoStat : AstStatement, AstScope
---@field node_type "dostat"
---@field do_token AstTokenNode
---@field end_token AstTokenNode
---@class AstForNum : AstStatement, AstScope, AstLoop
---@field node_type "fornum"
---`var` is referring to a `whole_block = true` local
---@field var AstLocalReference
---@field start AstExpression
---@field stop AstExpression
---@field step AstExpression|nil
---`var` is referring to a `whole_block = true` local
---@field for_token AstTokenNode @ position for the `forloop` instruction
---@field eq_token AstTokenNode
---@field first_comma_token AstTokenNode
---@field second_comma_token AstTokenNode|nil @ only used when `step` is not `nil`
---@field do_token AstTokenNode @ position for the `forprep` instruction
---@field end_token AstTokenNode
---@class AstForList : AstStatement, AstScope, AstLoop
---@field node_type "forlist"
---@field name_list AstLocalReference[]
---@field exp_list AstExpression[]
---@field exp_list_comma_tokens AstTokenNode[]
---all `name_list` names are used for a `whole_block = true` local
---@field for_token AstTokenNode @ position for the `tforcall` and `tforloop` instructions
---@field comma_tokens AstTokenNode[] @ max length is `#name_list - 1`
---@field in_token AstTokenNode
---@field do_token AstTokenNode @ position for the `jmp` to `tforcall` instruction
---@field end_token AstTokenNode
---@class AstRepeatStat : AstStatement, AstScope, AstLoop
---@field node_type "repeatstat"
---@field condition AstExpression
---@field repeat_token AstTokenNode
---@field until_token AstTokenNode @ position for the loop `jmp` instruction
---@class AstFuncStat : AstStatement, AstFuncBase
---@field node_type "funcstat"
---@field name AstExpression
---@class AstLocalFunc : AstStatement, AstFuncBase
---@field node_type "localfunc"
---@field name AstLocalReference
---@field local_token AstTokenNode
---@class AstLocalStat : AstStatement
---@field node_type "localstat"
---@field lhs AstLocalReference[]
---@field rhs AstExpression[]|nil @ `nil` = no assignment
---@field local_token AstTokenNode
---@field lhs_comma_tokens AstTokenNode[] @ max length is `#lhs - 1`
---@field rhs_comma_tokens AstTokenNode[]|nil @ `nil` when `rhs` is `nil`. max length is `#rhs - 1`
---@field eq_token AstTokenNode|nil @ only used if `rhs` is not `nil`
---@class AstLabel : AstStatement
---@field node_type "label"
---@field name string
---@field name_token AstTokenNode @ its value is `nil`
---@field open_token AstTokenNode @ opening `::`
---@field close_token AstTokenNode @ closing `::`
---@field linked_gotos AstGotoStat[]|nil @ evaluated by the jump linker. not `nil` after successful linking
---@class AstRetStat : AstStatement
---@field node_type "retstat"
---@field exp_list AstExpression[]|nil @ `nil` = no return values
---@field return_token AstTokenNode @ position for the `return` instruction
---@field exp_list_comma_tokens AstTokenNode[]
---@field semi_colon_token AstTokenNode|nil @ trailing `;`. `nil` = no semi colon
---@class AstBreakStat : AstStatement
---@field node_type "breakstat"
---@field break_token AstTokenNode @ position for the break `jmp` instruction
---@field linked_loop AstLoop[]|nil @ evaluated by the jump linker. not `nil` after successful linking
---@class AstGotoStat : AstStatement
---@field node_type "gotostat"
---@field target_name string @ name of the label to jump to
---@field target_token AstTokenNode @ its value is `nil`
---@field goto_token AstTokenNode @ position for the goto `jmp` instruction
---@field linked_label AstLabel|nil @ evaluated by the jump linker. not `nil` after successful linking
---@class AstCall : AstStatement, AstExpression
---@field node_type "call"
---@field is_selfcall boolean
---@field ex AstExpression
---only used if `is_selfcall == true`\
---function name. `src_is_ident` is always `true`
---@field suffix AstString
---@field args AstExpression[]
---@field args_comma_tokens AstTokenNode[]
---@field colon_token AstTokenNode @ position for the `self` instruction
---@field open_paren_token AstTokenNode|nil @ position for the `call` instruction
---@field close_paren_token AstTokenNode|nil @ position for `move` instructions moving out of temp regs
---@class AstAssignment : AstStatement
---@field node_type "assignment"
---@field lhs AstExpression[]
---@field rhs AstExpression[]
---@field lhs_comma_tokens AstTokenNode[]
---@field eq_token AstTokenNode
---@field rhs_comma_tokens AstTokenNode[]
---@class AstInlineIIFERetstat : AstStatement
---@field node_type "inline_iife_retstat"
---@field return_token AstTokenNode
---@field exp_list AstExpression[]|nil @ `nil` = no return values
---@field exp_list_comma_tokens AstTokenNode[]
---@field semi_colon_token AstTokenNode|nil @ trailing `;`. `nil` = no semi colon
---@field linked_inline_iife AstInlineIIFE
---@field leave_block_goto AstGotoStat
---@class AstLoopStat : AstStatement, AstScope, AstLoop
---@field node_type "loopstat"
---@field do_jump_back boolean|nil @ when false behaves like a dostat, except breakstat can link to this
---@field open_token AstTokenNode
---@field close_token AstTokenNode @ position for the loop `jmp` instruction
---uses line, column and leading
---@class AstLocalReference : AstExpression
---@field node_type "local_ref"
---@field name string
---@field reference_def AstLocalDef
---uses line, column and leading
---@class AstUpvalReference : AstExpression
---@field node_type "upval_ref"
---@field name string
---@field reference_def AstUpvalDef
---@class AstIndex : AstExpression
---@field node_type "index"
---@field ex AstExpression
---if this is an AstString with `src_is_ident == true`
---then it is representing a literal identifier
---@field suffix AstExpression
---Only used if it is a literal identifier\
---position for index related instructions
---@field dot_token AstTokenNode|nil
---`[` node_type if it is not a literal identifier
---@field suffix_open_token AstTokenNode|nil
---`]` node_type if it is not a literal identifier
---@field suffix_close_token AstTokenNode|nil
---if this is an index into `_ENV` where `_ENV.` did not exist in source
---@field src_ex_did_not_exist boolean|nil
---uses line, column and leading
---@class AstString : AstExpression
---@field node_type "string"
---@field value string
---if it was just an identifier in source.\
---Used in record field keys for table constructors\
---And when indexing with literal identifiers\
---Always `true` for AstCall `suffix` (where `is_selfcall == true`)
---@field src_is_ident boolean|nil
---used when `src_is_ident` is falsy
---@field src_is_block_str boolean|nil
---@field src_quote string|nil @ for non block strings
---@field src_value string|nil @ for non block strings
---@field src_has_leading_newline boolean|nil @ for block strings
---@field src_pad string|nil @ the `=` chain for block strings
---@alias AstUnOpOp "not"|"-"|"#"
---@class AstUnOp : AstExpression
---@field node_type "unop"
---@field op AstUnOpOp
---@field ex AstExpression
---@field op_token AstTokenNode @ position for the various unop instructions
---@alias ILBinOpOpBase "^"|"*"|"/"|"%"|"+"|"-"|"=="|"<"|"<="|"~="|">"|">="
---@alias AstBinOpOp ILBinOpOpBase|"and"|"or"
---@class AstBinOp : AstExpression
---@field node_type "binop"
---@field op AstBinOpOp
---@field left AstExpression
---@field right AstExpression
---@field op_token AstTokenNode @ position for the various binop instructions
---@class AstConcat : AstExpression
---@field node_type "concat"
---@field exp_list AstExpression[]
---max length is `#exp_list - 1`\
---first one is position for the `concat` instruction
---@field op_tokens AstTokenNode[]
---replaced by `concat_src_paren_wrappers`
---@field src_paren_wrappers nil
---replaces `src_paren_wrappers`. Think of each element in the main array
---containing the paren wrappers for the expression at that index.
---The `open_paren_token` comes before that expression, the `close_paren_token`
---comes after the very last expression.\
---For that reason this array will always be 1 shorter than the `exp_list`,
---since the wrappers around the last expression are handled by its own
---`src_paren_wrappers`.\
---a concat node is right associative, which means no paren wrapper can close
---any earlier than after the last expression. That means an expression like
---`(foo..bar)..baz` results in 2 concat nodes, while `foo..(bar..baz)` results in 1
---@field concat_src_paren_wrappers AstParenWrapper[][]
---uses line, column and leading
---@class AstNumber : AstExpression
---@field node_type "number"
---@field value number
---@field src_value string
---uses line, column and leading
---@class AstNil : AstExpression
---@field node_type "nil"
---uses line, column and leading
---@class AstBoolean : AstExpression
---@field node_type "boolean"
---@field value boolean
---uses line, column and leading
---@class AstVarArg : AstExpression
---@field node_type "vararg"
---@class AstFuncProto : AstExpression, AstFuncBase
---@field node_type "func_proto"
---@class AstField
---@field type "rec"|"list"
---@class AstRecordField : AstField
---@field type "rec"
---to represent a literal identifier this is
---a string expression with `src_is_ident == true`
---@field key AstExpression
---@field value AstExpression
---@field key_open_token AstTokenNode|nil @ `[` node_type if the key is using it
---@field key_close_token AstTokenNode|nil @ `]` node_type if the key is using it
---@field eq_token AstTokenNode @ position for the `settable` instruction
---@class AstListField : AstField
---@field type "list"
---@field value AstExpression
---@class AstConstructor : AstExpression
---@field node_type "constructor"
---@field fields AstField[]
---@field open_token AstTokenNode @ position for the `newtable` instruction
---`,` or `;` tokens, max length is `#fields`\
---position for `setlist` instructions if they are in the middle of the table constructor\
---(so the ones created because of fields per flush being reached)\
---also position for `call` instructions for calls without `open_paren_token`
---@field comma_tokens AstTokenNode[]
---position for `setlist` instructions if they are the last one\
---(so the ones not created because of fields per flush being reached)\
---also position for `move` instructions out of temp regs for calls without `close_paren_token`
---@field close_token AstTokenNode
---@class AstInlineIIFE : AstExpression, AstScope
---@field node_type "inline_iife"
---@field leave_block_label AstLabel
---@field linked_inline_iife_retstats AstInlineIIFERetstat[]
---@class AstUpvalDef
---@field def_type "upval"
---@field name string
---@field scope AstScope
---@field parent_def AstUpvalDef|AstLocalDef
---@field child_defs AstUpvalDef[]
---@field refs AstUpvalReference[] @ all upval references referring to this upval
---@class AstLocalDef
---@field def_type "local"
---@field name string
---@field scope AstScope
---i think this means it is defined at the start of
---the block and lasts for the entire block
---@field whole_block boolean?
---@field start_at AstStatement?
---@field start_offset (0|1)? @ `0` for "start before/at", `1` for "start after"
---@field child_defs AstUpvalDef[]
---@field refs AstLocalReference[] @ all local references referring to this local
---when true this did not exist in source, but
---was added because methods implicitly have the `self` parameter
---@field src_is_method_self boolean?
---NOTE: inheriting AstScope even though AstFunctionDef already inherits it [...]
---because sumneko.lua `3.4.2` otherwise thinks AstMain isn't an AstScope
---@class AstMain : AstFunctionDef, AstStatement, AstScope
---@field parent_scope AstENVScope
---@field is_main true
---@field is_method false
---@field line 0
---@field column 0
---@field end_line 0
---@field end_column 0
---@field is_vararg true
---if the first character of the parsed string is `#` then this contains
---the first line terminated by `\n` exclusive, but inclusive `#`
---@field shebang_line string|nil
---@field eof_token AstTokenNode @ to store trailing blank and comment tokens
---@class AstENVScope : AstScope
---@field node_type "env_scope"
---@field parent_scope nil @ overridden
---@field main AstMain
---@field body AstStatementList @ always empty
---@field locals AstLocalDef[] @ always exactly 1 `whole_block = true` local with the name `_ENV`
---@field labels AstLabel[] @ always empty
--------------------------------------------------
-- intermediate language:
---This data structure is created right before compilation as it is only needed during compilation
---@class ILRegisterGroup
---@field regs ILRegister[]
---the index for the first register in the `regs` array, once it has been determined
---@field first_reg_index integer?
---@alias ILPointerType
---| "reg"
---| "number"
---| "string"
---| "boolean"
---| "nil"
---@class ILPointer
---@field ptr_type ILPointerType
---@class ILRegister : ILPointer
---@field ptr_type "reg"
---@field name string|nil
---@field is_vararg boolean
---post IL generation data
---@field start_at ILInstruction
---@field stop_at ILInstruction
---@field total_get_count integer
---@field total_set_count integer
---@field temporary boolean?
---@field captured_as_upval boolean?
---@field current_reg ILCompiledRegister
---temp compilation data
---@field reg_group ILRegisterGroup?
---@field index_in_reg_group integer?
---@class ILVarargRegister : ILRegister
---@field name nil
---@field is_vararg true
---@class ILNumber : ILPointer
---@field ptr_type "number"
---@field value number
---@class ILString : ILPointer
---@field ptr_type "string"
---@field value string
---@class ILBoolean : ILPointer
---@field ptr_type "boolean"
---@field value boolean
---@class ILNil : ILPointer
---@field ptr_type "nil"
---@class ILUpval
---@field name string|nil
---@field parent_type "upval"|"local"|"env"
---@field parent_upval ILUpval|nil @ used if `parent_type == "upval"`
---@field reg_in_parent_func ILRegister|nil @ used if `parent_type == "local"`
---@field child_upvals ILUpval[]
---temp compilation data
---@field upval_index integer @ **zero based** needed for instructions using upvals
---technically most `ILPosition`s are tokens and therefore most of them have `leading` but it's not used atm
---@alias ILPosition Position
---@alias ILTypeFlags
---| 1 @ nil
---| 2 @ boolean
---| 4 @ number
---| 8 @ string
---| 16 @ function
---| 32 @ table
---| 64 @ userdata
---| 128 @ thread
---TODO: add some way to represent `NaN`
---@class ILType
---@field type_flags ILTypeFlags @ bit field
---bit field. Will never contain `table`. `userdata` only affects `light_userdata_prototypes`
---@field inferred_flags ILTypeFlags
---@field number_ranges ILTypeNumberRanges? @ -- TODO: make ranges non nullable when the flag is set
---@field string_ranges ILTypeNumberRanges? @ restriction on strings, like tostring-ed numbers
---@field string_values string[]? @ nil means no restriction - any string
---@field boolean_value boolean?
---@field function_prototypes ILFunction[]?
---TODO: this being `nil` means "any identity", which means an empty type actually requires an empty array.
---I'm pretty sure this is handled incorrectly for most type operations
---@field identities ILTypeIdentity[]?
---@field table_classes ILClass[]? @ union of classes
---@field userdata_classes ILClass[]? @ union of classes with metatables for full userdata objects
---@field light_userdata_prototypes string[]? @ named light userdata to make it comparable
-- TODO: what do threads even look like and what data do I need to represent a group of them?
---@class ILClass
---@field kvps ILClassKvp[]? @ `nil` if this class is for a (full) userdata object
---@field metatable ILClass?
---@field inferred boolean?
---@class ILClassKvp
---@field key_type ILType
---@field value_type ILType
---@alias ILTypeNumberRangePointType
---| 0 @ nothing
---| 1 @ everything
---| 2 @ integral
---| 3 @ non_integral
---@alias ILTypeNumberRanges ILTypeNumberRangePoint[]
---the first point in a ranges array must always exist and must be (-1/0) inclusive\
---points in a ranges array must be in order and there must not be duplicates
---@class ILTypeNumberRangePoint
---@field range_type ILTypeNumberRangePointType
---@field value number
---@field inclusive boolean
---The big benefit with this is that none of the data needs to be compared,
---it's just the id that needs to match
---@class ILTypeIdentity
---@field id number @ -- TODO: just how global is this id? I feel like it has to be truly unique
---@field type_flag ILTypeFlags @ a single flag indicating what type the identity is for
---@field function_instance any? @ -- TODO: what data structure
---@field table_instance any? @ -- TODO: what data structure
---@field userdata_instance any? @ -- TODO: what data structure
---@field thread_instance any? @ -- TODO: what data structure
---@alias ILInstructionType
---| "move"
---| "get_upval"
---| "set_upval"
---| "get_table"
---| "set_table"
---| "set_list"
---| "new_table"
---| "concat"
---| "binop"
---| "unop"
---| "label"
---| "jump"
---| "test"
---| "call"
---| "ret"
---| "closure"
---| "vararg"
---| "close_up"
---| "scoping"
---| "to_number"
---@alias ILInstructionGroupType
---| "forprep"
---| "forloop"
---| "tforcall"
---| "tforloop"
---@class ILInstructionGroup
---@field group_type ILInstructionGroupType
---@field start ILInstruction
---@field stop ILInstruction
---@field position Position?
---@class ILForprepGroup : ILInstructionGroup
---@field group_type "forprep"
---@field index_reg ILRegister
---@field limit_reg ILRegister
---@field step_reg ILRegister
---@field loop_jump ILJump
---@class ILForloopGroup : ILInstructionGroup
---@field group_type "forloop"
---@field index_reg ILRegister
---@field limit_reg ILRegister
---@field step_reg ILRegister
---@field loop_jump ILJump
---@class ILTforcallGroup : ILInstructionGroup
---@field group_type "tforcall"
---@class ILTforloopGroup : ILInstructionGroup
---@field group_type "tforloop"
---@class ILInstruction : ILLNode<ILInstruction>
---@field list ILInstructionList @ (overridden) back reference
---@field prev ILInstruction? @ (overridden) `nil` if this is the first node
---@field next ILInstruction? @ (overridden) `nil` if this is the last node
---@field inst_type ILInstructionType
---@field inst_group ILInstructionGroup
---@field position ILPosition|nil
---post IL generation data
---@field block ILBlock
---@field regs_start_at_list ILRegister[]?
---@field regs_start_at_lut table<ILRegister, boolean>?
---@field regs_stop_at_list ILRegister[]?
---@field regs_stop_at_lut table<ILRegister, boolean>?
---@field live_regs ILRegister[]
---@field pre_state ILState
---@field post_state ILState
---@field forced_list_index integer?
---@class ILInstructionList : IntrusiveIndexedLinkedList<ILInstruction>
---@field first ILInstruction? @ (overridden)
---@field last ILInstruction? @ (overridden)
---@class ILState
---@field reg_types table<ILRegister, ILType>
---@class ILMove : ILInstruction
---@field inst_type "move"
---@field result_reg ILRegister
---@field right_ptr ILPointer
---@class ILGetUpval : ILInstruction
---@field inst_type "get_upval"
---@field result_reg ILRegister
---@field upval ILUpval
---@class ILSetUpval : ILInstruction
---@field inst_type "set_upval"
---@field upval ILUpval
---@field right_ptr ILPointer
---@class ILGetTable : ILInstruction
---@field inst_type "get_table"
---@field result_reg ILRegister
---@field table_reg ILRegister
---@field key_ptr ILPointer
---@class ILSetTable : ILInstruction
---@field inst_type "set_table"
---@field table_reg ILRegister
---@field key_ptr ILPointer
---@field right_ptr ILPointer
---@class ILSetList : ILInstruction
---@field inst_type "set_list"
---@field table_reg ILRegister
---@field start_index integer
---@field right_ptrs ILPointer[] @ The last one can be an `ILVarargRegister`
---temp compilation data
---@field forced_list_index integer?
---@class ILNewTable : ILInstruction
---@field inst_type "new_table"
---@field result_reg ILRegister
---@field array_size integer
---@field hash_size integer
---@class ILConcat : ILInstruction
---@field inst_type "concat"
---@field result_reg ILRegister
---@field right_ptrs ILPointer[]
---temp compilation data
---@field forced_list_index integer?
---@class ILBinop : ILInstruction
---@field inst_type "binop"
---@field result_reg ILRegister
---@field op ILBinOpOpBase @ note the absence of "and" and "or"
---@field left_ptr ILPointer
---@field right_ptr ILPointer
---@field raw boolean @ wether or not this instruction can use meta methods or not. Used for fornum
---@class ILUnop : ILInstruction
---@field inst_type "unop"
---@field result_reg ILRegister
---@field op AstUnOpOp
---@field right_ptr ILPointer
---@class ILLabel : ILInstruction
---@field inst_type "label"
---@field name string|nil
---temp compilation data
---@field target_inst ILCompiledInstruction @ the instruction jumps to this label will jump to
---@class ILJump : ILInstruction
---@field inst_type "jump"
---@field label ILLabel
---temp compilation data\
---the jmp instruction that needs its `sbx` set after `inst_index`es have been evaluated
---@field jump_inst ILCompiledInstruction
---@class ILTest : ILInstruction
---@field inst_type "test"
---@field label ILLabel
---@field condition_ptr ILPointer
---@field jump_if_true boolean
---temp compilation data\
---the jmp instruction that needs its `sbx` set after `inst_index`es have been evaluated
---@field jump_inst ILCompiledInstruction
---@class ILCall : ILInstruction
---@field inst_type "call"
---@field func_reg ILRegister
---@field arg_ptrs ILPointer[] @ The last one can be an `ILVarargRegister`
---@field result_regs ILRegister[] @ The last one can be an `ILVarargRegister`
---temp compilation data
---@field register_list_index integer
---@field forced_list_index integer?
---@class ILRet : ILInstruction
---@field inst_type "ret"
---@field ptrs ILPointer[] @ The last one can be an `ILVarargRegister`
---temp compilation data
---@field forced_list_index integer?
---@class ILClosure : ILInstruction
---@field inst_type "closure"
---@field result_reg ILRegister
---@field func ILFunction
---@class ILVararg : ILInstruction
---@field inst_type "vararg"
---@field result_regs ILRegister[] @ The last one can be an `ILVarargRegister`
---temp compilation data
---@field register_list_index integer
---@class ILCloseUp : ILInstruction
---@field inst_type "close_up"
---@field regs ILRegister[]
---@class ILScoping : ILInstruction
---@field inst_type "scoping"
---@field regs ILRegister[]
---@class ILToNumber : ILInstruction
---@field inst_type "to_number"
---@field result_reg ILRegister
---@field right_ptr ILPointer
---@class ILFunction
---@field parent_func ILFunction|nil @ `nil` if main chunk
---@field inner_functions ILFunction[]
---@field instructions ILInstructionList @ intrusive ILL
---@field upvals ILUpval[]
---@field param_regs ILRegister[]
---@field is_vararg boolean
---@field source string?
---@field defined_position Position? @ usually the position of the `function_token`
---@field last_defined_position Position? @ usually the position of the `end_token`
---post IL generation data
---@field has_blocks boolean @ `blocks` on ILFunction and `block` on ILInstruction
---@field has_start_stop_insts boolean @ `start_at` and `stop_at` on ILRegister
---@field has_reg_liveliness boolean @ `regs_(start|stop)_at_(list|lut)` and `live_regs` on ILInstruction
---@field blocks ILBLockList @ intrusive ILL
---@field has_types boolean @ `(pre|post)_state` on ILInstruction
---@field has_reg_usage boolean @ `total_get/set_count` and `temporary` on ILRegister
---@field is_compiling boolean @ `closure_index` on ILFUnction and `captured_as_upval` and `current_reg` on ILRegister
---
---@field temp ILFunctionTemp
---temp compilation data
---@field closure_index integer @ **zero based** needed for closure instructions to know the function index
---@class ILBlock : ILLNode<ILBlock>
---@field list ILBLockList @ (overridden) back reference
---@field prev ILBlock? @ (overridden) `nil` if this is the first node
---@field next ILBlock? @ (overridden) `nil` if this is the last node
---@field source_links ILBlockLink[] @ blocks flowing into this block
---@field start_inst ILInstruction @ the first instruction in this block
---@field stop_inst ILInstruction @ the last instruction in this block
---@field is_main_entry_block boolean
---@field target_links ILBlockLink[] @ blocks this block can flow to
---@class ILBLockList : IntrusiveIndexedLinkedList<ILBLock>
---@field first ILBlock? @ (overridden)
---@field last ILBlock? @ (overridden)
---@class ILBlockLink
---@field source_block ILBlock @ the block flowing to `target_block`
---@field target_block ILBlock @ the block `source_block` is flowing to
---a loop link is the link determined to be the one closing the loop of a collection of blocks
---which are ultimately forming a loop.
---(currently all backwards jumps are marked as loop links)
---@field is_loop boolean
---@class ILFunctionTemp
---@field local_reg_lut table<AstLocalDef, ILRegister>
---@field upval_def_lut table<AstUpvalDef, ILUpval>
---@field break_jump_lut table<AstBreakStat, ILJump>
---@field label_inst_lut table<AstLabel, ILLabel>
---@field goto_inst_lut table<AstGotoStat, ILJump>
--------------------------------------------------
-- generated/bytecode stuff:
---@alias OpcodeParamType
---| 1 @ register
---| 2 @ constant
---| 3 @ register_or_constant
---| 4 @ upval
---| 5 @ bool
---| 6 @ floating_byte
---| 7 @ jump_pc_offset
---| 8 @ other
---| nil @ unused
---@class OpcodeParams
---@field a OpcodeParamType
---@field b OpcodeParamType
---@field c OpcodeParamType
---@field ax OpcodeParamType
---@field bx OpcodeParamType
---@field sbx OpcodeParamType
---by how much the raw value has to be reduced to get the actual value
---of the param if the raw value is not equal to zero.\
---Used for a few params where 0 has a special meaning line `var`
---@class OpcodeReduceIfNotZero
---@field a number|nil
---@field b number|nil
---@field c number|nil
---@field ax number|nil
---@field bx number|nil
---@field sbx number|nil
---technically only used for`name == "extraarg"`\
---these param types completely override the entire `params` of the referenced opcode
---@class OpcodeNextOpcode
---@field name string @ name of the opcode that has to follow this opcode
---Under what condition this opcode has to be followed by this next opcode as defined here
---@field condition nil|fun(inst: Instruction):boolean
---@field a OpcodeParamType
---@field b OpcodeParamType
---@field c OpcodeParamType