-
Notifications
You must be signed in to change notification settings - Fork 4
/
codeNode.mpl
4325 lines (3652 loc) · 132 KB
/
codeNode.mpl
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
# Copyright (C) 2021 Matway Burkow
#
# This repository and all its contents belong to Matway Burkow (referred here and below as "the owner").
# The content is for demonstration purposes only.
# It is forbidden to use the content or any part of it for any purpose without explicit permission from the owner.
# By contributing to the repository, contributors acknowledge that ownership of their work transfers to the owner.
"Array" use
"HashTable" use
"Owner" use
"String" use
"algorithm" use
"control" use
"conventions" use
"memory" use
"Block" use
"MplFile" use
"Var" use
"astNodeType" use
"debugWriter" use
"declarations" use
"defaultImpl" use
"irWriter" use
"logger" use
"pathUtils" use
"processor" use
"staticCall" use
"variable" use
startsFrom: [
s1: s2: makeStringView; makeStringView;
s1.size s2.size < ~ [s2.size Natx cast s2.data storageAddress s1.data storageAddress memcmp 0 =] &&
];
addNameInfo: [
processor: block: ;;
params:;
forOverload: params "overload" has [params.overload new] [FALSE dynamic] if;
mplFieldIndex: params "mplFieldIndex" has [params.mplFieldIndex new] [-1 dynamic] if;
object: params "object" has [params.object new] [RefToVar] if;
reg: params "reg" has [params.reg new] [TRUE dynamic] if;
startPoint: params "startPoint" has [params.startPoint new] [block.id new] if;
overloadDepth: params "overloadDepth" has [params.overloadDepth new] [0 dynamic] if;
file: params "file" has [params.file] [processor.positions.last.file] if;
addNameCase: params.addNameCase new dynamic;
refToVar: params.refToVar new dynamic;
nameInfo: params.nameInfo new dynamic;
[params.refToVar.assigned] "Add name must have corrent refToVar!" assert
#reg [block.parent 0 =] && [
# nameInfo processor.nameManager.getText "lambda." startsFrom [
# "Lambdas are not allowed in root!" failProc
# ] when
#] when
[
nameInfo 0 < ~ [
addInfo: TRUE;
reg ~ [addNameCase NameCaseBuiltin =] || [
] [
nameWithOverload: NameWithOverloadAndRefToVar;
refToVar @nameWithOverload.@refToVar set
overloadDepth @nameWithOverload.@nameOverloadDepth set
nameInfo @nameWithOverload.@nameInfo set
startPoint @nameWithOverload.@startPoint set
forOverload @nameWithOverload.@hasOverloadWord set
addNameCase NameCaseLocal = [
nameWithOverload @[email protected]
] [
addNameCase NameCaseFromModule = [
nameWithOverload @[email protected]
] [
addNameCase NameCaseCapture = [addNameCase NameCaseSelfObjectCapture =] || [addNameCase NameCaseClosureObjectCapture =] || [
FALSE @addInfo set
] [
addNameCase NameCaseSelfMember = [addNameCase NameCaseClosureMember =] || [
FALSE @addInfo set
] [
addNameCase NameCaseSelfObject = [addNameCase NameCaseClosureObject =] || [
# do nothing
FALSE @addInfo set
] [
"wrong name info case" failProc
] if
] if
] if
] if
] if
] if
addInfo [ # captures dont live in stack
nameInfoEntry: NameInfoEntry;
forOverload [
File Cref @nameInfoEntry.!file
] [
file @nameInfoEntry.!file
] if
isLocal: startPoint processor.blocks.at.get.parent 0 = ~;
object @nameInfoEntry.@object set
refToVar @nameInfoEntry.@refToVar set
addNameCase @nameInfoEntry.@nameCase set
startPoint @nameInfoEntry.@startPoint set
mplFieldIndex @nameInfoEntry.@mplFieldIndex set
isLocal @nameInfoEntry.@isLocal set
@nameInfoEntry nameInfo @[email protected]
] when
] [
#we add "self" or "closure" but dont use them in program
] if
] call
];
getNameLastIndexInfo: [
nameInfo:;
currentNameInfo: nameInfo @[email protected];
result: IndexInfo;
currentNameInfo.stack.size 1 - @result.@overload set
currentNameInfo.stack.last.size 1 - @result.@index set
result
];
deleteNameInfo: [
nameInfo: new;
nameInfo @[email protected]
];
makeStaticity: [
refToVar: staticity: processor: block:;;;;
refToVar isVirtual ~ [
var: @refToVar getVar;
staticity @var.@staticity.@begin set
staticity @var.@staticity.@end set
staticity Virtual < ~ [
@refToVar @processor block makeVariableType
] when
] when
refToVar new
];
makeEndStaticity: [
refToVar: staticity: processor: block:;;;;
refToVar isVirtual ~ [
var: @refToVar getVar;
staticity @var.@staticity.@end set
staticity Virtual < ~ [
@refToVar @processor block makeVariableType
] when
] when
refToVar new
];
makeStorageStaticity: [
refToVar: staticity: processor: block:;;;;
refToVar isVirtual ~ [
staticity @refToVar getVar.@storageStaticity set
] when
refToVar new
];
createVariable: [
processor: block:;;
FALSE dynamic TRUE dynamic @processor @block createVariableWithVirtual
];
createVariableWithVirtual: [
processor: block: ;;
makeType: new;
makeVirtual: new;
tag: new;
data:;
v: Variable;
tag @[email protected]
branch: tag @[email protected];
@data @branch set
block.parent 0 = @v.@global set
v.global [
processor.globalVarId @v.@globalId set
processor.globalVarId 1 + @processor.@globalVarId set
] when
processor.variables.size 0 = [processor.variables.last.size 4096 =] || [
processor.variables.size 1 + @[email protected]
4096 @[email protected]
] when
# now forget about v
result: RefToVar;
@[email protected] @result.setVar
TRUE @result.setMoved
@block @result [email protected]
result @result getVar.@sourceOfValue set
makeVirtual [
Virtual @result getVar.@staticity.@begin set
] [
result isPlain [processor.options.staticLiterals ~] && [
Weak @result getVar.@staticity.@begin set
] [
Static @result getVar.@staticity.@begin set
] if
] if
result getVar.staticity.begin @result getVar.@staticity.@end set
result @result getVar.@capturedHead set
result @result getVar.@capturedTail set
result isNonrecursiveType ~ [result isUnallocable ~] && @result.setMutable
makeType [@result @processor block makeVariableType] when
@result @processor block makeVariableIRName
processor.varCount 1 + @processor.@varCount set
@result
];
createRefVariable: [
branch: createDependent: processor: block: ;;;;
result: branch VarRef @processor @block createVariable;
branch.refToVar getVar.storageStaticity Dynamic = [
@result Dynamic @processor @block makeStaticity drop
createDependent [
(result new branch.refToVar new TRUE) @[email protected]
] when
] when
@result
];
getNilVar: [
refToVar: processor: block: ;;;
varSchema: refToVar @processor getMplSchema;
varSchema.nilVar.assigned ~ [
block: 0 @[email protected];
refToVar @processor @block copyVarFromType Dirty @processor @block makeStaticity Virtual @processor @block makeStorageStaticity @varSchema.@nilVar set
var: @varSchema.@nilVar getVar;
"null" toString @processor makeStringId @var.@irNameId set
@varSchema.@nilVar fullUntemporize
"; null" @block createComment
block.program.size 1 - @var.@allocationInstructionIndex set
] when
varSchema.nilVar new
];
getLastShadow: [
refToVar: processor: block: ;;;
result: RefToVar;
@result refToVar ShadowReasonCapture @processor @block makeShadows
@result fullUntemporize
@result
];
updateInputCountInMatchingInfo: [
delta: matchingInfo: ;;
matchingInfo.currentInputCount delta + @matchingInfo.!currentInputCount
matchingInfo.currentInputCount matchingInfo.maxInputCount > [
matchingInfo.currentInputCount new @matchingInfo.!maxInputCount
] when
];
updateInputCount: [
delta: block:;;
delta @block.@buildingMatchingInfo updateInputCountInMatchingInfo
block.state NodeStateNew = [
delta @block.@matchingInfo updateInputCountInMatchingInfo
] when
];
{
block: Block Ref;
entry: RefToVar Cref;
} () {} [
entry: block:;;
entry @[email protected]
-1 @block updateInputCount
] "push" exportFunction
{
block: Block Ref;
entry: RefToVar Cref;
} () {} [
entry: block:;;
entry @[email protected]
] "pushForMatching" exportFunction
setTopologyIndex: [
block: refToVar: ;;
refToVar noMatterToCopy ~ [
var: @refToVar getVar;
var.buildingTopologyIndex 0 < [
topologyIndex: @block.@buildingMatchingInfo.@lastTopologyIndex;
topologyIndex @var.@buildingTopologyIndex set
block.state NodeStateNew = [topologyIndex @var.@topologyIndex set] when
topologyIndex 1 + @topologyIndex set
] when
] when
];
makeVarCode: [VarCode @processor @block createVariable];
makeVarInt8: [VarInt8 @processor @block checkValue makeValuePair VarInt8 @processor @block createVariable @processor @block createPlainIR];
makeVarInt16: [VarInt16 @processor @block checkValue makeValuePair VarInt16 @processor @block createVariable @processor @block createPlainIR];
makeVarInt32: [VarInt32 @processor @block checkValue makeValuePair VarInt32 @processor @block createVariable @processor @block createPlainIR];
makeVarInt64: [VarInt64 @processor @block checkValue makeValuePair VarInt64 @processor @block createVariable @processor @block createPlainIR];
makeVarIntX: [VarIntX @processor @block checkValue makeValuePair VarIntX @processor @block createVariable @processor @block createPlainIR];
makeVarNat8: [VarNat8 @processor @block checkValue makeValuePair VarNat8 @processor @block createVariable @processor @block createPlainIR];
makeVarNat16: [VarNat16 @processor @block checkValue makeValuePair VarNat16 @processor @block createVariable @processor @block createPlainIR];
makeVarNat32: [VarNat32 @processor @block checkValue makeValuePair VarNat32 @processor @block createVariable @processor @block createPlainIR];
makeVarNat64: [VarNat64 @processor @block checkValue makeValuePair VarNat64 @processor @block createVariable @processor @block createPlainIR];
makeVarNatX: [VarNatX @processor @block checkValue makeValuePair VarNatX @processor @block createVariable @processor @block createPlainIR];
makeVarReal32: [VarReal32 @processor @block checkValue makeValuePair VarReal32 @processor @block createVariable @processor @block createPlainIR];
makeVarReal64: [VarReal64 @processor @block checkValue makeValuePair VarReal64 @processor @block createVariable @processor @block createPlainIR];
getPointeeForMatching: [
processor: block: ;;
refToVar:;
var: refToVar getVar;
[var.data.getTag VarRef =] "Not a reference!" assert
pointee: VarRef var.data.get.refToVar; # reference
result: pointee new;
refToVar.mutable pointee.mutable and @result.setMutable # to deref is
result
];
getPointeeWith: [
refToVar: makeDerefIR: dynamize: processor: block: ;;;;;
var: @refToVar getVar;
[var.data.getTag VarRef =] "Not a reference!" assert
refToVar isVirtualType [
refToVar new
] [
pointee: VarRef @[email protected].@refToVar; # reference
fromParent: pointee getVar.host block is ~;
pointeeIsGlobal: FALSE dynamic;
needReallyDeref: FALSE dynamic;
refToVar staticityOfVar Dynamic > ~ [
# create new var of dynamic dereference
result: pointee @processor @block copyOneVarFromType
Dynamic @processor @block makeStorageStaticity
Dirty @processor @block makeStaticity;
@result @processor block unglobalize
result.var @pointee.setVar
result.mutable @pointee.setMutable
(refToVar new pointee new TRUE) @[email protected]
TRUE @needReallyDeref set
] [
pointeeGDI: pointee getVar.globalDeclarationInstructionIndex;
fromParent [ # capture or argument
result: RefToVar;
@result pointee ShadowReasonPointee @processor @block makeShadows
result.var @pointee.setVar
result.mutable @pointee.setMutable
TRUE @needReallyDeref set
] when
pointee isGlobal [
TRUE @pointeeIsGlobal set
] when
sourceValueVar: var.sourceOfValue getVar;
sourceValueVar.buildingTopologyIndex 0 < ~ [ #source can be local var in child scope, we must handle this case
shadowUsed: VarRef @[email protected].@usedHere;
refToVar noMatterToCopy ~ [sourceValueVar.capturedHead getVar.host block is ~] && [pointee noMatterToCopy ~] && [shadowUsed ~] && [sourceValueVar.staticity.begin Static =] && [
TRUE @shadowUsed set
newEvent: ShadowEvent;
ShadowReasonPointee @newEvent.setTag
branch: ShadowReasonPointee @newEvent.get;
[sourceValueVar.host var.host is] "Source of value is from another node!" assert
var.sourceOfValue @branch.@pointer set
pointee @branch.@pointee set
@block @branch.@pointee setTopologyIndex
@newEvent @processor @block addShadowEvent
] when
] when
] if
pointee untemporize
pointeeVar: @pointee getVar;
pointeeVar.getInstructionIndex 0 < [pointeeVar.allocationInstructionIndex 0 <] && [pointeeIsGlobal ~] && [
TRUE @needReallyDeref set
] [
FALSE @needReallyDeref set
] if
needReallyDeref makeDerefIR and [
refToVar pointeeVar.irNameId @processor @block createDerefTo
block.program.size 1 - @pointeeVar.@getInstructionIndex set
] when
result: pointee new;
refToVar.mutable pointee.mutable and @result.setMutable # to deref is
result
] if
];
getPointee: [processor: block: ;; TRUE FALSE @processor @block getPointeeWith];
getPointeeNoDerefIR: [processor: block: ;; FALSE FALSE @processor @block getPointeeWith];
getPointeeWhileDynamize: [processor: block: ;; FALSE TRUE @processor @block getPointeeWith];
getFieldForMatching: [
mplFieldIndex: refToVar: processor: block: ;;;;
var: refToVar getVar;
[var.data.getTag VarStruct =] "Not a combined!" assert
structInfo: VarStruct @[email protected];
mplFieldIndex 0 < ~ [
fieldRefToVar: mplFieldIndex structInfo.fields.at.refToVar new;
refToVar.mutable @fieldRefToVar.setMutable
@fieldRefToVar @processor block unglobalize
refToVar varIsMoved @fieldRefToVar.setMoved
fieldRefToVar
] [
"index is out of bounds" @processor block compilerError
RefToVar
] if
];
getFieldWith: [
whileMakingTreeDynamicStoraged: mplFieldIndex: refToVar: processor: block: ;;;;;
var: @refToVar getVar;
[var.data.getTag VarStruct =] "Not a combined!" assert
structInfo: VarStruct @[email protected];
mplFieldIndex 0 < ~ [mplFieldIndex structInfo.fields.size <] && [
fieldRefToVar: mplFieldIndex @[email protected].@refToVar;
fieldVar: @fieldRefToVar getVar;
fieldVar.data.getTag VarStruct = [
fieldStruct: VarStruct @[email protected];
refToVar varIsMoved @fieldRefToVar.setMoved
] when
structIsDynamicStoraged: var.storageStaticity Dynamic =;
fieldShadow: RefToVar;
fieldRefToVar noMatterToCopy ~ [
structIsDynamicStoraged [
mplFieldIndex structInfo.fields.at.usedHere ~ [
fieldRefToVar @processor @block copyOneVarFromType Dynamic @processor @block makeStorageStaticity Dirty @processor @block makeStaticity @fieldShadow set
TRUE mplFieldIndex @[email protected].!usedHere
TRUE
] &&
] [
fieldVar.host block is ~ [
@fieldShadow fieldRefToVar ShadowReasonField @processor @block makeShadows
var.storageStaticity Virtual = [
@fieldShadow Dirty @processor @block makeStaticity drop
] when
@fieldShadow @processor block unglobalize
TRUE
] &&
] if
] && [ # capture or argument
fieldShadow getVar.data.getTag VarStruct = [
fieldStruct: VarStruct @fieldShadow [email protected];
refToVar varIsMoved @fieldShadow.setMoved
] when
fieldShadow @fieldRefToVar set
fieldVar: @fieldRefToVar getVar;
var.staticity.end fieldVar.staticity.end < [
var.staticity.end @fieldVar.@staticity.@end set
] when
] when
fieldRefToVar.mutable @fieldRefToVar.setMutable
refToVar noMatterToCopy ~ [fieldRefToVar noMatterToCopy ~] && [
var.capturedHead getVar.host block is ~ [var.buildingTopologyIndex 0 < ~] && [mplFieldIndex structInfo.fields.at.usedHere ~] && [structIsDynamicStoraged ~] && [
TRUE mplFieldIndex @[email protected].!usedHere
newEvent: ShadowEvent;
ShadowReasonField @newEvent.setTag
branch: ShadowReasonField @newEvent.get;
refToVar @branch.@object set
mplFieldIndex @branch.@mplFieldIndex set
fieldRefToVar @branch.@field set
@block @branch.@field setTopologyIndex
@newEvent @processor @block addShadowEvent
] [
structIsDynamicStoraged [
(refToVar new fieldRefToVar new FALSE) @[email protected]
] when
] if
] when
refToVar.mutable @fieldRefToVar.setMutable
@fieldRefToVar
] [
"index is out of bounds" @processor block compilerError
failResult: RefToVar Ref;
@failResult
] if
];
getField: [
mplFieldIndex: refToVar: processor: block: ;;;;
FALSE dynamic mplFieldIndex refToVar @processor @block getFieldWith
];
captureEntireStruct: [
refToVar:;
unprocessed: RefToVar Array;
refToVar @unprocessed.append
i: 0 dynamic;
[
i unprocessed.size < [
current: i unprocessed.at new;
currentVar: current getVar;
currentVar.data.getTag VarStruct = [current noMatterToCopy ~] && [
branch: VarStruct currentVar.data.get.get;
f: 0 dynamic;
[
f branch.fields.size < [
f @current @processor @block getField @unprocessed.append
f 1 + @f set TRUE
] &&
] loop
] when
i 1 + @i set TRUE
] &&
] loop
];
setOneVar: [
first: new;
refDst:;
refSrc:;
srcVar: refSrc getVar;
dstVar: @refDst getVar;
[srcVar.data.getTag dstVar.data.getTag =] "Variable types mismatch!" assert
[refSrc isVirtual refDst isVirtual =] "Virtualness mismatch!" assert
[refDst.mutable] "Constness mismatch!" assert
srcVar.data.getTag VarStruct = ~ [
srcVar.data.getTag VarRef = [
VarRef srcVar.data.get
VarRef @[email protected] set
] [
srcVar.data.getTag VarCond VarReal64 1 + [
tag: new;
tag srcVar.data.get.end
tag @[email protected].@end set
] staticCall
] if
] when
@refDst makeVarPtrCaptured
@refDst @processor @block makeVarRealCaptured
[srcVar.sourceOfValue getVar.host dstVar.sourceOfValue getVar.host is] "Source of value is from another node!" assert
srcVar.sourceOfValue @dstVar.@sourceOfValue set
refDst staticityOfVar Dirty > [
staticity: refSrc staticityOfVar;
staticity Weak = [refDst staticityOfVar @staticity set] when
@refDst staticity @processor block makeEndStaticity drop
] [
srcVar.data.getTag VarRef = [refSrc.mutable] && [VarRef srcVar.data.get.refToVar.mutable] && [
staticity: refSrc staticityOfVar;
refSrc @processor @block makeVarTreeDirty
@refSrc staticity @processor block makeEndStaticity drop
] when
] if
];
{
block: Block Ref;
processor: Processor Ref;
createOperation: Cond;
mutable: Cond;
refToVar: RefToVar Cref;
result: RefToVar Ref;
} () {} [
result: refToVar: mutable: createOperation: processor: block: ;;;;;;
overload failProc: processor block FailProcForProcessor;
refToVar isVirtual [
@refToVar untemporize
refToVar @result set #for dropping or getting callables for example
] [
pointee: refToVar new;
var: @pointee getVar;
pointee staticityOfVar Weak = [Dynamic @var.@staticity.@end set] when
@pointee fullUntemporize
pointee.mutable [mutable new] && @pointee.setMutable
newRefToVar: pointee makeRefBranch TRUE @processor @block createRefVariable;
createOperation [pointee @newRefToVar @processor @block createRefOperation] when
newRefToVar @result set
] if
] "createRefWithImpl" exportFunction
createCheckedStaticGEP: [
fieldRef: index: refToStruct: processor: block: ;;;;;
fieldVar: @fieldRef getVar;
fieldVar.getInstructionIndex 0 < [fieldVar.allocationInstructionIndex 0 <] && [
@fieldRef @processor block unglobalize
fieldRef index refToStruct @processor @block createStaticGEP
block.program.size 1 - @fieldVar.@getInstructionIndex set
] when
];
makeVirtualVarReal: [
refToVar: processor: block: ;;;
refToVar isVirtualType [
refToVar new
] [
processor.options.verboseIR [("made virtual var real, type: " refToVar @processor block getMplType) assembleString @block createComment] when
realValue: @refToVar getVar.@realValue;
unfinishedSrc: RefToVar Array;
unfinishedDst: RefToVar Array;
result: refToVar @processor @block copyOneVar;
result isVirtualType ~ [
Static makeValuePair @result getVar.@staticity set
refToVar @unfinishedSrc.append
result @unfinishedDst.append
# first pass: make new variable type
[
unfinishedSrc.size 0 > [
lastSrc: unfinishedSrc.last new;
lastDst: unfinishedDst.last new;
@unfinishedSrc.popBack
@unfinishedDst.popBack
varSrc: lastSrc getVar;
varDst: @lastDst getVar;
lastDst noMatterToCopy ~ [lastDst @varDst.@sourceOfValue set] when
# noMatterToCopy
varSrc.data.getTag VarStruct = [
struct: VarStruct varSrc.data.get.get;
j: 0 dynamic;
[
j struct.fields.size < [
srcField: j struct.fields.at;
srcField.refToVar isVirtual ~ [
srcField.refToVar @unfinishedSrc.append
dstField: j @lastDst @processor @block getField;
dstField @unfinishedDst.append
@dstField @processor block unglobalize
] [
dstField: j @lastDst @processor @block getField;
@dstField Virtual @processor block makeStaticity r:;
@dstField @processor block unglobalize
] if
j 1 + @j set TRUE
] &&
] loop
] when
processor compilable
] &&
] loop
# second pass: create IR code for variable
@result @processor block makeVariableType
refToVar @unfinishedSrc.append
@result @processor @block createAllocIR @unfinishedDst.append
[
unfinishedSrc.size 0 > [
lastSrc: unfinishedSrc.last new;
lastDst: unfinishedDst.last new;
@unfinishedSrc.popBack
@unfinishedDst.popBack
varSrc: lastSrc getVar;
varSrc.data.getTag VarStruct = [
struct: VarStruct varSrc.data.get.get;
j: 0 dynamic;
[
j struct.fields.size < [
srcField: j struct.fields.at;
srcField.refToVar isVirtual ~ [
srcField.refToVar @unfinishedSrc.append
dstField: j @lastDst @processor @block getField;
dstField @unfinishedDst.append
@dstField @processor block unglobalize
@dstField j lastDst @processor @block createCheckedStaticGEP
] when
j 1 + @j set TRUE
] &&
] loop
] [
lastSrc isVirtualType ~ [
varSrc.data.getTag VarRef = [
] [
lastSrc isPlain [
lastSrc lastDst @processor @block createStoreConstant
] when
] if
] when
] if
processor compilable
] &&
] loop
] when
result isPlain [
FALSE @result.setMutable
] when
result @realValue set
realValue new
] if
];
makeVarSchema: [
refToVar:;
@refToVar Schema @processor block makeStaticity drop
];
makeVarVirtual: [
refToVar:;
unfinished: RefToVar Array;
refToVar @unfinished.append
[
unfinished.size 0 > [
cur: @unfinished.last new;
@unfinished.popBack
curVar: cur getVar;
curVar.data.getTag VarStruct = [
cur isAutoStruct [
"can not virtualize automatic struct" @processor block compilerError
] [
struct: VarStruct curVar.data.get.get;
j: 0 dynamic;
[
j struct.fields.size < [processor compilable] && [
curField: j struct.fields.at;
curField.refToVar isVirtual ~ [
curField.refToVar @unfinished.append
] when
j 1 + @j set TRUE
] &&
] loop
] if
] [
curVar.data.getTag VarRef = [
pointee: VarRef curVar.data.get.refToVar;
pointee isUnallocable [
cur staticityOfVar Weak < [
"can not virtualize dynamic value" @processor block compilerError
] when
] [
pointee getVar.storageStaticity Virtual = [
] [
"can not virtualize reference to local variable" @processor block compilerError
] if
] if
] [
cur staticityOfVar Weak < [
"can not virtualize dynamic value" @processor block compilerError
] when
] if
] if
processor compilable
] &&
] loop
processor compilable [
@refToVar Virtual @processor block makeStaticity drop
] when
];
makeVarTreeDirty: [
refToVar: processor: block:;;;
unfinishedVars: RefToVar Array;
refToVar @unfinishedVars.append
[
unfinishedVars.size 0 > [
lastRefToVar: unfinishedVars.last new;
@unfinishedVars.popBack
lastRefToVar staticityOfVar Virtual = ["can't dynamize virtual value" @processor block compilerError] when
lastRefToVar staticityOfVar Dirty = [
#skip
] [
processor compilable [
var: lastRefToVar getVar;
var.data.getTag VarStruct = [
struct: VarStruct var.data.get.get;
j: 0 dynamic;
[
j struct.fields.size < [
j struct.fields.at.refToVar isVirtual ~ [
j @lastRefToVar @processor @block getField @unfinishedVars.append
] when
j 1 + @j set TRUE
] &&
] loop
] [
var.data.getTag VarRef = [
lastRefToVar staticityOfVar Static = [
pointee: @lastRefToVar @processor @block getPointeeWhileDynamize;
pointee @unfinishedVars.append
] [
[lastRefToVar staticityOfVar Dynamic > ~] "Ref must be only Static or Dynamic!" assert
] if
] when
] if
var.data.getTag VarImport = ~ var.data.getTag VarString = ~ and [
@lastRefToVar Dirty @processor block makeEndStaticity @lastRefToVar set
] when
] when
] if
processor compilable
] &&
] loop
];
makePointeeDirtyIfRef: [
refToVar: processor: block: ;;;
var: refToVar getVar;
var.data.getTag VarRef = [var.staticity.end Static =] && [
pointee: @refToVar @processor @block getPointeeWhileDynamize;
@pointee makeVarPtrCaptured
pointee.mutable [pointee @processor @block makeVarTreeDirty] when
] when
];
makeVarDynamicOrDirty: [
processor: block: ;;
newStaticity:;
refToVar:;
var: refToVar getVar;
refToVar staticityOfVar Virtual = ["can't dynamize virtual value" @processor block compilerError] when
@refToVar @processor @block makePointeeDirtyIfRef
newStaticity var.staticity.end < [
newStaticity @var.@staticity.@end set
] when
];
makeVarDynamic: [processor: block: ;; Dynamic @processor @block makeVarDynamicOrDirty];
makeVarDirty: [processor: block: ;; Dirty @processor @block makeVarDynamicOrDirty];
makeVarTreeDynamicWith: [
refToVar: dynamicStoraged: processor: block: ;;;;
unfinishedVars: RefToVar Array;
refToVar @unfinishedVars.append
[
unfinishedVars.size 0 > [
lastRefToVar: unfinishedVars.last new;
@unfinishedVars.popBack
var: lastRefToVar getVar;
lastRefToVar staticityOfVar Virtual = ["can't dynamize virtual value" @processor block compilerError] when
var.data.getTag VarStruct = [
struct: VarStruct var.data.get.get;
j: 0 dynamic;
[
j struct.fields.size < [
j struct.fields.at.refToVar isVirtual ~ [
dynamicStoraged j @lastRefToVar @processor @block getFieldWith @unfinishedVars.append
] when
j 1 + @j set TRUE
] &&
] loop
] [
var.data.getTag VarRef = [
lastRefToVar staticityOfVar Static = [
dynamicStoraged ~ [
pointee: @lastRefToVar @processor @block getPointeeWhileDynamize;
pointee.mutable [pointee @processor @block makeVarTreeDirty] when
] when # dynamic storaged data is not real
] [
[lastRefToVar staticityOfVar Dynamic = lastRefToVar staticityOfVar Dirty = or] "Ref must be only Static or Dirty or Dynamic!" assert
] if
] when
] if
dynamicStoraged [
lastRefToVar Dynamic @processor block makeStorageStaticity drop
@lastRefToVar Dirty @processor block makeEndStaticity drop
] [
var.data.getTag VarStruct = ~ [var.staticity.end Dynamic >] && [
@lastRefToVar Dynamic @processor block makeEndStaticity drop
] when
] if
processor compilable
] &&
] loop
];
makeVarTreeDynamic: [processor: block: ;; FALSE dynamic @processor @block makeVarTreeDynamicWith];
makeVarTreeDynamicStoraged: [processor: block: ;; TRUE dynamic @processor @block makeVarTreeDynamicWith];
checkPossibleUnstables: [
nameInfo: processor: block: ;;;
block.parent 0 = [
nameInfo processor.possibleUnstables.size < [
current: nameInfo @[email protected];
current [
blockId:;
unstableBlock: blockId @[email protected];
TRUE @unstableBlock.@changedStableName set
] each
@current.clear
] when
] when
];
createNamedVariable: [
nameInfo: refToVar: processor: block: ;;;;
processor compilable [
newRefToVar: refToVar new;
staticity: refToVar staticityOfVar;
var: @newRefToVar getVar;
block.nextLabelIsVirtual [
refToVar isVirtual ~ [
staticity Weak = [Static @var.@staticity.@end set] when
] when
] when
isGlobalLabel: [
refToVar:;
block.nextLabelIsVirtual ~ [refToVar isVirtual ~] && [refToVar isGlobal] &&
];
var.temporary [refToVar isGlobalLabel] && [
refToVar @processor @block makeVarTreeDirty
Dirty @staticity set
] when
var.temporary [
staticity @var.@staticity.@end set