-
-
Notifications
You must be signed in to change notification settings - Fork 12
/
decl.bmx
4481 lines (3587 loc) · 110 KB
/
decl.bmx
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) 2013-2024 Bruce A Henderson
'
' Based on the public domain Monkey "trans" by Mark Sibly
'
' This software is provided 'as-is', without any express or implied
' warranty. In no event will the authors be held liable for any damages
' arising from the use of this software.
'
' Permission is granted to anyone to use this software for any purpose,
' including commercial applications, and to alter it and redistribute it
' freely, subject to the following restrictions:
'
' 1. The origin of this software must not be misrepresented; you must not
' claim that you wrote the original software. If you use this software
' in a product, an acknowledgment in the product documentation would be
' appreciated but is not required.
'
' 2. Altered source versions must be plainly marked as such, and must not be
' misrepresented as being the original software.
'
' 3. This notice may not be removed or altered from any source
' distribution.
'
Const DECL_EXTERN:Long= $010000
Const DECL_PRIVATE:Long= $020000
Const DECL_ABSTRACT:Long= $040000
Const DECL_FINAL:Long= $080000
Const DECL_READ_ONLY:Long= $000100
Const DECL_STATIC:Long= $20000000
Const DECL_OVERRIDE:Long= $40000000
Const DECL_INLINE:Long= $80000000
Const DECL_THREADED:Long= $100000000:Long
Const DECL_NO_VAR:Long= $200000000:Long
Const DECL_SEMANTED:Long= $100000
Const DECL_SEMANTING:Long= $200000
Const DECL_CYCLIC:Long= $8000000
Const DECL_POINTER:Long= $400000
Const DECL_ARG:Long= $800000
Const DECL_INITONLY:Long= $1000000
Const DECL_NODEBUG:Long= $2000000
Const DECL_PROTECTED:Long= $4000000
Const DECL_EXPORT:Long= $8000000
Const DECL_API_CDECL:Long= $00000000
Const DECL_API_STDCALL:Long= $10000000
Const DECL_API_DEFAULT:Long=DECL_API_CDECL
Const DECL_API_FLAGS:Long= DECL_API_CDECL | DECL_API_STDCALL
Const DECL_NESTED:Long= $20000000
Const CLASS_INTERFACE:Long= $002000
Const CLASS_THROWABLE:Long= $004000
Const CLASS_STRUCT:Long= $008000
Const CLASS_GENERIC:Long= $001000
Const CLASS_FLAGS:Long = CLASS_INTERFACE | CLASS_THROWABLE | CLASS_STRUCT | CLASS_GENERIC
Const SCOPE_FUNC:Int = 0
Const SCOPE_CLASS_LOCAL:Int = 1
Const SCOPE_CLASS_HEIRARCHY:Int = 2
Const SCOPE_MODULE:Int = 3
Const SCOPE_ALL:Int = 4
Const BLOCK_OTHER:Int = $000
Const BLOCK_LOOP:Int = $001
Const BLOCK_TRY:Int = $002
Const BLOCK_CATCH:Int = $004
Const BLOCK_FINALLY:Int = $008
Const BLOCK_IF:Int = $010
Const BLOCK_ELSE:Int = $020
Const BLOCK_FUNCTION:Int = $040
Const BLOCK_TRY_CATCH:Int = BLOCK_TRY | BLOCK_CATCH
Const BLOCK_IF_ELSE:Int = BLOCK_IF | BLOCK_ELSE
Const OPTION_WANT_LOOP_LABEL:Int = 1
Const OPTION_WANT_DATA_LABEL:Int = 2
'Const CALL_CONV_CDECL:Int = 0
'Const CALL_CONV_STDCALL:Int = 1
'Const CALL_CONV_DEFAULT:Int = CALL_CONV_CDECL
Global _env:TScopeDecl
Global _envStack:TList=New TList
Global _appInstance:TAppDecl
Global _loopnest:Int
Function PushEnv( env:TScopeDecl )
If _env _envStack.AddLast( _env )
_env=env
End Function
Function PopEnv()
_env=TScopeDecl( _envStack.RemoveLast() )
End Function
Type TFuncDeclList Extends TList
Field ident:String
Field _identLower:String
Method IdentLower:String()
If Not _identLower Then
_identLower = ident.ToLower()
End If
Return _identLower
End Method
Method AddLast:TLink( value:Object )
If Not Contains(value) Then
Return Super.AddLast(value)
End If
End Method
End Type
Type TMetadata
Field metadataString:String
' key/value pairs
Field meta:TMap
Method InsertMeta(key:String, value:String)
If Not meta Then
meta = New TMap
End If
meta.Insert(key, value)
End Method
Method HasMeta:Int(key:String)
Return meta And meta.Contains(key.ToLower())
End Method
End Type
Type TDecl
Field ident$
Field munged$
Field errInfo$
Field actual:TDecl
Field scope:TScopeDecl
Field attrs:Long
Field metadata:TMetadata = New TMetadata
Field declImported:Int = False
Field generated:Int
Field _identLower:String
Field scopeIndex:Int = -1
Method New()
errInfo=_errInfo
actual=Self
End Method
Method OnCopy:TDecl(deep:Int = True) Abstract
Method IdentLower:String()
If Not _identLower Then
_identLower = ident.ToLower()
End If
Return _identLower
End Method
Method ToString$()
If TClassDecl( scope ) Return scope.ToString()+"."+ident
Return ident
End Method
Method ToTypeString:String()
End Method
Method IsExtern:Int()
Return (attrs & DECL_EXTERN)<>0
End Method
Method IsFinal:Int()
Return (attrs & DECL_FINAL)<>0
End Method
Method IsPrivate:Int()
Return (attrs & DECL_PRIVATE)<>0
End Method
Method IsProtected:Int()
Return (attrs & DECL_PROTECTED)<>0
End Method
Method IsPublic:Int()
Return Not (IsPrivate() Or IsProtected())
End Method
Method IsReadOnly:Int()
Return (attrs & DECL_READ_ONLY)<>0
End Method
Method IsAbstract:Int()
Return (attrs & DECL_ABSTRACT)<>0
End Method
Method IsStatic:Int()
Return (attrs & DECL_STATIC)<>0
End Method
Method IsSemanted:Int()
Return (attrs & DECL_SEMANTED)<>0
End Method
Method IsSemanting:Int()
Return (attrs & DECL_SEMANTING)<>0
End Method
Method IsNoDebug:Int()
Return (attrs & DECL_NODEBUG)<>0
End Method
Method IsThreaded:Int()
Return (attrs & DECL_THREADED)<>0
End Method
Method FuncScope:TFuncDecl()
If TFuncDecl( Self ) Return TFuncDecl( Self )
If scope Return scope.FuncScope()
End Method
Method ClassScope:TClassDecl()
If TClassDecl( Self ) Return TClassDecl( Self )
If scope Return scope.ClassScope()
End Method
Method ModuleScope:TModuleDecl()
If TModuleDecl( Self ) Return TModuleDecl( Self )
' "app" is a module container
If TAppDecl( Self ) Return TAppDecl( Self).mainModule
If scope Return scope.ModuleScope()
End Method
Method AppScope:TAppDecl()
If TAppDecl( Self ) Return TAppDecl( Self )
If scope Return scope.AppScope()
End Method
' find an owning scope of function, class or module
Method ParentScope:TScopeDecl()
If scope Then
' func scope
If TFuncDecl( scope ) Return TFuncDecl( scope )
' class scope
If TClassDecl( scope ) Return TClassDecl( scope )
' module scope
If TModuleDecl( scope ) Return TModuleDecl( scope )
Return scope.ParentScope()
End If
End Method
Method CheckAccess:Int()
If IsPrivate() And ModuleScope()<>_env.ModuleScope() Return False
Return True
End Method
Method AssertAccess()
If Not CheckAccess()
If IsPrivate() Then
Err ToString() +" is private."
Else
Err ToString() +" is protected."
End If
EndIf
End Method
Method Copy:TDecl(deep:Int = True)
Local t:TDecl=OnCopy(deep)
t.munged=munged
t.errInfo=errInfo
Return t
End Method
Method Semant()
If IsSemanted() Return
If IsSemanting() Then
If attrs & DECL_CYCLIC Then
Return
End If
Err "Cyclic declaration of '"+ident+"'."
End If
If actual<>Self
actual.Semant
EndIf
PushErr errInfo
If scope
PushEnv scope
EndIf
attrs:|DECL_SEMANTING
'If ident And ClassScope() Print "Semanting "+ToString()
OnSemant
attrs:&~DECL_SEMANTING
attrs:|DECL_SEMANTED
If scope
'If Not IsExtern()
If TFuncDecl(Self) And attrs & FUNC_PTR
'DebugLog "**** " + ident
Else
' a nested function/class needs to be scoped to another function, class or module.
If attrs & FUNC_NESTED Or attrs & DECL_NESTED Then
Local sc:TScopeDecl = ParentScope()
' if our scope isn't one of the above, let it be so.
If sc <> scope Then
scope = Null
sc.InsertDecl(Self)
End If
End If
scope._semanted.AddLast Self
If TGlobalDecl( Self )
' FIXME
If AppScope() Then
If TGlobalDecl( Self ).mscope Then
AppScope()._semanted.AddLast Self
End If
AppScope().semantedGlobals.AddLast TGlobalDecl( Self )
End If
Else
If TModuleDecl( scope )
' FIXME
Local app:TAppDecl = AppScope()
If app Then
app._semanted.AddLast Self
End If
EndIf
End If
EndIf
If TValDecl(Self) And TValDecl(Self).deferInit Then
TValDecl(Self).SemantInit
End If
PopEnv
Else
If TValDecl(Self) And TValDecl(Self).deferInit Then
TValDecl(Self).SemantInit
End If
EndIf
Semant2()
PopErr
End Method
Method Semant2()
PushErr errInfo
If scope
PushEnv scope
EndIf
OnSemant2()
If scope
PopEnv
End If
PopErr
End Method
Method InitInstance:TDecl( decl:TDecl )
decl.ident=ident
decl.munged=munged
decl.errInfo=errInfo
decl.actual=actual
decl.scope=Null
decl.attrs=attrs & ~(DECL_SEMANTED|DECL_SEMANTING)
Return decl
End Method
Method GenInstance:TDecl()
InternalErr "TDecl.GenInstance"
End Method
Method OnSemant() Abstract
Method OnSemant2()
End Method
Method Clear()
End Method
End Type
Type TValDecl Extends TDecl
'pre-semant
Field declTy:TType
Field declInit:TExpr
'post-semant
Field ty:TType
Field init:TExpr
Field deferInit:Int = False
Method ToString$()
Local t$=Super.ToString()
If ty Return t+":"+ty.ToString()
If declTy Return t+":"+declTy.ToString()
Return t+":?"
End Method
Method ToTypeString:String()
If ty Return ty.ToString()
If declTy Return declTy.ToString()
End Method
Method CopyInit:TExpr()
If init Return init.Copy()
End Method
Method OnSemant()
'DebugStop
If declTy
Local at:TType = TArrayType(declTy)
While TArrayType(at)
at = TArrayType(at).elemType
Wend
' ensure to set the scope for a function pointer array before semanting
If TFunctionPtrType(at) Then
If Not TFunctionPtrType(at).func.scope Then
If scope Then
TFunctionPtrType(at).func.scope = scope
Else
TFunctionPtrType(at).func.scope = _env
End If
End If
End If
' pass the scope into the function ptr
If TFunctionPtrType(declTy) Then
If Not TFunctionPtrType(declTy).func.scope Then
If scope Then
TFunctionPtrType(declTy).func.scope = scope
Else
TFunctionPtrType(declTy).func.scope = _env
End If
End If
End If
ty=declTy.Semant()
If Not deferInit Then
SemantInit()
End If
Else If declInit
If Not deferInit Then
SemantInit()
End If
Else
InternalErr "TValDecl.OnSemant"
EndIf
End Method
Method SemantInit()
' for field initialisation, create a stub New() method to use as current scope
' since fields are initialised in New(). Otherwise the scope would be "class", which is
' incorrect for processing field inits.
If TFieldDecl(Self) Then
If Not declInit And TClassDecl(scope) And Not TClassDecl(scope).IsStruct() Then
declInit=New TConstExpr.Create( ty,"" )
End If
If declInit Then
Local newScope:TFuncDecl = New TFuncDecl.CreateF( "new", Null,Null,FUNC_METHOD )
newScope.scope = _env
PushEnv(newScope)
End If
End If
' for imported enum args with a default value, we need to set the type of the value to the enum
' since at this point it's just a number with no context
If TArgDecl(Self) And declInit And scope And scope.declImported And TEnumType(ty) Then
declInit = New TConstExpr.Create(ty, TConstExpr(declInit).value).Semant()
End If
If declTy
If declInit Then
If TFunctionPtrType(ty) Then
Local expr:TExpr
If TInvokeExpr(declInit) Then
expr = declInit.Copy()
Else If TConstExpr(declInit) Then
expr = declInit.Copy().Semant()
Else If TFuncCallExpr(declInit) Then
expr=declInit.Copy().Semant()
Else If TNullExpr(declInit) Then
expr = declInit
Else
' declInit can only be an expression, never a statement
' this means that any function call in there is required to have parentheses, and will
' thus appear in the form of a TFuncCallExpr
' as such, trying SemantFunc in the Else branch seems pointless and will in fact wrongly
' interpret function pointers (as TIdentExpr, TIndexExpr, possibly others?) as calls
Rem
Local argExpr:TExpr[] = New TExpr[0]
For Local arg:TArgDecl = EachIn TFunctionPtrType(ty).func.argDecls
Local ldecl:TLocalDecl = New TLocalDecl.Create(arg.ident, arg.declTy, Null, 0)
ldecl.Semant()
Local aexp:TVarExpr = New TVarExpr.Create(ldecl)
'Local aexp:TIdentTypeExpr = New TIdentTypeExpr.Create(arg.declTy)
aexp.Semant()
argExpr :+ [aexp]
Next
expr=declInit.Copy().SemantFunc(argExpr, False, False)
If Not expr Then
expr = declInit.Copy().Semant()
End If
End Rem
expr = declInit.Copy().Semant()
End If
If expr.exprType.EqualsType( ty ) Then
init = expr
Else
init = New TCastExpr.Create( ty,expr,CAST_EXPLICIT ).Semant()
End If
Else
If TArrayType(ty) And TArrayType(ty).isStatic Then
init = declInit.Copy().Semant()
If Not TConstExpr(init) and not TIdentEnumExpr(init) Then
Err "Static array initialiser must be constant"
End If
If Not Int(TArrayType(ty).length) Then
TArrayType(ty).length = init.Eval()
End If
Else
If TArrayExpr(declInit) And TArrayType(ty) And TNumericType(TArrayType(ty).elemType) Then
TArrayExpr(declInit).toType = TArrayType(ty).elemType
End If
init=declInit.Copy().SemantAndCast(ty)
' check if struct has been initialised
If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() And Not TObjectType(ty).classDecl.IsExtern() Then
' new not used
If TConstExpr(init) And Not TConstExpr(init).value And Not IsPointerType(ty,0,TType.T_POINTER) Then
' always call the default constructor to init all the fields correctly
init = New TNewObjectExpr.Create(ty, Null).Semant()
End If
End If
End If
End If
End If
Else If declInit
init=declInit.Copy().Semant()
ty=init.exprType.Copy()
If attrs & DECL_NO_VAR And ty._flags & TType.T_VAR Then
ty._flags :~ TType.T_VAR ' remove var for variable
End If
End If
If init Then
If TVarExpr(init) And TVarExpr(init).decl = Self Then
Err "Identifier '" + TVarExpr(init).decl.ident + "' not found."
End If
If TNewObjectExpr(init) And TVarExpr(TNewObjectExpr(init).instanceExpr) And TVarExpr(TNewObjectExpr(init).instanceExpr).decl = Self Then
Err "Identifier '" + Self.ident + "' not found."
End If
End If
' remove the temporary scope
If TFieldDecl(Self) And declInit Then
PopEnv()
End If
End Method
Method Clear()
End Method
End Type
Type TConstDecl Extends TValDecl
Field value$
Method Create:TConstDecl( ident$,ty:TType,init:TExpr,attrs:Long )
Self.ident=ident
Self.munged=ident
Self.declTy=ty
Self.declInit=init
Self.attrs=attrs
Return Self
End Method
Method GenInstance:TDecl()
Local inst:TConstDecl = New TConstDecl
InitInstance inst
inst.declTy=declTy
inst.declInit=declInit
Return inst
End Method
Method OnCopy:TDecl(deep:Int = True)
If IsSemanted() Then
Return New TConstDecl.Create( ident,ty,CopyInit(), attrs )
Else
Return New TConstDecl.Create( ident, declTy, declInit, attrs)
End If
End Method
Method OnSemant()
Super.OnSemant()
'If Not IsExtern() value=init.Eval()
If init Then
value=init.Eval()
If TStringType(ty) And Not _appInstance.hasStringConst(value) Then
_appInstance.mapStringConsts(value)
End If
End If
End Method
Method ToString$()
Return "Const "+Super.ToString()
End Method
End Type
Type TVarDecl Extends TValDecl
End Type
Type TLocalDecl Extends TVarDecl
Field done:Int
Field volatile:Int = False
Field declaredInTry:TTryStmtDecl
Method Create:TLocalDecl( ident$,ty:TType,init:TExpr,attrs:Long=0, generated:Int = False, volatile:Int = False )
Self.ident=ident
Self.declTy=ty
Self.declInit=init
Self.attrs=attrs
Self.generated=generated
Self.volatile=volatile
Return Self
End Method
Method OnCopy:TDecl(deep:Int = True)
Local decl:TLocalDecl = New TLocalDecl.Create( ident,declTy,declInit,attrs &~ DECL_SEMANTED, generated, volatile )
decl.scope = scope
decl.ty = ty
decl.init = init
decl.declaredInTry = declaredInTry
Return decl
End Method
Method GetDeclPrefix:String()
Return "Local "
End Method
Method OnSemant()
If declTy Then
If TObjectType(declTy) Then
volatile = True
End If
End If
Super.OnSemant()
End Method
Method ToString$()
Return GetDeclPrefix() + Super.ToString()
End Method
Method Clear()
done = False
End Method
End Type
Type TArgDecl Extends TLocalDecl
Field castTo:String
Method Create:TArgDecl( ident$,ty:TType,init:TExpr,attrs:Long=0, generated:Int = False, volatile:Int = True )
Self.ident=ident
Self.declTy=ty
Self.declInit=init
Self.attrs=attrs
Self.generated=generated
Self.volatile=volatile
Return Self
End Method
Method GenInstance:TDecl()
Local inst:TArgDecl=New TArgDecl
InitInstance inst
inst.declTy=declTy
inst.declInit=declInit
Return inst
End Method
Method OnCopy:TDecl(deep:Int = True)
Local d:TArgDecl = New TArgDecl.Create( ident,declTy,declInit,attrs,generated,volatile )
d.ty = ty
d.init = init
Return d
End Method
Method GetDeclPrefix:String()
Return ""
End Method
Method OnSemant()
Super.OnSemant()
If ty Then
ty = ty.Semant()
End If
If attrs & DECL_STATIC Then
If Not TArrayType(ty) Then
Err "Expecting array"
End If
Local et:TType = TArrayType(ty).elemType
If Not TNumericType(et) And Not (TObjectType(et) And TObjectType(et).classDecl.IsStruct()) Then
Err "Static array elements must be numeric or a Struct"
End If
End If
If init And Not TConstExpr(init) Then
If TCastExpr(init) Then
If TConstExpr(TCastExpr(init).expr) Or TNullExpr(TCastExpr(init).expr) Then
Return
End If
End If
If TInvokeExpr(init) And TFunctionPtrType(TInvokeExpr(init).exprType) Then
Return
End If
If TIdentEnumExpr(init) Then
Return
End If
Err "Function defaults must be constant"
End If
End Method
Method ToString$()
Return Super.ToString()
End Method
End Type
Type TGlobalDecl Extends TVarDecl
Field inited:Int
Field funcGlobal:Int
Field mscope:TScopeDecl
Method Create:TGlobalDecl( ident$,ty:TType,init:TExpr,attrs:Long=0,funcGlobal:Int=False )
Self.deferInit = True
Self.ident=ident
Self.declTy=ty
Self.declInit=init
Self.attrs=attrs
Self.funcGlobal=funcGlobal
Return Self
End Method
Method OnCopy:TDecl(deep:Int = True)
Local g:TGlobalDecl = New TGlobalDecl.Create( ident,declTy,declInit,attrs,funcGlobal )
g.ty = ty
g.init = init
g.mscope = mscope
Return g
End Method
Method ToString$()
Return "Global "+Super.ToString()
End Method
Method GenInstance:TDecl()
' PushErr errInfo
' Err "Global variables cannot be used inside generic classes."
Local inst:TGlobalDecl=New TGlobalDecl
InitInstance inst
inst.declTy=declTy
inst.declInit=declInit
Return inst
End Method
Method CheckAccess:Int()
Local cd:TClassDecl = ClassScope()
If cd Then
If cd.modulescope() = _env.modulescope() Return True
If IsPrivate() And cd<>_env.ClassScope() Return False
If IsProtected() Then
Local ec:TClassDecl = _env.ClassScope()
If Not ec Return False
If Not ec.ExtendsClass(cd) Return False
End If
Return True
End If
Return Super.CheckAccess()
End Method
End Type
Type TFieldDecl Extends TVarDecl
' location offset in object variable data
Field offset:Int
Method Create:TFieldDecl( ident$,ty:TType,init:TExpr,attrs:Long=0 )
Self.ident=ident
Self.declTy=ty
Self.declInit=init
Self.attrs=attrs
Return Self
End Method
Method OnCopy:TDecl(deep:Int = True)
Local f:TFieldDecl = New TFieldDecl.Create( ident,declTy,declInit,attrs )
f.ty = ty
f.init = init
f.metadata = metadata
Return f
End Method
Method ToString$()
Return "Field "+Super.ToString()
End Method
Method GenInstance:TDecl()
Local inst:TFieldDecl=New TFieldDecl
InitInstance inst
inst.declTy=declTy
inst.declInit=declInit
Return inst
End Method
Method CheckAccess:Int()
If ModuleScope() = _env.ModuleScope() Then
Return True
End If
Local cs:TClassDecl = ClassScope()
If IsPrivate() And cs Then
Local ec:TClassDecl = _env.ClassScope()
While ec
If cs = ec Then
Return True
End If
ec = ec.scope.ClassScope()
Wend
If Not ec Then
Return False
End If
End If
If IsProtected() And cs Then
Local ec:TClassDecl = _env.ClassScope()
While ec
If ec.ExtendsClass(cs) Then
Return True
End If
ec = ec.scope.ClassScope()
Wend
If Not ec Then
Return False
End If
End If
Return True
End Method
Method OnSemant()
Super.OnSemant()
If TObjectType(ty) And TObjectType(ty).classDecl.IsStruct() Then
TObjectType(ty).classDecl.exposed = True
End If
End Method
End Type
Type TAliasDecl Extends TDecl
Field decl:Object
Method Create:TAliasDecl( ident$,decl:Object,attrs:Long=0 )
Self.ident=ident
Self.decl=decl
Self.attrs=attrs
Return Self
End Method
Method OnCopy:TDecl(deep:Int = True)
Return New TAliasDecl.Create( ident,decl,attrs )
End Method
Method OnSemant()
End Method
Method Clear()
End Method
End Type
Type TScopeDecl Extends TDecl
'Private
Field _decls:TList=New TList'<TDecl>
Field _semanted:TList=New TList'<TDecl>
Field declsMap:TMap=New TMap'<Object>
'Public
Method OnCopy:TDecl(deep:Int = True)
InternalErr "TScopeDecl.OnCopy"
End Method
Method Decls:TList()
Return _decls
End Method
Method Semanted:TList()
Return _semanted
End Method
Method FuncDecls:TList( id$="" )
Local fdecls:TList=New TList
For Local decl:TDecl=EachIn _decls
If id And decl.ident<>id Continue
Local fdecl:TFuncDecl=TFuncDecl( decl )
If fdecl fdecls.AddLast fdecl
Next
Return fdecls
End Method
Method MethodDecls:TList( id$="" )
Local fdecls:TList=New TList
For Local decl:TDecl=EachIn _decls
If id And decl.ident<>id Continue
Local fdecl:TFuncDecl=TFuncDecl( decl )
If fdecl And fdecl.IsMethod() fdecls.AddLast fdecl
Next
Return fdecls
End Method
Method SemantedFuncs:TList( id$="" )
Local fdecls:TList=New TList
For Local decl:TDecl=EachIn _semanted
If id And decl.ident<>id Continue
Local fdecl:TFuncDecl=TFuncDecl( decl )
If fdecl fdecls.AddLast fdecl
Next
Return fdecls
End Method
Method SemantedMethods:TList( id$="" )
Local fdecls:TList=New TList
For Local decl:TDecl=EachIn _decls
If id And decl.ident<>id Continue