]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/m2/gm2-compiler/SymbolTable.mod
PR modula2/102989: reimplement overflow detection in ztype though WIDE_INT_MAX_PRECISION
[thirdparty/gcc.git] / gcc / m2 / gm2-compiler / SymbolTable.mod
1 (* SymbolTable.mod provides access to the symbol table.
2
3 Copyright (C) 2001-2023 Free Software Foundation, Inc.
4 Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
5
6 This file is part of GNU Modula-2.
7
8 GNU Modula-2 is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3, or (at your option)
11 any later version.
12
13 GNU Modula-2 is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Modula-2; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. *)
21
22 IMPLEMENTATION MODULE SymbolTable ;
23
24
25 FROM SYSTEM IMPORT ADDRESS, ADR ;
26 FROM Storage IMPORT ALLOCATE, DEALLOCATE ;
27 FROM M2Debug IMPORT Assert ;
28 FROM libc IMPORT printf ;
29
30 IMPORT Indexing ;
31 FROM Indexing IMPORT InitIndex, InBounds, LowIndice, HighIndice, PutIndice, GetIndice ;
32 FROM Sets IMPORT Set, InitSet, IncludeElementIntoSet, IsElementInSet ;
33 FROM m2linemap IMPORT location_t ;
34
35 FROM M2Options IMPORT Pedantic, ExtendedOpaque, DebugFunctionLineNumbers, ScaffoldDynamic, DebugBuiltins ;
36
37 FROM M2LexBuf IMPORT UnknownTokenNo, TokenToLineNo,
38 FindFileNameFromToken, TokenToLocation ;
39
40 FROM M2ALU IMPORT InitValue, PtrToValue, PushCard, PopInto,
41 PushString, PushFrom, PushChar, PushInt,
42 IsSolved, IsValueConst ;
43
44 FROM M2Error IMPORT Error, NewError, ChainError, InternalError,
45 ErrorFormat0, ErrorFormat1, ErrorFormat2,
46 WriteFormat0, WriteFormat1, WriteFormat2, ErrorString,
47 ErrorAbort0, FlushErrors, ErrorScope, GetCurrentErrorScope ;
48
49 FROM M2MetaError IMPORT MetaError1, MetaError2, MetaError3, MetaErrors1,
50 MetaErrorT0,
51 MetaErrorString1,
52 MetaErrorStringT0, MetaErrorStringT1,
53 MetaErrorT1, MetaErrorT2 ;
54
55 FROM M2LexBuf IMPORT GetTokenNo ;
56 FROM FormatStrings IMPORT Sprintf1 ;
57 FROM M2Printf IMPORT printf0, printf1, printf2, printf3, printf4 ;
58
59 FROM DynamicStrings IMPORT String, string, InitString,
60 InitStringCharStar, Mark, KillString, Length, ConCat,
61 Index, char ;
62
63 FROM Lists IMPORT List, InitList, GetItemFromList, PutItemIntoList,
64 IsItemInList, IncludeItemIntoList, NoOfItemsInList,
65 RemoveItemFromList, ForeachItemInListDo ;
66
67 FROM NameKey IMPORT Name, MakeKey, makekey, NulName, WriteKey, LengthKey, GetKey, KeyToCharStar ;
68
69 FROM SymbolKey IMPORT NulKey, SymbolTree, IsSymbol,
70 InitTree,
71 GetSymKey, PutSymKey, DelSymKey, IsEmptyTree,
72 DoesTreeContainAny, ForeachNodeDo, ForeachNodeConditionDo,
73 NoOfNodes ;
74
75 FROM M2Base IMPORT MixTypes, InitBase, Char, Integer, LongReal,
76 Cardinal, LongInt, LongCard, ZType, RType ;
77
78 FROM M2System IMPORT Address ;
79 FROM m2expr IMPORT OverflowZType ;
80 FROM m2tree IMPORT Tree ;
81 FROM m2linemap IMPORT BuiltinsLocation ;
82 FROM StrLib IMPORT StrEqual ;
83 FROM m2builtins IMPORT BuiltinExists ;
84
85 FROM M2Comp IMPORT CompilingDefinitionModule,
86 CompilingImplementationModule ;
87
88 FROM FormatStrings IMPORT HandleEscape ;
89 FROM M2Scaffold IMPORT DeclareArgEnvParams ;
90
91 FROM M2SymInit IMPORT InitDesc, InitSymInit, GetInitialized, ConfigSymInit,
92 SetInitialized, SetFieldInitialized, GetFieldInitialized,
93 PrintSymInit ;
94
95 IMPORT Indexing ;
96
97
98 CONST
99 DebugUnknowns = FALSE ;
100
101 (*
102 The Unbounded is a pseudo type used within the compiler
103 to implement dynamic parameter arrays. It is implmented
104 as a record structure which has the following fields:
105
106 RECORD
107 _m2_contents: POINTER TO type ;
108 _m2_high : CARDINAL ;
109 END ;
110 *)
111
112 UnboundedAddressName = "_m2_contents" ;
113 UnboundedHighName = "_m2_high_%d" ;
114
115 TYPE
116 ConstLitPoolEntry = POINTER TO RECORD
117 sym : CARDINAL ;
118 tok : CARDINAL ;
119 constName: Name ;
120 constType: CARDINAL ;
121 next : ConstLitPoolEntry ;
122 END ;
123
124 LRLists = ARRAY [RightValue..LeftValue] OF List ;
125
126 LRInitDesc = ARRAY [RightValue..LeftValue] OF InitDesc ;
127
128 TypeOfSymbol = (RecordSym, VarientSym, DummySym,
129 VarSym, EnumerationSym, SubrangeSym, ArraySym,
130 ConstStringSym, ConstVarSym, ConstLitSym,
131 VarParamSym, ParamSym, PointerSym,
132 UndefinedSym, TypeSym,
133 RecordFieldSym, VarientFieldSym, EnumerationFieldSym,
134 DefImpSym, ModuleSym, SetSym, ProcedureSym, ProcTypeSym,
135 SubscriptSym, UnboundedSym, GnuAsmSym, InterfaceSym,
136 ObjectSym, PartialUnboundedSym, TupleSym, OAFamilySym,
137 ImportSym, ImportStatementSym,
138 EquivSym, ErrorSym) ;
139
140 Where = RECORD
141 DefDeclared,
142 ModDeclared,
143 FirstUsed : CARDINAL ;
144 END ;
145
146 PackedInfo = RECORD
147 IsPacked : BOOLEAN ; (* is this type packed? *)
148 PackedEquiv : CARDINAL ; (* the equivalent packed type *)
149 END ;
150
151 PtrToAsmConstraint = POINTER TO RECORD
152 tokpos: CARDINAL ;
153 name : Name ;
154 str : CARDINAL ; (* regnames or constraints *)
155 obj : CARDINAL ; (* list of M2 syms *)
156 END ;
157
158 ModuleCtor = RECORD
159 ctor: CARDINAL ; (* Procedure which will become a ctor. *)
160 init: CARDINAL ; (* Module initialization block proc. *)
161 fini: CARDINAL ; (* Module Finalization block proc. *)
162 dep : CARDINAL ; (* Module dependency proc. *)
163 END ;
164
165 (* Each import list has a import statement symbol. *)
166
167 SymImportStatement = RECORD
168 listNo : CARDINAL ; (* The import list no. *)
169 ListOfImports: List ; (* Vector of SymImports. *)
170 at : Where ; (* The FROM or IMPORT token. *)
171 END ;
172
173 SymImport = RECORD
174 module : CARDINAL ; (* The module imported. *)
175 listNo : CARDINAL ; (* The import list no. *)
176 qualified: BOOLEAN ; (* Is the complete module imported? *)
177 at : Where ; (* token corresponding to the *)
178 (* module name in the import. *)
179 END ;
180
181 SymEquiv = RECORD
182 packedInfo: PackedInfo ;
183 nonPacked : CARDINAL ;
184 END ;
185
186 SymOAFamily = RECORD
187 MaxDimensions: CARDINAL ;
188 SimpleType : CARDINAL ;
189 Dimensions : Indexing.Index ;
190 END ;
191
192 SymTuple = RECORD
193 At : Where ;
194 nTuple: CARDINAL ;
195 list : Indexing.Index ;
196 END ;
197
198 SymError = RECORD
199 name : Name ;
200 At : Where ; (* Where was sym declared/used *)
201 END ;
202
203 SymObject = RECORD
204 name : Name ;
205 At : Where ; (* Where was sym declared/used *)
206 END ;
207
208 SymUndefined = RECORD
209 name : Name ; (* Index into name array, name *)
210 (* of record. *)
211 oafamily : CARDINAL ; (* The oafamily for this sym *)
212 errorScope: ErrorScope ; (* Title scope used if an *)
213 (* error is emitted. *)
214 At : Where ; (* Where was sym declared/used *)
215 END ;
216
217 SymGnuAsm = RECORD
218 String : CARDINAL ; (* (ConstString) the assembly *)
219 (* instruction. *)
220 At : Where ; (* Where was sym declared/used *)
221 Inputs,
222 Outputs,
223 Trashed : CARDINAL ; (* The interface symbols. *)
224 Volatile : BOOLEAN ; (* Declared as ASM VOLATILE ? *)
225 Simple : BOOLEAN ; (* is a simple kind? *)
226 END ;
227
228 SymInterface = RECORD
229 Parameters: Indexing.Index ;
230 (* regnames or constraints *)
231 (* list of M2 syms. *)
232 At : Where ; (* Where was sym declared/used *)
233 END ;
234
235 SymVarient = RECORD
236 Size : PtrToValue ; (* Size at runtime of symbol. *)
237 ListOfSons : List ; (* ListOfSons contains a list *)
238 (* of SymRecordField and *)
239 (* SymVarients *)
240 (* declared by the source *)
241 (* file. *)
242 DeclPacked : BOOLEAN ; (* Is this varient packed? *)
243 DeclResolved: BOOLEAN ; (* has we resolved packed? *)
244 Parent : CARDINAL ; (* Points to the parent symbol *)
245 Varient : CARDINAL ; (* Index into symbol table to *)
246 (* determine the associated *)
247 (* varient symbol. *)
248 tag : CARDINAL ; (* The tag of the varient *)
249 (* this can either be a type *)
250 (* or a varient field. *)
251 Scope : CARDINAL ; (* Scope of declaration. *)
252 At : Where ; (* Where was sym declared/used *)
253 END ;
254
255 SymRecord = RECORD
256 name : Name ; (* Index into name array, name *)
257 (* of record. *)
258 LocalSymbols : SymbolTree ; (* Contains all record fields. *)
259 Size : PtrToValue ; (* Size at runtime of symbol. *)
260 ListOfSons : List ; (* ListOfSons contains a list *)
261 (* of SymRecordField and *)
262 (* SymVarients *)
263 (* declared by the source *)
264 (* file. *)
265 Align : CARDINAL ; (* The alignment of this type. *)
266 DefaultAlign : CARDINAL ; (* The default field alignment *)
267 DeclPacked : BOOLEAN ; (* Is this record packed? *)
268 DeclResolved : BOOLEAN ; (* has we resolved packed? *)
269 oafamily : CARDINAL ; (* The oafamily for this sym. *)
270 Parent : CARDINAL ; (* Points to the parent symbol *)
271 Scope : CARDINAL ; (* Scope of declaration. *)
272 At : Where ; (* Where was sym declared/used *)
273 END ;
274
275 SymSubrange = RECORD
276 name : Name ; (* Index into name array, name *)
277 (* of subrange. *)
278 Low : CARDINAL ; (* Index to symbol for lower *)
279 High : CARDINAL ; (* Index to symbol for higher *)
280 Size : PtrToValue ; (* Size of subrange type. *)
281 Type : CARDINAL ; (* Index to type symbol for *)
282 (* the type of subrange. *)
283 Align : CARDINAL ; (* Alignment for this type. *)
284 ConstLitTree: SymbolTree ; (* constants of this type. *)
285 packedInfo : PackedInfo ; (* the equivalent packed type *)
286 oafamily : CARDINAL ; (* The oafamily for this sym *)
287 Scope : CARDINAL ; (* Scope of declaration. *)
288 At : Where ; (* Where was sym declared/used *)
289 END ;
290
291 SymEnumeration =
292 RECORD
293 name : Name ; (* Index into name array, name *)
294 (* of enumeration. *)
295 NoOfElements: CARDINAL ; (* No elements in enumeration *)
296 LocalSymbols: SymbolTree ; (* Contains all enumeration *)
297 (* fields (alphabetical). *)
298 ListOfFields: List ; (* Ordered as declared. *)
299 Size : PtrToValue ; (* Size at runtime of symbol. *)
300 packedInfo : PackedInfo ; (* the equivalent packed type *)
301 oafamily : CARDINAL ; (* The oafamily for this sym *)
302 Scope : CARDINAL ; (* Scope of declaration. *)
303 At : Where ; (* Where was sym declared/used *)
304 END ;
305
306 SymArray = RECORD
307 name : Name ; (* Index into name array, name *)
308 (* of array. *)
309 Subscript : CARDINAL ; (* the subscript for this *)
310 (* array. *)
311 Size : PtrToValue ; (* Size at runtime of symbol. *)
312 Offset : PtrToValue ; (* Offset at runtime of symbol *)
313 Type : CARDINAL ; (* Type of the Array. *)
314 Align : CARDINAL ; (* Alignment for this type. *)
315 Large : BOOLEAN ; (* is this a large array? *)
316 oafamily : CARDINAL ; (* The oafamily for this sym *)
317 Scope : CARDINAL ; (* Scope of declaration. *)
318 At : Where ; (* Where was sym declared/used *)
319 END ;
320
321 SymSubscript = RECORD
322 Type : CARDINAL ; (* Index to a subrange symbol. *)
323 Size : PtrToValue ; (* Size of this indice in*Size *)
324 Offset : PtrToValue ; (* Offset at runtime of symbol *)
325 (* Pseudo ie: Offset+Size*i *)
326 (* 1..n. The array offset is *)
327 (* the real memory offset. *)
328 (* This offset allows the a[i] *)
329 (* to be calculated without *)
330 (* the need to perform *)
331 (* subtractions when a[4..10] *)
332 (* needs to be indexed. *)
333 At : Where ; (* Where was sym declared/used *)
334 END ;
335
336 SymUnbounded = RECORD
337 Type : CARDINAL ; (* Index to Simple type symbol *)
338 Size : PtrToValue ;(* Max No of words ever *)
339 (* passed to this type. *)
340 RecordType : CARDINAL ; (* Record type used to *)
341 (* implement the unbounded. *)
342 Dimensions : CARDINAL ; (* No of dimensions this
343 open array uses. *)
344 Scope : CARDINAL ; (* Scope of declaration. *)
345 At : Where ; (* Where was sym declared/used *)
346 END ;
347
348 SymPartialUnbounded = RECORD
349 Type: CARDINAL ; (* Index to Simple type symbol *)
350 NDim: CARDINAL ; (* dimensions associated *)
351 END ;
352
353 SymProcedure
354 = RECORD
355 name : Name ; (* Index into name array, name *)
356 (* of procedure. *)
357 ListOfParam : List ; (* Contains a list of all the *)
358 (* parameters in this procedure. *)
359 ParamDefined : BOOLEAN ; (* Have the parameters been *)
360 (* defined yet? *)
361 DefinedInDef : BOOLEAN ; (* Were the parameters defined *)
362 (* in the Definition module? *)
363 (* Note that this depends on *)
364 (* whether the compiler has read *)
365 (* the .def or .mod first. *)
366 (* The second occurence is *)
367 (* compared to the first. *)
368 DefinedInImp : BOOLEAN ; (* Were the parameters defined *)
369 (* in the Implementation module? *)
370 (* Note that this depends on *)
371 (* whether the compiler has read *)
372 (* the .def or .mod first. *)
373 (* The second occurence is *)
374 (* compared to the first. *)
375 HasVarArgs : BOOLEAN ; (* Does this procedure use ... ? *)
376 HasOptArg : BOOLEAN ; (* Does this procedure use [ ] ? *)
377 OptArgInit : CARDINAL ; (* The optarg initial value. *)
378 IsBuiltin : BOOLEAN ; (* Was it declared __BUILTIN__ ? *)
379 BuiltinName : Name ; (* name of equivalent builtin *)
380 IsInline : BOOLEAN ; (* Was it declared __INLINE__ ? *)
381 IsNoReturn : BOOLEAN ; (* Attribute noreturn ? *)
382 ReturnOptional: BOOLEAN ; (* Is the return value optional? *)
383 IsExtern : BOOLEAN ; (* Make this procedure extern. *)
384 IsPublic : BOOLEAN ; (* Make this procedure visible. *)
385 IsCtor : BOOLEAN ; (* Is this procedure a ctor? *)
386 IsMonoName : BOOLEAN ; (* Ignores module name prefix. *)
387 Unresolved : SymbolTree ; (* All symbols currently *)
388 (* unresolved in this procedure. *)
389 ScopeQuad : CARDINAL ; (* Index into quads for scope *)
390 StartQuad : CARDINAL ; (* Index into quads for start *)
391 (* of procedure. *)
392 EndQuad : CARDINAL ; (* Index into quads for end of *)
393 (* procedure. *)
394 Reachable : BOOLEAN ; (* Defines if procedure will *)
395 (* ever be called by the main *)
396 (* Module. *)
397 SavePriority : BOOLEAN ; (* Does procedure need to save *)
398 (* and restore interrupts? *)
399 ReturnType : CARDINAL ; (* Return type for function. *)
400 Offset : CARDINAL ; (* Location of procedure used *)
401 (* in Pass 2 and if procedure *)
402 (* is a syscall. *)
403 LocalSymbols: SymbolTree ; (* Contains all symbols declared *)
404 (* within this procedure. *)
405 EnumerationScopeList: List ;
406 (* Enumeration scope list which *)
407 (* contains a list of all *)
408 (* enumerations which are *)
409 (* visable within this scope. *)
410 ListOfVars : List ; (* List of variables in this *)
411 (* scope. *)
412 ListOfProcs : List ; (* List of all procedures *)
413 (* declared within this *)
414 (* procedure. *)
415 NamedObjects : SymbolTree ; (* Names of all items declared. *)
416 Size : PtrToValue ; (* Activation record size. *)
417 TotalParamSize: PtrToValue ; (* size of all parameters. *)
418 ExceptionFinally,
419 ExceptionBlock: BOOLEAN ; (* does it have an exception? *)
420 Scope : CARDINAL ; (* Scope of declaration. *)
421 errorScope : ErrorScope ; (* The title scope. *)
422 ListOfModules : List ; (* List of all inner modules. *)
423 Begin, End : CARDINAL ; (* Tokens marking the BEGIN END *)
424 At : Where ; (* Where was sym declared/used *)
425 END ;
426
427 SymProcType
428 = RECORD
429 name : Name ; (* Index into name array, name *)
430 (* of procedure. *)
431 ListOfParam : List ; (* Contains a list of all the *)
432 (* parameters in this procedure. *)
433 HasVarArgs : BOOLEAN ; (* Does this proc type use ... ? *)
434 HasOptArg : BOOLEAN ; (* Does this procedure use [ ] ? *)
435 OptArgInit : CARDINAL ; (* The optarg initial value. *)
436 ReturnType : CARDINAL ; (* Return type for function. *)
437 ReturnOptional: BOOLEAN ; (* Is the return value optional? *)
438 Scope : CARDINAL ; (* Scope of declaration. *)
439 Size : PtrToValue ; (* Runtime size of symbol. *)
440 TotalParamSize: PtrToValue ; (* size of all parameters. *)
441 oafamily : CARDINAL ; (* The oafamily for this sym *)
442 At : Where ; (* Where was sym declared/used *)
443 END ;
444
445 SymParam = RECORD
446 name : Name ; (* Index into name array, name *)
447 (* of param. *)
448 Type : CARDINAL ; (* Index to the type of param. *)
449 IsUnbounded : BOOLEAN ; (* Is it an ARRAY OF Type? *)
450 ShadowVar : CARDINAL ; (* The local variable used to *)
451 (* shadow this parameter. *)
452 At : Where ; (* Where was sym declared/used *)
453 END ;
454
455 SymVarParam = RECORD
456 name : Name ; (* Index into name array, name *)
457 (* of param. *)
458 Type : CARDINAL ;(* Index to the type of param. *)
459 IsUnbounded : BOOLEAN ; (* Is it an ARRAY OF Type? *)
460 HeapVar : CARDINAL ;(* The pointer value on heap. *)
461 (* Only used by static *)
462 (* analysis. *)
463 ShadowVar : CARDINAL ;(* The local variable used to *)
464 (* shadow this parameter. *)
465 At : Where ; (* Where was sym declared/used *)
466 END ;
467
468 ConstStringVariant = (m2str, cstr, m2nulstr, cnulstr) ;
469
470 SymConstString
471 = RECORD
472 name : Name ; (* Index into name array, name *)
473 (* of const. *)
474 Contents : Name ; (* Contents of the string. *)
475 Length : CARDINAL ; (* StrLen (Contents) *)
476 M2Variant,
477 NulM2Variant,
478 CVariant,
479 NulCVariant : CARDINAL ; (* variants of the same string *)
480 StringVariant : ConstStringVariant ;
481 Scope : CARDINAL ; (* Scope of declaration. *)
482 At : Where ; (* Where was sym declared/used *)
483 END ;
484
485 SymConstLit = RECORD
486 name : Name ; (* Index into name array, name *)
487 (* of const. *)
488 Value : PtrToValue ; (* Value of the constant. *)
489 Type : CARDINAL ; (* TYPE of constant, char etc *)
490 IsSet : BOOLEAN ; (* is the constant a set? *)
491 IsConstructor: BOOLEAN ; (* is the constant a set? *)
492 FromType : CARDINAL ; (* type is determined FromType *)
493 RangeError : BOOLEAN ; (* Have we reported an error? *)
494 UnresFromType: BOOLEAN ; (* is Type unresolved? *)
495 Scope : CARDINAL ; (* Scope of declaration. *)
496 At : Where ; (* Where was sym declared/used *)
497 END ;
498
499 SymConstVar = RECORD
500 name : Name ; (* Index into name array, name *)
501 (* of const. *)
502 Value : PtrToValue ; (* Value of the constant *)
503 Type : CARDINAL ; (* TYPE of constant, char etc *)
504 IsSet : BOOLEAN ; (* is the constant a set? *)
505 IsConstructor: BOOLEAN ; (* is the constant a set? *)
506 FromType : CARDINAL ; (* type is determined FromType *)
507 UnresFromType: BOOLEAN ; (* is Type resolved? *)
508 IsTemp : BOOLEAN ; (* is it a temporary? *)
509 Scope : CARDINAL ; (* Scope of declaration. *)
510 At : Where ; (* Where was sym declared/used *)
511 END ;
512
513 SymVar = RECORD
514 name : Name ; (* Index into name array, name *)
515 (* of const. *)
516 Type : CARDINAL ; (* Index to a type symbol. *)
517 BackType : CARDINAL ; (* specific back end symbol. *)
518 Size : PtrToValue ; (* Runtime size of symbol. *)
519 Offset : PtrToValue ; (* Offset at runtime of symbol *)
520 AddrMode : ModeOfAddr ; (* Type of Addressing mode. *)
521 Scope : CARDINAL ; (* Scope of declaration. *)
522 AtAddress : BOOLEAN ; (* Is declared at address? *)
523 Address : CARDINAL ; (* Address at which declared *)
524 IsComponentRef: BOOLEAN ; (* Is temporary referencing a *)
525 (* record field? *)
526 list : Indexing.Index ; (* the record and fields *)
527 IsTemp : BOOLEAN ; (* Is variable a temporary? *)
528 IsParam : BOOLEAN ; (* Is variable a parameter? *)
529 IsPointerCheck: BOOLEAN ; (* Is variable used to *)
530 (* dereference a pointer? *)
531 IsWritten : BOOLEAN ; (* Is variable written to? *)
532 IsSSA : BOOLEAN ; (* Is variable a SSA? *)
533 IsConst : BOOLEAN ; (* Is variable read/only? *)
534 ArrayRef : BOOLEAN ; (* Is variable used to point *)
535 (* to an array? *)
536 Heap : BOOLEAN ; (* Is var on the heap? *)
537 InitState : LRInitDesc ; (* Initialization state. *)
538 At : Where ; (* Where was sym declared/used *)
539 ReadUsageList, (* list of var read quads *)
540 WriteUsageList: LRLists ; (* list of var write quads *)
541 END ;
542
543 SymType = RECORD
544 name : Name ; (* Index into name array, name *)
545 (* of type. *)
546 Type : CARDINAL ; (* Index to a type symbol. *)
547 IsHidden : BOOLEAN ; (* Was it declared as hidden? *)
548 ConstLitTree: SymbolTree ; (* constants of this type. *)
549 Size : PtrToValue ; (* Runtime size of symbol. *)
550 packedInfo : PackedInfo ; (* the equivalent packed type *)
551 oafamily : CARDINAL ; (* The oafamily for this sym *)
552 Align : CARDINAL ; (* The alignment of this type *)
553 Scope : CARDINAL ; (* Scope of declaration. *)
554 At : Where ; (* Where was sym declared/used *)
555 END ;
556
557 SymPointer
558 = RECORD
559 name : Name ; (* Index into name array, name *)
560 (* of pointer. *)
561 Type : CARDINAL ; (* Index to a type symbol. *)
562 Size : PtrToValue ; (* Runtime size of symbol. *)
563 Align : CARDINAL ; (* The alignment of this type *)
564 ConstLitTree: SymbolTree ; (* constants of this type. *)
565 oafamily : CARDINAL ; (* The oafamily for this sym *)
566 Scope : CARDINAL ; (* Scope of declaration. *)
567 At : Where ; (* Where was sym declared/used *)
568 END ;
569
570 SymRecordField =
571 RECORD
572 name : Name ; (* Index into name array, name *)
573 (* of record field. *)
574 Type : CARDINAL ; (* Index to a type symbol. *)
575 Tag : BOOLEAN ; (* is the record field really *)
576 (* a varient tag? *)
577 Size : PtrToValue ; (* Runtime size of symbol. *)
578 Offset : PtrToValue ; (* Offset at runtime of symbol *)
579 Parent : CARDINAL ; (* Index into symbol table to *)
580 (* determine the parent symbol *)
581 (* for this record field. Used *)
582 (* for BackPatching. *)
583 Varient : CARDINAL ; (* Index into symbol table to *)
584 (* determine the associated *)
585 (* varient symbol. *)
586 Align : CARDINAL ; (* The alignment of this type *)
587 Used : BOOLEAN ; (* pragma usused unsets this. *)
588 DeclPacked: BOOLEAN ; (* Is this declared packed? *)
589 DeclResolved: BOOLEAN ; (* has we resolved packed? *)
590 Scope : CARDINAL ; (* Scope of declaration. *)
591 At : Where ; (* Where was sym declared/used *)
592 END ;
593
594 SymVarientField =
595 RECORD
596 name : Name ; (* Index into name array, name *)
597 (* of varient field (internal) *)
598 Size : PtrToValue ; (* Runtime size of symbol. *)
599 Offset : PtrToValue ; (* Offset at runtime of symbol *)
600 Parent : CARDINAL ; (* Index into symbol table to *)
601 (* determine the parent symbol *)
602 (* for this record field. Used *)
603 (* for BackPatching. *)
604 Varient : CARDINAL ; (* Index into symbol table to *)
605 (* determine the associated *)
606 (* varient symbol. *)
607 ListOfSons: List ; (* Contains a list of the *)
608 (* RecordField symbols and *)
609 (* SymVarients *)
610 DeclPacked: BOOLEAN ; (* Is this varient field *)
611 (* packed? *)
612 DeclResolved: BOOLEAN ; (* is it resolved? *)
613 Scope : CARDINAL ; (* Scope of declaration. *)
614 At : Where ; (* Where was sym declared/used *)
615 END ;
616
617 SymEnumerationField =
618 RECORD
619 name : Name ; (* Index into name array, name *)
620 (* of enumeration field. *)
621 Value : PtrToValue ; (* Enumeration field value. *)
622 Type : CARDINAL ; (* Index to the enumeration. *)
623 Scope : CARDINAL ; (* Scope of declaration. *)
624 At : Where ; (* Where was sym declared/used *)
625 END ;
626
627 SymSet = RECORD
628 name : Name ; (* Index into name array, name *)
629 (* of set. *)
630 Type : CARDINAL ; (* Index to a type symbol. *)
631 (* (subrange or enumeration). *)
632 packedInfo: PackedInfo ; (* the equivalent packed type *)
633 ispacked : BOOLEAN ;
634 Size : PtrToValue ; (* Runtime size of symbol. *)
635 oafamily : CARDINAL ; (* The oafamily for this sym *)
636 Scope : CARDINAL ; (* Scope of declaration. *)
637 At : Where ; (* Where was sym declared/used *)
638 END ;
639
640 SymDefImp =
641 RECORD
642 name : Name ; (* Index into name array, name *)
643 (* of record field. *)
644 libname : Name ; (* Library (dialect) with module *)
645 ctors : ModuleCtor ; (* All the ctor functions. *)
646 DefListOfDep,
647 ModListOfDep : List ; (* Vector of SymDependency. *)
648 ExportQualifiedTree: SymbolTree ;
649 (* Holds all the export *)
650 (* Qualified identifiers. *)
651 (* This tree may be *)
652 (* deleted at the end of Pass 1. *)
653 ExportUnQualifiedTree: SymbolTree ;
654 (* Holds all the export *)
655 (* UnQualified identifiers. *)
656 (* This tree may be *)
657 (* deleted at the end of Pass 1. *)
658 ExportRequest : SymbolTree ; (* Contains all identifiers that *)
659 (* have been requested by other *)
660 (* modules before this module *)
661 (* declared its export list. *)
662 (* This tree should be empty at *)
663 (* the end of the compilation. *)
664 (* Each time a symbol is *)
665 (* exported it is removed from *)
666 (* this list. *)
667 IncludeList : List ; (* Contains all included symbols *)
668 (* which are included by *)
669 (* IMPORT modulename ; *)
670 (* modulename.Symbol *)
671 DefIncludeList: List ; (* Contains all included symbols *)
672 (* which are included by *)
673 (* IMPORT modulename ; *)
674 (* in the definition module only *)
675 ImportTree : SymbolTree ; (* Contains all IMPORTed *)
676 (* identifiers. *)
677 ExportUndeclared: SymbolTree ;
678 (* ExportUndeclared contains all *)
679 (* the identifiers which were *)
680 (* exported but have not yet *)
681 (* been declared. *)
682 NeedToBeImplemented: SymbolTree ;
683 (* NeedToBeImplemented contains *)
684 (* the identifiers which have *)
685 (* been exported and declared *)
686 (* but have not yet been *)
687 (* implemented. *)
688 LocalSymbols : SymbolTree ; (* The LocalSymbols hold all the *)
689 (* variables declared local to *)
690 (* the block. It contains the *)
691 (* IMPORT r ; *)
692 (* FROM _ IMPORT x, y, x ; *)
693 (* and also *)
694 (* MODULE WeAreHere ; *)
695 (* x y z visible by localsym *)
696 (* MODULE Inner ; *)
697 (* EXPORT x, y, z ; *)
698 (* END Inner ; *)
699 (* END WeAreHere. *)
700 EnumerationScopeList: List ; (* Enumeration scope list which *)
701 (* contains a list of all *)
702 (* enumerations which are *)
703 (* visible within this scope. *)
704 NamedObjects : SymbolTree ; (* Names of all items declared. *)
705 NamedImports : SymbolTree ; (* Names of items imported. *)
706 WhereImported : SymbolTree ; (* Sym to TokenNo where import *)
707 (* occurs. Error message use. *)
708 Priority : CARDINAL ; (* Priority of the module. This *)
709 (* is an index to a constant. *)
710 Unresolved : SymbolTree ; (* All symbols currently *)
711 (* unresolved in this module. *)
712 StartQuad : CARDINAL ; (* Signify the initialization *)
713 (* code. *)
714 EndQuad : CARDINAL ; (* EndQuad should point to a *)
715 (* goto quad. *)
716 StartFinishQuad: CARDINAL ; (* Signify the finalization *)
717 (* code. *)
718 EndFinishQuad : CARDINAL ; (* should point to a finish *)
719 FinallyFunction: Tree ; (* The GCC function for finally *)
720 ExceptionFinally,
721 ExceptionBlock: BOOLEAN ; (* does it have an exception? *)
722 ContainsHiddenType: BOOLEAN ;(* True if this module *)
723 (* implements a hidden type. *)
724 ContainsBuiltin: BOOLEAN ; (* Does the module define a *)
725 (* builtin procedure? *)
726 ForC : BOOLEAN ; (* Is it a definition for "C" *)
727 NeedExportList: BOOLEAN ; (* Must user supply export list? *)
728 ModLink, (* Is the Def/Mod module parsed *)
729 DefLink : BOOLEAN ; (* for linkage only? *)
730 Builtin : BOOLEAN ; (* Is the module builtin? *)
731 ListOfVars : List ; (* List of variables in this *)
732 (* scope. *)
733 ListOfProcs : List ; (* List of all procedures *)
734 (* declared within this module. *)
735 ListOfModules : List ; (* List of all inner modules. *)
736 errorScope : ErrorScope ; (* The title scope. *)
737 At : Where ; (* Where was sym declared/used *)
738 END ;
739
740 SymModule =
741 RECORD
742 name : Name ; (* Index into name array, name *)
743 (* of record field. *)
744 libname : Name ; (* Library (dialect) with module *)
745 ctors : ModuleCtor ; (* All the ctor functions. *)
746 ModListOfDep : List ; (* Vector of SymDependency. *)
747 LocalSymbols : SymbolTree ; (* The LocalSymbols hold all the *)
748 (* variables declared local to *)
749 (* the block. It contains the *)
750 (* IMPORT r ; *)
751 (* FROM _ IMPORT x, y, x ; *)
752 (* and also *)
753 (* MODULE WeAreHere ; *)
754 (* x y z visible by localsym *)
755 (* MODULE Inner ; *)
756 (* EXPORT x, y, z ; *)
757 (* END Inner ; *)
758 (* END WeAreHere. *)
759 ExportTree : SymbolTree ; (* Holds all the exported *)
760 (* identifiers. *)
761 (* This tree may be *)
762 (* deleted at the end of Pass 1. *)
763 IncludeList : List ; (* Contains all included symbols *)
764 (* which are included by *)
765 (* IMPORT modulename ; *)
766 (* modulename.Symbol *)
767 ImportTree : SymbolTree ; (* Contains all IMPORTed *)
768 (* identifiers. *)
769 ExportUndeclared: SymbolTree ;
770 (* ExportUndeclared contains all *)
771 (* the identifiers which were *)
772 (* exported but have not yet *)
773 (* been declared. *)
774 EnumerationScopeList: List ; (* Enumeration scope list which *)
775 (* contains a list of all *)
776 (* enumerations which are *)
777 (* visable within this scope. *)
778 NamedObjects : SymbolTree ; (* Names of all items declared. *)
779 NamedImports : SymbolTree ; (* Names of items imported. *)
780 WhereImported : SymbolTree ; (* Sym to TokenNo where import *)
781 (* occurs. Error message use. *)
782 Scope : CARDINAL ; (* Scope of declaration. *)
783 Priority : CARDINAL ; (* Priority of the module. This *)
784 (* is an index to a constant. *)
785 Unresolved : SymbolTree ; (* All symbols currently *)
786 (* unresolved in this module. *)
787 StartQuad : CARDINAL ; (* Signify the initialization *)
788 (* code. *)
789 EndQuad : CARDINAL ; (* EndQuad should point to a *)
790 (* goto quad. *)
791 StartFinishQuad: CARDINAL ; (* Signify the finalization *)
792 (* code. *)
793 EndFinishQuad : CARDINAL ; (* should point to a finish *)
794 FinallyFunction: Tree ; (* The GCC function for finally *)
795 ExceptionFinally,
796 ExceptionBlock: BOOLEAN ; (* does it have an exception? *)
797 ModLink : BOOLEAN ; (* Is the module parsed for *)
798 (* linkage only? *)
799 Builtin : BOOLEAN ; (* Is the module builtin? *)
800 ListOfVars : List ; (* List of variables in this *)
801 (* scope. *)
802 ListOfProcs : List ; (* List of all procedures *)
803 (* declared within this module. *)
804 ListOfModules : List ; (* List of all inner modules. *)
805 errorScope : ErrorScope ; (* The title scope. *)
806 At : Where ; (* Where was sym declared/used *)
807 END ;
808
809 SymDummy =
810 RECORD
811 NextFree : CARDINAL ; (* Link to the next free symbol. *)
812 END ;
813
814
815 Symbol = RECORD
816 CASE SymbolType : TypeOfSymbol OF
817 (* Determines the type of symbol *)
818
819 OAFamilySym : OAFamily : SymOAFamily |
820 ObjectSym : Object : SymObject |
821 EquivSym : Equiv : SymEquiv |
822 RecordSym : Record : SymRecord |
823 VarientSym : Varient : SymVarient |
824 VarSym : Var : SymVar |
825 EnumerationSym : Enumeration : SymEnumeration |
826 SubrangeSym : Subrange : SymSubrange |
827 SubscriptSym : Subscript : SymSubscript |
828 ArraySym : Array : SymArray |
829 UnboundedSym : Unbounded : SymUnbounded |
830 PartialUnboundedSym : PartialUnbounded : SymPartialUnbounded |
831 ConstVarSym : ConstVar : SymConstVar |
832 ConstLitSym : ConstLit : SymConstLit |
833 ConstStringSym : ConstString : SymConstString |
834 VarParamSym : VarParam : SymVarParam |
835 ParamSym : Param : SymParam |
836 ErrorSym : Error : SymError |
837 UndefinedSym : Undefined : SymUndefined |
838 TypeSym : Type : SymType |
839 PointerSym : Pointer : SymPointer |
840 RecordFieldSym : RecordField : SymRecordField |
841 VarientFieldSym : VarientField : SymVarientField |
842 EnumerationFieldSym : EnumerationField : SymEnumerationField |
843 DefImpSym : DefImp : SymDefImp |
844 ModuleSym : Module : SymModule |
845 SetSym : Set : SymSet |
846 ProcedureSym : Procedure : SymProcedure |
847 ProcTypeSym : ProcType : SymProcType |
848 ImportStatementSym : ImportStatement : SymImportStatement |
849 ImportSym : Import : SymImport |
850 GnuAsmSym : GnuAsm : SymGnuAsm |
851 InterfaceSym : Interface : SymInterface |
852 TupleSym : Tuple : SymTuple |
853 DummySym : Dummy : SymDummy
854
855 END
856 END ;
857
858 CallFrame = RECORD
859 Main : CARDINAL ; (* Main scope for insertions *)
860 Search: CARDINAL ; (* Search scope for symbol searches *)
861 Start : CARDINAL ; (* ScopePtr value before StartScope *)
862 (* was called. *)
863 END ;
864
865 PtrToSymbol = POINTER TO Symbol ;
866 PtrToCallFrame = POINTER TO CallFrame ;
867
868 CheckProcedure = PROCEDURE (CARDINAL) ;
869
870 VAR
871 Symbols : Indexing.Index ; (* ARRAY [1..MaxSymbols] OF Symbol. *)
872 ScopeCallFrame: Indexing.Index ; (* ARRAY [1..MaxScopes] OF CallFrame. *)
873 FreeSymbol : CARDINAL ; (* The next free symbol indice. *)
874 DefModuleTree : SymbolTree ;
875 ModuleTree : SymbolTree ; (* Tree of all modules ever used. *)
876 ConstLitStringTree
877 : SymbolTree ; (* String Literal Constants only need *)
878 (* to be declared once. *)
879 CurrentModule : CARDINAL ; (* Index into symbols determining the *)
880 (* current module being compiled. *)
881 (* This maybe an inner module. *)
882 MainModule : CARDINAL ; (* Index into symbols determining the *)
883 (* module the user requested to *)
884 (* compile. *)
885 FileModule : CARDINAL ; (* Index into symbols determining *)
886 (* which module (file) is being *)
887 (* compiled. (Maybe an import def) *)
888 ScopePtr : CARDINAL ; (* An index to the ScopeCallFrame. *)
889 (* ScopePtr determines the top of the *)
890 (* ScopeCallFrame. *)
891 BaseScopePtr : CARDINAL ; (* An index to the ScopeCallFrame of *)
892 (* the top of BaseModule. BaseModule *)
893 (* is always left at the bottom of *)
894 (* stack since it is used so *)
895 (* frequently. When the BaseModule *)
896 (* needs to be searched the ScopePtr *)
897 (* is temporarily altered to *)
898 (* BaseScopePtr and GetScopeSym is *)
899 (* called. *)
900 BaseModule : CARDINAL ; (* Index to the symbol table of the *)
901 (* Base pseudo modeule declaration. *)
902 TemporaryNo : CARDINAL ; (* The next temporary number. *)
903 CurrentError : Error ; (* Current error chain. *)
904 AddressTypes : List ; (* A list of type symbols which must *)
905 (* be declared as ADDRESS or pointer *)
906 UnresolvedConstructorType: List ; (* all constructors whose type *)
907 (* is not yet known. *)
908 AnonymousName : CARDINAL ; (* anonymous type name unique id *)
909 ReportedUnknowns : Set ; (* set of symbols already reported as *)
910 (* unknowns to the user. *)
911 ConstLitPoolTree : SymbolTree ; (* Pool of constants to ensure *)
912 (* constants are reused between *)
913 (* passes and reduce duplicate *)
914 (* errors. *)
915 ConstLitArray : Indexing.Index ;
916
917
918 (*
919 CheckAnonymous - checks to see whether the name is NulName and if so
920 it creates a unique anonymous name.
921 *)
922
923 PROCEDURE CheckAnonymous (name: Name) : Name ;
924 BEGIN
925 IF name=NulName
926 THEN
927 INC(AnonymousName) ;
928 name := makekey(string(Mark(Sprintf1(Mark(InitString('$$%d')), AnonymousName))))
929 END ;
930 RETURN( name )
931 END CheckAnonymous ;
932
933
934 (*
935 IsNameAnonymous - returns TRUE if the symbol, sym, has an anonymous name
936 or no name.
937 *)
938
939 PROCEDURE IsNameAnonymous (sym: CARDINAL) : BOOLEAN ;
940 VAR
941 a: ARRAY [0..1] OF CHAR ;
942 n: Name ;
943 BEGIN
944 n := GetSymName(sym) ;
945 IF n=NulName
946 THEN
947 RETURN( TRUE )
948 ELSE
949 GetKey(n, a) ;
950 RETURN( StrEqual(a, '$$') )
951 END
952 END IsNameAnonymous ;
953
954
955 (*
956 InitWhereDeclared - sets the Declared and FirstUsed fields of record, at.
957 *)
958
959 PROCEDURE InitWhereDeclaredTok (tok: CARDINAL; VAR at: Where) ;
960 BEGIN
961 WITH at DO
962 IF CompilingDefinitionModule ()
963 THEN
964 DefDeclared := tok ;
965 ModDeclared := UnknownTokenNo
966 ELSE
967 DefDeclared := UnknownTokenNo ;
968 ModDeclared := tok
969 END ;
970 FirstUsed := tok (* we assign this field to something legal *)
971 END
972 END InitWhereDeclaredTok ;
973
974
975 (*
976 InitWhereDeclared - sets the Declared and FirstUsed fields of record, at.
977 *)
978
979 PROCEDURE InitWhereDeclared (VAR at: Where) ;
980 BEGIN
981 InitWhereDeclaredTok (GetTokenNo (), at)
982 END InitWhereDeclared ;
983
984
985 (*
986 InitWhereFirstUsed - sets the FirstUsed field of record, at.
987 *)
988
989 PROCEDURE InitWhereFirstUsed (VAR at: Where) ;
990 BEGIN
991 InitWhereFirstUsedTok (GetTokenNo (), at)
992 END InitWhereFirstUsed ;
993
994
995 (*
996 InitWhereFirstUsedTok - sets the FirstUsed field of record, at.
997 *)
998
999 PROCEDURE InitWhereFirstUsedTok (tok: CARDINAL; VAR at: Where) ;
1000 BEGIN
1001 WITH at DO
1002 FirstUsed := tok
1003 END
1004 END InitWhereFirstUsedTok ;
1005
1006
1007 (*
1008 FinalSymbol - returns the highest number symbol used.
1009 *)
1010
1011 PROCEDURE FinalSymbol () : CARDINAL ;
1012 BEGIN
1013 RETURN( FreeSymbol-1 )
1014 END FinalSymbol ;
1015
1016
1017 (*
1018 NewSym - Sets Sym to a new symbol index.
1019 *)
1020
1021 PROCEDURE NewSym (VAR sym: CARDINAL) ;
1022 VAR
1023 pSym: PtrToSymbol ;
1024 BEGIN
1025 sym := FreeSymbol ;
1026 NEW(pSym) ;
1027 WITH pSym^ DO
1028 SymbolType := DummySym
1029 END ;
1030 PutIndice(Symbols, sym, pSym) ;
1031 INC(FreeSymbol)
1032 END NewSym ;
1033
1034
1035 (*
1036 GetPsym - returns the pointer to, sym.
1037 *)
1038
1039 PROCEDURE GetPsym (sym: CARDINAL) : PtrToSymbol ;
1040 VAR
1041 pSym: PtrToSymbol ;
1042 BEGIN
1043 IF InBounds(Symbols, sym)
1044 THEN
1045 pSym := GetIndice(Symbols, sym) ;
1046 RETURN( pSym )
1047 ELSE
1048 InternalError ('symbol out of bounds')
1049 END
1050 END GetPsym ;
1051
1052
1053 (*
1054 GetPcall - returns the pointer to the CallFrame.
1055 *)
1056
1057 PROCEDURE GetPcall (call: CARDINAL) : PtrToCallFrame ;
1058 VAR
1059 pCall: PtrToCallFrame ;
1060 BEGIN
1061 IF InBounds(ScopeCallFrame, call)
1062 THEN
1063 pCall := GetIndice(ScopeCallFrame, call) ;
1064 RETURN( pCall )
1065 ELSE
1066 InternalError ('symbol out of bounds')
1067 END
1068 END GetPcall ;
1069
1070
1071 (*
1072 MakeImport - create and return an import symbol.
1073 moduleSym is the symbol being imported.
1074 isqualified is FALSE if it were IMPORT modulename and
1075 TRUE for the qualified FROM modulename IMPORT etc.
1076 listno is the import list count for this module.
1077 tok should match this modulename position.
1078 *)
1079
1080 PROCEDURE MakeImport (tok: CARDINAL;
1081 moduleSym: CARDINAL;
1082 listno: CARDINAL;
1083 isqualified: BOOLEAN) : CARDINAL ;
1084 VAR
1085 importSym: CARDINAL ;
1086 pSym : PtrToSymbol ;
1087 BEGIN
1088 NewSym (importSym) ;
1089 pSym := GetPsym (importSym) ;
1090 WITH pSym^ DO
1091 SymbolType := ImportSym ;
1092 WITH Import DO
1093 module := moduleSym ;
1094 listNo := listno ;
1095 qualified := isqualified ;
1096 InitWhereDeclaredTok (tok, at)
1097 END
1098 END ;
1099 RETURN importSym
1100 END MakeImport ;
1101
1102
1103 (*
1104 MakeImportStatement - return a dependent symbol which represents an import statement
1105 or a qualified import statement. The tok should either match
1106 the FROM token or the IMPORT token. listno is the import list
1107 count for the module.
1108 *)
1109
1110 PROCEDURE MakeImportStatement (tok: CARDINAL; listno: CARDINAL) : CARDINAL ;
1111 VAR
1112 dependentSym: CARDINAL ;
1113 pSym : PtrToSymbol ;
1114 BEGIN
1115 NewSym (dependentSym) ;
1116 pSym := GetPsym (dependentSym) ;
1117 WITH pSym^ DO
1118 SymbolType := ImportStatementSym ;
1119 WITH ImportStatement DO
1120 listNo := listno ;
1121 InitList (ListOfImports) ;
1122 InitWhereDeclaredTok (tok, at)
1123 END
1124 END ;
1125 RETURN dependentSym
1126 END MakeImportStatement ;
1127
1128
1129 (*
1130 AppendModuleImportStatement - appends the ImportStatement symbol onto the
1131 module import list.
1132
1133 For example:
1134
1135 FROM x IMPORT y, z ;
1136 ^^^^
1137
1138 also:
1139
1140 IMPORT p, q, r;
1141 ^^^^^^
1142 will result in a new ImportStatement symbol added
1143 to the current module import list.
1144 The statement symbol is expected to be created
1145 by MakeImportStatement using the token positions
1146 outlined above.
1147 *)
1148
1149 PROCEDURE AppendModuleImportStatement (module, statement: CARDINAL) ;
1150 VAR
1151 pSym: PtrToSymbol ;
1152 BEGIN
1153 IF IsDefImp (module)
1154 THEN
1155 pSym := GetPsym (module) ;
1156 IF CompilingDefinitionModule ()
1157 THEN
1158 IncludeItemIntoList (pSym^.DefImp.DefListOfDep, statement)
1159 ELSE
1160 IncludeItemIntoList (pSym^.DefImp.ModListOfDep, statement)
1161 END
1162 ELSIF IsModule (module)
1163 THEN
1164 pSym := GetPsym (module) ;
1165 IncludeItemIntoList (pSym^.Module.ModListOfDep, statement)
1166 ELSE
1167 InternalError ('expecting DefImp or Module symbol')
1168 END
1169 END AppendModuleImportStatement ;
1170
1171
1172 (*
1173 AppendModuleOnImportStatement - appends the import symbol onto the
1174 dependent list (chain).
1175
1176 For example each:
1177
1178 FROM x IMPORT y, z ;
1179 ^
1180 x are added to the dependent list.
1181
1182 also:
1183
1184 IMPORT p, q, r;
1185 ^ ^ ^
1186 will result in p, q and r added to
1187 to the dependent list.
1188
1189 The import symbol is created by MakeImport
1190 and the token is expected to match the module
1191 name position outlined above.
1192 *)
1193
1194 PROCEDURE AppendModuleOnImportStatement (module, import: CARDINAL) ;
1195 VAR
1196 l : List ;
1197 lastImportStatement: CARDINAL ;
1198 BEGIN
1199 Assert (IsImport (import)) ;
1200 IF CompilingDefinitionModule ()
1201 THEN
1202 l := GetModuleDefImportStatementList (module)
1203 ELSE
1204 l := GetModuleModImportStatementList (module)
1205 END ;
1206 Assert (l # NIL) ;
1207 Assert (NoOfItemsInList (l) > 0) ; (* There should always be one on the list. *)
1208 lastImportStatement := GetItemFromList (l, NoOfItemsInList (l)) ;
1209 Assert (IsImportStatement (lastImportStatement)) ;
1210 l := GetImportStatementList (lastImportStatement) ;
1211 IncludeItemIntoList (l, import)
1212 END AppendModuleOnImportStatement ;
1213
1214
1215 (*
1216 IsImport - returns TRUE if sym is an import symbol.
1217 *)
1218
1219 PROCEDURE IsImport (sym: CARDINAL) : BOOLEAN ;
1220 VAR
1221 pSym: PtrToSymbol ;
1222 BEGIN
1223 pSym := GetPsym (sym) ;
1224 RETURN pSym^.SymbolType=ImportSym
1225 END IsImport ;
1226
1227
1228 (*
1229 IsImportStatement - returns TRUE if sym is a dependent symbol.
1230 *)
1231
1232 PROCEDURE IsImportStatement (sym: CARDINAL) : BOOLEAN ;
1233 VAR
1234 pSym: PtrToSymbol ;
1235 BEGIN
1236 pSym := GetPsym (sym) ;
1237 RETURN pSym^.SymbolType=ImportStatementSym
1238 END IsImportStatement ;
1239
1240
1241 (*
1242 GetImportModule - returns the module associated with the import symbol.
1243 *)
1244
1245 PROCEDURE GetImportModule (sym: CARDINAL) : CARDINAL ;
1246 VAR
1247 pSym: PtrToSymbol ;
1248 BEGIN
1249 Assert (IsImport (sym)) ;
1250 pSym := GetPsym (sym) ;
1251 RETURN pSym^.Import.module
1252 END GetImportModule ;
1253
1254
1255 (*
1256 GetImportDeclared - returns the token associated with the import symbol.
1257 *)
1258
1259 PROCEDURE GetImportDeclared (sym: CARDINAL) : CARDINAL ;
1260 VAR
1261 tok : CARDINAL ;
1262 BEGIN
1263 Assert (IsImport (sym)) ;
1264 tok := GetDeclaredDefinition (sym) ;
1265 IF tok = UnknownTokenNo
1266 THEN
1267 RETURN GetDeclaredModule (sym)
1268 END ;
1269 RETURN tok
1270 END GetImportDeclared ;
1271
1272
1273 (*
1274 GetImportStatementList - returns the list of imports for this dependent.
1275 Each import symbol corresponds to a module.
1276 *)
1277
1278 PROCEDURE GetImportStatementList (sym: CARDINAL) : List ;
1279 VAR
1280 pSym: PtrToSymbol ;
1281 BEGIN
1282 Assert (IsImportStatement (sym)) ;
1283 pSym := GetPsym (sym) ;
1284 RETURN pSym^.ImportStatement.ListOfImports
1285 END GetImportStatementList ;
1286
1287
1288 (*
1289 GetModuleDefImportStatementList - returns the list of dependents associated with
1290 the definition module.
1291 *)
1292
1293 PROCEDURE GetModuleDefImportStatementList (sym: CARDINAL) : List ;
1294 VAR
1295 pSym: PtrToSymbol ;
1296 BEGIN
1297 Assert (IsModule (sym) OR IsDefImp (sym)) ;
1298 IF IsDefImp (sym)
1299 THEN
1300 pSym := GetPsym (sym) ;
1301 RETURN pSym^.DefImp.DefListOfDep
1302 END ;
1303 RETURN NIL
1304 END GetModuleDefImportStatementList ;
1305
1306
1307 (*
1308 GetModuleModImportStatementList - returns the list of dependents associated with
1309 the implementation or program module.
1310 *)
1311
1312 PROCEDURE GetModuleModImportStatementList (sym: CARDINAL) : List ;
1313 VAR
1314 pSym: PtrToSymbol ;
1315 BEGIN
1316 Assert (IsModule (sym) OR IsDefImp (sym)) ;
1317 pSym := GetPsym (sym) ;
1318 IF IsDefImp (sym)
1319 THEN
1320 RETURN pSym^.DefImp.ModListOfDep
1321 ELSE
1322 RETURN pSym^.Module.ModListOfDep
1323 END
1324 END GetModuleModImportStatementList ;
1325
1326
1327 (*
1328 DebugProcedureLineNumber -
1329 *)
1330
1331 PROCEDURE DebugProcedureLineNumber (sym: CARDINAL) ;
1332 VAR
1333 begin, end: CARDINAL ;
1334 n : Name ;
1335 f : String ;
1336 l : CARDINAL ;
1337 BEGIN
1338 GetProcedureBeginEnd (sym, begin, end) ;
1339 n := GetSymName(sym) ;
1340 IF begin#0
1341 THEN
1342 f := FindFileNameFromToken (begin, 0) ;
1343 l := TokenToLineNo(begin, 0) ;
1344 printf3 ('%s:%d:%a:begin\n', f, l, n)
1345 END ;
1346 IF end#0
1347 THEN
1348 f := FindFileNameFromToken (end, 0) ;
1349 l := TokenToLineNo(end, 0) ;
1350 printf3 ('%s:%d:%a:end\n', f, l, n)
1351 END
1352 END DebugProcedureLineNumber ;
1353
1354
1355 (*
1356 DebugLineNumbers - internal debugging, emit all procedure names in this module
1357 together with the line numbers for the corresponding begin/end
1358 tokens.
1359 *)
1360
1361 PROCEDURE DebugLineNumbers (sym: CARDINAL) ;
1362 BEGIN
1363 IF DebugFunctionLineNumbers
1364 THEN
1365 printf0 ('<lines>\n') ;
1366 ForeachProcedureDo(sym, DebugProcedureLineNumber) ;
1367 printf0 ('</lines>\n')
1368 END
1369 END DebugLineNumbers ;
1370
1371
1372 (*
1373 IsPartialUnbounded - returns TRUE if, sym, is a partially unbounded symbol.
1374 *)
1375
1376 PROCEDURE IsPartialUnbounded (sym: CARDINAL) : BOOLEAN ;
1377 VAR
1378 pSym: PtrToSymbol ;
1379 BEGIN
1380 IF sym>0
1381 THEN
1382 pSym := GetPsym(sym) ;
1383 WITH pSym^ DO
1384 CASE SymbolType OF
1385
1386 PartialUnboundedSym: RETURN( TRUE )
1387
1388 ELSE
1389 RETURN( FALSE )
1390 END
1391 END
1392 ELSE
1393 RETURN( FALSE )
1394 END
1395 END IsPartialUnbounded ;
1396
1397
1398 (*
1399 PutPartialUnbounded -
1400 *)
1401
1402 PROCEDURE PutPartialUnbounded (sym: CARDINAL; type: CARDINAL; ndim: CARDINAL) ;
1403 VAR
1404 pSym: PtrToSymbol ;
1405 BEGIN
1406 pSym := GetPsym(sym) ;
1407 IF IsDummy(sym)
1408 THEN
1409 pSym^.SymbolType := PartialUnboundedSym
1410 END ;
1411 WITH pSym^ DO
1412 CASE SymbolType OF
1413
1414 PartialUnboundedSym: PartialUnbounded.Type := type ;
1415 PartialUnbounded.NDim := ndim
1416
1417 ELSE
1418 InternalError ('not expecting this type')
1419 END
1420 END
1421 END PutPartialUnbounded ;
1422
1423
1424 (*
1425 AlreadyDeclaredError - generate an error message, a, and two areas of code showing
1426 the places where the symbols were declared.
1427 *)
1428
1429 PROCEDURE AlreadyDeclaredError (s: String; name: Name; OtherOccurance: CARDINAL) ;
1430 VAR
1431 e: Error ;
1432 BEGIN
1433 IF (OtherOccurance=0) OR (OtherOccurance=GetTokenNo())
1434 THEN
1435 e := NewError(GetTokenNo()) ;
1436 ErrorString(e, s)
1437 ELSE
1438 e := NewError(GetTokenNo()) ;
1439 ErrorString(e, s) ;
1440 e := ChainError(OtherOccurance, e) ;
1441 ErrorFormat1(e, 'and symbol (%a) is also declared here', name)
1442 END
1443 END AlreadyDeclaredError ;
1444
1445
1446 (*
1447 AlreadyImportedError - generate an error message, a, and two areas of code showing
1448 the places where the symbols was imported and also declared.
1449 *)
1450
1451 (*
1452 PROCEDURE AlreadyImportedError (s: String; name: Name; OtherOccurance: CARDINAL) ;
1453 VAR
1454 e: Error ;
1455 BEGIN
1456 IF (OtherOccurance=0) OR (OtherOccurance=GetTokenNo())
1457 THEN
1458 e := NewError(GetTokenNo()) ;
1459 ErrorString(e, s)
1460 ELSE
1461 e := NewError(GetTokenNo()) ;
1462 ErrorString(e, s) ;
1463 e := ChainError(OtherOccurance, e) ;
1464 ErrorFormat1(e, 'and symbol (%a) was also seen here', name)
1465 END
1466 END AlreadyImportedError ;
1467 *)
1468
1469
1470 (*
1471 MakeError - creates an error node, which can be used in MetaError messages.
1472 It will be removed from ExportUndeclared and Unknown trees.
1473 *)
1474
1475 PROCEDURE MakeError (tok: CARDINAL; name: Name) : CARDINAL ;
1476 VAR
1477 pSym: PtrToSymbol ;
1478 Sym : CARDINAL ;
1479 BEGIN
1480 (* if Sym is present on the unknown tree then remove it *)
1481 Sym := FetchUnknownSym (name) ;
1482 IF Sym=NulSym
1483 THEN
1484 NewSym(Sym)
1485 ELSE
1486 (*
1487 remove symbol from this tree as we have already generated
1488 a meaningful error message
1489 *)
1490 RemoveExportUndeclared(GetCurrentModuleScope(), Sym)
1491 END ;
1492 pSym := GetPsym(Sym) ;
1493 WITH pSym^ DO
1494 SymbolType := ErrorSym ;
1495 Error.name := name ;
1496 InitWhereDeclaredTok(tok, Error.At) ;
1497 InitWhereFirstUsedTok(tok, Error.At)
1498 END ;
1499 RETURN( Sym )
1500 END MakeError ;
1501
1502
1503 (*
1504 MakeErrorS - creates an error node from a string, which can be used
1505 in MetaError messages.
1506 It will be removed from ExportUndeclared and Unknown trees.
1507 *)
1508
1509 PROCEDURE MakeErrorS (tok: CARDINAL; name: String) : CARDINAL ;
1510 BEGIN
1511 RETURN MakeError (tok, makekey (string (name)))
1512 END MakeErrorS ;
1513
1514
1515 (*
1516 IsError - returns TRUE if the symbol is an error symbol.
1517 *)
1518
1519 PROCEDURE IsError (Sym: CARDINAL) : BOOLEAN ;
1520 VAR
1521 pSym: PtrToSymbol ;
1522 BEGIN
1523 CheckLegal(Sym) ;
1524 pSym := GetPsym(Sym) ;
1525 RETURN( pSym^.SymbolType=ErrorSym )
1526 END IsError ;
1527
1528
1529 (*
1530 MakeObject - creates an object node.
1531 *)
1532
1533 PROCEDURE MakeObject (name: Name) : CARDINAL ;
1534 VAR
1535 pSym: PtrToSymbol ;
1536 Sym : CARDINAL ;
1537 BEGIN
1538 NewSym(Sym) ;
1539 pSym := GetPsym(Sym) ;
1540 WITH pSym^ DO
1541 SymbolType := ObjectSym ;
1542 Object.name := name ;
1543 InitWhereDeclared(Object.At) ;
1544 InitWhereFirstUsed(Object.At)
1545 END ;
1546 RETURN( Sym )
1547 END MakeObject ;
1548
1549
1550 (*
1551 IsTuple - returns TRUE if the symbol is a tuple symbol.
1552 *)
1553
1554 PROCEDURE IsTuple (Sym: CARDINAL) : BOOLEAN ;
1555 VAR
1556 pSym: PtrToSymbol ;
1557 BEGIN
1558 CheckLegal(Sym) ;
1559 pSym := GetPsym(Sym) ;
1560 RETURN( pSym^.SymbolType=TupleSym )
1561 END IsTuple ;
1562
1563
1564 (*
1565 IsObject - returns TRUE if the symbol is an object symbol.
1566 *)
1567
1568 PROCEDURE IsObject (Sym: CARDINAL) : BOOLEAN ;
1569 VAR
1570 pSym: PtrToSymbol ;
1571 BEGIN
1572 CheckLegal(Sym) ;
1573 pSym := GetPsym(Sym) ;
1574 RETURN( pSym^.SymbolType=ObjectSym )
1575 END IsObject ;
1576
1577
1578 (*
1579 DeclareSym - returns a symbol which was either in the unknown tree or
1580 a New symbol, since name is about to be declared.
1581 *)
1582
1583 PROCEDURE DeclareSym (tok: CARDINAL; name: Name) : CARDINAL ;
1584 VAR
1585 Sym: CARDINAL ;
1586 BEGIN
1587 IF name = NulName
1588 THEN
1589 NewSym (Sym)
1590 ELSIF IsAlreadyDeclaredSym (name)
1591 THEN
1592 Sym := GetSym (name) ;
1593 IF IsImported (GetCurrentModuleScope (), Sym)
1594 THEN
1595 MetaErrorT1 (GetWhereImported(Sym),
1596 'symbol {%1Rad} is already present in this scope, check both definition and implementation modules, use a different name or remove the import',
1597 Sym) ;
1598 MetaErrorT1 (tok, 'symbol {%1Cad} also declared in this module', Sym) ;
1599 IF Sym # GetVisibleSym (name)
1600 THEN
1601 MetaErrorT1 (tok, 'symbol {%1CMad} also declared in this module', GetVisibleSym (name))
1602 END
1603 ELSE
1604 MetaErrorT1 (tok, 'symbol {%1RMad} is already declared in this scope, use a different name or remove the declaration', Sym) ;
1605 MetaErrorT1 (tok, 'symbol {%1Cad} also declared in this module', Sym) ;
1606 IF Sym # GetVisibleSym(name)
1607 THEN
1608 MetaErrorT1(tok, 'symbol {%1CMad} also declared in this module', GetVisibleSym (name))
1609 END
1610 END ;
1611 Sym := MakeError (tok, name)
1612 ELSE
1613 Sym := FetchUnknownSym (name) ;
1614 IF Sym=NulSym
1615 THEN
1616 NewSym (Sym)
1617 END ;
1618 CheckForExportedDeclaration (Sym)
1619 END ;
1620 RETURN Sym
1621 END DeclareSym ;
1622
1623
1624 (*
1625 Init - Initializes the data structures and variables in this module.
1626 Initialize the trees.
1627 *)
1628
1629 PROCEDURE Init ;
1630 VAR
1631 pCall: PtrToCallFrame ;
1632 BEGIN
1633 AnonymousName := 0 ;
1634 CurrentError := NIL ;
1635 InitTree (ConstLitPoolTree) ;
1636 InitTree (ConstLitStringTree) ;
1637 InitTree (DefModuleTree) ;
1638 InitTree (ModuleTree) ;
1639 Symbols := InitIndex (1) ;
1640 ConstLitArray := InitIndex (1) ;
1641 FreeSymbol := 1 ;
1642 ScopePtr := 1 ;
1643 ScopeCallFrame := InitIndex(1) ;
1644 NEW(pCall) ;
1645 WITH pCall^ DO
1646 Main := NulSym ;
1647 Search := NulSym
1648 END ;
1649 PutIndice(ScopeCallFrame, ScopePtr, pCall) ;
1650 CurrentModule := NulSym ;
1651 MainModule := NulSym ;
1652 FileModule := NulSym ;
1653 TemporaryNo := 0 ;
1654 (*
1655 InitList(FreeFVarientList) ; (* Lists used to maintain GC of field *)
1656 InitList(UsedFVarientList) ; (* varients. *)
1657 *)
1658 InitList(UnresolvedConstructorType) ;
1659
1660 InitBase(BuiltinsLocation(), BaseModule) ;
1661 StartScope(BaseModule) ; (* BaseModule scope placed at the bottom of the stack *)
1662 BaseScopePtr := ScopePtr ; (* BaseScopePtr points to the top of the BaseModule scope *)
1663 InitList(AddressTypes) ;
1664 ReportedUnknowns := InitSet(1)
1665 END Init ;
1666
1667
1668 (*
1669 FromModuleGetSym - attempts to find a symbol of name, n, in the
1670 module, mod, scope. An unknown symbol is created
1671 at token position tok if necessary.
1672 *)
1673
1674 PROCEDURE FromModuleGetSym (tok: CARDINAL; n: Name; mod: CARDINAL) : CARDINAL ;
1675 VAR
1676 n1 : Name ;
1677 sym : CARDINAL ;
1678 OldScopePtr: CARDINAL ;
1679 BEGIN
1680 OldScopePtr := ScopePtr ;
1681 StartScope (mod) ;
1682 sym := RequestSym (tok, n) ;
1683 EndScope ;
1684 IF sym=NulSym
1685 THEN
1686 (* --fixme-- can sym ever be NulSym? *)
1687 n1 := GetSymName(mod) ;
1688 WriteFormat2('cannot find procedure %a in module, %a',
1689 n, n1)
1690 END ;
1691 ScopePtr := OldScopePtr ;
1692 RETURN( sym )
1693 END FromModuleGetSym ;
1694
1695
1696 (*
1697 AddSymToUnknown -
1698 *)
1699
1700 PROCEDURE AddSymToUnknown (scope: CARDINAL; name: Name; Sym: CARDINAL) ;
1701 VAR
1702 pSym: PtrToSymbol ;
1703 n : Name ;
1704 BEGIN
1705 IF DebugUnknowns
1706 THEN
1707 n := GetSymName(scope) ;
1708 printf3('adding unknown %a (%d) to scope %a\n', name, Sym, n)
1709 END ;
1710
1711 (* Add symbol to unknown tree *)
1712 pSym := GetPsym(scope) ;
1713 WITH pSym^ DO
1714 CASE SymbolType OF
1715
1716 DefImpSym : PutSymKey(DefImp.Unresolved, name, Sym) |
1717 ModuleSym : PutSymKey(Module.Unresolved, name, Sym) |
1718 ProcedureSym: PutSymKey(Procedure.Unresolved, name, Sym)
1719
1720 ELSE
1721 InternalError ('expecting DefImp, Module or Procedure symbol')
1722 END
1723 END
1724 END AddSymToUnknown ;
1725
1726
1727 (*
1728 AddSymToUnknownTree - adds a symbol with name, name, and Sym to the
1729 unknown tree.
1730 *)
1731
1732 PROCEDURE AddSymToUnknownTree (ScopeId: INTEGER; name: Name; Sym: CARDINAL) ;
1733 VAR
1734 pCall : PtrToCallFrame ;
1735 ScopeSym: CARDINAL ;
1736 BEGIN
1737 IF ScopeId>0
1738 THEN
1739 (* choose to place the unknown symbol in the first module scope
1740 outside the current scope *)
1741 REPEAT
1742 pCall := GetPcall(ScopeId) ;
1743 ScopeSym := pCall^.Main ;
1744 IF (ScopeSym>0) AND (IsDefImp(ScopeSym) OR IsModule(ScopeSym))
1745 THEN
1746 AddSymToUnknown(ScopeSym, name, Sym) ;
1747 RETURN
1748 END ;
1749 DEC(ScopeId)
1750 UNTIL ScopeId=0
1751 END ;
1752 AddSymToUnknown(CurrentModule, name, Sym)
1753 END AddSymToUnknownTree ;
1754
1755
1756 (*
1757 SubSymFromUnknownTree - removes a symbol with name, name, from the
1758 unknown tree.
1759 *)
1760
1761 PROCEDURE SubSymFromUnknownTree (name: Name) ;
1762 VAR
1763 pCall : PtrToCallFrame ;
1764 ScopeSym,
1765 ScopeId : CARDINAL ;
1766 BEGIN
1767 IF ScopePtr>0
1768 THEN
1769 ScopeId := ScopePtr ;
1770 REPEAT
1771 pCall := GetPcall(ScopeId) ;
1772 ScopeSym := pCall^.Search ;
1773 IF IsModule(ScopeSym) OR IsDefImp(ScopeSym) OR IsProcedure(ScopeSym)
1774 THEN
1775 IF RemoveFromUnresolvedTree(ScopeSym, name)
1776 THEN
1777 RETURN
1778 END
1779 END ;
1780 DEC(ScopeId) ;
1781 UNTIL (ScopeId>0) AND (IsModule(ScopeSym) OR IsDefImp(ScopeSym))
1782 END ;
1783 IF RemoveFromUnresolvedTree(CurrentModule, name)
1784 THEN
1785 END
1786 END SubSymFromUnknownTree ;
1787
1788
1789 (*
1790 GetSymFromUnknownTree - returns a symbol with name, name, from the
1791 unknown tree.
1792 If no symbol with name is found then NulSym
1793 is returned.
1794 *)
1795
1796 PROCEDURE GetSymFromUnknownTree (name: Name) : CARDINAL ;
1797 VAR
1798 pCall : PtrToCallFrame ;
1799 ScopeSym,
1800 ScopeId ,
1801 Sym : CARDINAL ;
1802 BEGIN
1803 IF ScopePtr>0
1804 THEN
1805 ScopeId := ScopePtr ;
1806 REPEAT
1807 pCall := GetPcall(ScopeId) ;
1808 ScopeSym := pCall^.Search ;
1809 IF IsModule(ScopeSym) OR IsDefImp(ScopeSym) OR IsProcedure(ScopeSym)
1810 THEN
1811 Sym := ExamineUnresolvedTree(ScopeSym, name) ;
1812 IF Sym#NulSym
1813 THEN
1814 RETURN( Sym )
1815 END
1816 END ;
1817 DEC(ScopeId) ;
1818 UNTIL (ScopeId>0) AND (IsModule(ScopeSym) OR IsDefImp(ScopeSym))
1819 END ;
1820 (* Get symbol from unknown tree *)
1821 RETURN( ExamineUnresolvedTree(CurrentModule, name) )
1822 END GetSymFromUnknownTree ;
1823
1824
1825 (*
1826 ExamineUnresolvedTree - returns a symbol with name, name, from the
1827 unresolved tree of module, ModSym.
1828 If no symbol with name is found then NulSym
1829 is returned.
1830 *)
1831
1832 PROCEDURE ExamineUnresolvedTree (ScopeSym: CARDINAL; name: Name) : CARDINAL ;
1833 VAR
1834 pSym: PtrToSymbol ;
1835 Sym : CARDINAL ;
1836 BEGIN
1837 (* Get symbol from unknown tree *)
1838 pSym := GetPsym(ScopeSym) ;
1839 WITH pSym^ DO
1840 CASE SymbolType OF
1841
1842 DefImpSym : Sym := GetSymKey(DefImp.Unresolved, name) |
1843 ModuleSym : Sym := GetSymKey(Module.Unresolved, name) |
1844 ProcedureSym: Sym := GetSymKey(Procedure.Unresolved, name)
1845
1846 ELSE
1847 InternalError ('expecting DefImp, Module or Procedure symbol')
1848 END
1849 END ;
1850 RETURN( Sym )
1851 END ExamineUnresolvedTree ;
1852
1853
1854 (*
1855 TryMoveUndeclaredSymToInnerModule - attempts to move a symbol of
1856 name, name, which is
1857 currently undefined in the
1858 outer scope to the inner scope.
1859 If successful then the symbol is
1860 returned otherwise NulSym is
1861 returned.
1862 *)
1863
1864 PROCEDURE TryMoveUndeclaredSymToInnerModule (OuterScope,
1865 InnerScope: CARDINAL;
1866 name: Name) : CARDINAL ;
1867 VAR
1868 pSym: PtrToSymbol ;
1869 sym : CARDINAL ;
1870 BEGIN
1871 (* assume this should not be called if OuterScope was a procedure
1872 as this case is handled by the caller (P1SymBuild)
1873 *)
1874 Assert(IsModule(OuterScope) OR IsDefImp(OuterScope)) ;
1875 sym := GetExportUndeclared(OuterScope, name) ;
1876 IF sym#NulSym
1877 THEN
1878 Assert(IsUnknown(sym)) ;
1879 RemoveExportUndeclared(OuterScope, sym) ;
1880 AddSymToModuleScope(OuterScope, sym) ;
1881 AddVarToScopeList(OuterScope, sym) ;
1882 pSym := GetPsym(OuterScope) ;
1883 WITH pSym^ DO
1884 CASE SymbolType OF
1885
1886 DefImpSym: IF GetSymKey(DefImp.Unresolved, name)=sym
1887 THEN
1888 DelSymKey(DefImp.Unresolved, name)
1889 END |
1890 ModuleSym: IF GetSymKey(Module.Unresolved, name)=sym
1891 THEN
1892 DelSymKey(Module.Unresolved, name)
1893 END
1894
1895 ELSE
1896 InternalError ('expecting DefImp, Module symbol')
1897 END
1898 END ;
1899 AddSymToUnknown(InnerScope, name, sym) ;
1900 PutExportUndeclared(InnerScope, sym)
1901 END ;
1902 RETURN( sym )
1903 END TryMoveUndeclaredSymToInnerModule ;
1904
1905
1906 (*
1907 RemoveFromUnresolvedTree - removes a symbol with name, name, from the
1908 unresolved tree of symbol, ScopeSym.
1909 *)
1910
1911 PROCEDURE RemoveFromUnresolvedTree (ScopeSym: CARDINAL; name: Name) : BOOLEAN ;
1912 VAR
1913 pSym: PtrToSymbol ;
1914 BEGIN
1915 (* Get symbol from unknown tree *)
1916 pSym := GetPsym(ScopeSym) ;
1917 WITH pSym^ DO
1918 CASE SymbolType OF
1919
1920 DefImpSym : IF GetSymKey(DefImp.Unresolved, name)#NulKey
1921 THEN
1922 DelSymKey(DefImp.Unresolved, name) ;
1923 RETURN( TRUE )
1924 END |
1925 ModuleSym : IF GetSymKey(Module.Unresolved, name)#NulKey
1926 THEN
1927 DelSymKey(Module.Unresolved, name) ;
1928 RETURN( TRUE )
1929 END |
1930 ProcedureSym: IF GetSymKey(Procedure.Unresolved, name)#NulKey
1931 THEN
1932 DelSymKey(Procedure.Unresolved, name) ;
1933 RETURN( TRUE )
1934 END
1935
1936 ELSE
1937 InternalError ('expecting DefImp, Module or Procedure symbol')
1938 END
1939 END ;
1940 RETURN( FALSE )
1941 END RemoveFromUnresolvedTree ;
1942
1943
1944 (*
1945 FetchUnknownSym - returns a symbol from the unknown tree if one is
1946 available. It also updates the unknown tree.
1947 *)
1948
1949 PROCEDURE FetchUnknownSym (name: Name) : CARDINAL ;
1950 VAR
1951 Sym: CARDINAL ;
1952 BEGIN
1953 Sym := GetSymFromUnknownTree(name) ;
1954 IF Sym#NulSym
1955 THEN
1956 SubSymFromUnknownTree(name)
1957 END ;
1958 RETURN( Sym )
1959 END FetchUnknownSym ;
1960
1961
1962 (*
1963 TransparentScope - returns true is the scope symbol Sym is allowed
1964 to look to an outer level for a symbol.
1965 ie is the symbol allowed to look to the parent
1966 scope for a symbol.
1967 *)
1968
1969 PROCEDURE TransparentScope (Sym: CARDINAL) : BOOLEAN ;
1970 VAR
1971 pSym: PtrToSymbol ;
1972 BEGIN
1973 pSym := GetPsym(Sym) ;
1974 WITH pSym^ DO
1975 RETURN( (SymbolType#DefImpSym) AND (SymbolType#ModuleSym) )
1976 END
1977 END TransparentScope ;
1978
1979
1980 (*
1981 AddSymToModuleScope - adds a symbol, Sym, to the scope of the module
1982 ModSym.
1983 *)
1984
1985 PROCEDURE AddSymToModuleScope (ModSym: CARDINAL; Sym: CARDINAL) ;
1986 VAR
1987 pSym: PtrToSymbol ;
1988 BEGIN
1989 pSym := GetPsym(ModSym) ;
1990 WITH pSym^ DO
1991 CASE SymbolType OF
1992
1993 DefImpSym : IF GetSymKey(DefImp.LocalSymbols, GetSymName(Sym))=NulKey
1994 THEN
1995 PutSymKey(DefImp.LocalSymbols, GetSymName(Sym), Sym)
1996 ELSE
1997 MetaError1 ('{%kIMPORT} name clash with symbol {%1Ead} symbol already declared ', Sym)
1998 END |
1999 ModuleSym : IF GetSymKey(Module.LocalSymbols, GetSymName(Sym))=NulKey
2000 THEN
2001 PutSymKey(Module.LocalSymbols, GetSymName(Sym), Sym)
2002 ELSE
2003 MetaError1 ('{%kIMPORT} name clash with symbol {%1Ead} symbol already declared ', Sym)
2004 END |
2005 ProcedureSym: IF GetSymKey(Procedure.LocalSymbols, GetSymName(Sym))=NulKey
2006 THEN
2007 PutSymKey(Procedure.LocalSymbols, GetSymName(Sym), Sym)
2008 ELSE
2009 MetaError1 ('{%kIMPORT} name clash with symbol {%1Ead} symbol already declared ', Sym)
2010 END
2011
2012 ELSE
2013 InternalError ('expecting Module or DefImp symbol')
2014 END
2015 END
2016 END AddSymToModuleScope ;
2017
2018
2019 (*
2020 GetCurrentModuleScope - returns the module symbol which forms the
2021 current (possibly inner most) module.
2022 *)
2023
2024 PROCEDURE GetCurrentModuleScope () : CARDINAL ;
2025 VAR
2026 pCall: PtrToCallFrame ;
2027 i : CARDINAL ;
2028 BEGIN
2029 i := ScopePtr ;
2030 pCall := GetPcall(i) ;
2031 WHILE (NOT IsModule(pCall^.Search)) AND
2032 (NOT IsDefImp(pCall^.Search)) DO
2033 Assert(i>0) ;
2034 DEC(i) ;
2035 pCall := GetPcall(i)
2036 END ;
2037 RETURN( pCall^.Search )
2038 END GetCurrentModuleScope ;
2039
2040
2041 (*
2042 GetLastModuleScope - returns the last module scope encountered,
2043 the module scope before the Current Module Scope.
2044 *)
2045
2046 PROCEDURE GetLastModuleScope () : CARDINAL ;
2047 VAR
2048 pCall: PtrToCallFrame ;
2049 i : CARDINAL ;
2050 BEGIN
2051 i := ScopePtr ;
2052 pCall := GetPcall(i) ;
2053 WHILE (NOT IsModule(pCall^.Search)) AND
2054 (NOT IsDefImp(pCall^.Search)) DO
2055 Assert(i>0) ;
2056 DEC(i) ;
2057 pCall := GetPcall(i)
2058 END ;
2059 (* Found module at position, i. *)
2060 DEC(i) ; (* Move to an outer level module scope *)
2061 pCall := GetPcall(i) ;
2062 WHILE (NOT IsModule(pCall^.Search)) AND
2063 (NOT IsDefImp(pCall^.Search)) DO
2064 Assert(i>0) ;
2065 DEC(i) ;
2066 pCall := GetPcall(i)
2067 END ;
2068 (* Found module at position, i. *)
2069 RETURN( pCall^.Search )
2070 END GetLastModuleScope ;
2071
2072
2073 (*
2074 GetLastModuleOrProcedureScope - returns the last module or procedure scope encountered,
2075 the scope before the current module scope.
2076 *)
2077
2078 PROCEDURE GetLastModuleOrProcedureScope () : CARDINAL ;
2079 VAR
2080 pCall: PtrToCallFrame ;
2081 i : CARDINAL ;
2082 BEGIN
2083 (* find current inner module *)
2084 i := ScopePtr ;
2085 pCall := GetPcall(i) ;
2086 WHILE (NOT IsModule(pCall^.Search)) AND
2087 (NOT IsDefImp(pCall^.Search)) DO
2088 Assert(i>0) ;
2089 DEC(i) ;
2090 pCall := GetPcall(i)
2091 END ;
2092 (* found module at position, i. *)
2093 DEC(i) ; (* Move to an outer level module or procedure scope *)
2094 pCall := GetPcall(i) ;
2095 WHILE (NOT IsModule(pCall^.Search)) AND
2096 (NOT IsDefImp(pCall^.Search)) AND
2097 (NOT IsProcedure(pCall^.Search)) DO
2098 Assert(i>0) ;
2099 DEC(i) ;
2100 pCall := GetPcall(i)
2101 END ;
2102 (* Found module at position, i. *)
2103 RETURN( pCall^.Search )
2104 END GetLastModuleOrProcedureScope ;
2105
2106
2107 (*
2108 AddSymToScope - adds a symbol Sym with name name to
2109 the current scope symbol tree.
2110 *)
2111
2112 PROCEDURE AddSymToScope (Sym: CARDINAL; name: Name) ;
2113 VAR
2114 pSym : PtrToSymbol ;
2115 pCall : PtrToCallFrame ;
2116 ScopeId: CARDINAL ;
2117 BEGIN
2118 pCall := GetPcall(ScopePtr) ;
2119 ScopeId := pCall^.Main ;
2120 (*
2121 WriteString('Adding ') ; WriteKey(name) ; WriteString(' :') ; WriteCard(Sym, 4) ; WriteString(' to scope: ') ;
2122 WriteKey(GetSymName(ScopeId)) ; WriteLn ;
2123 *)
2124 pSym := GetPsym(ScopeId) ;
2125 WITH pSym^ DO
2126 CASE SymbolType OF
2127
2128 DefImpSym : IF name#NulName
2129 THEN
2130 PutSymKey(DefImp.LocalSymbols, name, Sym)
2131 END ;
2132 IF IsEnumeration(Sym)
2133 THEN
2134 CheckEnumerationInList(DefImp.EnumerationScopeList, Sym)
2135 END |
2136 ModuleSym : IF name#NulName
2137 THEN
2138 PutSymKey(Module.LocalSymbols, name, Sym)
2139 END ;
2140 IF IsEnumeration(Sym)
2141 THEN
2142 CheckEnumerationInList(Module.EnumerationScopeList, Sym)
2143 END |
2144 ProcedureSym: IF name#NulName
2145 THEN
2146 PutSymKey(Procedure.LocalSymbols, name, Sym)
2147 END ;
2148 IF IsEnumeration(Sym)
2149 THEN
2150 CheckEnumerationInList(Procedure.EnumerationScopeList, Sym)
2151 END
2152
2153 ELSE
2154 InternalError ('should never get here')
2155 END
2156 END
2157 END AddSymToScope ;
2158
2159
2160 (*
2161 GetCurrentScope - returns the symbol who is responsible for the current
2162 scope. Note that it ignore pseudo scopes.
2163 *)
2164
2165 PROCEDURE GetCurrentScope () : CARDINAL ;
2166 VAR
2167 pCall: PtrToCallFrame ;
2168 BEGIN
2169 pCall := GetPcall(ScopePtr) ;
2170 RETURN( pCall^.Main )
2171 END GetCurrentScope ;
2172
2173
2174 (*
2175 StartScope - starts a block scope at Sym. Transparent determines
2176 whether the search for a symbol will look at the
2177 previous ScopeCallFrame if Sym does not contain the
2178 symbol that GetSym is searching.
2179
2180 WITH statements are partially implemented by calling
2181 StartScope. Therefore we must retain the old Main from
2182 the previous ScopePtr when a record is added to the scope
2183 stack. (Main contains the symbol where all identifiers
2184 should be added.)
2185 *)
2186
2187 PROCEDURE StartScope (Sym: CARDINAL) ;
2188 VAR
2189 oCall,
2190 pCall: PtrToCallFrame ;
2191 BEGIN
2192 Sym := SkipType(Sym) ;
2193 (*
2194 WriteString('New scope is: ') ; WriteKey(GetSymName(Sym)) ; WriteLn ;
2195 *)
2196 INC(ScopePtr) ;
2197 IF InBounds(ScopeCallFrame, ScopePtr)
2198 THEN
2199 pCall := GetPcall(ScopePtr)
2200 ELSE
2201 NEW(pCall) ;
2202 PutIndice(ScopeCallFrame, ScopePtr, pCall)
2203 END ;
2204 WITH pCall^ DO
2205 Start := ScopePtr-1 ; (* Previous ScopePtr value before StartScope *)
2206 Search := Sym ;
2207
2208 (* If Sym is a record then maintain the old Main scope for adding *)
2209 (* new symbols to ie temporary variables. *)
2210 IF IsRecord(Sym)
2211 THEN
2212 oCall := GetPcall(ScopePtr-1) ;
2213 Main := oCall^.Main
2214 ELSE
2215 Main := Sym ;
2216 PlaceMajorScopesEnumerationListOntoStack(Sym)
2217 END
2218 END
2219 (* ; DisplayScopes *)
2220 END StartScope ;
2221
2222
2223 (*
2224 PlaceMajorScopesEnumerationListOntoStack - places the DefImp, Module and
2225 Procedure symbols enumeration
2226 list onto the scope stack.
2227 *)
2228
2229 PROCEDURE PlaceMajorScopesEnumerationListOntoStack (Sym: CARDINAL) ;
2230 VAR
2231 pSym: PtrToSymbol ;
2232 BEGIN
2233 pSym := GetPsym(Sym) ;
2234 WITH pSym^ DO
2235 CASE SymbolType OF
2236
2237 DefImpSym : PlaceEnumerationListOntoScope(DefImp.EnumerationScopeList) |
2238 ModuleSym : PlaceEnumerationListOntoScope(Module.EnumerationScopeList) |
2239 ProcedureSym: PlaceEnumerationListOntoScope(Procedure.EnumerationScopeList)
2240
2241 ELSE
2242 InternalError ('expecting - DefImp, Module or Procedure symbol')
2243 END
2244 END
2245 END PlaceMajorScopesEnumerationListOntoStack ;
2246
2247
2248 (*
2249 PlaceEnumerationListOntoScope - places an enumeration list, l, onto the
2250 scope stack. This list will automatically
2251 removed via one call to EndScope which
2252 matches the StartScope by which this
2253 procedure is invoked.
2254 *)
2255
2256 PROCEDURE PlaceEnumerationListOntoScope (l: List) ;
2257 VAR
2258 i, n: CARDINAL ;
2259 BEGIN
2260 n := NoOfItemsInList(l) ;
2261 i := 1 ;
2262 WHILE i<=n DO
2263 PseudoScope(GetItemFromList(l, i)) ;
2264 INC(i)
2265 END
2266 END PlaceEnumerationListOntoScope ;
2267
2268
2269 (*
2270 EndScope - ends a block scope started by StartScope. The current
2271 head of the symbol scope reverts back to the symbol
2272 which was the Head of the symbol scope before the
2273 last StartScope was called.
2274 *)
2275
2276 PROCEDURE EndScope ;
2277 VAR
2278 pCall: PtrToCallFrame ;
2279 BEGIN
2280 (*
2281 ; WriteString('EndScope - ending scope: ') ;
2282 pCall := GetPcall(ScopePtr) ;
2283 ; WriteKey(GetSymName(pCall^.Search)) ; WriteLn ;
2284 *)
2285 pCall := GetPcall(ScopePtr) ;
2286 ScopePtr := pCall^.Start
2287 (* ; DisplayScopes *)
2288 END EndScope ;
2289
2290
2291 (*
2292 PseudoScope - starts a pseudo scope at Sym.
2293 We always connect parent up to the last scope,
2294 to determine the transparancy of a scope we call
2295 TransparentScope.
2296
2297 A Pseudo scope has no end block,
2298 but is terminated when the next EndScope is used.
2299 The function of the pseudo scope is to provide an
2300 automatic mechanism to solve enumeration types.
2301 A declared enumeration type is a Pseudo scope and
2302 identifiers used with the name of an enumeration
2303 type field will find the enumeration symbol by
2304 the scoping algorithm.
2305 *)
2306
2307 PROCEDURE PseudoScope (Sym: CARDINAL) ;
2308 VAR
2309 oCall,
2310 pCall: PtrToCallFrame ;
2311 BEGIN
2312 IF IsEnumeration(Sym)
2313 THEN
2314 INC(ScopePtr) ;
2315 IF InBounds(ScopeCallFrame, ScopePtr)
2316 THEN
2317 pCall := GetPcall(ScopePtr)
2318 ELSE
2319 NEW(pCall) ;
2320 PutIndice(ScopeCallFrame, ScopePtr, pCall)
2321 END ;
2322 WITH pCall^ DO
2323 oCall := GetPcall(ScopePtr-1) ;
2324 Main := oCall^.Main ;
2325 Start := oCall^.Start ;
2326 Search := Sym
2327 END
2328 ELSE
2329 InternalError ('expecting EnumerationSym')
2330 END
2331 END PseudoScope ;
2332
2333
2334 (*
2335 IsDeclaredIn - returns TRUE if a symbol was declared in, scope.
2336 *)
2337
2338 PROCEDURE IsDeclaredIn (scope, sym: CARDINAL) : BOOLEAN ;
2339 VAR
2340 s: CARDINAL ;
2341 BEGIN
2342 s := GetScope(sym) ;
2343 WHILE s#scope DO
2344 IF (s=NulSym) OR IsProcedure(s) OR IsModule(s) OR IsDefImp(s)
2345 THEN
2346 RETURN( FALSE )
2347 ELSE
2348 s := GetScope(s)
2349 END
2350 END ;
2351 RETURN( TRUE )
2352 END IsDeclaredIn ;
2353
2354
2355 (*
2356 SetFirstUsed - assigns the FirstUsed field in at to tok providing
2357 it has not already been set.
2358 *)
2359
2360 PROCEDURE SetFirstUsed (tok: CARDINAL; VAR at: Where) ;
2361 BEGIN
2362 IF at.FirstUsed = UnknownTokenNo
2363 THEN
2364 at.FirstUsed := tok
2365 END
2366 END SetFirstUsed ;
2367
2368
2369 (*
2370 PutFirstUsed - sets tok to the first used providing it has not already been set.
2371 It also includes the read and write quad into the usage list
2372 providing the quad numbers are not 0.
2373 *)
2374
2375 PROCEDURE PutFirstUsed (object: CARDINAL; tok: CARDINAL; read, write: CARDINAL) ;
2376 VAR
2377 pSym: PtrToSymbol ;
2378 BEGIN
2379 IF IsVar (object)
2380 THEN
2381 pSym := GetPsym (object) ;
2382 SetFirstUsed (tok, pSym^.Var.At) ;
2383 IF read # 0
2384 THEN
2385 PutReadQuad (object, GetMode (object), read)
2386 END ;
2387 IF write # 0
2388 THEN
2389 PutWriteQuad (object, GetMode (object), write)
2390 END
2391 END
2392 END PutFirstUsed ;
2393
2394
2395 (*
2396 MakeGnuAsm - create a GnuAsm symbol.
2397 *)
2398
2399 PROCEDURE MakeGnuAsm () : CARDINAL ;
2400 VAR
2401 pSym: PtrToSymbol ;
2402 Sym : CARDINAL ;
2403 BEGIN
2404 NewSym(Sym) ;
2405 pSym := GetPsym (Sym) ;
2406 WITH pSym^ DO
2407 SymbolType := GnuAsmSym ;
2408 WITH GnuAsm DO
2409 String := NulSym ;
2410 InitWhereDeclared (At) ;
2411 Inputs := NulSym ;
2412 Outputs := NulSym ;
2413 Trashed := NulSym ;
2414 Volatile := FALSE ;
2415 Simple := FALSE
2416 END
2417 END ;
2418 RETURN( Sym )
2419 END MakeGnuAsm ;
2420
2421
2422 (*
2423 PutGnuAsm - places the instruction textual name into the GnuAsm symbol.
2424 *)
2425
2426 PROCEDURE PutGnuAsm (sym: CARDINAL; string: CARDINAL) ;
2427 VAR
2428 pSym: PtrToSymbol ;
2429 BEGIN
2430 Assert (IsConstString (string)) ;
2431 pSym := GetPsym(sym) ;
2432 WITH pSym^ DO
2433 CASE SymbolType OF
2434
2435 GnuAsmSym: GnuAsm.String := string
2436
2437 ELSE
2438 InternalError ('expecting PutGnuAsm symbol')
2439 END
2440 END
2441 END PutGnuAsm ;
2442
2443
2444 (*
2445 GetGnuAsm - returns the string symbol, representing the instruction textual
2446 of the GnuAsm symbol. It will return a ConstString.
2447 *)
2448
2449 PROCEDURE GetGnuAsm (sym: CARDINAL) : CARDINAL ;
2450 VAR
2451 pSym: PtrToSymbol ;
2452 BEGIN
2453 pSym := GetPsym(sym) ;
2454 WITH pSym^ DO
2455 CASE SymbolType OF
2456
2457 GnuAsmSym: RETURN GnuAsm.String
2458
2459 ELSE
2460 InternalError ('expecting GnuAsm symbol')
2461 END
2462 END
2463 END GetGnuAsm ;
2464
2465
2466 (*
2467 PutGnuAsmOutput - places the interface object, out, into GnuAsm symbol, sym.
2468 *)
2469
2470 PROCEDURE PutGnuAsmOutput (sym: CARDINAL; out: CARDINAL) ;
2471 VAR
2472 pSym: PtrToSymbol ;
2473 BEGIN
2474 pSym := GetPsym(sym) ;
2475 WITH pSym^ DO
2476 CASE SymbolType OF
2477
2478 GnuAsmSym: GnuAsm.Outputs := out
2479
2480 ELSE
2481 InternalError ('expecting PutGnuAsm symbol')
2482 END
2483 END
2484 END PutGnuAsmOutput ;
2485
2486
2487 (*
2488 PutGnuAsmInput - places the interface object, in, into GnuAsm symbol, sym.
2489 *)
2490
2491 PROCEDURE PutGnuAsmInput (sym: CARDINAL; in: CARDINAL) ;
2492 VAR
2493 pSym: PtrToSymbol ;
2494 BEGIN
2495 pSym := GetPsym (sym) ;
2496 WITH pSym^ DO
2497 CASE SymbolType OF
2498
2499 GnuAsmSym: GnuAsm.Inputs := in
2500
2501 ELSE
2502 InternalError ('expecting PutGnuAsm symbol')
2503 END
2504 END
2505 END PutGnuAsmInput ;
2506
2507
2508 (*
2509 PutGnuAsmTrash - places the interface object, trash, into GnuAsm symbol, sym.
2510 *)
2511
2512 PROCEDURE PutGnuAsmTrash (sym: CARDINAL; trash: CARDINAL) ;
2513 VAR
2514 pSym: PtrToSymbol ;
2515 BEGIN
2516 pSym := GetPsym (sym) ;
2517 WITH pSym^ DO
2518 CASE SymbolType OF
2519
2520 GnuAsmSym: GnuAsm.Trashed := trash
2521
2522 ELSE
2523 InternalError ('expecting PutGnuAsm symbol')
2524 END
2525 END
2526 END PutGnuAsmTrash ;
2527
2528
2529 (*
2530 GetGnuAsmInput - returns the input list of registers.
2531 *)
2532
2533 PROCEDURE GetGnuAsmInput (sym: CARDINAL) : CARDINAL ;
2534 VAR
2535 pSym: PtrToSymbol ;
2536 BEGIN
2537 pSym := GetPsym (sym) ;
2538 WITH pSym^ DO
2539 CASE SymbolType OF
2540
2541 GnuAsmSym: RETURN GnuAsm.Inputs
2542
2543 ELSE
2544 InternalError ('expecting PutGnuAsm symbol')
2545 END
2546 END
2547 END GetGnuAsmInput ;
2548
2549
2550 (*
2551 GetGnuAsmOutput - returns the output list of registers.
2552 *)
2553
2554 PROCEDURE GetGnuAsmOutput (sym: CARDINAL) : CARDINAL ;
2555 VAR
2556 pSym: PtrToSymbol ;
2557 BEGIN
2558 pSym := GetPsym (sym) ;
2559 WITH pSym^ DO
2560 CASE SymbolType OF
2561
2562 GnuAsmSym: RETURN GnuAsm.Outputs
2563
2564 ELSE
2565 InternalError ('expecting PutGnuAsm symbol')
2566 END
2567 END
2568 END GetGnuAsmOutput ;
2569
2570
2571 (*
2572 GetGnuAsmTrash - returns the list of trashed registers.
2573 *)
2574
2575 PROCEDURE GetGnuAsmTrash (sym: CARDINAL) : CARDINAL ;
2576 VAR
2577 pSym: PtrToSymbol ;
2578 BEGIN
2579 pSym := GetPsym (sym) ;
2580 WITH pSym^ DO
2581 CASE SymbolType OF
2582
2583 GnuAsmSym: RETURN GnuAsm.Trashed
2584
2585 ELSE
2586 InternalError ('expecting PutGnuAsm symbol')
2587 END
2588 END
2589 END GetGnuAsmTrash ;
2590
2591
2592 (*
2593 PutGnuAsmVolatile - defines a GnuAsm symbol as VOLATILE.
2594 *)
2595
2596 PROCEDURE PutGnuAsmVolatile (Sym: CARDINAL) ;
2597 VAR
2598 pSym: PtrToSymbol ;
2599 BEGIN
2600 pSym := GetPsym (Sym) ;
2601 WITH pSym^ DO
2602 CASE SymbolType OF
2603
2604 GnuAsmSym: GnuAsm.Volatile := TRUE
2605
2606 ELSE
2607 InternalError ('expecting GnuAsm symbol')
2608 END
2609 END
2610 END PutGnuAsmVolatile ;
2611
2612
2613 (*
2614 PutGnuAsmSimple - defines a GnuAsm symbol as a simple kind.
2615 *)
2616
2617 PROCEDURE PutGnuAsmSimple (Sym: CARDINAL) ;
2618 VAR
2619 pSym: PtrToSymbol ;
2620 BEGIN
2621 pSym := GetPsym (Sym) ;
2622 WITH pSym^ DO
2623 CASE SymbolType OF
2624
2625 GnuAsmSym: GnuAsm.Simple := TRUE
2626
2627 ELSE
2628 InternalError ('expecting GnuAsm symbol')
2629 END
2630 END
2631 END PutGnuAsmSimple ;
2632
2633
2634 (*
2635 MakeRegInterface - creates and returns a register interface symbol.
2636 *)
2637
2638 PROCEDURE MakeRegInterface () : CARDINAL ;
2639 VAR
2640 pSym: PtrToSymbol ;
2641 Sym : CARDINAL ;
2642 BEGIN
2643 NewSym (Sym) ;
2644 pSym := GetPsym (Sym) ;
2645 WITH pSym^ DO
2646 SymbolType := InterfaceSym ;
2647 WITH Interface DO
2648 Parameters := InitIndex (1) ;
2649 InitWhereDeclared (At)
2650 END
2651 END ;
2652 RETURN( Sym )
2653 END MakeRegInterface ;
2654
2655
2656 (*
2657 PutRegInterface - places a, name, string, and, object, into the interface array,
2658 sym, at position, i.
2659 The string symbol will either be a register name or a constraint.
2660 The object is an optional Modula-2 variable or constant symbol.
2661 read and write are the quadruple numbers representing any read
2662 or write operation.
2663 *)
2664
2665 PROCEDURE PutRegInterface (tok: CARDINAL;
2666 sym: CARDINAL; i: CARDINAL; n: Name; string, object: CARDINAL;
2667 read, write: CARDINAL) ;
2668 VAR
2669 pSym : PtrToSymbol ;
2670 p : PtrToAsmConstraint ;
2671 BEGIN
2672 pSym := GetPsym(sym) ;
2673 WITH pSym^ DO
2674 CASE SymbolType OF
2675
2676 InterfaceSym: IF Indexing.InBounds(Interface.Parameters, i)
2677 THEN
2678 p := Indexing.GetIndice(Interface.Parameters, i)
2679 ELSIF i=Indexing.HighIndice(Interface.Parameters)+1
2680 THEN
2681 NEW(p) ;
2682 Indexing.PutIndice(Interface.Parameters, i, p)
2683 ELSE
2684 InternalError ('expecting to add parameters sequentially')
2685 END ;
2686 WITH p^ DO
2687 tokpos := tok ;
2688 name := n ;
2689 str := string ;
2690 obj := object
2691 END ;
2692 PutFirstUsed (object, tok, read, write)
2693
2694 ELSE
2695 InternalError ('expecting Interface symbol')
2696 END
2697 END
2698 END PutRegInterface ;
2699
2700
2701 (*
2702 GetRegInterface - gets a, name, string, and, object, from the interface array,
2703 sym, from position, i.
2704 *)
2705
2706 PROCEDURE GetRegInterface (sym: CARDINAL; i: CARDINAL;
2707 VAR tok: CARDINAL; VAR n: Name; VAR string, object: CARDINAL) ;
2708 VAR
2709 pSym: PtrToSymbol ;
2710 p : PtrToAsmConstraint ;
2711 BEGIN
2712 pSym := GetPsym(sym) ;
2713 WITH pSym^ DO
2714 CASE SymbolType OF
2715
2716 InterfaceSym: IF Indexing.InBounds(Interface.Parameters, i)
2717 THEN
2718 p := Indexing.GetIndice(Interface.Parameters, i) ;
2719 WITH p^ DO
2720 tok := tokpos ;
2721 n := name ;
2722 string := str ;
2723 object := obj
2724 END
2725 ELSE
2726 tok := UnknownTokenNo ;
2727 n := NulName ;
2728 string := NulSym ;
2729 object := NulSym
2730 END
2731
2732 ELSE
2733 InternalError ('expecting Interface symbol')
2734 END
2735 END
2736 END GetRegInterface ;
2737
2738
2739 (*
2740 GetSubrange - returns HighSym and LowSym - two constants which make up the
2741 subrange.
2742 *)
2743
2744 PROCEDURE GetSubrange (Sym: CARDINAL; VAR HighSym, LowSym: CARDINAL) ;
2745 VAR
2746 pSym: PtrToSymbol ;
2747 BEGIN
2748 pSym := GetPsym(Sym) ;
2749 WITH pSym^ DO
2750 CASE SymbolType OF
2751
2752 SubrangeSym: HighSym := Subrange.High ;
2753 LowSym := Subrange.Low
2754
2755 ELSE
2756 InternalError ('expecting Subrange symbol')
2757 END
2758 END
2759 END GetSubrange ;
2760
2761
2762 (*
2763 PutSubrange - places LowSym and HighSym as two symbols
2764 which provide the limits of the range.
2765 *)
2766
2767 PROCEDURE PutSubrange (Sym: CARDINAL; LowSym, HighSym: CARDINAL;
2768 TypeSymbol: CARDINAL) ;
2769 VAR
2770 pSym: PtrToSymbol ;
2771 BEGIN
2772 pSym := GetPsym(Sym) ;
2773 WITH pSym^ DO
2774 CASE SymbolType OF
2775
2776 SubrangeSym: Subrange.Low := LowSym ; (* Index to symbol for lower *)
2777 Subrange.High := HighSym ; (* Index to symbol for higher *)
2778 Subrange.Type := TypeSymbol ; (* Index to type symbol for *)
2779 (* the type of subrange. *)
2780 ELSE
2781 InternalError ('expecting Subrange symbol')
2782 END
2783 END
2784 END PutSubrange ;
2785
2786
2787 (*
2788 SetCurrentModule - Used to set the CurrentModule to a symbol, Sym.
2789 This Sym must represent the module name of the
2790 file currently being compiled.
2791 *)
2792
2793 PROCEDURE SetCurrentModule (Sym: CARDINAL) ;
2794 BEGIN
2795 CurrentModule := Sym
2796 END SetCurrentModule ;
2797
2798
2799 (*
2800 GetCurrentModule - returns the current module Sym that is being
2801 compiled.
2802 *)
2803
2804 PROCEDURE GetCurrentModule () : CARDINAL ;
2805 BEGIN
2806 RETURN( CurrentModule )
2807 END GetCurrentModule ;
2808
2809
2810 (*
2811 SetMainModule - Used to set the MainModule to a symbol, Sym.
2812 This Sym must represent the main module which was
2813 envoked by the user to be compiled.
2814 *)
2815
2816 PROCEDURE SetMainModule (Sym: CARDINAL) ;
2817 BEGIN
2818 MainModule := Sym
2819 END SetMainModule ;
2820
2821
2822 (*
2823 GetMainModule - returns the main module symbol that was requested by
2824 the user to be compiled.
2825 *)
2826
2827 PROCEDURE GetMainModule () : CARDINAL ;
2828 BEGIN
2829 RETURN( MainModule )
2830 END GetMainModule ;
2831
2832
2833 (*
2834 SetFileModule - Used to set the FileModule to a symbol, Sym.
2835 This Sym must represent the current program module
2836 file which is being parsed.
2837 *)
2838
2839 PROCEDURE SetFileModule (Sym: CARDINAL) ;
2840 BEGIN
2841 FileModule := Sym
2842 END SetFileModule ;
2843
2844
2845 (*
2846 GetFileModule - returns the FileModule symbol that was requested by
2847 the user to be compiled.
2848 *)
2849
2850 PROCEDURE GetFileModule () : CARDINAL ;
2851 BEGIN
2852 RETURN( FileModule )
2853 END GetFileModule ;
2854
2855
2856 (*
2857 GetBaseModule - returns the base module symbol that contains Modula-2
2858 base types, procedures and functions.
2859 *)
2860
2861 PROCEDURE GetBaseModule () : CARDINAL ;
2862 BEGIN
2863 RETURN( BaseModule )
2864 END GetBaseModule ;
2865
2866
2867 (*
2868 GetSym - searches the current scope (and previous scopes if the
2869 scope tranparent allows) for a symbol with name.
2870 *)
2871
2872 PROCEDURE GetSym (name: Name) : CARDINAL ;
2873 VAR
2874 Sym : CARDINAL ;
2875 OldScopePtr: CARDINAL ;
2876 BEGIN
2877 Sym := GetScopeSym(name, TRUE) ;
2878 IF Sym=NulSym
2879 THEN
2880 (* Check default base types for symbol *)
2881 OldScopePtr := ScopePtr ; (* Save ScopePtr *)
2882 ScopePtr := BaseScopePtr ; (* Alter ScopePtr to point to top of BaseModule *)
2883 Sym := GetScopeSym(name, FALSE) ; (* Search BaseModule for name *)
2884 ScopePtr := OldScopePtr (* Restored ScopePtr *)
2885 END ;
2886 RETURN( Sym )
2887 END GetSym ;
2888
2889
2890 (*
2891 CanLookThroughScope - by default this procedure returns TRUE. It only returns
2892 FALSE if, throughProcedure, is FALSE and the ScopeSym is
2893 a procedure.
2894 *)
2895
2896 PROCEDURE CanLookThroughScope (ScopeSym: CARDINAL; throughProcedure: BOOLEAN) : BOOLEAN ;
2897 BEGIN
2898 IF IsProcedure(ScopeSym)
2899 THEN
2900 RETURN( throughProcedure )
2901 ELSE
2902 RETURN( TRUE )
2903 END
2904 END CanLookThroughScope ;
2905
2906
2907 (*
2908 GetScopeSym - searches the current scope and below, providing that the
2909 scopes are transparent, for a symbol with name, name.
2910 It only passes over procedure scopes if, throughProcedure,
2911 is TRUE.
2912 *)
2913
2914 PROCEDURE GetScopeSym (name: Name; throughProcedure: BOOLEAN) : CARDINAL ;
2915 VAR
2916 pCall : PtrToCallFrame ;
2917 ScopeSym,
2918 ScopeId ,
2919 Sym : CARDINAL ;
2920 BEGIN
2921 (* DisplayScopes ; *)
2922 ScopeId := ScopePtr ;
2923 pCall := GetPcall(ScopeId) ;
2924 ScopeSym := pCall^.Search ;
2925 (* WriteString(' scope: ') ; WriteKey(GetSymName(ScopeSym)) ; *)
2926 Sym := CheckScopeForSym(ScopeSym, name) ;
2927 WHILE (ScopeId>0) AND (Sym=NulSym) AND TransparentScope(ScopeSym) AND
2928 CanLookThroughScope(ScopeSym, throughProcedure) DO
2929 DEC(ScopeId) ;
2930 pCall := GetPcall(ScopeId) ;
2931 ScopeSym := pCall^.Search ;
2932 Sym := CheckScopeForSym(ScopeSym, name) ;
2933 (* WriteString(' scope: ') ; WriteKey(GetSymName(ScopeSym)) *)
2934 END ;
2935 (* IF Sym#NulSym THEN WriteKey(GetSymName(Sym)) END ; WriteLn ; *)
2936 RETURN( Sym )
2937 END GetScopeSym ;
2938
2939
2940 (*
2941 CheckScopeForSym - checks the scope, ScopeSym, for an identifier
2942 of name, name. CheckScopeForSym checks for
2943 the symbol by the GetLocalSym and also
2944 ExamineUnresolvedTree.
2945 *)
2946
2947 PROCEDURE CheckScopeForSym (ScopeSym: CARDINAL; name: Name) : CARDINAL ;
2948 VAR
2949 Sym: CARDINAL ;
2950 BEGIN
2951 Sym := GetLocalSym(ScopeSym, name) ;
2952 IF (Sym=NulSym) AND (IsModule(ScopeSym) OR IsDefImp(ScopeSym) OR
2953 IsProcedure(ScopeSym))
2954 THEN
2955 Sym := ExamineUnresolvedTree(ScopeSym, name)
2956 END ;
2957 RETURN( Sym )
2958 END CheckScopeForSym ;
2959
2960
2961 (*
2962 DisplayScopes - displays the scopes that will be searched to find
2963 a requested symbol.
2964 *)
2965
2966 (*
2967 PROCEDURE DisplayScopes ;
2968 VAR
2969 pCall: PtrToCallFrame ;
2970 n : Name ;
2971 i : CARDINAL ;
2972 Sym : CARDINAL ;
2973 BEGIN
2974 i := ScopePtr ;
2975 printf0('Displaying scopes\n') ;
2976 WHILE i>=1 DO
2977 pCall := GetPcall(i) ;
2978 Sym := pCall^.Search ;
2979 printf1('Symbol %4d', Sym) ;
2980 IF Sym#NulSym
2981 THEN
2982 n := GetSymName(Sym) ;
2983 printf1(' : name %a is ', n) ;
2984 IF NOT TransparentScope(Sym)
2985 THEN
2986 printf0('not')
2987 END ;
2988 printf0(' transparent\n')
2989 END ;
2990 DEC(i)
2991 END ;
2992 printf0('\n')
2993 END DisplayScopes ;
2994 *)
2995
2996
2997 (*
2998 GetModuleScopeId - returns the scope index to the next module starting
2999 at index, Id.
3000 Id will either point to a null scope (NulSym) or
3001 alternatively point to a Module or DefImp symbol.
3002 *)
3003
3004 PROCEDURE GetModuleScopeId (Id: CARDINAL) : CARDINAL ;
3005 VAR
3006 pCall: PtrToCallFrame ;
3007 s : CARDINAL ;
3008 BEGIN
3009 pCall := GetPcall(Id) ;
3010 s := pCall^.Search ;
3011 WHILE (Id>0) AND (s#NulSym) AND
3012 ((NOT IsModule(s)) AND
3013 (NOT IsDefImp(s))) DO
3014 DEC(Id) ;
3015 pCall := GetPcall(Id) ;
3016 s := pCall^.Search ;
3017 END ;
3018 RETURN( Id )
3019 END GetModuleScopeId ;
3020
3021
3022 (*
3023 GetVisibleSym -
3024 *)
3025
3026 PROCEDURE GetVisibleSym (name: Name) : CARDINAL ;
3027 VAR
3028 pCall: PtrToCallFrame ;
3029 Sym,
3030 i : CARDINAL ;
3031 BEGIN
3032 i := ScopePtr ;
3033 WHILE i>=1 DO
3034 pCall := GetPcall(i) ;
3035 WITH pCall^ DO
3036 IF Search=Main
3037 THEN
3038 RETURN( GetLocalSym(Main, name) )
3039 ELSE
3040 IF IsEnumeration(Search)
3041 THEN
3042 Sym := GetLocalSym(Search, name) ;
3043 IF Sym#NulSym
3044 THEN
3045 RETURN( Sym )
3046 END
3047 END
3048 END
3049 END ;
3050 DEC(i)
3051 END ;
3052 RETURN( NulSym )
3053 END GetVisibleSym ;
3054
3055
3056 (*
3057 IsAlreadyDeclaredSym - returns true if Sym has already been declared
3058 in the current main scope.
3059 *)
3060
3061 PROCEDURE IsAlreadyDeclaredSym (name: Name) : BOOLEAN ;
3062 VAR
3063 pCall: PtrToCallFrame ;
3064 i : CARDINAL ;
3065 BEGIN
3066 i := ScopePtr ;
3067 WHILE i>=1 DO
3068 pCall := GetPcall(i) ;
3069 WITH pCall^ DO
3070 IF Search=Main
3071 THEN
3072 RETURN( GetLocalSym(Main, name)#NulSym )
3073 ELSE
3074 IF IsEnumeration(Search) AND (GetLocalSym(Search, name)#NulSym)
3075 THEN
3076 RETURN( TRUE )
3077 END
3078 END
3079 END ;
3080 DEC(i)
3081 END ;
3082 RETURN( FALSE )
3083 END IsAlreadyDeclaredSym ;
3084
3085
3086 (*
3087 IsImplicityExported - returns TRUE if, Sym, is implicitly exported from module, ModSym.
3088 ModSym must be a defimp symbol.
3089 *)
3090
3091 PROCEDURE IsImplicityExported (ModSym, Sym: CARDINAL) : BOOLEAN ;
3092 VAR
3093 type: CARDINAL ;
3094 pSym: PtrToSymbol ;
3095 BEGIN
3096 IF IsDefImp(ModSym) AND IsFieldEnumeration(Sym)
3097 THEN
3098 pSym := GetPsym(ModSym) ;
3099 type := SkipType(GetType(Sym)) ;
3100 RETURN( IsItemInList(pSym^.DefImp.EnumerationScopeList, type) )
3101 END ;
3102 RETURN( FALSE )
3103 END IsImplicityExported ;
3104
3105
3106 (*
3107 MakeProcedureCtorExtern - creates an extern ctor procedure
3108 *)
3109
3110 PROCEDURE MakeProcedureCtorExtern (tokenno: CARDINAL; libname, modulename: Name) : CARDINAL ;
3111 VAR
3112 ctor: CARDINAL ;
3113 BEGIN
3114 ctor := MakeProcedure (tokenno, GenName (libname, '_M2_', modulename, '_ctor')) ;
3115 PutExtern (ctor, TRUE) ;
3116 RETURN ctor
3117 END MakeProcedureCtorExtern ;
3118
3119
3120 (*
3121 GenName - returns a new name consisting of pre, name, post concatenation.
3122 *)
3123
3124 PROCEDURE GenName (libname: Name; pre: ARRAY OF CHAR; name: Name; post: ARRAY OF CHAR) : Name ;
3125 VAR
3126 str : String ;
3127 result: Name ;
3128 BEGIN
3129 str := InitStringCharStar (KeyToCharStar (libname)) ;
3130 str := ConCat (str, Mark (InitString (pre))) ;
3131 str := ConCat (str, Mark (InitStringCharStar (KeyToCharStar (name)))) ;
3132 str := ConCat (str, InitString (post)) ;
3133 result := makekey (string (str)) ;
3134 str := KillString (str) ;
3135 RETURN result
3136 END GenName ;
3137
3138
3139 (*
3140 InitCtor - initialize the ModuleCtor fields to NulSym.
3141 *)
3142
3143 PROCEDURE InitCtor (VAR ctor: ModuleCtor) ;
3144 BEGIN
3145 ctor.ctor := NulSym ;
3146 ctor.dep := NulSym ;
3147 ctor.init := NulSym ;
3148 ctor.fini := NulSym
3149 END InitCtor ;
3150
3151
3152 (*
3153 MakeModuleCtor - for a defimp or module symbol create all the ctor
3154 related procedures.
3155 *)
3156
3157 PROCEDURE MakeModuleCtor (moduleTok, beginTok, finallyTok: CARDINAL;
3158 moduleSym: CARDINAL) ;
3159 VAR
3160 pSym: PtrToSymbol ;
3161 BEGIN
3162 Assert (IsDefImp (moduleSym) OR IsModule (moduleSym)) ;
3163 pSym := GetPsym (moduleSym) ;
3164 IF IsDefImp (moduleSym)
3165 THEN
3166 InitCtorFields (moduleTok, beginTok, finallyTok,
3167 moduleSym,
3168 pSym^.DefImp.ctors, GetSymName (moduleSym),
3169 FALSE, TRUE)
3170 ELSE
3171 InitCtorFields (moduleTok, beginTok, finallyTok,
3172 moduleSym,
3173 pSym^.Module.ctors, GetSymName (moduleSym),
3174 IsInnerModule (moduleSym), TRUE)
3175 END
3176 END MakeModuleCtor ;
3177
3178
3179 (*
3180 InitCtorFields - initialize the ModuleCtor fields. An inner module has no
3181 ctor procedure.
3182 *)
3183
3184 PROCEDURE InitCtorFields (moduleTok, beginTok, finallyTok: CARDINAL;
3185 moduleSym: CARDINAL;
3186 VAR ctor: ModuleCtor; name: Name;
3187 inner, pub: BOOLEAN) ;
3188 BEGIN
3189 IF ScaffoldDynamic AND (NOT inner)
3190 THEN
3191 (* The ctor procedure must be public. *)
3192 ctor.ctor := MakeProcedure (moduleTok,
3193 GenName (GetLibName (moduleSym),
3194 "_M2_", name, "_ctor")) ;
3195 PutCtor (ctor.ctor, TRUE) ;
3196 Assert (pub) ;
3197 PutPublic (ctor.ctor, pub) ;
3198 PutExtern (ctor.ctor, NOT pub) ;
3199 PutMonoName (ctor.ctor, TRUE) ;
3200 (* The dep procedure is local to the module. *)
3201 ctor.dep := MakeProcedure (moduleTok,
3202 GenName (GetLibName (moduleSym),
3203 "_M2_", name, "_dep")) ;
3204 PutMonoName (ctor.dep, TRUE)
3205 ELSE
3206 ctor.ctor := NulSym ;
3207 ctor.dep := NulSym
3208 END ;
3209 (* The init/fini procedures must be public. *)
3210 ctor.init := MakeProcedure (beginTok,
3211 GenName (GetLibName (moduleSym),
3212 "_M2_", name, "_init")) ;
3213 PutPublic (ctor.init, pub) ;
3214 PutExtern (ctor.init, NOT pub) ;
3215 PutMonoName (ctor.init, NOT inner) ;
3216 DeclareArgEnvParams (beginTok, ctor.init) ;
3217 ctor.fini := MakeProcedure (finallyTok,
3218 GenName (GetLibName (moduleSym),
3219 "_M2_", name, "_fini")) ;
3220 PutPublic (ctor.fini, pub) ;
3221 PutExtern (ctor.fini, NOT pub) ;
3222 PutMonoName (ctor.fini, NOT inner) ;
3223 DeclareArgEnvParams (beginTok, ctor.fini)
3224 END InitCtorFields ;
3225
3226
3227 (*
3228 GetModuleCtors - mod can be a DefImp or Module symbol. ctor, init and fini
3229 are assigned for this module. An inner module ctor value will
3230 be NulSym.
3231 *)
3232
3233 PROCEDURE GetModuleCtors (mod: CARDINAL; VAR ctor, init, fini, dep: CARDINAL) ;
3234 VAR
3235 pSym : PtrToSymbol ;
3236 BEGIN
3237 pSym := GetPsym (mod) ;
3238 WITH pSym^ DO
3239 CASE SymbolType OF
3240
3241 ModuleSym: ctor := Module.ctors.ctor ;
3242 init := Module.ctors.init ;
3243 fini := Module.ctors.fini ;
3244 dep := Module.ctors.dep |
3245 DefImpSym: ctor := DefImp.ctors.ctor ;
3246 init := DefImp.ctors.init ;
3247 fini := DefImp.ctors.fini ;
3248 dep := DefImp.ctors.dep
3249
3250 ELSE
3251 InternalError ('expecting Module or DefImp symbol')
3252 END
3253 END
3254 END GetModuleCtors ;
3255
3256
3257 (*
3258 MakeModule - creates a module sym with ModuleName. It returns the
3259 symbol index.
3260 *)
3261
3262 PROCEDURE MakeModule (tok: CARDINAL; ModuleName: Name) : CARDINAL ;
3263 VAR
3264 pSym : PtrToSymbol ;
3265 pCall: PtrToCallFrame ;
3266 Sym : CARDINAL ;
3267 BEGIN
3268 (*
3269 Make a new symbol since we are at the outer scope level.
3270 DeclareSym examines the current scope level for any symbols
3271 that have the correct name, but are yet undefined.
3272 Therefore we must not call DeclareSym but create a symbol
3273 directly.
3274 *)
3275 NewSym(Sym) ;
3276 pSym := GetPsym(Sym) ;
3277 WITH pSym^ DO
3278 SymbolType := ModuleSym ;
3279 WITH Module DO
3280 name := ModuleName ; (* Index into name array, name *)
3281 (* of record field. *)
3282 libname := NulName ; (* Library association. *)
3283 InitCtor (ctors) ; (* Init all ctor functions. *)
3284 InitList(ModListOfDep) ; (* Vector of SymDependency. *)
3285 InitTree(LocalSymbols) ; (* The LocalSymbols hold all the *)
3286 (* variables declared local to *)
3287 (* the block. It contains the *)
3288 (* FROM _ IMPORT x, y, x ; *)
3289 (* IMPORT A ; *)
3290 (* and also *)
3291 (* MODULE WeAreHere ; *)
3292 (* x y z visiable by localsym *)
3293 (* MODULE Inner ; *)
3294 (* EXPORT x, y, z ; *)
3295 (* END Inner ; *)
3296 (* END WeAreHere. *)
3297 InitTree(ExportTree) ; (* Holds all the exported *)
3298 (* identifiers. *)
3299 (* This tree may be *)
3300 (* deleted at the end of Pass 1. *)
3301 InitTree(ImportTree) ; (* Contains all IMPORTed *)
3302 (* identifiers. *)
3303 InitList(IncludeList) ; (* Contains all included symbols *)
3304 (* which are included by *)
3305 (* IMPORT modulename ; *)
3306 (* modulename.Symbol *)
3307 InitTree(ExportUndeclared) ; (* ExportUndeclared contains all *)
3308 (* the identifiers which were *)
3309 (* exported but have not yet *)
3310 (* been declared. *)
3311 InitList(EnumerationScopeList) ; (* Enumeration scope list which *)
3312 (* contains a list of all *)
3313 (* enumerations which are *)
3314 (* visable within this scope. *)
3315 (* Outer Module. *)
3316 InitTree(NamedObjects) ; (* Names of all items declared. *)
3317 InitTree(NamedImports) ; (* Names of items imported. *)
3318 InitTree(WhereImported) ; (* Sym to TokenNo where import *)
3319 (* occurs. Error message use. *)
3320 Priority := NulSym ; (* Priority of the module. This *)
3321 (* is an index to a constant. *)
3322 InitTree(Unresolved) ; (* All symbols currently *)
3323 (* unresolved in this module. *)
3324 StartQuad := 0 ; (* Signify the initialization *)
3325 (* code. *)
3326 EndQuad := 0 ; (* EndQuad should point to a *)
3327 (* goto quad. *)
3328 StartFinishQuad := 0 ; (* Signify the finalization *)
3329 (* code. *)
3330 EndFinishQuad := 0 ; (* should point to a finish *)
3331 FinallyFunction := NIL ; (* The GCC function for finally *)
3332 ExceptionFinally := FALSE ; (* does it have an exception? *)
3333 ExceptionBlock := FALSE ; (* does it have an exception? *)
3334 ModLink := GetLink () ; (* Is this parsed for linkage? *)
3335 Builtin := FALSE ; (* Is the module builtin? *)
3336 InitList(ListOfVars) ; (* List of variables in this *)
3337 (* scope. *)
3338 InitList(ListOfProcs) ; (* List of all procedures *)
3339 (* declared within this module. *)
3340 InitList(ListOfModules) ; (* List of all inner modules. *)
3341 InitWhereDeclaredTok(tok, At) ; (* Where symbol declared. *)
3342 InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used. *)
3343 pCall := GetPcall(ScopePtr) ;
3344 IF pCall^.Main=GetBaseModule()
3345 THEN
3346 Scope := NulSym
3347 ELSE
3348 Scope := pCall^.Main
3349 END ;
3350 errorScope := GetCurrentErrorScope () ; (* Title error scope. *)
3351 END
3352 END ;
3353 PutSymKey(ModuleTree, ModuleName, Sym) ;
3354 RETURN Sym
3355 END MakeModule ;
3356
3357
3358 (*
3359 PutModLink - assigns link to module sym.
3360 *)
3361
3362 PROCEDURE PutModLink (sym: CARDINAL; link: BOOLEAN) ;
3363 VAR
3364 pSym: PtrToSymbol ;
3365 BEGIN
3366 IF IsModule (sym)
3367 THEN
3368 pSym := GetPsym (sym) ;
3369 pSym^.Module.ModLink := link
3370 ELSIF IsDefImp (sym)
3371 THEN
3372 pSym := GetPsym (sym) ;
3373 pSym^.DefImp.ModLink := link
3374 ELSE
3375 InternalError ('expecting a DefImp or Module symbol')
3376 END
3377 END PutModLink ;
3378
3379
3380 (*
3381 IsModLink - returns the ModLink value associated with the module symbol.
3382 *)
3383
3384 PROCEDURE IsModLink (sym: CARDINAL) : BOOLEAN ;
3385 VAR
3386 pSym: PtrToSymbol ;
3387 BEGIN
3388 IF IsModule (sym)
3389 THEN
3390 pSym := GetPsym (sym) ;
3391 RETURN pSym^.Module.ModLink
3392 ELSIF IsDefImp (sym)
3393 THEN
3394 pSym := GetPsym (sym) ;
3395 RETURN pSym^.DefImp.ModLink
3396 ELSE
3397 InternalError ('expecting a DefImp or Module symbol')
3398 END
3399 END IsModLink ;
3400
3401
3402 (*
3403 PutDefLink - assigns link to the definition module sym.
3404 *)
3405
3406 PROCEDURE PutDefLink (sym: CARDINAL; link: BOOLEAN) ;
3407 VAR
3408 pSym: PtrToSymbol ;
3409 BEGIN
3410 IF IsDefImp (sym)
3411 THEN
3412 pSym := GetPsym (sym) ;
3413 pSym^.DefImp.DefLink := link
3414 ELSE
3415 InternalError ('expecting a DefImp symbol')
3416 END
3417 END PutDefLink ;
3418
3419
3420 (*
3421 IsDefLink - returns the DefLink value associated with the definition module symbol.
3422 *)
3423
3424 PROCEDURE IsDefLink (sym: CARDINAL) : BOOLEAN ;
3425 VAR
3426 pSym: PtrToSymbol ;
3427 BEGIN
3428 IF IsDefImp (sym)
3429 THEN
3430 pSym := GetPsym (sym) ;
3431 RETURN pSym^.DefImp.DefLink
3432 ELSE
3433 InternalError ('expecting a DefImp symbol')
3434 END
3435 END IsDefLink ;
3436
3437
3438 (*
3439 GetLink - returns TRUE if the current module is only used for linkage.
3440 *)
3441
3442 PROCEDURE GetLink () : BOOLEAN ;
3443 VAR
3444 OuterModule: CARDINAL ;
3445 BEGIN
3446 OuterModule := GetCurrentModule () ;
3447 IF OuterModule # NulSym
3448 THEN
3449 IF CompilingDefinitionModule ()
3450 THEN
3451 RETURN IsDefLink (OuterModule)
3452 ELSE
3453 RETURN IsModLink (OuterModule)
3454 END
3455 END ;
3456 (* Default is that the module is for compiling. *)
3457 RETURN FALSE
3458 END GetLink ;
3459
3460
3461 (*
3462 IsModuleBuiltin - returns TRUE if the module is a builtin module.
3463 (For example _BaseTypes).
3464 *)
3465
3466 PROCEDURE IsModuleBuiltin (sym: CARDINAL) : BOOLEAN ;
3467 VAR
3468 pSym: PtrToSymbol ;
3469 BEGIN
3470 IF IsDefImp (sym)
3471 THEN
3472 pSym := GetPsym (sym) ;
3473 RETURN pSym^.DefImp.Builtin
3474 ELSIF IsModule (sym)
3475 THEN
3476 pSym := GetPsym (sym) ;
3477 RETURN pSym^.Module.Builtin
3478 END ;
3479 RETURN FALSE
3480 END IsModuleBuiltin ;
3481
3482
3483 (*
3484 PutModuleBuiltin - sets the Builtin flag to value.
3485 Currently the procedure expects sym to be a DefImp
3486 module only.
3487 *)
3488
3489 PROCEDURE PutModuleBuiltin (sym: CARDINAL; value: BOOLEAN) ;
3490 VAR
3491 pSym: PtrToSymbol ;
3492 BEGIN
3493 IF IsDefImp (sym)
3494 THEN
3495 pSym := GetPsym (sym) ;
3496 pSym^.DefImp.Builtin := value
3497 ELSIF IsModule (sym)
3498 THEN
3499 pSym := GetPsym (sym) ;
3500 pSym^.Module.Builtin := value
3501 ELSE
3502 InternalError ('expecting Module or DefImp symbol')
3503 END
3504 END PutModuleBuiltin ;
3505
3506
3507 (*
3508 AddModuleToParent - adds symbol, Sym, to module, Parent.
3509 *)
3510
3511 PROCEDURE AddModuleToParent (Sym: CARDINAL; Parent: CARDINAL) ;
3512 VAR
3513 pSym: PtrToSymbol ;
3514 BEGIN
3515 pSym := GetPsym(Parent) ;
3516 WITH pSym^ DO
3517 CASE SymbolType OF
3518
3519 DefImpSym : PutItemIntoList(DefImp.ListOfModules, Sym) |
3520 ModuleSym : PutItemIntoList(Module.ListOfModules, Sym) |
3521 ProcedureSym: PutItemIntoList(Procedure.ListOfModules, Sym)
3522
3523 ELSE
3524 InternalError ('expecting DefImp or Module symbol')
3525 END
3526 END
3527 END AddModuleToParent ;
3528
3529
3530 (*
3531 MakeInnerModule - creates an inner module sym with ModuleName. It returns the
3532 symbol index.
3533 *)
3534
3535 PROCEDURE MakeInnerModule (tok: CARDINAL; ModuleName: Name) : CARDINAL ;
3536 VAR
3537 pSym: PtrToSymbol ;
3538 Sym : CARDINAL ;
3539 BEGIN
3540 Sym := DeclareSym (tok, ModuleName) ;
3541 IF NOT IsError(Sym)
3542 THEN
3543 pSym := GetPsym(Sym) ;
3544 WITH pSym^ DO
3545 SymbolType := ModuleSym ;
3546 WITH Module DO
3547 name := ModuleName ; (* Index into name array, name *)
3548 (* of record field. *)
3549 libname := NulName ; (* Library association. *)
3550 InitCtor (ctors) ; (* Init all ctor functions. *)
3551 InitTree(LocalSymbols) ; (* The LocalSymbols hold all the *)
3552 (* variables declared local to *)
3553 (* the block. It contains the *)
3554 (* FROM _ IMPORT x, y, x ; *)
3555 (* IMPORT A ; *)
3556 (* and also *)
3557 (* MODULE WeAreHere ; *)
3558 (* x y z visiable by localsym *)
3559 (* MODULE Inner ; *)
3560 (* EXPORT x, y, z ; *)
3561 (* END Inner ; *)
3562 (* END WeAreHere. *)
3563 InitTree(ExportTree) ; (* Holds all the exported *)
3564 (* identifiers. *)
3565 (* This tree may be *)
3566 (* deleted at the end of Pass 1. *)
3567 InitTree(ImportTree) ; (* Contains all IMPORTed *)
3568 (* identifiers. *)
3569 InitList(IncludeList) ; (* Contains all included symbols *)
3570 (* which are included by *)
3571 (* IMPORT modulename ; *)
3572 (* modulename.Symbol *)
3573 InitTree(ExportUndeclared) ; (* ExportUndeclared contains all *)
3574 (* the identifiers which were *)
3575 (* exported but have not yet *)
3576 (* been declared. *)
3577 InitList(EnumerationScopeList) ;(* Enumeration scope list which *)
3578 (* contains a list of all *)
3579 (* enumerations which are *)
3580 (* visable within this scope. *)
3581 InitTree(NamedObjects) ; (* Names of all items declared. *)
3582 InitTree(NamedImports) ; (* Names of items imported. *)
3583 InitTree(WhereImported) ; (* Sym to TokenNo where import *)
3584 (* occurs. Error message use. *)
3585 Priority := NulSym ; (* Priority of the module. This *)
3586 (* is an index to a constant. *)
3587 InitTree(Unresolved) ; (* All symbols currently *)
3588 (* unresolved in this module. *)
3589 StartQuad := 0 ; (* Signify the initialization *)
3590 (* code. *)
3591 EndQuad := 0 ; (* EndQuad should point to a *)
3592 (* goto quad. *)
3593 StartFinishQuad := 0 ; (* Signify the finalization *)
3594 (* code. *)
3595 EndFinishQuad := 0 ; (* should point to a finish *)
3596 FinallyFunction := NIL ; (* The GCC function for finally *)
3597 ExceptionFinally := FALSE ; (* does it have an exception? *)
3598 ExceptionBlock := FALSE ; (* does it have an exception? *)
3599 ModLink := GetLink () ; (* Is this parsed for linkage? *)
3600 InitList(ListOfVars) ; (* List of variables in this *)
3601 (* scope. *)
3602 InitList(ListOfProcs) ; (* List of all procedures *)
3603 (* declared within this module. *)
3604 InitList(ListOfModules) ; (* List of all inner modules. *)
3605 InitWhereDeclaredTok(tok, At) ; (* Where symbol declared. *)
3606 InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used. *)
3607 IF GetCurrentScope()=GetBaseModule()
3608 THEN
3609 Scope := NulSym
3610 ELSE
3611 Scope := GetCurrentScope() ;
3612 AddModuleToParent(Sym, Scope)
3613 END ;
3614 errorScope := GetCurrentErrorScope () ; (* Title error scope. *)
3615 END ;
3616 END ;
3617 AddSymToScope(Sym, ModuleName)
3618 END ;
3619 RETURN Sym
3620 END MakeInnerModule ;
3621
3622
3623 (*
3624 MakeDefImp - creates a definition and implementation module sym
3625 with name DefImpName. It returns the symbol index.
3626 *)
3627
3628 PROCEDURE MakeDefImp (tok: CARDINAL; DefImpName: Name) : CARDINAL ;
3629 VAR
3630 pSym: PtrToSymbol ;
3631 Sym : CARDINAL ;
3632 BEGIN
3633 (* Make a new symbol since we are at the outer scope level. *)
3634 (* We cannot use DeclareSym as it examines the current scope *)
3635 (* for any symbols which have the correct name, but are yet *)
3636 (* undefined. *)
3637
3638 NewSym(Sym) ;
3639 pSym := GetPsym(Sym) ;
3640 WITH pSym^ DO
3641 SymbolType := DefImpSym ;
3642 WITH DefImp DO
3643 name := DefImpName ; (* Index into name array, name *)
3644 (* of record field. *)
3645 libname := NulName ; (* Library association. *)
3646 InitCtor (ctors) ;
3647 (* Init all ctor functions. *)
3648 InitList(DefListOfDep) ; (* Vector of SymDependency. *)
3649 InitList(ModListOfDep) ; (* Vector of SymDependency. *)
3650 InitTree(ExportQualifiedTree) ;
3651 (* Holds all the EXPORT *)
3652 (* QUALIFIED identifiers. *)
3653 (* This tree may be *)
3654 (* deleted at the end of Pass 1. *)
3655 InitTree(ExportUnQualifiedTree) ;
3656 (* Holds all the EXPORT *)
3657 (* UNQUALIFIED identifiers. *)
3658 (* This tree may be *)
3659 (* deleted at the end of Pass 1. *)
3660 InitTree(ExportRequest) ; (* Contains all identifiers that *)
3661 (* have been requested by other *)
3662 (* modules before this module *)
3663 (* declared its export list. *)
3664 (* This tree should be empty at *)
3665 (* the end of the compilation. *)
3666 (* Each time a symbol is *)
3667 (* exported it is removed from *)
3668 (* this list. *)
3669 InitTree(ImportTree) ; (* Contains all IMPORTed *)
3670 (* identifiers. *)
3671 InitList(IncludeList) ; (* Contains all included symbols *)
3672 (* which are included by *)
3673 (* IMPORT modulename ; *)
3674 (* modulename.Symbol *)
3675 InitList(DefIncludeList) ; (* Contains all included symbols *)
3676 (* which are included by *)
3677 (* IMPORT modulename ; *)
3678 (* in the definition module only *)
3679 InitTree(ExportUndeclared) ; (* ExportUndeclared contains all *)
3680 (* the identifiers which were *)
3681 (* exported but have not yet *)
3682 (* been declared. *)
3683 InitTree(NeedToBeImplemented) ;
3684 (* NeedToBeImplemented contains *)
3685 (* the identifiers which have *)
3686 (* been exported and declared *)
3687 (* but have not yet been *)
3688 (* implemented. *)
3689 InitTree(LocalSymbols) ; (* The LocalSymbols hold all the *)
3690 (* variables declared local to *)
3691 (* the block. It contains the *)
3692 (* IMPORT r ; *)
3693 (* FROM _ IMPORT x, y, x ; *)
3694 (* and also *)
3695 (* MODULE WeAreHere ; *)
3696 (* x y z visiable by localsym *)
3697 (* MODULE Inner ; *)
3698 (* EXPORT x, y, z ; *)
3699 (* END Inner ; *)
3700 (* END WeAreHere. *)
3701 InitList(EnumerationScopeList) ;
3702 (* Enumeration scope list which *)
3703 (* contains a list of all *)
3704 (* enumerations which are *)
3705 (* visable within this scope. *)
3706 InitTree(NamedObjects) ; (* names of all items declared. *)
3707 InitTree(NamedImports) ; (* Names of items imported. *)
3708 InitTree(WhereImported) ; (* Sym to TokenNo where import *)
3709 (* occurs. Error message use. *)
3710 Priority := NulSym ; (* Priority of the module. This *)
3711 (* is an index to a constant. *)
3712 InitTree(Unresolved) ; (* All symbols currently *)
3713 (* unresolved in this module. *)
3714 StartQuad := 0 ; (* Signify the initialization *)
3715 (* code. *)
3716 EndQuad := 0 ; (* EndQuad should point to a *)
3717 (* goto quad. *)
3718 StartFinishQuad := 0 ; (* Signify the finalization *)
3719 (* code. *)
3720 EndFinishQuad := 0 ; (* should point to a finish *)
3721 FinallyFunction := NIL ; (* The GCC function for finally *)
3722 ExceptionFinally := FALSE ; (* does it have an exception? *)
3723 ExceptionBlock := FALSE ; (* does it have an exception? *)
3724 ContainsHiddenType := FALSE ;(* True if this module *)
3725 (* implements a hidden type. *)
3726 ContainsBuiltin := FALSE ; (* Does module define a builtin *)
3727 (* procedure? *)
3728 ForC := FALSE ; (* Is it a definition for "C" *)
3729 NeedExportList := FALSE ; (* Must user supply export list? *)
3730 DefLink := GetLink () ; (* Is the def/mod file only *)
3731 ModLink := GetLink () ; (* parsed for linkage? *)
3732 Builtin := FALSE ; (* Is the module builtin? *)
3733 InitList(ListOfVars) ; (* List of variables in this *)
3734 (* scope. *)
3735 InitList(ListOfProcs) ; (* List of all procedures *)
3736 (* declared within this module. *)
3737 InitList(ListOfModules) ; (* List of all inner modules. *)
3738 InitWhereDeclaredTok(tok, At) ; (* Where symbol declared. *)
3739 InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used. *)
3740 errorScope := GetCurrentErrorScope () ; (* Title error scope. *)
3741 END
3742 END ;
3743 PutSymKey(ModuleTree, DefImpName, Sym) ;
3744 RETURN Sym
3745 END MakeDefImp ;
3746
3747
3748 (*
3749 PutLibName - places libname into defimp or module sym.
3750 *)
3751
3752 PROCEDURE PutLibName (sym: CARDINAL; libname: Name) ;
3753 VAR
3754 pSym: PtrToSymbol ;
3755 BEGIN
3756 Assert (IsModule (sym) OR IsDefImp (sym)) ;
3757 pSym := GetPsym (sym) ;
3758 WITH pSym^ DO
3759 CASE SymbolType OF
3760
3761 DefImpSym: DefImp.libname := libname |
3762 ModuleSym: Module.libname := libname
3763
3764 ELSE
3765 InternalError ('expecting DefImp or Module symbol')
3766 END
3767 END
3768 END PutLibName ;
3769
3770
3771 (*
3772 GetLibName - returns libname associated with a defimp or module sym.
3773 *)
3774
3775 PROCEDURE GetLibName (sym: CARDINAL) : Name ;
3776 VAR
3777 pSym: PtrToSymbol ;
3778 BEGIN
3779 Assert (IsModule (sym) OR IsDefImp (sym)) ;
3780 pSym := GetPsym (sym) ;
3781 WITH pSym^ DO
3782 CASE SymbolType OF
3783
3784 DefImpSym: RETURN DefImp.libname |
3785 ModuleSym: RETURN Module.libname
3786
3787 ELSE
3788 InternalError ('expecting DefImp or Module symbol')
3789 END
3790 END
3791 END GetLibName ;
3792
3793
3794 (*
3795 PutProcedureExternPublic - if procedure is not NulSym set extern
3796 and public booleans.
3797 *)
3798
3799 PROCEDURE PutProcedureExternPublic (procedure: CARDINAL; extern, pub: BOOLEAN) ;
3800 BEGIN
3801 IF procedure # NulSym
3802 THEN
3803 PutExtern (procedure, extern) ;
3804 PutPublic (procedure, pub)
3805 END
3806 END PutProcedureExternPublic ;
3807
3808
3809 (*
3810 PutCtorExtern -
3811 *)
3812
3813 PROCEDURE PutCtorExtern (tok: CARDINAL; sym: CARDINAL;
3814 VAR ctor: ModuleCtor; extern: BOOLEAN) ;
3815 BEGIN
3816 (* If the ctor does not exist then make it extern/ (~extern) public. *)
3817 IF ctor.ctor = NulSym
3818 THEN
3819 ctor.ctor := MakeProcedure (tok, GenName (GetLibName (sym), "_M2_", GetSymName (sym), "_ctor")) ;
3820 PutMonoName (ctor.ctor, TRUE)
3821 END ;
3822 PutProcedureExternPublic (ctor.ctor, extern, NOT extern) ;
3823 PutCtor (ctor.ctor, TRUE) ;
3824 (* If the ctor does not exist then make it extern/ (~extern) public. *)
3825 IF ctor.dep = NulSym
3826 THEN
3827 ctor.dep := MakeProcedure (tok, GenName (GetLibName (sym), "_M2_", GetSymName (sym), "_dep")) ;
3828 PutMonoName (ctor.dep, TRUE)
3829 END ;
3830 PutProcedureExternPublic (ctor.dep, extern, NOT extern) ;
3831 (* If init/fini do not exist then create them. *)
3832 IF ctor.init = NulSym
3833 THEN
3834 ctor.init := MakeProcedure (tok, GenName (GetLibName (sym), "_M2_", GetSymName (sym), "_init")) ;
3835 DeclareArgEnvParams (tok, ctor.init) ;
3836 PutMonoName (ctor.init, NOT IsInnerModule (sym))
3837 END ;
3838 PutProcedureExternPublic (ctor.init, extern, NOT extern) ;
3839 IF ctor.fini = NulSym
3840 THEN
3841 ctor.fini := MakeProcedure (tok, GenName (GetLibName (sym), "_M2_", GetSymName (sym), "_fini")) ;
3842 DeclareArgEnvParams (tok, ctor.fini) ;
3843 PutMonoName (ctor.fini, NOT IsInnerModule (sym))
3844 END ;
3845 PutProcedureExternPublic (ctor.fini, extern, NOT extern)
3846 END PutCtorExtern ;
3847
3848
3849 (*
3850 PutModuleCtorExtern - for every ctor related procedure in module sym.
3851 Make it external. It will create any missing
3852 init/fini procedures but not any missing dep/ctor
3853 procedures.
3854 *)
3855
3856 PROCEDURE PutModuleCtorExtern (tok: CARDINAL; sym: CARDINAL; external: BOOLEAN) ;
3857 VAR
3858 pSym: PtrToSymbol ;
3859 BEGIN
3860 Assert (IsModule (sym) OR IsDefImp (sym)) ;
3861 pSym := GetPsym (sym) ;
3862 WITH pSym^ DO
3863 CASE SymbolType OF
3864
3865 DefImpSym: PutCtorExtern (tok, sym, DefImp.ctors, external) |
3866 ModuleSym: PutCtorExtern (tok, sym, Module.ctors, external)
3867
3868 ELSE
3869 InternalError ('expecting DefImp or Module symbol')
3870 END
3871 END
3872 END PutModuleCtorExtern ;
3873
3874
3875 (*
3876 MakeProcedure - creates a procedure sym with name. It returns
3877 the symbol index.
3878 *)
3879
3880 PROCEDURE MakeProcedure (tok: CARDINAL; ProcedureName: Name) : CARDINAL ;
3881 VAR
3882 pSym: PtrToSymbol ;
3883 Sym : CARDINAL ;
3884 BEGIN
3885 Sym := DeclareSym(tok, ProcedureName) ;
3886 IF NOT IsError(Sym)
3887 THEN
3888 pSym := GetPsym(Sym) ;
3889 WITH pSym^ DO
3890 SymbolType := ProcedureSym ;
3891 WITH Procedure DO
3892 name := ProcedureName ;
3893 InitList(ListOfParam) ; (* Contains a list of all the *)
3894 (* parameters in this procedure. *)
3895 ParamDefined := FALSE ; (* Have the parameters been *)
3896 (* defined yet? *)
3897 DefinedInDef := FALSE ; (* Were the parameters defined *)
3898 (* in the Definition module? *)
3899 (* Note that this depends on *)
3900 (* whether the compiler has read *)
3901 (* the .def or .mod first. *)
3902 (* The second occurence is *)
3903 (* compared to the first. *)
3904 DefinedInImp := FALSE ; (* Were the parameters defined *)
3905 (* in the Implementation module? *)
3906 (* Note that this depends on *)
3907 (* whether the compiler has read *)
3908 (* the .def or .mod first. *)
3909 (* The second occurence is *)
3910 (* compared to the first. *)
3911 HasVarArgs := FALSE ; (* Does the procedure use ... ? *)
3912 HasOptArg := FALSE ; (* Does this procedure use [ ] ? *)
3913 OptArgInit := NulSym ; (* The optarg initial value. *)
3914 IsBuiltin := FALSE ; (* Was it declared __BUILTIN__ ? *)
3915 BuiltinName := NulName ; (* name of equivalent builtin *)
3916 IsInline := FALSE ; (* Was is declared __INLINE__ ? *)
3917 IsNoReturn := FALSE ; (* Declared attribute noreturn ? *)
3918 ReturnOptional := FALSE ; (* Is the return value optional? *)
3919 IsExtern := FALSE ; (* Make this procedure external. *)
3920 IsPublic := FALSE ; (* Make this procedure visible. *)
3921 IsCtor := FALSE ; (* Is this procedure a ctor? *)
3922 IsMonoName := FALSE ; (* Overrides module name prefix. *)
3923 Scope := GetCurrentScope() ; (* Scope of procedure. *)
3924 InitTree(Unresolved) ; (* All symbols currently *)
3925 (* unresolved in this procedure. *)
3926 ScopeQuad := 0 ; (* Index into list of quads, *)
3927 StartQuad := 0 ; (* defining the scope, start and *)
3928 EndQuad := 0 ; (* end of the procedure. *)
3929 Reachable := FALSE ; (* Procedure not known to be *)
3930 (* reachable. *)
3931 SavePriority := FALSE ; (* Does procedure need to save *)
3932 (* and restore interrupts? *)
3933 ReturnType := NulSym ; (* Not a function yet! *)
3934 Offset := 0 ; (* Location of procedure. *)
3935 InitTree(LocalSymbols) ;
3936 InitList(EnumerationScopeList) ;
3937 (* Enumeration scope list which *)
3938 (* contains a list of all *)
3939 (* enumerations which are *)
3940 (* visable within this scope. *)
3941 InitTree(NamedObjects) ; (* Names of all items declared. *)
3942 InitList(ListOfVars) ; (* List of variables in this *)
3943 (* scope. *)
3944 InitList(ListOfProcs) ; (* List of all procedures *)
3945 (* declared within this *)
3946 (* procedure. *)
3947 InitList(ListOfModules) ; (* List of all inner modules. *)
3948 ExceptionFinally := FALSE ; (* does it have an exception? *)
3949 ExceptionBlock := FALSE ; (* does it have an exception? *)
3950 Size := InitValue() ; (* Activation record size. *)
3951 TotalParamSize
3952 := InitValue() ; (* size of all parameters. *)
3953 Begin := 0 ; (* token number for BEGIN *)
3954 End := 0 ; (* token number for END *)
3955 InitWhereDeclaredTok(tok, At) ; (* Where symbol declared. *)
3956 errorScope := GetCurrentErrorScope () ; (* Title error scope. *)
3957 END
3958 END ;
3959 (* Now add this procedure to the symbol table of the current scope *)
3960 AddSymToScope(Sym, ProcedureName) ;
3961 AddProcedureToList(GetCurrentScope(), Sym)
3962 END ;
3963 RETURN Sym
3964 END MakeProcedure ;
3965
3966
3967 (*
3968 PutProcedureNoReturn - places value into the no return attribute
3969 field of procedure sym.
3970 *)
3971
3972 PROCEDURE PutProcedureNoReturn (Sym: CARDINAL; value: BOOLEAN) ;
3973 VAR
3974 pSym: PtrToSymbol ;
3975 BEGIN
3976 pSym := GetPsym (Sym) ;
3977 WITH pSym^ DO
3978 CASE SymbolType OF
3979
3980 ProcedureSym: Procedure.IsNoReturn := value
3981
3982 ELSE
3983 InternalError ('expecting ProcedureSym symbol')
3984 END
3985 END
3986 END PutProcedureNoReturn ;
3987
3988
3989 (*
3990 IsProcedureNoReturn - returns TRUE if this procedure never returns.
3991 *)
3992
3993 PROCEDURE IsProcedureNoReturn (Sym: CARDINAL) : BOOLEAN ;
3994 VAR
3995 pSym: PtrToSymbol ;
3996 BEGIN
3997 pSym := GetPsym (Sym) ;
3998 WITH pSym^ DO
3999 CASE SymbolType OF
4000
4001 ProcedureSym: RETURN Procedure.IsNoReturn
4002
4003 ELSE
4004 InternalError ('expecting ProcedureSym symbol')
4005 END
4006 END
4007 END IsProcedureNoReturn ;
4008
4009
4010 (*
4011 PutMonoName - changes the IsMonoName boolean inside the procedure.
4012 *)
4013
4014 PROCEDURE PutMonoName (sym: CARDINAL; value: BOOLEAN) ;
4015 VAR
4016 pSym: PtrToSymbol ;
4017 BEGIN
4018 pSym := GetPsym (sym) ;
4019 WITH pSym^ DO
4020 CASE SymbolType OF
4021
4022 ProcedureSym: Procedure.IsMonoName := value
4023
4024 ELSE
4025 InternalError ('expecting ProcedureSym symbol')
4026 END
4027 END
4028 END PutMonoName ;
4029
4030
4031 (*
4032 IsMonoName - returns the public boolean associated with a procedure.
4033 *)
4034
4035 PROCEDURE IsMonoName (sym: CARDINAL) : BOOLEAN ;
4036 VAR
4037 pSym: PtrToSymbol ;
4038 BEGIN
4039 pSym := GetPsym (sym) ;
4040 WITH pSym^ DO
4041 CASE SymbolType OF
4042
4043 ProcedureSym: RETURN Procedure.IsMonoName
4044
4045 ELSE
4046 InternalError ('expecting ProcedureSym symbol')
4047 END
4048 END
4049 END IsMonoName ;
4050
4051
4052 (*
4053 PutExtern - changes the extern boolean inside the procedure.
4054 *)
4055
4056 PROCEDURE PutExtern (sym: CARDINAL; value: BOOLEAN) ;
4057 VAR
4058 pSym: PtrToSymbol ;
4059 BEGIN
4060 pSym := GetPsym (sym) ;
4061 WITH pSym^ DO
4062 CASE SymbolType OF
4063
4064 ProcedureSym: Procedure.IsExtern := value
4065
4066 ELSE
4067 InternalError ('expecting ProcedureSym symbol')
4068 END
4069 END
4070 END PutExtern ;
4071
4072
4073 (*
4074 IsExtern - returns the public boolean associated with a procedure.
4075 *)
4076
4077 PROCEDURE IsExtern (sym: CARDINAL) : BOOLEAN ;
4078 VAR
4079 pSym: PtrToSymbol ;
4080 BEGIN
4081 pSym := GetPsym (sym) ;
4082 WITH pSym^ DO
4083 CASE SymbolType OF
4084
4085 ProcedureSym: RETURN Procedure.IsExtern
4086
4087 ELSE
4088 InternalError ('expecting ProcedureSym symbol')
4089 END
4090 END
4091 END IsExtern ;
4092
4093
4094 (*
4095 PutPublic - changes the public boolean inside the procedure.
4096 *)
4097
4098 PROCEDURE PutPublic (sym: CARDINAL; value: BOOLEAN) ;
4099 VAR
4100 pSym: PtrToSymbol ;
4101 BEGIN
4102 pSym := GetPsym (sym) ;
4103 WITH pSym^ DO
4104 CASE SymbolType OF
4105
4106 ProcedureSym : Procedure.IsPublic := value
4107
4108 ELSE
4109 InternalError ('expecting ProcedureSym symbol')
4110 END
4111 END
4112 END PutPublic ;
4113
4114
4115 (*
4116 IsPublic - returns the public boolean associated with a procedure.
4117 *)
4118
4119 PROCEDURE IsPublic (sym: CARDINAL) : BOOLEAN ;
4120 VAR
4121 pSym: PtrToSymbol ;
4122 BEGIN
4123 pSym := GetPsym (sym) ;
4124 WITH pSym^ DO
4125 CASE SymbolType OF
4126
4127 ProcedureSym : RETURN Procedure.IsPublic
4128
4129 ELSE
4130 InternalError ('expecting ProcedureSym symbol')
4131 END
4132 END
4133 END IsPublic ;
4134
4135
4136 (*
4137 PutCtor - changes the ctor boolean inside the procedure.
4138 *)
4139
4140 PROCEDURE PutCtor (sym: CARDINAL; value: BOOLEAN) ;
4141 VAR
4142 pSym: PtrToSymbol ;
4143 BEGIN
4144 pSym := GetPsym (sym) ;
4145 WITH pSym^ DO
4146 CASE SymbolType OF
4147
4148 ProcedureSym : Procedure.IsCtor := value
4149
4150 ELSE
4151 InternalError ('expecting ProcedureSym symbol')
4152 END
4153 END
4154 END PutCtor ;
4155
4156
4157 (*
4158 IsCtor - returns the ctor boolean associated with a procedure.
4159 *)
4160
4161 PROCEDURE IsCtor (sym: CARDINAL) : BOOLEAN ;
4162 VAR
4163 pSym: PtrToSymbol ;
4164 BEGIN
4165 pSym := GetPsym (sym) ;
4166 WITH pSym^ DO
4167 CASE SymbolType OF
4168
4169 ProcedureSym : RETURN Procedure.IsCtor
4170
4171 ELSE
4172 InternalError ('expecting ProcedureSym symbol')
4173 END
4174 END
4175 END IsCtor ;
4176
4177
4178 (*
4179 AddProcedureToList - adds a procedure, Proc, to the list of procedures
4180 in module, Mod.
4181 *)
4182
4183 PROCEDURE AddProcedureToList (Mod, Proc: CARDINAL) ;
4184 VAR
4185 pSym: PtrToSymbol ;
4186 BEGIN
4187 pSym := GetPsym(Mod) ;
4188 WITH pSym^ DO
4189 CASE SymbolType OF
4190
4191 DefImpSym : PutItemIntoList(DefImp.ListOfProcs, Proc) |
4192 ModuleSym : PutItemIntoList(Module.ListOfProcs, Proc) |
4193 ProcedureSym: PutItemIntoList(Procedure.ListOfProcs, Proc)
4194
4195 ELSE
4196 InternalError ('expecting ModuleSym, DefImpSym or ProcedureSym symbol')
4197 END
4198 END
4199 END AddProcedureToList ;
4200
4201
4202 (*
4203 AddVarToScopeList - adds symbol, sym, to, scope.
4204 *)
4205
4206 PROCEDURE AddVarToScopeList (scope, sym: CARDINAL) ;
4207 VAR
4208 pSym: PtrToSymbol ;
4209 BEGIN
4210 pSym := GetPsym(scope) ;
4211 WITH pSym^ DO
4212 CASE SymbolType OF
4213
4214 ProcedureSym: PutItemIntoList(Procedure.ListOfVars, sym) |
4215 ModuleSym : PutItemIntoList(Module.ListOfVars, sym) |
4216 DefImpSym : PutItemIntoList(DefImp.ListOfVars, sym)
4217
4218 ELSE
4219 InternalError ('expecting Procedure or Module symbol')
4220 END
4221 END
4222 END AddVarToScopeList ;
4223
4224
4225 (*
4226 AddVarToList - add a variable symbol to the list of variables maintained
4227 by the inner most scope. (Procedure or Module).
4228 *)
4229
4230 PROCEDURE AddVarToList (Sym: CARDINAL) ;
4231 VAR
4232 pCall: PtrToCallFrame ;
4233 BEGIN
4234 pCall := GetPcall(ScopePtr) ;
4235 AddVarToScopeList(pCall^.Main, Sym)
4236 END AddVarToList ;
4237
4238
4239 (*
4240 MakeVar - creates a variable sym with VarName. It returns the
4241 symbol index.
4242 *)
4243
4244 PROCEDURE MakeVar (tok: CARDINAL; VarName: Name) : CARDINAL ;
4245 VAR
4246 pSym: PtrToSymbol ;
4247 Sym : CARDINAL ;
4248 BEGIN
4249 Sym := DeclareSym (tok, VarName) ;
4250 IF NOT IsError(Sym)
4251 THEN
4252 pSym := GetPsym(Sym) ;
4253 WITH pSym^ DO
4254 SymbolType := VarSym ;
4255 WITH Var DO
4256 name := VarName ;
4257 Type := NulSym ;
4258 BackType := NulSym ;
4259 Size := InitValue() ;
4260 Offset := InitValue() ;
4261 AddrMode := RightValue ;
4262 Scope := GetCurrentScope() ; (* Procedure or Module? *)
4263 AtAddress := FALSE ;
4264 Address := NulSym ; (* Address at which declared. *)
4265 IsTemp := FALSE ;
4266 IsComponentRef := FALSE ;
4267 IsParam := FALSE ;
4268 IsPointerCheck := FALSE ;
4269 IsWritten := FALSE ;
4270 IsSSA := FALSE ;
4271 IsConst := FALSE ;
4272 ArrayRef := FALSE ;
4273 Heap := FALSE ;
4274 InitWhereDeclaredTok(tok, At) ;
4275 InitWhereFirstUsedTok(tok, At) ; (* Where symbol first used. *)
4276 InitList(ReadUsageList[RightValue]) ;
4277 InitList(WriteUsageList[RightValue]) ;
4278 InitList(ReadUsageList[LeftValue]) ;
4279 InitList(WriteUsageList[LeftValue]) ;
4280 InitState[LeftValue] := InitSymInit () ;
4281 InitState[RightValue] := InitSymInit ()
4282 END
4283 END ;
4284 (* Add Var to Procedure or Module variable list. *)
4285 AddVarToList(Sym) ;
4286 (* Now add this Var to the symbol table of the current scope. *)
4287 AddSymToScope(Sym, VarName)
4288 END ;
4289 RETURN Sym
4290 END MakeVar ;
4291
4292
4293 (*
4294 PutExceptionBlock - sets a BOOLEAN in block module/procedure/defimp,
4295 sym, indicating that this block as an EXCEPT
4296 statement sequence.
4297 *)
4298
4299 PROCEDURE PutExceptionBlock (sym: CARDINAL) ;
4300 VAR
4301 pSym: PtrToSymbol ;
4302 BEGIN
4303 pSym := GetPsym(sym) ;
4304 WITH pSym^ DO
4305 CASE SymbolType OF
4306
4307 ProcedureSym: Procedure.ExceptionBlock := TRUE |
4308 ModuleSym : Module.ExceptionBlock := TRUE |
4309 DefImpSym : DefImp.ExceptionBlock := TRUE
4310
4311 ELSE
4312 InternalError ('expecting Procedure')
4313 END
4314 END
4315 END PutExceptionBlock ;
4316
4317
4318 (*
4319 HasExceptionBlock - returns a BOOLEAN determining whether
4320 module/procedure/defimp, sym, has
4321 an EXCEPT statement sequence.
4322 *)
4323
4324 PROCEDURE HasExceptionBlock (sym: CARDINAL) : BOOLEAN ;
4325 VAR
4326 pSym: PtrToSymbol ;
4327 BEGIN
4328 pSym := GetPsym(sym) ;
4329 WITH pSym^ DO
4330 CASE SymbolType OF
4331
4332 ProcedureSym: RETURN( Procedure.ExceptionBlock ) |
4333 ModuleSym : RETURN( Module.ExceptionBlock ) |
4334 DefImpSym : RETURN( DefImp.ExceptionBlock )
4335
4336 ELSE
4337 InternalError ('expecting Procedure')
4338 END
4339 END
4340 END HasExceptionBlock ;
4341
4342
4343 (*
4344 PutExceptionFinally - sets a BOOLEAN in block module/defimp,
4345 sym, indicating that this FINALLY block
4346 as an EXCEPT statement sequence.
4347 *)
4348
4349 PROCEDURE PutExceptionFinally (sym: CARDINAL) ;
4350 VAR
4351 pSym: PtrToSymbol ;
4352 BEGIN
4353 pSym := GetPsym(sym) ;
4354 WITH pSym^ DO
4355 CASE SymbolType OF
4356
4357 ProcedureSym: Procedure.ExceptionFinally := TRUE |
4358 ModuleSym : Module.ExceptionFinally := TRUE |
4359 DefImpSym : DefImp.ExceptionFinally := TRUE
4360
4361 ELSE
4362 InternalError ('expecting DefImp or Module symbol')
4363 END
4364 END
4365 END PutExceptionFinally ;
4366
4367
4368 (*
4369 HasExceptionFinally - returns a BOOLEAN determining whether
4370 module/defimp, sym, has
4371 an EXCEPT statement sequence.
4372 *)
4373
4374 PROCEDURE HasExceptionFinally (sym: CARDINAL) : BOOLEAN ;
4375 VAR
4376 pSym: PtrToSymbol ;
4377 BEGIN
4378 pSym := GetPsym(sym) ;
4379 WITH pSym^ DO
4380 CASE SymbolType OF
4381
4382 ProcedureSym: RETURN( Procedure.ExceptionFinally ) |
4383 ModuleSym : RETURN( Module.ExceptionFinally ) |
4384 DefImpSym : RETURN( DefImp.ExceptionFinally )
4385
4386 ELSE
4387 InternalError ('expecting DefImp or Module symbol')
4388 END
4389 END
4390 END HasExceptionFinally ;
4391
4392
4393 (*
4394 FillInRecordFields - given a new symbol, sym, make it a record symbol
4395 and initialize its fields.
4396 *)
4397
4398 PROCEDURE FillInRecordFields (tok: CARDINAL; sym: CARDINAL; RecordName: Name;
4399 scope: CARDINAL; oaf: CARDINAL) ;
4400 VAR
4401 pSym: PtrToSymbol ;
4402 BEGIN
4403 IF NOT IsError(sym)
4404 THEN
4405 pSym := GetPsym (sym) ;
4406 WITH pSym^ DO
4407 SymbolType := RecordSym ;
4408 WITH Record DO
4409 name := RecordName ;
4410 InitTree (LocalSymbols) ;
4411 Size := InitValue () ;
4412 InitList (ListOfSons) ; (* List of RecordFieldSym and VarientSym *)
4413 oafamily := oaf ;
4414 Parent := NulSym ;
4415 Align := NulSym ;
4416 DefaultAlign := NulSym ;
4417 DeclPacked := FALSE ;
4418 DeclResolved := FALSE ;
4419 Scope := scope ;
4420 InitWhereDeclaredTok (tok, At)
4421 END
4422 END
4423 END
4424 END FillInRecordFields ;
4425
4426
4427 (*
4428 HandleHiddenOrDeclare -
4429 *)
4430
4431 PROCEDURE HandleHiddenOrDeclare (tok: CARDINAL; name: Name; VAR oaf: CARDINAL) : CARDINAL ;
4432 VAR
4433 sym: CARDINAL ;
4434 BEGIN
4435 sym := CheckForHiddenType (name) ;
4436 IF sym=NulSym
4437 THEN
4438 sym := DeclareSym (tok, name) ;
4439 IF NOT IsError (sym)
4440 THEN
4441 (* Now add this type to the symbol table of the current scope *)
4442 AddSymToScope (sym, name)
4443 END
4444 END ;
4445 oaf := GetOAFamily (sym) ;
4446 RETURN sym
4447 END HandleHiddenOrDeclare ;
4448
4449
4450 (*
4451 MakeRecord - makes a Record symbol with name RecordName.
4452 *)
4453
4454 PROCEDURE MakeRecord (tok: CARDINAL; RecordName: Name) : CARDINAL ;
4455 VAR
4456 oaf, sym: CARDINAL ;
4457 BEGIN
4458 sym := HandleHiddenOrDeclare (tok, RecordName, oaf) ;
4459 FillInRecordFields (tok, sym, RecordName, GetCurrentScope (), oaf) ;
4460 ForeachOAFamily (oaf, doFillInOAFamily) ;
4461 RETURN sym
4462 END MakeRecord ;
4463
4464
4465 (*
4466 MakeVarient - creates a new symbol, a varient symbol for record or varient field
4467 symbol, RecOrVarFieldSym.
4468 *)
4469
4470 PROCEDURE MakeVarient (tok: CARDINAL; RecOrVarFieldSym: CARDINAL) : CARDINAL ;
4471 VAR
4472 pSym: PtrToSymbol ;
4473 Sym : CARDINAL ;
4474 BEGIN
4475 NewSym (Sym) ;
4476 pSym := GetPsym(Sym) ;
4477 WITH pSym^ DO
4478 SymbolType := VarientSym ;
4479 WITH Varient DO
4480 Size := InitValue() ;
4481 Parent := RecOrVarFieldSym ; (* GetRecord(RecOrVarFieldSym) ; *)
4482 IF IsRecord(RecOrVarFieldSym)
4483 THEN
4484 Varient := NulSym
4485 ELSE
4486 Varient := RecOrVarFieldSym
4487 END ;
4488 tag := NulSym ;
4489 DeclPacked := FALSE ;
4490 Scope := GetCurrentScope() ;
4491 InitList(ListOfSons) ;
4492 InitWhereDeclaredTok(tok, At)
4493 END
4494 END ;
4495 (* Now add Sym to the record RecSym field list *)
4496 pSym := GetPsym(RecOrVarFieldSym) ;
4497 WITH pSym^ DO
4498 CASE SymbolType OF
4499
4500 RecordSym : PutItemIntoList(Record.ListOfSons, Sym) |
4501 VarientFieldSym: PutItemIntoList(VarientField.ListOfSons, Sym)
4502
4503 ELSE
4504 InternalError ('expecting Record or VarientField symbol')
4505 END
4506 END ;
4507 RETURN Sym
4508 END MakeVarient ;
4509
4510
4511 (*
4512 GetRecord - fetches the record symbol from the parent of Sym.
4513 Sym maybe a varient symbol in which case its parent is searched
4514 etc.
4515 *)
4516
4517 PROCEDURE GetRecord (Sym: CARDINAL) : CARDINAL ;
4518 VAR
4519 pSym: PtrToSymbol ;
4520 BEGIN
4521 pSym := GetPsym (Sym) ;
4522 WITH pSym^ DO
4523 CASE SymbolType OF
4524
4525 RecordSym : RETURN Sym |
4526 VarientSym : RETURN GetRecord(Varient.Parent) |
4527 VarientFieldSym: RETURN GetRecord(VarientField.Parent)
4528
4529 ELSE
4530 InternalError ('expecting Record or Varient symbol')
4531 END
4532 END
4533 END GetRecord ;
4534
4535
4536 (*
4537 PutDeclaredPacked - sets the Packed field of the record or record field symbol.
4538 *)
4539
4540 PROCEDURE PutDeclaredPacked (sym: CARDINAL; b: BOOLEAN) ;
4541 VAR
4542 pSym: PtrToSymbol ;
4543 BEGIN
4544 pSym := GetPsym(sym) ;
4545 WITH pSym^ DO
4546 CASE SymbolType OF
4547
4548 RecordSym : Record.DeclPacked := b ;
4549 Record.DeclResolved := TRUE |
4550 RecordFieldSym : RecordField.DeclPacked := b ;
4551 RecordField.DeclResolved := TRUE |
4552 VarientFieldSym: VarientField.DeclPacked := b ;
4553 VarientField.DeclResolved := TRUE |
4554 VarientSym : Varient.DeclPacked := b ;
4555 Varient.DeclResolved := TRUE
4556
4557 ELSE
4558 InternalError ('expecting a record or field record symbol')
4559 END
4560 END
4561 END PutDeclaredPacked ;
4562
4563
4564 (*
4565 IsDeclaredPacked - was the record symbol or record field, sym,
4566 declared as packed?
4567 *)
4568
4569 PROCEDURE IsDeclaredPacked (sym: CARDINAL) : BOOLEAN ;
4570 VAR
4571 pSym: PtrToSymbol ;
4572 BEGIN
4573 pSym := GetPsym (sym) ;
4574 WITH pSym^ DO
4575 CASE SymbolType OF
4576
4577 RecordSym : RETURN Record.DeclPacked |
4578 RecordFieldSym : RETURN RecordField.DeclPacked |
4579 VarientFieldSym: RETURN VarientField.DeclPacked |
4580 VarientSym : RETURN Varient.DeclPacked
4581
4582 ELSE
4583 InternalError ('expecting a record or a record field symbol')
4584 END
4585 END
4586 END IsDeclaredPacked ;
4587
4588
4589 (*
4590 IsDeclaredPackedResolved - do we know if the record symbol or record
4591 field, sym, declared as packed or not packed?
4592 *)
4593
4594 PROCEDURE IsDeclaredPackedResolved (sym: CARDINAL) : BOOLEAN ;
4595 VAR
4596 pSym: PtrToSymbol ;
4597 BEGIN
4598 pSym := GetPsym (sym) ;
4599 WITH pSym^ DO
4600 CASE SymbolType OF
4601
4602 RecordSym : RETURN Record.DeclResolved |
4603 RecordFieldSym : RETURN RecordField.DeclResolved |
4604 VarientFieldSym: RETURN VarientField.DeclResolved |
4605 VarientSym : RETURN Varient.DeclResolved
4606
4607 ELSE
4608 InternalError ('expecting a record or a record field symbol')
4609 END
4610 END
4611 END IsDeclaredPackedResolved ;
4612
4613
4614 (*
4615 MakeEnumeration - places a new symbol in the current scope, the symbol
4616 is an enumeration symbol. The symbol index is returned.
4617 *)
4618
4619 PROCEDURE MakeEnumeration (tok: CARDINAL; EnumerationName: Name) : CARDINAL ;
4620 VAR
4621 pSym : PtrToSymbol ;
4622 sym, oaf: CARDINAL ;
4623 BEGIN
4624 sym := CheckForHiddenType (EnumerationName) ;
4625 IF sym=NulSym
4626 THEN
4627 sym := DeclareSym (tok, EnumerationName) ;
4628 oaf := GetOAFamily (sym) ;
4629 IF NOT IsError (sym)
4630 THEN
4631 pSym := GetPsym (sym) ;
4632 pSym^.SymbolType := EnumerationSym ; (* To satisfy AddSymToScope *)
4633 (* Now add this type to the symbol table of the current scope *)
4634 AddSymToScope (sym, EnumerationName)
4635 END
4636 ELSE
4637 oaf := GetOAFamily (sym)
4638 END ;
4639 IF NOT IsError (sym)
4640 THEN
4641 pSym := GetPsym (sym) ;
4642 WITH pSym^ DO
4643 SymbolType := EnumerationSym ;
4644 WITH Enumeration DO
4645 name := EnumerationName ; (* Name of enumeration. *)
4646 NoOfElements := 0 ; (* No of elements in the *)
4647 (* enumeration type. *)
4648 Size := InitValue () ; (* Size at runtime of sym *)
4649 InitTree (LocalSymbols) ; (* Enumeration fields. *)
4650 InitList (ListOfFields) ; (* Ordered as declared. *)
4651 InitPacked (packedInfo) ; (* not packed and no *)
4652 (* equivalent (yet). *)
4653 oafamily := oaf ; (* The open array family *)
4654 Scope := GetCurrentScope () ; (* Which scope created it *)
4655 InitWhereDeclaredTok (tok, At) (* Declared here *)
4656 END
4657 END ;
4658 CheckIfEnumerationExported (sym, ScopePtr)
4659 END ;
4660 ForeachOAFamily (oaf, doFillInOAFamily) ;
4661 RETURN sym
4662 END MakeEnumeration ;
4663
4664
4665 (*
4666 MakeType - makes a type symbol with name TypeName.
4667 *)
4668
4669 PROCEDURE MakeType (tok: CARDINAL; TypeName: Name) : CARDINAL ;
4670 VAR
4671 pSym : PtrToSymbol ;
4672 sym, oaf: CARDINAL ;
4673 BEGIN
4674 sym := HandleHiddenOrDeclare (tok, TypeName, oaf) ;
4675 IF NOT IsError(sym)
4676 THEN
4677 pSym := GetPsym(sym) ;
4678 WITH pSym^ DO
4679 SymbolType := TypeSym ;
4680 WITH Type DO
4681 name := TypeName ; (* Index into name array, name *)
4682 (* of type. *)
4683 Type := NulSym ; (* Index to a type symbol. *)
4684 IsHidden := FALSE ; (* Was it declared as hidden? *)
4685 InitTree(ConstLitTree) ; (* constants of this type. *)
4686 Size := InitValue() ; (* Runtime size of symbol. *)
4687 Align := NulSym ; (* Alignment of this type. *)
4688 InitPacked(packedInfo) ; (* not packed and no *)
4689 (* equivalent yet. *)
4690 oafamily := oaf ; (* The open array family. *)
4691 Scope := GetCurrentScope() ; (* Which scope created it *)
4692 InitWhereDeclaredTok(tok, At) (* Declared here *)
4693 END
4694 END
4695 END ;
4696 ForeachOAFamily(oaf, doFillInOAFamily) ;
4697 RETURN sym
4698 END MakeType ;
4699
4700
4701 (*
4702 MakeHiddenType - makes a type symbol that is hidden from the
4703 definition module.
4704 This symbol is placed into the UnImplemented list of
4705 the definition/implementation module.
4706 The type will be filled in when the implementation module
4707 is reached.
4708 *)
4709
4710 PROCEDURE MakeHiddenType (tok: CARDINAL; TypeName: Name) : CARDINAL ;
4711 VAR
4712 pSym: PtrToSymbol ;
4713 Sym : CARDINAL ;
4714 BEGIN
4715 Sym := DeclareSym (tok, TypeName) ;
4716 IF NOT IsError(Sym)
4717 THEN
4718 pSym := GetPsym(Sym) ;
4719 WITH pSym^ DO
4720 SymbolType := TypeSym ;
4721 WITH Type DO
4722 name := TypeName ; (* Index into name array, name *)
4723 (* of type. *)
4724 IsHidden := GetMainModule()#GetCurrentScope() ;
4725 IF ExtendedOpaque OR (NOT IsHidden)
4726 THEN
4727 Type := NulSym (* will be filled in later *)
4728 ELSE
4729 Type := Address
4730 END ;
4731 Align := NulSym ; (* Alignment of this type. *)
4732 Scope := GetCurrentScope() ; (* Which scope created it *)
4733 oafamily := NulSym ;
4734 IF NOT ExtendedOpaque
4735 THEN
4736 IncludeItemIntoList(AddressTypes, Sym)
4737 END ;
4738 Size := InitValue() ; (* Runtime size of symbol. *)
4739 InitWhereDeclaredTok(tok, At) (* Declared here *)
4740 END
4741 END ;
4742 PutExportUnImplemented (tok, Sym) ;
4743 IF ExtendedOpaque OR (GetMainModule()=GetCurrentScope())
4744 THEN
4745 PutHiddenTypeDeclared
4746 END ;
4747 (* Now add this type to the symbol table of the current scope *)
4748 AddSymToScope(Sym, TypeName)
4749 END ;
4750 RETURN Sym
4751 END MakeHiddenType ;
4752
4753
4754 (*
4755 GetConstFromTypeTree - return a constant symbol from the tree owned by constType.
4756 NulSym is returned if the symbol is unknown.
4757 *)
4758
4759 (*
4760 PROCEDURE GetConstFromTypeTree (constName: Name; constType: CARDINAL) : CARDINAL ;
4761 VAR
4762 pSym: PtrToSymbol ;
4763 BEGIN
4764 IF constType=NulSym
4765 THEN
4766 RETURN GetSymKey(ConstLitTree, constName)
4767 ELSE
4768 pSym := GetPsym(constType) ;
4769 Assert(IsType(constType) OR IsSubrange(constType) OR IsPointer(constType)) ;
4770 WITH pSym^ DO
4771 CASE SymbolType OF
4772
4773 TypeSym : RETURN GetSymKey (Type.ConstLitTree, constName) |
4774 SubrangeSym: RETURN GetSymKey (Subrange.ConstLitTree, constName) |
4775 PointerSym : RETURN GetSymKey (Pointer.ConstLitTree, constName)
4776
4777 ELSE
4778 InternalError ('expecting Type symbol')
4779 END
4780 END
4781 END
4782 END GetConstFromTypeTree ;
4783 *)
4784
4785
4786 (*
4787 PutConstIntoTypeTree - places, constSym, into the tree of constants owned by, constType.
4788 constName is the name of constSym.
4789 *)
4790
4791 (*
4792 PROCEDURE PutConstIntoTypeTree (constName: Name; constType: CARDINAL; constSym: CARDINAL) ;
4793 VAR
4794 pSym: PtrToSymbol ;
4795 BEGIN
4796 IF constType=NulSym
4797 THEN
4798 PutSymKey(ConstLitTree, constName, constSym)
4799 ELSE
4800 pSym := GetPsym(constType) ;
4801 Assert(IsType(constType) OR IsSubrange(constType) OR IsPointer(constType)) ;
4802 WITH pSym^ DO
4803 CASE SymbolType OF
4804
4805 TypeSym : PutSymKey (Type.ConstLitTree, constName, constSym) |
4806 SubrangeSym: PutSymKey (Subrange.ConstLitTree, constName, constSym) |
4807 PointerSym : PutSymKey (Pointer.ConstLitTree, constName, constSym)
4808
4809 ELSE
4810 InternalError ('expecting Type symbol')
4811 END
4812 END
4813 END
4814 END PutConstIntoTypeTree ;
4815 *)
4816
4817
4818 (*
4819 MakeConstant - create a constant cardinal and return the symbol.
4820 *)
4821
4822 PROCEDURE MakeConstant (tok: CARDINAL; value: CARDINAL) : CARDINAL ;
4823 VAR
4824 str: String ;
4825 sym: CARDINAL ;
4826 BEGIN
4827 str := Sprintf1 (Mark (InitString ("%d")), value) ;
4828 sym := MakeConstLit (tok, makekey (string (str)), Cardinal) ;
4829 str := KillString (str) ;
4830 RETURN sym
4831 END MakeConstant ;
4832
4833
4834 (*
4835 CreateConstLit -
4836 *)
4837
4838 PROCEDURE CreateConstLit (tok: CARDINAL; constName: Name; constType: CARDINAL) : CARDINAL ;
4839 VAR
4840 pSym : PtrToSymbol ;
4841 Sym : CARDINAL ;
4842 overflow : BOOLEAN ;
4843 BEGIN
4844 overflow := FALSE ;
4845 IF constType=NulSym
4846 THEN
4847 constType := GetConstLitType (tok, constName, overflow, TRUE)
4848 END ;
4849 NewSym (Sym) ;
4850 pSym := GetPsym (Sym) ;
4851 WITH pSym^ DO
4852 SymbolType := ConstLitSym ;
4853 CASE SymbolType OF
4854
4855 ConstLitSym : ConstLit.name := constName ;
4856 ConstLit.Value := InitValue () ;
4857 PushString (tok, constName, NOT overflow) ;
4858 PopInto (ConstLit.Value) ;
4859 ConstLit.Type := constType ;
4860 ConstLit.IsSet := FALSE ;
4861 ConstLit.IsConstructor := FALSE ;
4862 ConstLit.FromType := NulSym ; (* type is determined FromType *)
4863 ConstLit.RangeError := overflow ;
4864 ConstLit.UnresFromType := FALSE ; (* is Type resolved? *)
4865 ConstLit.Scope := GetCurrentScope () ;
4866 InitWhereDeclaredTok (tok, ConstLit.At) ;
4867 InitWhereFirstUsedTok (tok, ConstLit.At)
4868
4869 ELSE
4870 InternalError ('expecting ConstLit symbol')
4871 END
4872 END ;
4873 RETURN Sym
4874 END CreateConstLit ;
4875
4876
4877 (*
4878 LookupConstLitPoolEntry - return a ConstLit symbol from the constant pool which
4879 matches tok, constName and constType.
4880 *)
4881
4882 PROCEDURE LookupConstLitPoolEntry (tok: CARDINAL;
4883 constName: Name; constType: CARDINAL) : CARDINAL ;
4884 VAR
4885 pe : ConstLitPoolEntry ;
4886 rootIndex: CARDINAL ;
4887 BEGIN
4888 rootIndex := GetSymKey (ConstLitPoolTree, constName) ;
4889 IF rootIndex # 0
4890 THEN
4891 pe := Indexing.GetIndice (ConstLitArray, rootIndex) ;
4892 WHILE pe # NIL DO
4893 IF (pe^.tok = tok) AND
4894 (pe^.constName = constName) AND
4895 (pe^.constType = constType)
4896 THEN
4897 RETURN pe^.sym
4898 END ;
4899 pe := pe^.next
4900 END
4901 END ;
4902 RETURN NulSym
4903 END LookupConstLitPoolEntry ;
4904
4905
4906 (*
4907 AddConstLitPoolEntry - adds sym to the constlit pool.
4908 *)
4909
4910 PROCEDURE AddConstLitPoolEntry (sym: CARDINAL; tok: CARDINAL;
4911 constName: Name; constType: CARDINAL) ;
4912 VAR
4913 pe, old : ConstLitPoolEntry ;
4914 rootIndex, high: CARDINAL ;
4915 BEGIN
4916 rootIndex := GetSymKey (ConstLitPoolTree, constName) ;
4917 IF rootIndex = NulKey
4918 THEN
4919 high := Indexing.HighIndice (ConstLitArray) ;
4920 NEW (pe) ;
4921 IF pe = NIL
4922 THEN
4923 InternalError ('out of memory')
4924 ELSE
4925 pe^.sym := sym ;
4926 pe^.tok := tok ;
4927 pe^.constName := constName ;
4928 pe^.constType := constType ;
4929 pe^.next := NIL ;
4930 PutSymKey (ConstLitPoolTree, constName, high+1) ;
4931 Indexing.PutIndice (ConstLitArray, high+1, pe)
4932 END
4933 ELSE
4934 NEW (pe) ;
4935 IF pe = NIL
4936 THEN
4937 InternalError ('out of memory')
4938 ELSE
4939 old := Indexing.GetIndice (ConstLitArray, rootIndex) ;
4940 pe^.sym := sym ;
4941 pe^.tok := tok ;
4942 pe^.constName := constName ;
4943 pe^.constType := constType ;
4944 pe^.next := old ;
4945 Indexing.PutIndice (ConstLitArray, rootIndex, pe)
4946 END
4947 END
4948 END AddConstLitPoolEntry ;
4949
4950
4951 (*
4952 MakeConstLit - returns a constant literal of type, constType, with a constName,
4953 at location, tok.
4954 *)
4955
4956 PROCEDURE MakeConstLit (tok: CARDINAL; constName: Name; constType: CARDINAL) : CARDINAL ;
4957 VAR
4958 sym: CARDINAL ;
4959 BEGIN
4960 sym := LookupConstLitPoolEntry (tok, constName, constType) ;
4961 IF sym = NulSym
4962 THEN
4963 sym := CreateConstLit (tok, constName, constType) ;
4964 AddConstLitPoolEntry (sym, tok, constName, constType)
4965 END ;
4966 RETURN sym
4967 END MakeConstLit ;
4968
4969
4970 (*
4971 MakeConstVar - makes a ConstVar type with
4972 name ConstVarName.
4973 *)
4974
4975 PROCEDURE MakeConstVar (tok: CARDINAL; ConstVarName: Name) : CARDINAL ;
4976 VAR
4977 pSym: PtrToSymbol ;
4978 Sym : CARDINAL ;
4979 BEGIN
4980 Sym := DeclareSym (tok, ConstVarName) ;
4981 IF NOT IsError(Sym)
4982 THEN
4983 pSym := GetPsym(Sym) ;
4984 WITH pSym^ DO
4985 SymbolType := ConstVarSym ;
4986 WITH ConstVar DO
4987 name := ConstVarName ;
4988 Value := InitValue() ;
4989 Type := NulSym ;
4990 IsSet := FALSE ;
4991 IsConstructor := FALSE ;
4992 FromType := NulSym ; (* type is determined FromType *)
4993 UnresFromType := FALSE ; (* is Type resolved? *)
4994 IsTemp := FALSE ;
4995 Scope := GetCurrentScope () ;
4996 InitWhereDeclaredTok (tok, At)
4997 END
4998 END ;
4999 (* Now add this constant to the symbol table of the current scope *)
5000 AddSymToScope(Sym, ConstVarName)
5001 END ;
5002 RETURN( Sym )
5003 END MakeConstVar ;
5004
5005
5006 (*
5007 MakeConstLitString - put a constant which has the string described by
5008 ConstName into the ConstantTree.
5009 The symbol number is returned.
5010 This symbol is known as a String Constant rather than a
5011 ConstLit which indicates a number.
5012 If the constant already exits
5013 then a duplicate constant is not entered in the tree.
5014 All values of constant strings
5015 are ignored in Pass 1 and evaluated in Pass 2 via
5016 character manipulation.
5017 In this procedure ConstName is the string.
5018 *)
5019
5020 PROCEDURE MakeConstLitString (tok: CARDINAL; ConstName: Name) : CARDINAL ;
5021 VAR
5022 pSym: PtrToSymbol ;
5023 sym : CARDINAL ;
5024 BEGIN
5025 sym := GetSymKey (ConstLitStringTree, ConstName) ;
5026 IF sym=NulSym
5027 THEN
5028 NewSym (sym) ;
5029 PutSymKey (ConstLitStringTree, ConstName, sym) ;
5030 pSym := GetPsym (sym) ;
5031 WITH pSym^ DO
5032 SymbolType := ConstStringSym ;
5033 CASE SymbolType OF
5034
5035 ConstStringSym: InitConstString (tok, sym, ConstName, ConstName,
5036 m2str,
5037 sym, NulSym, NulSym, NulSym)
5038
5039 ELSE
5040 InternalError ('expecting ConstString symbol')
5041 END
5042 END
5043 END ;
5044 RETURN sym
5045 END MakeConstLitString ;
5046
5047
5048 (*
5049 BackFillString -
5050 *)
5051
5052 PROCEDURE BackFillString (sym, m2sym, m2nulsym, csym, cnulsym: CARDINAL) ;
5053 VAR
5054 pSym: PtrToSymbol ;
5055 BEGIN
5056 IF sym # NulSym
5057 THEN
5058 pSym := GetPsym (sym) ;
5059 WITH pSym^ DO
5060 CASE SymbolType OF
5061
5062 ConstStringSym: ConstString.M2Variant := m2sym ;
5063 ConstString.NulM2Variant := m2nulsym ;
5064 ConstString.CVariant := csym ;
5065 ConstString.NulCVariant := cnulsym
5066
5067 ELSE
5068 InternalError ('expecting ConstStringSym')
5069 END
5070 END
5071 END
5072 END BackFillString ;
5073
5074
5075 (*
5076 InitConstString - initialize the constant string and back fill any
5077 previous string variants.
5078 *)
5079
5080 PROCEDURE InitConstString (tok: CARDINAL; sym: CARDINAL; name, contents: Name;
5081 kind: ConstStringVariant;
5082 m2sym, m2nulsym, csym, cnulsym: CARDINAL) ;
5083 VAR
5084 pSym: PtrToSymbol ;
5085 BEGIN
5086 pSym := GetPsym (sym) ;
5087 WITH pSym^ DO
5088 SymbolType := ConstStringSym ;
5089 CASE SymbolType OF
5090
5091 ConstStringSym: ConstString.name := name ;
5092 ConstString.StringVariant := kind ;
5093 PutConstString (tok, sym, contents) ;
5094 BackFillString (sym,
5095 m2sym, m2nulsym, csym, cnulsym) ;
5096 BackFillString (m2sym,
5097 m2sym, m2nulsym, csym, cnulsym) ;
5098 BackFillString (m2nulsym,
5099 m2sym, m2nulsym, csym, cnulsym) ;
5100 BackFillString (csym,
5101 m2sym, m2nulsym, csym, cnulsym) ;
5102 BackFillString (cnulsym,
5103 m2sym, m2nulsym, csym, cnulsym) ;
5104 ConstString.Scope := GetCurrentScope() ;
5105 InitWhereDeclaredTok (tok, ConstString.At)
5106
5107 ELSE
5108 InternalError ('expecting ConstStringSym')
5109 END
5110 END
5111 END InitConstString ;
5112
5113
5114 (*
5115 GetConstStringM2 - returns the Modula-2 variant of a string
5116 (with no added nul terminator).
5117 *)
5118
5119 PROCEDURE GetConstStringM2 (sym: CARDINAL) : CARDINAL ;
5120 VAR
5121 pSym: PtrToSymbol ;
5122 BEGIN
5123 pSym := GetPsym (sym) ;
5124 WITH pSym^ DO
5125 CASE SymbolType OF
5126
5127 ConstStringSym: RETURN ConstString.M2Variant
5128
5129 ELSE
5130 InternalError ('expecting ConstStringSym')
5131 END
5132 END
5133 END GetConstStringM2 ;
5134
5135
5136 (*
5137 GetConstStringC - returns the C variant of a string
5138 (with no added nul terminator).
5139 *)
5140
5141 PROCEDURE GetConstStringC (sym: CARDINAL) : CARDINAL ;
5142 VAR
5143 pSym: PtrToSymbol ;
5144 BEGIN
5145 pSym := GetPsym (sym) ;
5146 WITH pSym^ DO
5147 CASE SymbolType OF
5148
5149 ConstStringSym: RETURN ConstString.CVariant
5150
5151 ELSE
5152 InternalError ('expecting ConstStringSym')
5153 END
5154 END
5155 END GetConstStringC ;
5156
5157
5158 (*
5159 GetConstStringM2nul - returns the Modula-2 variant of a string
5160 (with added nul terminator).
5161 *)
5162
5163 PROCEDURE GetConstStringM2nul (sym: CARDINAL) : CARDINAL ;
5164 VAR
5165 pSym: PtrToSymbol ;
5166 BEGIN
5167 pSym := GetPsym (sym) ;
5168 WITH pSym^ DO
5169 CASE SymbolType OF
5170
5171 ConstStringSym: RETURN ConstString.NulM2Variant
5172
5173 ELSE
5174 InternalError ('expecting ConstStringSym')
5175 END
5176 END
5177 END GetConstStringM2nul ;
5178
5179
5180 (*
5181 GetConstStringCnul - returns the C variant of a string
5182 (with no added nul terminator).
5183 *)
5184
5185 PROCEDURE GetConstStringCnul (sym: CARDINAL) : CARDINAL ;
5186 VAR
5187 pSym: PtrToSymbol ;
5188 BEGIN
5189 pSym := GetPsym (sym) ;
5190 WITH pSym^ DO
5191 CASE SymbolType OF
5192
5193 ConstStringSym: RETURN ConstString.NulCVariant
5194
5195 ELSE
5196 InternalError ('expecting ConstStringSym')
5197 END
5198 END
5199 END GetConstStringCnul ;
5200
5201
5202 (*
5203 IsConstStringNulTerminated - returns TRUE if the constant string, sym,
5204 should be created with a nul terminator.
5205 *)
5206
5207 PROCEDURE IsConstStringNulTerminated (sym: CARDINAL) : BOOLEAN ;
5208 VAR
5209 pSym: PtrToSymbol ;
5210 BEGIN
5211 pSym := GetPsym (sym) ;
5212 WITH pSym^ DO
5213 CASE SymbolType OF
5214
5215 ConstStringSym: RETURN ((ConstString.StringVariant = m2nulstr) OR
5216 (ConstString.StringVariant = cnulstr))
5217
5218 ELSE
5219 InternalError ('expecting ConstStringSym')
5220 END
5221 END
5222 END IsConstStringNulTerminated ;
5223
5224
5225 (*
5226 MakeConstStringCnul - creates a constant string nul terminated string suitable for C.
5227 sym is a ConstString and a new symbol is returned
5228 with the escape sequences converted into characters.
5229 *)
5230
5231 PROCEDURE MakeConstStringCnul (tok: CARDINAL; sym: CARDINAL) : CARDINAL ;
5232 VAR
5233 pSym : PtrToSymbol ;
5234 newstr: CARDINAL ;
5235 BEGIN
5236 pSym := GetPsym (GetConstStringM2 (sym)) ;
5237 WITH pSym^ DO
5238 CASE SymbolType OF
5239
5240 ConstStringSym: Assert (ConstString.StringVariant = m2str) ;
5241 ConstString.CVariant := MakeConstStringC (tok, sym) ;
5242 IF ConstString.NulCVariant = NulSym
5243 THEN
5244 NewSym (newstr) ;
5245 ConstString.NulCVariant := newstr ;
5246 InitConstString (tok, newstr, ConstString.name, GetString (ConstString.CVariant),
5247 cnulstr,
5248 ConstString.M2Variant, ConstString.NulM2Variant, ConstString.CVariant, ConstString.NulCVariant)
5249 END ;
5250 RETURN ConstString.NulCVariant
5251
5252 ELSE
5253 InternalError ('expecting ConstStringSym')
5254 END
5255 END
5256 END MakeConstStringCnul ;
5257
5258
5259 (*
5260 MakeConstStringM2nul - creates a constant string nul terminated string.
5261 sym is a ConstString and a new symbol is returned.
5262 *)
5263
5264 PROCEDURE MakeConstStringM2nul (tok: CARDINAL; sym: CARDINAL) : CARDINAL ;
5265 VAR
5266 pSym: PtrToSymbol ;
5267 BEGIN
5268 pSym := GetPsym (GetConstStringM2 (sym)) ;
5269 WITH pSym^ DO
5270 CASE SymbolType OF
5271
5272 ConstStringSym: Assert (ConstString.StringVariant = m2str) ;
5273 IF ConstString.NulM2Variant = NulSym
5274 THEN
5275 NewSym (ConstString.NulM2Variant) ;
5276 InitConstString (tok, ConstString.NulM2Variant,
5277 ConstString.name, ConstString.Contents,
5278 m2nulstr,
5279 ConstString.M2Variant, ConstString.NulM2Variant,
5280 ConstString.CVariant, ConstString.NulCVariant)
5281 END ;
5282 RETURN ConstString.NulM2Variant
5283
5284 ELSE
5285 InternalError ('expecting ConstStringSym')
5286 END
5287 END
5288 END MakeConstStringM2nul ;
5289
5290
5291 (*
5292 MakeConstStringC - creates a constant string suitable for C.
5293 sym is a Modula-2 ConstString and a new symbol is returned
5294 with the escape sequences converted into characters.
5295 It is not nul terminated.
5296 *)
5297
5298 PROCEDURE MakeConstStringC (tok: CARDINAL; sym: CARDINAL) : CARDINAL ;
5299 VAR
5300 pSym : PtrToSymbol ;
5301 s : String ;
5302 BEGIN
5303 pSym := GetPsym (sym) ;
5304 WITH pSym^ DO
5305 CASE SymbolType OF
5306
5307 ConstStringSym: IF ConstString.StringVariant = cstr
5308 THEN
5309 RETURN sym (* this is already the C variant. *)
5310 ELSIF ConstString.CVariant = NulSym
5311 THEN
5312 Assert (ConstString.StringVariant = m2str) ; (* we can only derive string variants from Modula-2 strings. *)
5313 Assert (sym = ConstString.M2Variant) ;
5314 (* we need to create a new one and return the new symbol. *)
5315 s := HandleEscape (InitStringCharStar (KeyToCharStar (GetString (ConstString.M2Variant)))) ;
5316 NewSym (ConstString.CVariant) ;
5317 InitConstString (tok, ConstString.CVariant, ConstString.name, makekey (string (s)),
5318 cstr,
5319 ConstString.M2Variant, ConstString.NulM2Variant, ConstString.CVariant, ConstString.NulCVariant) ;
5320 s := KillString (s)
5321 END ;
5322 RETURN ConstString.CVariant
5323
5324 ELSE
5325 InternalError ('expecting ConstStringSym')
5326 END
5327 END
5328 END MakeConstStringC ;
5329
5330
5331 (*
5332 MakeConstString - puts a constant into the symboltable which is a string.
5333 The string value is unknown at this time and will be
5334 filled in later by PutString.
5335 *)
5336
5337 PROCEDURE MakeConstString (tok: CARDINAL; ConstName: Name) : CARDINAL ;
5338 VAR
5339 pSym: PtrToSymbol ;
5340 sym : CARDINAL ;
5341 BEGIN
5342 NewSym (sym) ;
5343 PutSymKey (ConstLitStringTree, ConstName, sym) ;
5344 pSym := GetPsym (sym) ;
5345 WITH pSym^ DO
5346 SymbolType := ConstStringSym ;
5347 CASE SymbolType OF
5348
5349 ConstStringSym : InitConstString (tok, sym, ConstName, NulName,
5350 m2str, sym, NulSym, NulSym, NulSym)
5351
5352 ELSE
5353 InternalError ('expecting ConstString symbol')
5354 END
5355 END ;
5356 RETURN sym
5357 END MakeConstString ;
5358
5359
5360 (*
5361 PutConstString - places a string, String, into a constant symbol, Sym.
5362 Sym maybe a ConstString or a ConstVar. If the later is
5363 true then the ConstVar is converted to a ConstString.
5364 *)
5365
5366 PROCEDURE PutConstString (tok: CARDINAL; sym: CARDINAL; contents: Name) ;
5367 VAR
5368 pSym: PtrToSymbol ;
5369 BEGIN
5370 pSym := GetPsym (sym) ;
5371 WITH pSym^ DO
5372 CASE SymbolType OF
5373
5374 ConstStringSym: ConstString.Length := LengthKey (contents) ;
5375 ConstString.Contents := contents ;
5376 InitWhereFirstUsedTok (tok, ConstString.At) |
5377
5378 ConstVarSym : (* ok altering this to ConstString *)
5379 (* copy name and alter symbol. *)
5380 InitConstString (tok, sym, ConstVar.name, contents,
5381 m2str,
5382 sym, NulSym, NulSym, NulSym)
5383
5384 ELSE
5385 InternalError ('expecting ConstString or ConstVar symbol')
5386 END
5387 END
5388 END PutConstString ;
5389
5390
5391 (*
5392 IsConstStringM2 - returns whether this conststring is an unaltered Modula-2 string.
5393 *)
5394
5395 PROCEDURE IsConstStringM2 (sym: CARDINAL) : BOOLEAN ;
5396 VAR
5397 pSym: PtrToSymbol ;
5398 BEGIN
5399 pSym := GetPsym (sym) ;
5400 WITH pSym^ DO
5401 CASE SymbolType OF
5402
5403 ConstStringSym: RETURN ConstString.StringVariant = m2str
5404
5405 ELSE
5406 InternalError ('expecting ConstString symbol')
5407 END
5408 END
5409 END IsConstStringM2 ;
5410
5411
5412 (*
5413 IsConstStringC - returns whether this conststring is a C style string
5414 which will have any escape translated.
5415 *)
5416
5417 PROCEDURE IsConstStringC (sym: CARDINAL) : BOOLEAN ;
5418 VAR
5419 pSym: PtrToSymbol ;
5420 BEGIN
5421 pSym := GetPsym (sym) ;
5422 WITH pSym^ DO
5423 CASE SymbolType OF
5424
5425 ConstStringSym: RETURN ConstString.StringVariant = cstr
5426
5427 ELSE
5428 InternalError ('expecting ConstString symbol')
5429 END
5430 END
5431 END IsConstStringC ;
5432
5433
5434 (*
5435 IsConstStringM2nul - returns whether this conststring is a Modula-2 string which
5436 contains a nul terminator.
5437 *)
5438
5439 PROCEDURE IsConstStringM2nul (sym: CARDINAL) : BOOLEAN ;
5440 VAR
5441 pSym: PtrToSymbol ;
5442 BEGIN
5443 pSym := GetPsym (sym) ;
5444 WITH pSym^ DO
5445 CASE SymbolType OF
5446
5447 ConstStringSym: RETURN ConstString.StringVariant = m2nulstr
5448
5449 ELSE
5450 InternalError ('expecting ConstString symbol')
5451 END
5452 END
5453 END IsConstStringM2nul ;
5454
5455
5456 (*
5457 IsConstStringCnul - returns whether this conststring is a C style string
5458 which will have any escape translated and also contains
5459 a nul terminator.
5460 *)
5461
5462 PROCEDURE IsConstStringCnul (sym: CARDINAL) : BOOLEAN ;
5463 VAR
5464 pSym: PtrToSymbol ;
5465 BEGIN
5466 pSym := GetPsym (sym) ;
5467 WITH pSym^ DO
5468 CASE SymbolType OF
5469
5470 ConstStringSym: RETURN ConstString.StringVariant = cnulstr
5471
5472 ELSE
5473 InternalError ('expecting ConstString symbol')
5474 END
5475 END
5476 END IsConstStringCnul ;
5477
5478
5479 (*
5480 GetString - returns the contents of the string symbol sym, note that
5481 this is not the same as GetName (unless it was a literal).
5482 *)
5483
5484 PROCEDURE GetString (Sym: CARDINAL) : Name ;
5485 VAR
5486 pSym: PtrToSymbol ;
5487 BEGIN
5488 pSym := GetPsym (Sym) ;
5489 WITH pSym^ DO
5490 CASE SymbolType OF
5491
5492 ConstStringSym: RETURN ConstString.Contents
5493
5494 ELSE
5495 InternalError ('expecting ConstString symbol')
5496 END
5497 END
5498 END GetString ;
5499
5500
5501 (*
5502 GetStringLength - returns the length of the string symbol Sym.
5503 *)
5504
5505 PROCEDURE GetStringLength (Sym: CARDINAL) : CARDINAL ;
5506 VAR
5507 pSym: PtrToSymbol ;
5508 BEGIN
5509 pSym := GetPsym (Sym) ;
5510 WITH pSym^ DO
5511 CASE SymbolType OF
5512
5513 ConstStringSym: RETURN ConstString.Length
5514
5515 ELSE
5516 InternalError ('expecting ConstString symbol')
5517 END
5518 END
5519 END GetStringLength ;
5520
5521
5522 (*
5523 PutVariableAtAddress - determines that a variable, sym, is declared at
5524 a specific address.
5525 *)
5526
5527 PROCEDURE PutVariableAtAddress (sym: CARDINAL; address: CARDINAL) ;
5528 VAR
5529 pSym: PtrToSymbol ;
5530 BEGIN
5531 Assert(sym#NulSym) ;
5532 pSym := GetPsym(sym) ;
5533 WITH pSym^ DO
5534 CASE SymbolType OF
5535
5536 VarSym: Var.AtAddress := TRUE ;
5537 Var.Address := address
5538
5539 ELSE
5540 InternalError ('expecting a variable symbol')
5541 END
5542 END
5543 END PutVariableAtAddress ;
5544
5545
5546 (*
5547 GetVariableAtAddress - returns the address at which variable, sym, is declared.
5548 *)
5549
5550 PROCEDURE GetVariableAtAddress (sym: CARDINAL) : CARDINAL ;
5551 VAR
5552 pSym: PtrToSymbol ;
5553 BEGIN
5554 Assert(sym#NulSym) ;
5555 pSym := GetPsym(sym) ;
5556 WITH pSym^ DO
5557 CASE SymbolType OF
5558
5559 VarSym: RETURN( Var.Address )
5560
5561 ELSE
5562 InternalError ('expecting a variable symbol')
5563 END
5564 END
5565 END GetVariableAtAddress ;
5566
5567
5568 (*
5569 IsVariableAtAddress - returns TRUE if a variable, sym, was declared at
5570 a specific address.
5571 *)
5572
5573 PROCEDURE IsVariableAtAddress (sym: CARDINAL) : BOOLEAN ;
5574 VAR
5575 pSym: PtrToSymbol ;
5576 BEGIN
5577 Assert(sym#NulSym) ;
5578 pSym := GetPsym(sym) ;
5579 WITH pSym^ DO
5580 CASE SymbolType OF
5581
5582 VarSym: RETURN( Var.AtAddress )
5583
5584 ELSE
5585 InternalError ('expecting a variable symbol')
5586 END
5587 END
5588 END IsVariableAtAddress ;
5589
5590
5591 (*
5592 PutVariableSSA - assigns value to the SSA field within variable sym.
5593 *)
5594
5595 PROCEDURE PutVariableSSA (sym: CARDINAL; value: BOOLEAN) ;
5596 VAR
5597 pSym: PtrToSymbol ;
5598 BEGIN
5599 Assert (sym#NulSym) ;
5600 pSym := GetPsym (sym) ;
5601 WITH pSym^ DO
5602 CASE SymbolType OF
5603
5604 VarSym: Var.IsSSA := value
5605
5606 ELSE
5607 InternalError ('expecting a variable symbol')
5608 END
5609 END
5610 END PutVariableSSA ;
5611
5612
5613 (*
5614 IsVariableSSA - returns TRUE if variable is known to be a SSA.
5615 *)
5616
5617 PROCEDURE IsVariableSSA (sym: CARDINAL) : BOOLEAN ;
5618 VAR
5619 pSym: PtrToSymbol ;
5620 BEGIN
5621 Assert (sym#NulSym) ;
5622 pSym := GetPsym (sym) ;
5623 WITH pSym^ DO
5624 CASE SymbolType OF
5625
5626 VarSym: RETURN Var.IsSSA
5627
5628 ELSE
5629 InternalError ('expecting a variable symbol')
5630 END
5631 END
5632 END IsVariableSSA ;
5633
5634
5635 (*
5636 PutPriority - places a interrupt, priority, value into module, module.
5637 *)
5638
5639 PROCEDURE PutPriority (module: CARDINAL; priority: CARDINAL) ;
5640 VAR
5641 pSym: PtrToSymbol ;
5642 BEGIN
5643 Assert(module#NulSym) ;
5644 pSym := GetPsym(module) ;
5645 WITH pSym^ DO
5646 CASE SymbolType OF
5647
5648 DefImpSym: DefImp.Priority := priority |
5649 ModuleSym: Module.Priority := priority
5650
5651 ELSE
5652 InternalError ('expecting DefImp or Module symbol')
5653 END
5654 END
5655 END PutPriority ;
5656
5657
5658 (*
5659 GetPriority - returns the interrupt priority which was assigned to
5660 module, module.
5661 *)
5662
5663 PROCEDURE GetPriority (module: CARDINAL) : CARDINAL ;
5664 VAR
5665 pSym: PtrToSymbol ;
5666 BEGIN
5667 Assert(module#NulSym) ;
5668 pSym := GetPsym(module) ;
5669 WITH pSym^ DO
5670 CASE SymbolType OF
5671
5672 DefImpSym: RETURN( DefImp.Priority ) |
5673 ModuleSym: RETURN( Module.Priority )
5674
5675 ELSE
5676 InternalError ('expecting DefImp or Module symbol')
5677 END
5678 END
5679 END GetPriority ;
5680
5681
5682 (*
5683 PutNeedSavePriority - set a boolean flag indicating that this procedure
5684 needs to save and restore interrupts.
5685 *)
5686
5687 PROCEDURE PutNeedSavePriority (sym: CARDINAL) ;
5688 VAR
5689 pSym: PtrToSymbol ;
5690 BEGIN
5691 pSym := GetPsym(sym) ;
5692 WITH pSym^ DO
5693 CASE SymbolType OF
5694
5695 ProcedureSym: Procedure.SavePriority := TRUE
5696
5697 ELSE
5698 InternalError ('expecting procedure symbol')
5699 END
5700 END
5701 END PutNeedSavePriority ;
5702
5703
5704 (*
5705 GetNeedSavePriority - returns the boolean flag indicating whether this procedure
5706 needs to save and restore interrupts.
5707 *)
5708
5709 PROCEDURE GetNeedSavePriority (sym: CARDINAL) : BOOLEAN ;
5710 VAR
5711 pSym: PtrToSymbol ;
5712 BEGIN
5713 pSym := GetPsym(sym) ;
5714 WITH pSym^ DO
5715 CASE SymbolType OF
5716
5717 ProcedureSym: RETURN( Procedure.SavePriority )
5718
5719 ELSE
5720 InternalError ('expecting procedure symbol')
5721 END
5722 END
5723 END GetNeedSavePriority ;
5724
5725
5726 (*
5727 GetProcedureBuiltin - returns the builtin name for the equivalent procedure, Sym.
5728 *)
5729
5730 PROCEDURE GetProcedureBuiltin (Sym: CARDINAL) : Name ;
5731 VAR
5732 pSym: PtrToSymbol ;
5733 BEGIN
5734 pSym := GetPsym(Sym) ;
5735 WITH pSym^ DO
5736 CASE SymbolType OF
5737
5738 ProcedureSym: RETURN( Procedure.BuiltinName )
5739
5740 ELSE
5741 InternalError ('expecting procedure symbol')
5742 END
5743 END
5744 END GetProcedureBuiltin ;
5745
5746
5747 (*
5748 PutProcedureBuiltin - assigns the builtin name for the equivalent procedure, Sym.
5749 *)
5750
5751 PROCEDURE PutProcedureBuiltin (Sym: CARDINAL; name: Name) ;
5752 VAR
5753 pSym: PtrToSymbol ;
5754 BEGIN
5755 pSym := GetPsym(Sym) ;
5756 WITH pSym^ DO
5757 CASE SymbolType OF
5758
5759 ProcedureSym : Procedure.BuiltinName := name ;
5760 Procedure.IsBuiltin := TRUE ;
5761 (* we use the same extra pass method as hidden types for builtins *)
5762 PutHiddenTypeDeclared
5763
5764 ELSE
5765 InternalError ('expecting procedure symbol')
5766 END
5767 END
5768 END PutProcedureBuiltin ;
5769
5770
5771 (*
5772 IsProcedureBuiltin - returns TRUE if this procedure has a builtin equivalent.
5773 *)
5774
5775 PROCEDURE IsProcedureBuiltin (Sym: CARDINAL) : BOOLEAN ;
5776 VAR
5777 pSym: PtrToSymbol ;
5778 BEGIN
5779 pSym := GetPsym(Sym) ;
5780 WITH pSym^ DO
5781 CASE SymbolType OF
5782
5783 ProcedureSym : RETURN( Procedure.IsBuiltin )
5784
5785 ELSE
5786 InternalError ('expecting procedure symbol')
5787 END
5788 END
5789 END IsProcedureBuiltin ;
5790
5791
5792 (*
5793 CanUseBuiltin - returns TRUE if the procedure, Sym, can be
5794 inlined via a builtin function.
5795 *)
5796
5797 PROCEDURE CanUseBuiltin (Sym: CARDINAL) : BOOLEAN ;
5798 BEGIN
5799 RETURN( (NOT DebugBuiltins) AND
5800 (BuiltinExists (KeyToCharStar (GetProcedureBuiltin (Sym))) OR
5801 BuiltinExists (KeyToCharStar (GetSymName (Sym)))) )
5802 END CanUseBuiltin ;
5803
5804
5805 (*
5806 IsProcedureBuiltinAvailable - return TRUE if procedure is available as a builtin
5807 for the target architecture.
5808 *)
5809
5810 PROCEDURE IsProcedureBuiltinAvailable (procedure: CARDINAL) : BOOLEAN ;
5811 BEGIN
5812 RETURN IsProcedureBuiltin (procedure) AND CanUseBuiltin (procedure)
5813 END IsProcedureBuiltinAvailable ;
5814
5815
5816 (*
5817 PutProcedureInline - determines that procedure, Sym, has been requested to be inlined.
5818 *)
5819
5820 PROCEDURE PutProcedureInline (Sym: CARDINAL) ;
5821 VAR
5822 pSym: PtrToSymbol ;
5823 BEGIN
5824 pSym := GetPsym(Sym) ;
5825 WITH pSym^ DO
5826 CASE SymbolType OF
5827
5828 ProcedureSym : Procedure.IsInline := TRUE ;
5829
5830 ELSE
5831 InternalError ('expecting procedure symbol')
5832 END
5833 END
5834 END PutProcedureInline ;
5835
5836
5837 (*
5838 IsProcedureBuiltin - returns TRUE if this procedure was declared as inlined.
5839 *)
5840
5841 PROCEDURE IsProcedureInline (Sym: CARDINAL) : BOOLEAN ;
5842 VAR
5843 pSym: PtrToSymbol ;
5844 BEGIN
5845 pSym := GetPsym(Sym) ;
5846 WITH pSym^ DO
5847 CASE SymbolType OF
5848
5849 ProcedureSym : RETURN( Procedure.IsInline )
5850
5851 ELSE
5852 InternalError ('expecting procedure symbol')
5853 END
5854 END
5855 END IsProcedureInline ;
5856
5857
5858 (*
5859 PutConstSet - informs the const var symbol, sym, that it is or will contain
5860 a set value.
5861 *)
5862
5863 PROCEDURE PutConstSet (Sym: CARDINAL) ;
5864 VAR
5865 pSym: PtrToSymbol ;
5866 BEGIN
5867 pSym := GetPsym(Sym) ;
5868 WITH pSym^ DO
5869 CASE SymbolType OF
5870
5871 ConstVarSym: ConstVar.IsSet := TRUE |
5872 ConstLitSym: ConstLit.IsSet := TRUE
5873
5874 ELSE
5875 InternalError ('expecting ConstVar symbol')
5876 END
5877 END
5878 END PutConstSet ;
5879
5880
5881 (*
5882 IsConstSet - returns TRUE if the constant is declared as a set.
5883 *)
5884
5885 PROCEDURE IsConstSet (Sym: CARDINAL) : BOOLEAN ;
5886 VAR
5887 pSym: PtrToSymbol ;
5888 BEGIN
5889 pSym := GetPsym(Sym) ;
5890 WITH pSym^ DO
5891 CASE SymbolType OF
5892
5893 ConstVarSym: RETURN( ConstVar.IsSet ) |
5894 ConstLitSym: RETURN( ConstLit.IsSet )
5895
5896 ELSE
5897 RETURN( FALSE )
5898 END
5899 END
5900 END IsConstSet ;
5901
5902
5903 (*
5904 PutConstructor - informs the const var symbol, sym, that it is or
5905 will contain a constructor (record, set or array)
5906 value.
5907 *)
5908
5909 PROCEDURE PutConstructor (Sym: CARDINAL) ;
5910 VAR
5911 pSym: PtrToSymbol ;
5912 BEGIN
5913 pSym := GetPsym(Sym) ;
5914 WITH pSym^ DO
5915 CASE SymbolType OF
5916
5917 ConstVarSym: ConstVar.IsConstructor := TRUE |
5918 ConstLitSym: ConstLit.IsConstructor := TRUE
5919
5920 ELSE
5921 InternalError ('expecting ConstVar or ConstLit symbol')
5922 END
5923 END
5924 END PutConstructor ;
5925
5926
5927 (*
5928 IsConstructor - returns TRUE if the constant is declared as a
5929 constant set, array or record.
5930 *)
5931
5932 PROCEDURE IsConstructor (Sym: CARDINAL) : BOOLEAN ;
5933 VAR
5934 pSym: PtrToSymbol ;
5935 BEGIN
5936 pSym := GetPsym(Sym) ;
5937 WITH pSym^ DO
5938 CASE SymbolType OF
5939
5940 ConstVarSym: RETURN( ConstVar.IsConstructor ) |
5941 ConstLitSym: RETURN( ConstLit.IsConstructor )
5942
5943 ELSE
5944 RETURN( FALSE )
5945 END
5946 END
5947 END IsConstructor ;
5948
5949
5950 (*
5951 PutConstructorFrom - sets the from type field in constructor,
5952 Sym, to, from.
5953 *)
5954
5955 PROCEDURE PutConstructorFrom (Sym: CARDINAL; from: CARDINAL) ;
5956 VAR
5957 pSym: PtrToSymbol ;
5958 BEGIN
5959 pSym := GetPsym(Sym) ;
5960 WITH pSym^ DO
5961 CASE SymbolType OF
5962
5963 ConstVarSym: ConstVar.FromType := from ;
5964 ConstVar.UnresFromType := TRUE |
5965 ConstLitSym: ConstLit.FromType := from ;
5966 ConstLit.UnresFromType := TRUE
5967
5968 ELSE
5969 InternalError ('expecting ConstVar or ConstLit symbol')
5970 END
5971 END ;
5972 IncludeItemIntoList(UnresolvedConstructorType, Sym)
5973 END PutConstructorFrom ;
5974
5975
5976 (*
5977 InitPacked - initialise packedInfo to FALSE and NulSym.
5978 *)
5979
5980 PROCEDURE InitPacked (VAR packedInfo: PackedInfo) ;
5981 BEGIN
5982 WITH packedInfo DO
5983 IsPacked := FALSE ;
5984 PackedEquiv := NulSym
5985 END
5986 END InitPacked ;
5987
5988
5989 (*
5990 doEquivalent - create a packed equivalent symbol for, sym, and return the
5991 new symbol. It sets both fields in packedInfo to FALSE
5992 and the new symbol.
5993 *)
5994
5995 PROCEDURE doEquivalent (VAR packedInfo: PackedInfo; sym: CARDINAL) : CARDINAL ;
5996 VAR
5997 nSym: CARDINAL ;
5998 pSym: PtrToSymbol ;
5999 BEGIN
6000 NewSym(nSym) ;
6001 pSym := GetPsym(nSym) ;
6002 WITH pSym^ DO
6003 SymbolType := EquivSym ;
6004 WITH Equiv DO
6005 nonPacked := sym ;
6006 packedInfo.IsPacked := TRUE ;
6007 packedInfo.PackedEquiv := NulSym
6008 END
6009 END ;
6010 packedInfo.IsPacked := FALSE ;
6011 packedInfo.PackedEquiv := nSym ;
6012 RETURN( nSym )
6013 END doEquivalent ;
6014
6015
6016 (*
6017 MakeEquivalent - return the equivalent packed symbol for, sym.
6018 *)
6019
6020 PROCEDURE MakeEquivalent (sym: CARDINAL) : CARDINAL ;
6021 VAR
6022 pSym: PtrToSymbol ;
6023 BEGIN
6024 pSym := GetPsym(sym) ;
6025 WITH pSym^ DO
6026 CASE SymbolType OF
6027
6028 EnumerationSym: RETURN( doEquivalent(Enumeration.packedInfo, sym) ) |
6029 SubrangeSym : RETURN( doEquivalent(Subrange.packedInfo, sym) ) |
6030 TypeSym : RETURN( doEquivalent(Type.packedInfo, sym) ) |
6031 SetSym : RETURN( doEquivalent(Set.packedInfo, sym) )
6032
6033 ELSE
6034 InternalError ('expecting type, subrange or enumerated type symbol')
6035 END
6036 END
6037 END MakeEquivalent ;
6038
6039
6040 (*
6041 GetEquivalent -
6042 *)
6043
6044 PROCEDURE GetEquivalent (VAR packedInfo: PackedInfo; sym: CARDINAL) : CARDINAL ;
6045 BEGIN
6046 WITH packedInfo DO
6047 IF IsPacked
6048 THEN
6049 RETURN( sym )
6050 ELSIF PackedEquiv=NulSym
6051 THEN
6052 PackedEquiv := MakeEquivalent(sym)
6053 END ;
6054 RETURN( PackedEquiv )
6055 END
6056 END GetEquivalent ;
6057
6058
6059 (*
6060 GetPackedEquivalent - returns the packed equivalent of type, sym.
6061 sym must be a type, subrange or enumerated type.
6062 *)
6063
6064 PROCEDURE GetPackedEquivalent (sym: CARDINAL) : CARDINAL ;
6065 VAR
6066 pSym: PtrToSymbol ;
6067 BEGIN
6068 pSym := GetPsym(sym) ;
6069 WITH pSym^ DO
6070 CASE SymbolType OF
6071
6072 EnumerationSym: RETURN( GetEquivalent(Enumeration.packedInfo, sym) ) |
6073 SubrangeSym : RETURN( GetEquivalent(Subrange.packedInfo, sym) ) |
6074 TypeSym : RETURN( GetEquivalent(Type.packedInfo, sym) ) |
6075 SetSym : RETURN( GetEquivalent(Set.packedInfo, sym) )
6076
6077 ELSE
6078 InternalError ('expecting type, subrange or enumerated type symbol')
6079 END
6080 END
6081 END GetPackedEquivalent ;
6082
6083
6084 (*
6085 GetNonPackedEquivalent - returns the equivalent non packed symbol associated with, sym.
6086 *)
6087
6088 PROCEDURE GetNonPackedEquivalent (sym: CARDINAL) : CARDINAL ;
6089 VAR
6090 pSym: PtrToSymbol ;
6091 BEGIN
6092 pSym := GetPsym(sym) ;
6093 WITH pSym^ DO
6094 CASE SymbolType OF
6095
6096 EquivSym: RETURN( Equiv.nonPacked )
6097
6098 ELSE
6099 InternalError ('expecting equivalent symbol')
6100 END
6101 END
6102 END GetNonPackedEquivalent ;
6103
6104
6105 (*
6106 IsEquivalent - returns TRUE if, sym, is an equivalent symbol.
6107 *)
6108
6109 PROCEDURE IsEquivalent (sym: CARDINAL) : BOOLEAN ;
6110 VAR
6111 pSym: PtrToSymbol ;
6112 BEGIN
6113 pSym := GetPsym(sym) ;
6114 WITH pSym^ DO
6115 CASE SymbolType OF
6116
6117 EquivSym: RETURN( TRUE )
6118
6119 ELSE
6120 RETURN( FALSE )
6121 END
6122 END
6123 END IsEquivalent ;
6124
6125
6126 (*
6127 MakeSubrange - makes a new symbol into a subrange type with
6128 name SubrangeName.
6129 *)
6130
6131 PROCEDURE MakeSubrange (tok: CARDINAL; SubrangeName: Name) : CARDINAL ;
6132 VAR
6133 pSym : PtrToSymbol ;
6134 sym, oaf: CARDINAL ;
6135 BEGIN
6136 sym := HandleHiddenOrDeclare (tok, SubrangeName, oaf) ;
6137 IF NOT IsError(sym)
6138 THEN
6139 pSym := GetPsym(sym) ;
6140 WITH pSym^ DO
6141 SymbolType := SubrangeSym ;
6142 WITH Subrange DO
6143 name := SubrangeName ;
6144 Low := NulSym ; (* Index to a symbol determining *)
6145 (* the lower bound of subrange. *)
6146 (* Points to a constant - *)
6147 (* possibly created by *)
6148 (* ConstExpression. *)
6149 High := NulSym ; (* Index to a symbol determining *)
6150 (* the lower bound of subrange. *)
6151 (* Points to a constant - *)
6152 (* possibly created by *)
6153 (* ConstExpression. *)
6154 Type := NulSym ; (* Index to a type. Determines *)
6155 (* the type of subrange. *)
6156 Align := NulSym ; (* The alignment of this type. *)
6157 InitPacked(packedInfo) ; (* not packed and no equivalent *)
6158 InitTree(ConstLitTree) ; (* constants of this type. *)
6159 Size := InitValue() ; (* Size determines the type size *)
6160 oafamily := oaf ; (* The unbounded sym for this *)
6161 Scope := GetCurrentScope() ; (* Which scope created it *)
6162 InitWhereDeclaredTok(tok, At) (* Declared here *)
6163 END
6164 END
6165 END ;
6166 ForeachOAFamily(oaf, doFillInOAFamily) ;
6167 RETURN sym
6168 END MakeSubrange ;
6169
6170
6171 (*
6172 MakeArray - makes an Array symbol with name ArrayName.
6173 *)
6174
6175 PROCEDURE MakeArray (tok: CARDINAL; ArrayName: Name) : CARDINAL ;
6176 VAR
6177 pSym : PtrToSymbol ;
6178 sym, oaf: CARDINAL ;
6179 BEGIN
6180 sym := HandleHiddenOrDeclare (tok, ArrayName, oaf) ;
6181 IF NOT IsError(sym)
6182 THEN
6183 pSym := GetPsym(sym) ;
6184 WITH pSym^ DO
6185 SymbolType := ArraySym ;
6186 WITH Array DO
6187 name := ArrayName ;
6188 Subscript := NulSym ; (* Contains the array subscripts. *)
6189 Size := InitValue() ; (* Size of array. *)
6190 Offset := InitValue() ; (* Offset of array. *)
6191 Type := NulSym ; (* The Array Type. ARRAY OF Type. *)
6192 Large := FALSE ; (* is this array large? *)
6193 Align := NulSym ; (* The alignment of this type. *)
6194 oafamily := oaf ; (* The unbounded for this array *)
6195 Scope := GetCurrentScope() ; (* Which scope created it *)
6196 InitWhereDeclaredTok(tok, At) (* Declared here *)
6197 END
6198 END
6199 END ;
6200 ForeachOAFamily(oaf, doFillInOAFamily) ;
6201 RETURN( sym )
6202 END MakeArray ;
6203
6204
6205 (*
6206 PutArrayLarge - indicates that this is a large array in which case
6207 the interface to gcc maps this array from 0..high-low,
6208 using an integer indice.
6209 *)
6210
6211 PROCEDURE PutArrayLarge (array: CARDINAL) ;
6212 VAR
6213 pSym: PtrToSymbol ;
6214 BEGIN
6215 IF NOT IsError(array)
6216 THEN
6217 Assert(IsArray(array)) ;
6218 pSym := GetPsym(array) ;
6219 WITH pSym^.Array DO
6220 Large := TRUE
6221 END
6222 END
6223 END PutArrayLarge ;
6224
6225
6226 (*
6227 IsArrayLarge - returns TRUE if we need to treat this as a large array.
6228 *)
6229
6230 PROCEDURE IsArrayLarge (array: CARDINAL) : BOOLEAN ;
6231 VAR
6232 pSym: PtrToSymbol ;
6233 BEGIN
6234 Assert(IsArray(array)) ;
6235 pSym := GetPsym(array) ;
6236 RETURN( pSym^.Array.Large )
6237 END IsArrayLarge ;
6238
6239
6240 (*
6241 GetModule - Returns the Module symbol for the module with name, name.
6242 *)
6243
6244 PROCEDURE GetModule (name: Name) : CARDINAL ;
6245 BEGIN
6246 RETURN( GetSymKey(ModuleTree, name) )
6247 END GetModule ;
6248
6249
6250 (*
6251 GetLowestType - Returns the lowest type in the type chain of
6252 symbol Sym.
6253 If NulSym is returned then we assume type unknown or
6254 you have reqested the type of a base type.
6255 *)
6256
6257 PROCEDURE GetLowestType (Sym: CARDINAL) : CARDINAL ;
6258 VAR
6259 pSym: PtrToSymbol ;
6260 type: CARDINAL ;
6261 BEGIN
6262 Assert(Sym#NulSym) ;
6263 pSym := GetPsym(Sym) ;
6264 WITH pSym^ DO
6265 CASE SymbolType OF
6266
6267 VarSym : type := Var.Type |
6268 ConstLitSym : type := ConstLit.Type |
6269 ConstVarSym : type := ConstVar.Type |
6270 ConstStringSym : type := NulSym | (* No type for a string *)
6271 TypeSym : type := Type.Type |
6272 RecordFieldSym : type := RecordField.Type |
6273 RecordSym : type := NulSym | (* No type for a record *)
6274 EnumerationFieldSym : type := EnumerationField.Type |
6275 EnumerationSym : type := NulSym | (* No type for enumeration *)
6276 PointerSym : type := Sym | (* we don't go to Pointer.Type *)
6277 ProcedureSym : type := Procedure.ReturnType |
6278 ProcTypeSym : type := ProcType.ReturnType |
6279 ParamSym : type := Param.Type |
6280 VarParamSym : type := VarParam.Type |
6281 SubrangeSym : type := Subrange.Type |
6282 ArraySym : type := Array.Type |
6283 SubscriptSym : type := Subscript.Type |
6284 SetSym : type := Set.Type |
6285 UnboundedSym : type := Unbounded.Type |
6286 UndefinedSym : type := NulSym |
6287 DummySym : type := NulSym
6288
6289 ELSE
6290 InternalError ('not implemented yet')
6291 END
6292 END ;
6293 pSym := GetPsym(Sym) ;
6294 IF (pSym^.SymbolType=TypeSym) AND (type=NulSym)
6295 THEN
6296 type := Sym (* Base Type *)
6297 ELSIF (type#NulSym) AND IsType(type) AND (GetAlignment(type)=NulSym)
6298 THEN
6299 type := GetLowestType(type) (* Type def *)
6300 END ;
6301 RETURN( type )
6302 END GetLowestType ;
6303
6304
6305 (*
6306 doGetType - subsiduary helper procedure function of GetDType, GetSType and GetLType.
6307 *)
6308
6309 PROCEDURE doGetType (sym: CARDINAL; skipEquiv, skipAlign, skipHidden, skipBase: BOOLEAN) : CARDINAL ;
6310 VAR
6311 pSym: PtrToSymbol ;
6312 type: CARDINAL ;
6313 BEGIN
6314 type := NulSym ;
6315 Assert (sym # NulSym) ;
6316 pSym := GetPsym (sym) ;
6317 WITH pSym^ DO
6318 CASE SymbolType OF
6319
6320 OAFamilySym : type := OAFamily.SimpleType |
6321 VarSym : type := GetTypeOfVar(sym) |
6322 ConstLitSym : type := ConstLit.Type |
6323 ConstVarSym : type := ConstVar.Type |
6324 ConstStringSym : IF ConstString.Length=1
6325 THEN
6326 type := Char
6327 ELSE
6328 type := NulSym (* No type for a string *)
6329 END |
6330 TypeSym : type := Type.Type |
6331 RecordFieldSym : type := RecordField.Type |
6332 RecordSym : type := NulSym | (* No type for a record *)
6333 VarientSym : type := NulSym | (* No type for a record *)
6334 EnumerationFieldSym : type := EnumerationField.Type |
6335 EnumerationSym : type := NulSym | (* No type for enumeration *)
6336 PointerSym : type := Pointer.Type |
6337 ProcedureSym : type := Procedure.ReturnType |
6338 ProcTypeSym : type := ProcType.ReturnType |
6339 ParamSym : type := Param.Type |
6340 VarParamSym : type := VarParam.Type |
6341 SubrangeSym : type := Subrange.Type |
6342 ArraySym : type := Array.Type |
6343 SubscriptSym : type := Subscript.Type |
6344 SetSym : type := Set.Type |
6345 UnboundedSym : type := Unbounded.Type |
6346 UndefinedSym : type := NulSym |
6347 PartialUnboundedSym : type := PartialUnbounded.Type |
6348 ObjectSym : type := NulSym
6349
6350 ELSE
6351 InternalError ('not implemented yet')
6352 END
6353 END ;
6354 IF (type=NulSym) AND IsType(sym) AND (NOT skipBase)
6355 THEN
6356 RETURN sym (* sym is a base type *)
6357 ELSIF type#NulSym
6358 THEN
6359 IF IsType(type) AND skipEquiv
6360 THEN
6361 IF (NOT IsHiddenType(type)) OR skipHidden
6362 THEN
6363 IF (GetAlignment(type)=NulSym) OR skipAlign
6364 THEN
6365 RETURN doGetType (type, skipEquiv, skipAlign, skipHidden, skipBase)
6366 END
6367 END
6368 END
6369 END ;
6370 RETURN type
6371 END doGetType ;
6372
6373
6374 (*
6375 GetLType - get lowest type. It returns the lowest type
6376 of symbol, sym. It skips over type equivalences.
6377 It will not skip over base types.
6378 *)
6379
6380 PROCEDURE GetLType (sym: CARDINAL) : CARDINAL ;
6381 BEGIN
6382 (*
6383 Assert (doGetType (sym, TRUE, TRUE, TRUE, FALSE) = GetLowestType (sym)) ;
6384 *)
6385 RETURN doGetType (sym, TRUE, TRUE, TRUE, FALSE)
6386 END GetLType ;
6387
6388
6389 (*
6390 GetSType - get source type. It returns the type closest
6391 to the object. It does not skip over type
6392 equivalences. It will skip over base types.
6393 *)
6394
6395 PROCEDURE GetSType (sym: CARDINAL) : CARDINAL ;
6396 BEGIN
6397 Assert (doGetType (sym, FALSE, FALSE, FALSE, TRUE) = GetType (sym)) ;
6398 RETURN doGetType (sym, FALSE, FALSE, FALSE, TRUE)
6399 END GetSType ;
6400
6401
6402 (*
6403 GetDType - get gcc declared type. It returns the type
6404 of the object which is declared to GCC.
6405 It does skip over type equivalences but only
6406 if they do not contain a user alignment.
6407 It does not skip over hidden types.
6408 It does not skip over base types.
6409 *)
6410
6411 PROCEDURE GetDType (sym: CARDINAL) : CARDINAL ;
6412 BEGIN
6413 (*
6414 Assert (doGetType (sym, TRUE, FALSE, FALSE, FALSE) = SkipType(GetType(sym))) ;
6415 *)
6416 RETURN doGetType (sym, TRUE, FALSE, FALSE, FALSE)
6417 END GetDType ;
6418
6419
6420 (*
6421 GetTypeOfVar - returns the type of symbol, var.
6422 *)
6423
6424 PROCEDURE GetTypeOfVar (var: CARDINAL) : CARDINAL ;
6425 VAR
6426 pSym: PtrToSymbol ;
6427 high: CARDINAL ;
6428 BEGIN
6429 pSym := GetPsym(var) ;
6430 WITH pSym^ DO
6431 CASE SymbolType OF
6432
6433 VarSym: IF Var.IsTemp AND Var.IsComponentRef
6434 THEN
6435 high := Indexing.HighIndice(Var.list) ;
6436 RETURN( GetType(GetFromIndex(Var.list, high)) )
6437 ELSE
6438 RETURN( Var.Type )
6439 END
6440
6441 ELSE
6442 InternalError ('expecting a var symbol')
6443 END
6444 END
6445 END GetTypeOfVar ;
6446
6447
6448 (*
6449 GetType - Returns the symbol that is the TYPE symbol to Sym.
6450 If zero is returned then we assume type unknown.
6451 *)
6452
6453 PROCEDURE GetType (Sym: CARDINAL) : CARDINAL ;
6454 VAR
6455 pSym: PtrToSymbol ;
6456 type: CARDINAL ;
6457 BEGIN
6458 Assert(Sym#NulSym) ;
6459 pSym := GetPsym(Sym) ;
6460 WITH pSym^ DO
6461 CASE SymbolType OF
6462
6463 OAFamilySym : type := OAFamily.SimpleType |
6464 VarSym : type := GetTypeOfVar(Sym) |
6465 ConstLitSym : type := ConstLit.Type |
6466 ConstVarSym : type := ConstVar.Type |
6467 ConstStringSym : IF ConstString.Length=1
6468 THEN
6469 type := Char
6470 ELSE
6471 type := NulSym (* No type for a string *)
6472 END |
6473 TypeSym : type := Type.Type |
6474 RecordFieldSym : type := RecordField.Type |
6475 RecordSym : type := NulSym | (* No type for a record *)
6476 VarientSym : type := NulSym | (* No type for a record *)
6477 EnumerationFieldSym : type := EnumerationField.Type |
6478 EnumerationSym : type := NulSym | (* No type for enumeration *)
6479 PointerSym : type := Pointer.Type |
6480 ProcedureSym : type := Procedure.ReturnType |
6481 ProcTypeSym : type := ProcType.ReturnType |
6482 ParamSym : type := Param.Type |
6483 VarParamSym : type := VarParam.Type |
6484 SubrangeSym : type := Subrange.Type |
6485 ArraySym : type := Array.Type |
6486 SubscriptSym : type := Subscript.Type |
6487 SetSym : type := Set.Type |
6488 UnboundedSym : type := Unbounded.Type |
6489 UndefinedSym : type := NulSym |
6490 PartialUnboundedSym : type := PartialUnbounded.Type |
6491 ObjectSym : type := NulSym
6492
6493 ELSE
6494 InternalError ('not implemented yet')
6495 END
6496 END ;
6497 RETURN( type )
6498 END GetType ;
6499
6500
6501 (*
6502 SkipType - if sym is a TYPE foo = bar
6503 then call SkipType(bar)
6504 else return sym
6505
6506 it does not skip over hidden types.
6507 *)
6508
6509 PROCEDURE SkipType (Sym: CARDINAL) : CARDINAL ;
6510 BEGIN
6511 IF (Sym#NulSym) AND IsType(Sym) AND
6512 (NOT IsHiddenType(Sym)) AND (GetType(Sym)#NulSym)
6513 THEN
6514 RETURN( SkipType(GetType(Sym)) )
6515 ELSE
6516 RETURN( Sym )
6517 END
6518 END SkipType ;
6519
6520
6521 (*
6522 SkipTypeAndSubrange - if sym is a TYPE foo = bar OR
6523 sym is declared as a subrange of bar
6524 then call SkipTypeAndSubrange(bar)
6525 else return sym
6526
6527 it does not skip over hidden types.
6528 *)
6529
6530 PROCEDURE SkipTypeAndSubrange (Sym: CARDINAL) : CARDINAL ;
6531 BEGIN
6532 IF (Sym#NulSym) AND (IsType(Sym) OR IsSubrange(Sym)) AND
6533 (NOT IsHiddenType(Sym)) AND (GetType(Sym)#NulSym)
6534 THEN
6535 RETURN( SkipTypeAndSubrange(GetType(Sym)) )
6536 ELSE
6537 RETURN( Sym )
6538 END
6539 END SkipTypeAndSubrange ;
6540
6541
6542 (*
6543 IsHiddenType - returns TRUE if, Sym, is a Type and is also declared as a hidden type.
6544 *)
6545
6546 PROCEDURE IsHiddenType (Sym: CARDINAL) : BOOLEAN ;
6547 VAR
6548 pSym: PtrToSymbol ;
6549 BEGIN
6550 pSym := GetPsym(Sym) ;
6551 WITH pSym^ DO
6552 CASE SymbolType OF
6553
6554 TypeSym: RETURN( Type.IsHidden )
6555
6556 ELSE
6557 RETURN( FALSE )
6558 END
6559 END
6560 END IsHiddenType ;
6561
6562
6563 (*
6564 GetConstLitType - returns the type of the constant of, name.
6565 All floating point constants have type LONGREAL.
6566 Character constants are type CHAR.
6567 Integer values are INTEGER, LONGINT or LONGCARD
6568 depending upon their value.
6569 *)
6570
6571 PROCEDURE GetConstLitType (tok: CARDINAL; name: Name;
6572 VAR overflow: BOOLEAN; issueError: BOOLEAN) : CARDINAL ;
6573 VAR
6574 loc: location_t ;
6575 s : String ;
6576 BEGIN
6577 s := InitStringCharStar (KeyToCharStar (name)) ;
6578 IF char (s, -1) = 'C'
6579 THEN
6580 s := KillString (s) ;
6581 RETURN Char
6582 ELSE
6583 IF Index (s, '.', 0) # -1 (* found a '.' in our constant *)
6584 THEN
6585 s := KillString (s) ;
6586 RETURN RType
6587 END ;
6588 loc := TokenToLocation (tok) ;
6589 CASE char (s, -1) OF
6590
6591 'H': overflow := OverflowZType (loc, string (s), 16, issueError) |
6592 'B': overflow := OverflowZType (loc, string (s), 8, issueError) |
6593 'A': overflow := OverflowZType (loc, string (s), 2, issueError)
6594
6595 ELSE
6596 overflow := OverflowZType (loc, string (s), 10, issueError)
6597 END ;
6598 s := KillString (s) ;
6599 RETURN ZType
6600 END
6601 END GetConstLitType ;
6602
6603
6604 (*
6605 GetLocalSym - only searches the scope Sym for a symbol with name
6606 and returns the index to the symbol.
6607 *)
6608
6609 PROCEDURE GetLocalSym (Sym: CARDINAL; name: Name) : CARDINAL ;
6610 VAR
6611 pSym : PtrToSymbol ;
6612 LocalSym: CARDINAL ;
6613 BEGIN
6614 (*
6615 WriteString('Attempting to retrieve symbol from ') ; WriteKey(GetSymName(Sym)) ;
6616 WriteString(' local symbol table') ; WriteLn ;
6617 *)
6618 pSym := GetPsym(Sym) ;
6619 WITH pSym^ DO
6620 CASE SymbolType OF
6621
6622 EnumerationSym : LocalSym := GetSymKey(Enumeration.LocalSymbols, name) |
6623 RecordSym : LocalSym := GetSymKey(Record.LocalSymbols, name) |
6624 ProcedureSym : LocalSym := GetSymKey(Procedure.LocalSymbols, name) |
6625 ModuleSym : LocalSym := GetSymKey(Module.LocalSymbols, name) |
6626 DefImpSym : LocalSym := GetSymKey(DefImp.LocalSymbols, name)
6627
6628 ELSE
6629 InternalError ('symbol does not have a LocalSymbols field')
6630 END
6631 END ;
6632 RETURN( LocalSym )
6633 END GetLocalSym ;
6634
6635
6636 (*
6637 GetNthFromComponent -
6638 *)
6639
6640 PROCEDURE GetNthFromComponent (Sym: CARDINAL; n: CARDINAL) : CARDINAL ;
6641 VAR
6642 pSym: PtrToSymbol ;
6643 BEGIN
6644 pSym := GetPsym(Sym) ;
6645 WITH pSym^ DO
6646 CASE SymbolType OF
6647
6648 VarSym: IF IsComponent(Sym)
6649 THEN
6650 IF InBounds(Var.list, n)
6651 THEN
6652 RETURN( GetFromIndex(Var.list, n) )
6653 ELSE
6654 RETURN( NulSym )
6655 END
6656 ELSE
6657 InternalError ('cannot GetNth from this symbol')
6658 END
6659
6660 ELSE
6661 InternalError ('cannot GetNth from this symbol')
6662 END
6663 END
6664 END GetNthFromComponent ;
6665
6666
6667 (*
6668 GetNth - returns the n th symbol in the list associated with the scope
6669 of Sym. Sym may be a Module, DefImp, Procedure, Record or
6670 Enumeration symbol.
6671 *)
6672
6673 PROCEDURE GetNth (Sym: CARDINAL; n: CARDINAL) : CARDINAL ;
6674 VAR
6675 pSym: PtrToSymbol ;
6676 i : CARDINAL ;
6677 BEGIN
6678 pSym := GetPsym(Sym) ;
6679 WITH pSym^ DO
6680 CASE SymbolType OF
6681
6682 RecordSym : i := GetItemFromList (Record.ListOfSons, n) |
6683 VarientSym : i := GetItemFromList (Varient.ListOfSons, n) |
6684 VarientFieldSym : i := GetItemFromList (VarientField.ListOfSons, n) |
6685 ProcedureSym : i := GetItemFromList (Procedure.ListOfVars, n) |
6686 DefImpSym : i := GetItemFromList (DefImp.ListOfVars, n) |
6687 ModuleSym : i := GetItemFromList (Module.ListOfVars, n) |
6688 TupleSym : i := GetFromIndex (Tuple.list, n) |
6689 VarSym : i := GetNthFromComponent (Sym, n) |
6690 EnumerationSym : i := GetItemFromList (Enumeration.ListOfFields, n)
6691
6692 ELSE
6693 InternalError ('cannot GetNth from this symbol')
6694 END
6695 END ;
6696 RETURN( i )
6697 END GetNth ;
6698
6699
6700 (*
6701 GetNthParam - returns the n th parameter of a procedure Sym.
6702 *)
6703
6704 PROCEDURE GetNthParam (Sym: CARDINAL; ParamNo: CARDINAL) : CARDINAL ;
6705 VAR
6706 pSym: PtrToSymbol ;
6707 i : CARDINAL ;
6708 BEGIN
6709 IF ParamNo=0
6710 THEN
6711 (* Demands the return type of the function *)
6712 i := GetType(Sym)
6713 ELSE
6714 pSym := GetPsym(Sym) ;
6715 WITH pSym^ DO
6716 CASE SymbolType OF
6717
6718 ProcedureSym: i := GetItemFromList(Procedure.ListOfParam, ParamNo) |
6719 ProcTypeSym : i := GetItemFromList(ProcType.ListOfParam, ParamNo)
6720
6721 ELSE
6722 InternalError ('expecting ProcedureSym or ProcTypeSym')
6723 END
6724 END
6725 END ;
6726 RETURN( i )
6727 END GetNthParam ;
6728
6729
6730 (*
6731 The Following procedures fill in the symbol table with the
6732 symbol entities.
6733 *)
6734
6735 (*
6736 PutVar - gives the VarSym symbol Sym a type Type.
6737 *)
6738
6739 PROCEDURE PutVar (Sym: CARDINAL; VarType: CARDINAL) ;
6740 VAR
6741 pSym: PtrToSymbol ;
6742 BEGIN
6743 pSym := GetPsym(Sym) ;
6744 WITH pSym^ DO
6745 CASE SymbolType OF
6746
6747 VarSym : Var.Type := VarType ;
6748 ConfigSymInit (Var.InitState[LeftValue], Sym) ;
6749 ConfigSymInit (Var.InitState[RightValue], Sym) |
6750 ConstVarSym: ConstVar.Type := VarType
6751
6752 ELSE
6753 InternalError ('expecting VarSym or ConstVarSym')
6754 END
6755 END
6756 END PutVar ;
6757
6758
6759 (*
6760 PutLeftValueFrontBackType - gives the variable symbol a front and backend type.
6761 The variable must be a LeftValue.
6762 *)
6763
6764 PROCEDURE PutLeftValueFrontBackType (Sym: CARDINAL; FrontType, BackType: CARDINAL) ;
6765 VAR
6766 pSym: PtrToSymbol ;
6767 BEGIN
6768 Assert(GetMode(Sym)=LeftValue) ;
6769 pSym := GetPsym(Sym) ;
6770 WITH pSym^ DO
6771 CASE SymbolType OF
6772
6773 VarSym : Var.Type := FrontType ;
6774 Var.BackType := BackType ;
6775 PushSize(Address) ;
6776 PopInto(Var.Size)
6777
6778 ELSE
6779 InternalError ('expecting VarSym')
6780 END
6781 END
6782 END PutLeftValueFrontBackType ;
6783
6784
6785 (*
6786 GetVarBackEndType - returns the back end type if specified.
6787 *)
6788
6789 PROCEDURE GetVarBackEndType (Sym: CARDINAL) : CARDINAL ;
6790 VAR
6791 pSym: PtrToSymbol ;
6792 BEGIN
6793 Assert(Sym#NulSym) ;
6794 pSym := GetPsym(Sym) ;
6795 WITH pSym^ DO
6796 CASE SymbolType OF
6797
6798 VarSym: RETURN( Var.BackType )
6799
6800 ELSE
6801 RETURN( NulSym )
6802 END
6803 END
6804 END GetVarBackEndType ;
6805
6806
6807 (*
6808 PutVarPointerCheck - marks variable, sym, as requiring (or not
6809 depending upon the, value), a NIL pointer check
6810 when this symbol is dereferenced.
6811 *)
6812
6813 PROCEDURE PutVarPointerCheck (sym: CARDINAL; value: BOOLEAN) ;
6814 VAR
6815 pSym: PtrToSymbol ;
6816 BEGIN
6817 IF IsVar(sym)
6818 THEN
6819 pSym := GetPsym(sym) ;
6820 WITH pSym^.Var DO
6821 IsPointerCheck := value
6822 END
6823 END
6824 END PutVarPointerCheck ;
6825
6826
6827 (*
6828 GetVarPointerCheck - returns TRUE if this symbol is a variable and
6829 has been marked as needing a pointer via NIL check.
6830 *)
6831
6832 PROCEDURE GetVarPointerCheck (sym: CARDINAL) : BOOLEAN ;
6833 VAR
6834 pSym: PtrToSymbol ;
6835 BEGIN
6836 IF IsVar(sym)
6837 THEN
6838 pSym := GetPsym(sym) ;
6839 WITH pSym^.Var DO
6840 RETURN( IsPointerCheck )
6841 END
6842 END ;
6843 RETURN FALSE
6844 END GetVarPointerCheck ;
6845
6846
6847 (*
6848 PutVarWritten - marks variable, sym, as being written to (or not
6849 depending upon the, value).
6850 *)
6851
6852 PROCEDURE PutVarWritten (sym: CARDINAL; value: BOOLEAN) ;
6853 VAR
6854 pSym: PtrToSymbol ;
6855 BEGIN
6856 IF IsVar(sym)
6857 THEN
6858 pSym := GetPsym(sym) ;
6859 WITH pSym^.Var DO
6860 IsWritten := value
6861 END
6862 END
6863 END PutVarWritten ;
6864
6865
6866 (*
6867 GetVarWritten - returns TRUE if this symbol is a variable and
6868 has been marked as being written.
6869 *)
6870
6871 PROCEDURE GetVarWritten (sym: CARDINAL) : BOOLEAN ;
6872 VAR
6873 pSym: PtrToSymbol ;
6874 BEGIN
6875 pSym := GetPsym(sym) ;
6876 WITH pSym^ DO
6877 CASE SymbolType OF
6878
6879 VarSym: RETURN( Var.IsWritten )
6880
6881 ELSE
6882 InternalError ('expecting VarSym')
6883 END
6884 END
6885 END GetVarWritten ;
6886
6887
6888 (*
6889 PutVarConst - sets the IsConst field to value indicating the variable is read only.
6890 *)
6891
6892 PROCEDURE PutVarConst (sym: CARDINAL; value: BOOLEAN) ;
6893 VAR
6894 pSym: PtrToSymbol ;
6895 BEGIN
6896 IF IsVar (sym)
6897 THEN
6898 pSym := GetPsym (sym) ;
6899 pSym^.Var.IsConst := value
6900 END
6901 END PutVarConst ;
6902
6903
6904 (*
6905 IsVarConst - returns the IsConst field indicating the variable is read only.
6906 *)
6907
6908 PROCEDURE IsVarConst (sym: CARDINAL) : BOOLEAN ;
6909 VAR
6910 pSym: PtrToSymbol ;
6911 BEGIN
6912 pSym := GetPsym(sym) ;
6913 WITH pSym^ DO
6914 CASE SymbolType OF
6915
6916 VarSym: RETURN( Var.IsConst )
6917
6918 ELSE
6919 InternalError ('expecting VarSym')
6920 END
6921 END
6922 END IsVarConst ;
6923
6924
6925 (*
6926 PutConst - gives the constant symbol Sym a type ConstType.
6927 *)
6928
6929 PROCEDURE PutConst (Sym: CARDINAL; ConstType: CARDINAL) ;
6930 VAR
6931 pSym: PtrToSymbol ;
6932 BEGIN
6933 pSym := GetPsym(Sym) ;
6934 WITH pSym^ DO
6935 CASE SymbolType OF
6936
6937 ConstVarSym: ConstVar.Type := ConstType
6938
6939 ELSE
6940 InternalError ('expecting ConstVarSym')
6941 END
6942 END
6943 END PutConst ;
6944
6945
6946 (*
6947 PutVarArrayRef - assigns ArrayRef field with value.
6948 *)
6949
6950 PROCEDURE PutVarArrayRef (sym: CARDINAL; value: BOOLEAN) ;
6951 VAR
6952 pSym: PtrToSymbol ;
6953 BEGIN
6954 pSym := GetPsym(sym) ;
6955 WITH pSym^ DO
6956 CASE SymbolType OF
6957
6958 VarSym: Var.ArrayRef := value
6959
6960 ELSE
6961 InternalError ('expecting VarSym')
6962 END
6963 END
6964 END PutVarArrayRef ;
6965
6966
6967 (*
6968 IsVarArrayRef - returns ArrayRef field value.
6969 *)
6970
6971 PROCEDURE IsVarArrayRef (sym: CARDINAL) : BOOLEAN ;
6972 VAR
6973 pSym: PtrToSymbol ;
6974 BEGIN
6975 pSym := GetPsym(sym) ;
6976 WITH pSym^ DO
6977 CASE SymbolType OF
6978
6979 VarSym: RETURN (Var.ArrayRef)
6980
6981 ELSE
6982 InternalError ('expecting VarSym')
6983 END
6984 END
6985 END IsVarArrayRef ;
6986
6987
6988 (*
6989 PutVarHeap - assigns ArrayRef field with value.
6990 *)
6991
6992 PROCEDURE PutVarHeap (sym: CARDINAL; value: BOOLEAN) ;
6993 VAR
6994 pSym: PtrToSymbol ;
6995 BEGIN
6996 pSym := GetPsym(sym) ;
6997 WITH pSym^ DO
6998 CASE SymbolType OF
6999
7000 VarSym: Var.Heap := value
7001
7002 ELSE
7003 InternalError ('expecting VarSym')
7004 END
7005 END
7006 END PutVarHeap ;
7007
7008
7009 (*
7010 IsVarHeap - returns ArrayRef field value.
7011 *)
7012
7013 PROCEDURE IsVarHeap (sym: CARDINAL) : BOOLEAN ;
7014 VAR
7015 pSym: PtrToSymbol ;
7016 BEGIN
7017 pSym := GetPsym(sym) ;
7018 WITH pSym^ DO
7019 CASE SymbolType OF
7020
7021 VarSym: RETURN (Var.Heap)
7022
7023 ELSE
7024 InternalError ('expecting VarSym')
7025 END
7026 END
7027 END IsVarHeap ;
7028
7029
7030 (*
7031 PutFieldRecord - places a field, FieldName and FieldType into a record, Sym.
7032 VarSym is a optional varient symbol which can be returned
7033 by a call to GetVarient(fieldsymbol). The created field
7034 is returned.
7035 *)
7036
7037 PROCEDURE PutFieldRecord (Sym: CARDINAL;
7038 FieldName: Name; FieldType: CARDINAL;
7039 VarSym: CARDINAL) : CARDINAL ;
7040 VAR
7041 oSym,
7042 pSym : PtrToSymbol ;
7043 esym,
7044 ParSym,
7045 SonSym: CARDINAL ;
7046 BEGIN
7047 NewSym(SonSym) ; (* Cannot be used before declared since use occurs *)
7048 (* in pass 3 and it will be declared in pass 2. *)
7049 (* Fill in the SonSym and connect it to its brothers (if any) and *)
7050 (* ensure that it is connected its parent. *)
7051 pSym := GetPsym(Sym) ;
7052 WITH pSym^ DO
7053 CASE SymbolType OF
7054
7055 RecordSym : WITH Record DO
7056 PutItemIntoList(ListOfSons, SonSym) ;
7057 Assert(IsItemInList(Record.ListOfSons, SonSym)) ;
7058 (*
7059 n := NoOfItemsInList(ListOfSons) ;
7060 printf3('record %d no of fields in ListOfSons = %d, field %d\n', Sym, n, SonSym) ;
7061 *)
7062 (* Ensure that the Field is in the Parents Local Symbols *)
7063 IF FieldName#NulName
7064 THEN
7065 IF GetSymKey(LocalSymbols, FieldName)=NulKey
7066 THEN
7067 PutSymKey(LocalSymbols, FieldName, SonSym)
7068 ELSE
7069 esym := GetSymKey(LocalSymbols, FieldName) ;
7070 MetaErrors1('field record {%1Dad} has already been declared',
7071 'field record duplicate', esym)
7072 END
7073 END
7074 END ;
7075 CheckRecordConsistency(Sym) |
7076 VarientFieldSym : WITH VarientField DO
7077 PutItemIntoList(ListOfSons, SonSym) ;
7078 ParSym := GetRecord(Parent)
7079 END ;
7080 oSym := GetPsym(ParSym) ;
7081 Assert(oSym^.SymbolType=RecordSym) ;
7082 IF FieldName#NulName
7083 THEN
7084 oSym := GetPsym(ParSym) ;
7085 PutSymKey(oSym^.Record.LocalSymbols, FieldName, SonSym)
7086 END
7087
7088 ELSE
7089 InternalError ('expecting Record symbol')
7090 END
7091 END ;
7092 (* Fill in SonSym *)
7093 oSym := GetPsym(SonSym) ;
7094 WITH oSym^ DO
7095 SymbolType := RecordFieldSym ;
7096 WITH RecordField DO
7097 Type := FieldType ;
7098 name := FieldName ;
7099 Tag := FALSE ;
7100 Parent := Sym ;
7101 Varient := VarSym ;
7102 Align := NulSym ;
7103 Used := TRUE ;
7104 DeclPacked := FALSE ; (* not known as packed (yet). *)
7105 DeclResolved := FALSE ;
7106 Scope := GetScope(Sym) ;
7107 Size := InitValue() ;
7108 Offset := InitValue() ;
7109 InitWhereDeclared(At)
7110 END
7111 END ;
7112 RETURN( SonSym )
7113 END PutFieldRecord ;
7114
7115
7116 (*
7117 MakeFieldVarient - returns a FieldVarient symbol which has been
7118 assigned to the Varient symbol, Sym.
7119 *)
7120
7121 PROCEDURE MakeFieldVarient (n: Name; Sym: CARDINAL) : CARDINAL ;
7122 VAR
7123 pSym : PtrToSymbol ;
7124 SonSym: CARDINAL ;
7125 BEGIN
7126 NewSym(SonSym) ;
7127 (*
7128 IF NoOfItemsInList(FreeFVarientList)=0
7129 THEN
7130 NewSym(SonSym)
7131 ELSE
7132 SonSym := GetItemFromList(FreeFVarientList, 1) ;
7133 RemoveItemFromList(FreeFVarientList, SonSym)
7134 END ;
7135 *)
7136 (* Fill in Sym *)
7137 pSym := GetPsym(SonSym) ;
7138 WITH pSym^ DO
7139 SymbolType := VarientFieldSym ;
7140 WITH VarientField DO
7141 name := n ;
7142 InitList(ListOfSons) ;
7143 Parent := GetRecord(Sym) ;
7144 Varient := NulSym ;
7145 Size := InitValue() ;
7146 Offset := InitValue() ;
7147 DeclPacked := FALSE ;
7148 DeclResolved := FALSE ;
7149 Scope := GetCurrentScope() ;
7150 InitWhereDeclared(At)
7151 END
7152 END ;
7153 RETURN( SonSym )
7154 END MakeFieldVarient ;
7155
7156
7157 (*
7158 PutFieldVarient - places the field varient, Field, as a brother to, the
7159 varient symbol, sym, and also tells Field that its varient
7160 parent is Sym.
7161 *)
7162
7163 PROCEDURE PutFieldVarient (Field, Sym: CARDINAL) ;
7164 VAR
7165 pSym: PtrToSymbol ;
7166 BEGIN
7167 Assert(IsVarient(Sym)) ;
7168 Assert(IsFieldVarient(Field)) ;
7169 pSym := GetPsym(Sym) ;
7170 WITH pSym^ DO
7171 CASE SymbolType OF
7172
7173 VarientSym : IncludeItemIntoList(Varient.ListOfSons, Field)
7174
7175 ELSE
7176 InternalError ('expecting Varient symbol')
7177 END
7178 END ;
7179 pSym := GetPsym(Field) ;
7180 WITH pSym^ DO
7181 CASE SymbolType OF
7182
7183 VarientFieldSym : VarientField.Varient := Sym
7184
7185 ELSE
7186 InternalError ('expecting VarientField symbol')
7187 END
7188 END ;
7189 (* PutItemIntoList(UsedFVarientList, Field) *)
7190 END PutFieldVarient ;
7191
7192
7193 (*
7194 GetVarient - returns the varient symbol associated with the
7195 record or varient field symbol, Field.
7196 *)
7197
7198 PROCEDURE GetVarient (Field: CARDINAL) : CARDINAL ;
7199 VAR
7200 pSym: PtrToSymbol ;
7201 BEGIN
7202 pSym := GetPsym(Field) ;
7203 WITH pSym^ DO
7204 CASE SymbolType OF
7205
7206 VarientFieldSym : RETURN( VarientField.Varient ) |
7207 RecordFieldSym : RETURN( RecordField.Varient ) |
7208 VarientSym : RETURN( Varient.Varient )
7209
7210 ELSE
7211 RETURN( NulSym )
7212 END
7213 END
7214 END GetVarient ;
7215
7216
7217 (*
7218 EnsureOrder - providing that both symbols, a, and, b, exist in
7219 list, l. Ensure that, b, is placed after a.
7220 *)
7221
7222 PROCEDURE EnsureOrder (l: List; a, b: CARDINAL) ;
7223 VAR
7224 n: CARDINAL ;
7225 BEGIN
7226 n := NoOfItemsInList(l) ;
7227 IF IsItemInList(l, a) AND IsItemInList(l, b)
7228 THEN
7229 RemoveItemFromList(l, b) ;
7230 IncludeItemIntoList(l, b)
7231 END ;
7232 Assert(n=NoOfItemsInList(l))
7233 END EnsureOrder ;
7234
7235
7236 VAR
7237 recordConsist: CARDINAL ; (* is used by CheckRecordConsistency and friends. *)
7238
7239
7240 (*
7241 DumpSons -
7242 *)
7243
7244 PROCEDURE DumpSons (sym: CARDINAL) ;
7245 VAR
7246 pSym : PtrToSymbol ;
7247 f, n, i: CARDINAL ;
7248 BEGIN
7249 pSym := GetPsym(sym) ;
7250 WITH pSym^ DO
7251 CASE SymbolType OF
7252
7253 RecordSym: n := NoOfItemsInList(Record.ListOfSons) ;
7254 i := 1 ;
7255 WHILE i<=n DO
7256 f := GetItemFromList(Record.ListOfSons, i) ;
7257 printf3('record %d field %d is %d\n', sym, i, f) ;
7258 INC(i)
7259 END
7260
7261 ELSE
7262 InternalError ('expecting record symbol')
7263 END
7264 END
7265 END DumpSons ;
7266
7267
7268
7269 (*
7270 CheckListOfSons - checks to see that sym, is present in, recordConsist, ListOfSons.
7271 *)
7272
7273 PROCEDURE CheckListOfSons (sym: WORD) ;
7274 VAR
7275 pSym: PtrToSymbol ;
7276 BEGIN
7277 pSym := GetPsym(recordConsist) ;
7278 WITH pSym^ DO
7279 CASE SymbolType OF
7280
7281 RecordSym: IF NOT IsItemInList(Record.ListOfSons, sym)
7282 THEN
7283 DumpSons(recordConsist) ;
7284 MetaError1('internal error: expecting {%1ad} to exist in record ListOfSons', sym)
7285 END
7286
7287 ELSE
7288 InternalError ('expecting record symbol')
7289 END
7290 END
7291 END CheckListOfSons ;
7292
7293
7294 (*
7295 CheckRecordConsistency -
7296 *)
7297
7298 PROCEDURE CheckRecordConsistency (sym: CARDINAL) ;
7299 VAR
7300 pSym: PtrToSymbol ;
7301 BEGIN
7302 RETURN ;
7303 pSym := GetPsym(sym) ;
7304 WITH pSym^ DO
7305 CASE SymbolType OF
7306
7307 RecordSym: recordConsist := sym ;
7308 WITH Record DO
7309 ForeachNodeDo(LocalSymbols, CheckListOfSons)
7310 END |
7311
7312 ELSE
7313 InternalError ('record symbol expected')
7314 END
7315 END
7316 END CheckRecordConsistency ;
7317
7318
7319 (*
7320 IsEmptyFieldVarient - returns TRUE if the field variant has
7321 no fields. This will occur then the
7322 compiler constructs 'else end' variants.
7323 *)
7324
7325 PROCEDURE IsEmptyFieldVarient (sym: CARDINAL) : BOOLEAN ;
7326 VAR
7327 pSym: PtrToSymbol ;
7328 BEGIN
7329 pSym := GetPsym(sym) ;
7330 WITH pSym^ DO
7331 CASE SymbolType OF
7332
7333 VarientFieldSym: RETURN( NoOfItemsInList(VarientField.ListOfSons)=0 )
7334
7335 ELSE
7336 InternalError ('varient field symbol expected')
7337 END
7338 END
7339 END IsEmptyFieldVarient ;
7340
7341
7342 (*
7343 IsRecordFieldAVarientTag - returns TRUE if record field, sym, is
7344 a varient tag.
7345 *)
7346
7347 PROCEDURE IsRecordFieldAVarientTag (sym: CARDINAL) : BOOLEAN ;
7348 VAR
7349 pSym: PtrToSymbol ;
7350 BEGIN
7351 IF IsRecordField(sym)
7352 THEN
7353 pSym := GetPsym(sym) ;
7354 RETURN( pSym^.RecordField.Tag )
7355 ELSE
7356 InternalError ('record field symbol expected')
7357 END
7358 END IsRecordFieldAVarientTag ;
7359
7360
7361 (*
7362 PutVarientTag - places, Tag, into varient, Sym.
7363 *)
7364
7365 PROCEDURE PutVarientTag (Sym, Tag: CARDINAL) ;
7366 VAR
7367 pSym : PtrToSymbol ;
7368 parent: CARDINAL ;
7369 BEGIN
7370 pSym := GetPsym(Sym) ;
7371 WITH pSym^ DO
7372 CASE SymbolType OF
7373
7374 VarientSym: Varient.tag := Tag
7375
7376 ELSE
7377 InternalError ('varient symbol expected')
7378 END
7379 END ;
7380 (* now ensure that if Tag is a RecordField then it must be
7381 placed before the varient symbol in its parent ListOfSons.
7382 This allows M2GCCDeclare to declare record fields in order
7383 and preserve the order of fields. Otherwise it will add the
7384 tag field after the C union. *)
7385 IF IsRecordField(Tag)
7386 THEN
7387 pSym := GetPsym(Tag) ;
7388 pSym^.RecordField.Tag := TRUE ;
7389 parent := GetParent(Sym) ;
7390 pSym := GetPsym(parent) ;
7391 WITH pSym^ DO
7392 CASE SymbolType OF
7393
7394 ErrorSym: |
7395 VarientSym : EnsureOrder(Varient.ListOfSons, Tag, Sym) |
7396 VarientFieldSym: EnsureOrder(VarientField.ListOfSons, Tag, Sym) |
7397 RecordSym : EnsureOrder(Record.ListOfSons, Tag, Sym) ;
7398 CheckRecordConsistency(parent)
7399
7400 ELSE
7401 InternalError ('not expecting this symbol type')
7402 END
7403 END
7404 END
7405 END PutVarientTag ;
7406
7407
7408 (*
7409 GetVarientTag - returns the varient tag from, Sym.
7410 *)
7411
7412 PROCEDURE GetVarientTag (Sym: CARDINAL) : CARDINAL ;
7413 VAR
7414 pSym: PtrToSymbol ;
7415 BEGIN
7416 pSym := GetPsym(Sym) ;
7417 WITH pSym^ DO
7418 CASE SymbolType OF
7419
7420 VarientSym: RETURN( Varient.tag )
7421
7422 ELSE
7423 InternalError ('varient symbol expected')
7424 END
7425 END
7426 END GetVarientTag ;
7427
7428
7429 (*
7430 IsFieldVarient - returns true if the symbol, Sym, is a
7431 varient field.
7432 *)
7433
7434 PROCEDURE IsFieldVarient (Sym: CARDINAL) : BOOLEAN ;
7435 VAR
7436 pSym: PtrToSymbol ;
7437 BEGIN
7438 pSym := GetPsym(Sym) ;
7439 RETURN( pSym^.SymbolType=VarientFieldSym )
7440 END IsFieldVarient ;
7441
7442
7443 (*
7444 IsFieldEnumeration - returns true if the symbol, Sym, is an
7445 enumeration field.
7446 *)
7447
7448 PROCEDURE IsFieldEnumeration (Sym: CARDINAL) : BOOLEAN ;
7449 VAR
7450 pSym: PtrToSymbol ;
7451 BEGIN
7452 pSym := GetPsym(Sym) ;
7453 RETURN( pSym^.SymbolType=EnumerationFieldSym )
7454 END IsFieldEnumeration ;
7455
7456
7457 (*
7458 IsVarient - returns true if the symbol, Sym, is a
7459 varient symbol.
7460 *)
7461
7462 PROCEDURE IsVarient (Sym: CARDINAL) : BOOLEAN ;
7463 VAR
7464 pSym: PtrToSymbol ;
7465 BEGIN
7466 pSym := GetPsym(Sym) ;
7467 RETURN( pSym^.SymbolType=VarientSym )
7468 END IsVarient ;
7469
7470
7471 (*
7472 PutUnused - sets, sym, as unused. This is a gm2 pragma.
7473 *)
7474
7475 PROCEDURE PutUnused (sym: CARDINAL) ;
7476 VAR
7477 pSym: PtrToSymbol ;
7478 BEGIN
7479 pSym := GetPsym(sym) ;
7480 WITH pSym^ DO
7481 CASE SymbolType OF
7482
7483 RecordFieldSym: RecordField.Used := FALSE
7484
7485 ELSE
7486 MetaError1("cannot use pragma 'unused' on symbol {%1ad}", sym)
7487 END
7488 END
7489 END PutUnused ;
7490
7491
7492 (*
7493 IsUnused - returns TRUE if the symbol was declared as unused with a
7494 gm2 pragma.
7495 *)
7496
7497 PROCEDURE IsUnused (sym: CARDINAL) : BOOLEAN ;
7498 VAR
7499 pSym: PtrToSymbol ;
7500 BEGIN
7501 pSym := GetPsym(sym) ;
7502 WITH pSym^ DO
7503 CASE SymbolType OF
7504
7505 RecordFieldSym: RETURN( NOT RecordField.Used )
7506
7507 ELSE
7508 InternalError ('expecting a record field symbol')
7509 END
7510 END
7511 END IsUnused ;
7512
7513
7514 (*
7515 PutFieldEnumeration - places a field into the enumeration type
7516 Sym. The field has a name FieldName and a
7517 value FieldVal.
7518 *)
7519
7520 PROCEDURE PutFieldEnumeration (tok: CARDINAL; Sym: CARDINAL; FieldName: Name) ;
7521 VAR
7522 oSym,
7523 pSym : PtrToSymbol ;
7524 s : String ;
7525 Field: CARDINAL ;
7526 BEGIN
7527 Field := CheckForHiddenType(FieldName) ;
7528 IF Field=NulSym
7529 THEN
7530 Field := DeclareSym (tok, FieldName)
7531 END ;
7532 IF NOT IsError(Field)
7533 THEN
7534 pSym := GetPsym(Field) ;
7535 WITH pSym^ DO
7536 SymbolType := EnumerationFieldSym ;
7537 WITH EnumerationField DO
7538 name := FieldName ; (* Index into name array, name *)
7539 (* of type. *)
7540 oSym := GetPsym(Sym) ;
7541 PushCard(oSym^.Enumeration.NoOfElements) ;
7542 Value := InitValue() ;
7543 PopInto(Value) ;
7544 Type := Sym ;
7545 Scope := GetCurrentScope() ;
7546 InitWhereDeclaredTok (tok, At) (* Declared here *)
7547 END
7548 END ;
7549 pSym := GetPsym(Sym) ;
7550 WITH pSym^ DO
7551 CASE SymbolType OF
7552
7553 EnumerationSym: WITH Enumeration DO
7554 INC(NoOfElements) ;
7555 IF GetSymKey(LocalSymbols, FieldName)#NulSym
7556 THEN
7557 s := Mark(InitStringCharStar(KeyToCharStar(FieldName))) ;
7558 AlreadyDeclaredError(Sprintf1(Mark(InitString('enumeration field (%s) is already declared elsewhere, use a different name or remove the declaration')), s),
7559 FieldName,
7560 GetDeclaredMod(GetSymKey(LocalSymbols, FieldName)))
7561 ELSE
7562 PutSymKey(LocalSymbols, FieldName, Field) ;
7563 IncludeItemIntoList (ListOfFields, Field)
7564 END
7565 END
7566
7567 ELSE
7568 InternalError ('expecting Sym=Enumeration')
7569 END
7570 END
7571 END
7572 END PutFieldEnumeration ;
7573
7574
7575 (*
7576 PutType - gives a type symbol Sym type TypeSymbol.
7577 *)
7578
7579 PROCEDURE PutType (Sym: CARDINAL; TypeSymbol: CARDINAL) ;
7580 VAR
7581 pSym: PtrToSymbol ;
7582 BEGIN
7583 IF TypeSymbol=Sym
7584 THEN
7585 InternalError ('not expecting a type to be declared as itself')
7586 END ;
7587 pSym := GetPsym(Sym) ;
7588 WITH pSym^ DO
7589 CASE SymbolType OF
7590
7591 ErrorSym: |
7592 TypeSym : Type.Type := TypeSymbol
7593
7594 ELSE
7595 InternalError ('expecting a Type symbol')
7596 END
7597 END
7598 END PutType ;
7599
7600
7601 (*
7602 IsDefImp - returns true is the Sym is a DefImp symbol.
7603 Definition/Implementation module symbol.
7604 *)
7605
7606 PROCEDURE IsDefImp (Sym: CARDINAL) : BOOLEAN ;
7607 VAR
7608 pSym: PtrToSymbol ;
7609 BEGIN
7610 pSym := GetPsym(Sym) ;
7611 RETURN( pSym^.SymbolType=DefImpSym )
7612 END IsDefImp ;
7613
7614
7615 (*
7616 IsModule - returns true is the Sym is a Module symbol.
7617 Program module symbol.
7618 *)
7619
7620 PROCEDURE IsModule (Sym: CARDINAL) : BOOLEAN ;
7621 VAR
7622 pSym: PtrToSymbol ;
7623 BEGIN
7624 pSym := GetPsym(Sym) ;
7625 RETURN( pSym^.SymbolType=ModuleSym )
7626 END IsModule ;
7627
7628
7629 (*
7630 IsInnerModule - returns true if the symbol, Sym, is an inner module.
7631 *)
7632
7633 PROCEDURE IsInnerModule (Sym: CARDINAL) : BOOLEAN ;
7634 BEGIN
7635 IF IsModule(Sym)
7636 THEN
7637 RETURN( GetScope(Sym)#NulSym )
7638 ELSE
7639 RETURN( FALSE )
7640 END
7641 END IsInnerModule ;
7642
7643
7644 (*
7645 GetSymName - returns the symbol name.
7646 *)
7647
7648 PROCEDURE GetSymName (Sym: CARDINAL) : Name ;
7649 VAR
7650 pSym: PtrToSymbol ;
7651 n : Name ;
7652 BEGIN
7653 IF Sym=NulSym
7654 THEN
7655 n := NulKey
7656 ELSE
7657 pSym := GetPsym(Sym) ;
7658 WITH pSym^ DO
7659 CASE SymbolType OF
7660
7661 ErrorSym : n := Error.name |
7662 ObjectSym : n := Object.name |
7663 DefImpSym : n := DefImp.name |
7664 ModuleSym : n := Module.name |
7665 TypeSym : n := Type.name |
7666 VarSym : n := Var.name |
7667 ConstLitSym : n := ConstLit.name |
7668 ConstVarSym : n := ConstVar.name |
7669 ConstStringSym : n := ConstString.name |
7670 EnumerationSym : n := Enumeration.name |
7671 EnumerationFieldSym : n := EnumerationField.name |
7672 UndefinedSym : n := Undefined.name |
7673 ProcedureSym : n := Procedure.name |
7674 ProcTypeSym : n := ProcType.name |
7675 RecordFieldSym : n := RecordField.name |
7676 RecordSym : n := Record.name |
7677 VarientSym : n := NulName |
7678 VarientFieldSym : n := VarientField.name |
7679 VarParamSym : n := VarParam.name |
7680 ParamSym : n := Param.name |
7681 PointerSym : n := Pointer.name |
7682 ArraySym : n := Array.name |
7683 UnboundedSym : n := NulName |
7684 SubrangeSym : n := Subrange.name |
7685 SetSym : n := Set.name |
7686 SubscriptSym : n := NulName |
7687 DummySym : n := NulName |
7688 PartialUnboundedSym : n := GetSymName(PartialUnbounded.Type) |
7689 TupleSym : n := NulName |
7690 GnuAsmSym : n := NulName |
7691 InterfaceSym : n := NulName |
7692 ImportSym : n := NulName |
7693 ImportStatementSym : n := NulName
7694
7695 ELSE
7696 InternalError ('unexpected symbol type')
7697 END
7698 END
7699 END ;
7700 RETURN( n )
7701 END GetSymName ;
7702
7703
7704 (*
7705 PutConstVarTemporary - indicates that constant, sym, is a temporary.
7706 *)
7707
7708 PROCEDURE PutConstVarTemporary (sym: CARDINAL) ;
7709 VAR
7710 pSym: PtrToSymbol ;
7711 BEGIN
7712 pSym := GetPsym(sym) ;
7713 WITH pSym^ DO
7714 CASE SymbolType OF
7715
7716 ConstVarSym: ConstVar.IsTemp := TRUE
7717
7718 ELSE
7719 InternalError ('expecting a Var symbol')
7720 END
7721 END
7722 END PutConstVarTemporary ;
7723
7724
7725 (*
7726 buildTemporary - builds the temporary filling in componentRef, record and sets mode.
7727 *)
7728
7729 PROCEDURE buildTemporary (tok: CARDINAL;
7730 Mode: ModeOfAddr; componentRef: BOOLEAN; record: CARDINAL) : CARDINAL ;
7731 VAR
7732 pSym: PtrToSymbol ;
7733 s : String ;
7734 Sym : CARDINAL ;
7735 BEGIN
7736 INC(TemporaryNo) ;
7737 (* Make the name *)
7738 s := Sprintf1(Mark(InitString('_T%d')), TemporaryNo) ;
7739 IF Mode=ImmediateValue
7740 THEN
7741 Sym := MakeConstVar(tok, makekey(string(s))) ;
7742 PutConstVarTemporary(Sym)
7743 ELSE
7744 Sym := MakeVar(tok, makekey(string(s))) ;
7745 pSym := GetPsym(Sym) ;
7746 WITH pSym^ DO
7747 CASE SymbolType OF
7748
7749 VarSym : Var.AddrMode := Mode ;
7750 Var.IsComponentRef := componentRef ;
7751 Var.IsTemp := TRUE ; (* Variable is a temporary var *)
7752 IF componentRef
7753 THEN
7754 Var.list := Indexing.InitIndex(1) ;
7755 PutIntoIndex(Var.list, 1, record)
7756 END ;
7757 InitWhereDeclaredTok(tok, Var.At) ; (* Declared here *)
7758 InitWhereFirstUsedTok(tok, Var.At) ; (* Where symbol first used. *)
7759
7760 ELSE
7761 InternalError ('expecting a Var symbol')
7762 END
7763 END
7764 END ;
7765 s := KillString(s) ;
7766 RETURN Sym
7767 END buildTemporary ;
7768
7769
7770 (*
7771 MakeComponentRef - use, sym, to reference, field, sym is returned.
7772 *)
7773
7774 PROCEDURE MakeComponentRef (sym: CARDINAL; field: CARDINAL) : CARDINAL ;
7775 VAR
7776 pSym: PtrToSymbol ;
7777 high: CARDINAL ;
7778 BEGIN
7779 pSym := GetPsym (sym) ;
7780 WITH pSym^ DO
7781 CASE SymbolType OF
7782
7783 VarSym: IF NOT Var.IsTemp
7784 THEN
7785 InternalError ('variable must be a temporary')
7786 ELSIF Var.IsComponentRef
7787 THEN
7788 high := Indexing.HighIndice (Var.list) ;
7789 PutIntoIndex (Var.list, high+1, field)
7790 ELSE
7791 InternalError ('temporary is not a component reference')
7792 END
7793
7794 ELSE
7795 InternalError ('expecting a variable symbol')
7796 END
7797 END ;
7798 RETURN( sym )
7799 END MakeComponentRef ;
7800
7801
7802 (*
7803 MakeComponentRecord - make a temporary which will be used to reference and field
7804 (or sub field) of record.
7805 *)
7806
7807 PROCEDURE MakeComponentRecord (tok: CARDINAL; Mode: ModeOfAddr; record: CARDINAL) : CARDINAL ;
7808 BEGIN
7809 RETURN buildTemporary (tok, Mode, TRUE, record)
7810 END MakeComponentRecord ;
7811
7812
7813 (*
7814 IsComponent - returns TRUE if symbol, sym, is a temporary and a component
7815 reference.
7816 *)
7817
7818 PROCEDURE IsComponent (sym: CARDINAL) : BOOLEAN ;
7819 VAR
7820 pSym: PtrToSymbol ;
7821 BEGIN
7822 pSym := GetPsym(sym) ;
7823 WITH pSym^ DO
7824 CASE SymbolType OF
7825
7826 VarSym: RETURN( Var.IsComponentRef )
7827
7828 ELSE
7829 RETURN( FALSE )
7830 END
7831 END
7832 END IsComponent ;
7833
7834
7835 (*
7836 MakeTemporary - Makes a new temporary variable at the highest real scope.
7837 The addressing mode of the temporary is set to NoValue.
7838 *)
7839
7840 PROCEDURE MakeTemporary (tok: CARDINAL; Mode: ModeOfAddr) : CARDINAL ;
7841 BEGIN
7842 RETURN buildTemporary (tok, Mode, FALSE, NulSym)
7843 END MakeTemporary ;
7844
7845
7846 (*
7847 MakeTemporaryFromExpressions - makes a new temporary variable at the
7848 highest real scope. The addressing
7849 mode of the temporary is set and the
7850 type is determined by expressions,
7851 e1 and e2.
7852 *)
7853
7854 PROCEDURE MakeTemporaryFromExpressions (tok: CARDINAL;
7855 e1, e2: CARDINAL;
7856 mode: ModeOfAddr) : CARDINAL ;
7857 VAR
7858 pSym: PtrToSymbol ;
7859 s : String ;
7860 t,
7861 Sym : CARDINAL ;
7862 BEGIN
7863 INC(TemporaryNo) ;
7864 (* Make the name *)
7865 s := Sprintf1(Mark(InitString('_T%d')), TemporaryNo) ;
7866 IF mode=ImmediateValue
7867 THEN
7868 Sym := MakeConstVar(tok, makekey(string(s))) ;
7869 IF IsConstructor(e1)
7870 THEN
7871 PutConstructor(Sym) ;
7872 PutConstructorFrom(Sym, e1)
7873 ELSIF IsConstructor(e2)
7874 THEN
7875 PutConstructor(Sym) ;
7876 PutConstructorFrom(Sym, e2)
7877 ELSE
7878 PutVar(Sym, MixTypes(GetType(e1), GetType(e2), tok))
7879 END ;
7880 PutConstVarTemporary(Sym)
7881 ELSE
7882 Sym := MakeVar(tok, makekey(string(s))) ;
7883 pSym := GetPsym(Sym) ;
7884 WITH pSym^ DO
7885 CASE SymbolType OF
7886
7887 VarSym : Var.AddrMode := mode ;
7888 Var.IsComponentRef := FALSE ;
7889 Var.IsTemp := TRUE ; (* Variable is a temporary var *)
7890 InitWhereDeclaredTok(tok, Var.At)
7891 (* Declared here *)
7892
7893 ELSE
7894 InternalError ('expecting a Var symbol')
7895 END
7896 END ;
7897 t := MixTypes(GetType(e1), GetType(e2), tok) ;
7898 IF t#NulSym
7899 THEN
7900 Assert(NOT IsConstructor(t)) ;
7901 PutVar(Sym, t)
7902 END
7903 END ;
7904 s := KillString(s) ;
7905 RETURN( Sym )
7906 END MakeTemporaryFromExpressions ;
7907
7908
7909 (*
7910 MakeTemporaryFromExpression - makes a new temporary variable at the
7911 highest real scope. The addressing
7912 mode of the temporary is set and the
7913 type is determined by expressions, e.
7914 *)
7915
7916 PROCEDURE MakeTemporaryFromExpression (tok: CARDINAL;
7917 e: CARDINAL;
7918 mode: ModeOfAddr) : CARDINAL ;
7919 BEGIN
7920 RETURN MakeTemporaryFromExpressions (tok, e, e, mode)
7921 END MakeTemporaryFromExpression ;
7922
7923
7924 (*
7925 PutMode - Puts the addressing mode, SymMode, into symbol Sym.
7926 The mode may only be altered if the mode
7927 is None.
7928 *)
7929
7930 PROCEDURE PutMode (Sym: CARDINAL; SymMode: ModeOfAddr) ;
7931 VAR
7932 pSym: PtrToSymbol ;
7933 BEGIN
7934 pSym := GetPsym(Sym) ;
7935 WITH pSym^ DO
7936 CASE SymbolType OF
7937
7938 ErrorSym: |
7939 VarSym : Var.AddrMode := SymMode
7940
7941 ELSE
7942 InternalError ('Expecting VarSym')
7943 END
7944 END
7945 END PutMode ;
7946
7947
7948 (*
7949 GetMode - Returns the addressing mode of a symbol.
7950 *)
7951
7952 PROCEDURE GetMode (Sym: CARDINAL) : ModeOfAddr ;
7953 VAR
7954 pSym: PtrToSymbol ;
7955 BEGIN
7956 pSym := GetPsym(Sym) ;
7957 WITH pSym^ DO
7958 CASE SymbolType OF
7959
7960 ErrorSym : ErrorAbort0('') |
7961 VarSym : RETURN( Var.AddrMode ) |
7962 ConstLitSym : RETURN( ImmediateValue ) |
7963 ConstVarSym : RETURN( ImmediateValue ) |
7964 ConstStringSym : RETURN( ImmediateValue ) |
7965 EnumerationFieldSym: RETURN( ImmediateValue ) |
7966 ProcedureSym : RETURN( ImmediateValue ) |
7967 RecordFieldSym : RETURN( ImmediateValue ) |
7968 VarientFieldSym : RETURN( ImmediateValue ) |
7969 TypeSym : RETURN( NoValue ) |
7970 ArraySym : RETURN( NoValue ) |
7971 SubrangeSym : RETURN( NoValue ) |
7972 EnumerationSym : RETURN( NoValue ) |
7973 RecordSym : RETURN( NoValue ) |
7974 PointerSym : RETURN( NoValue ) |
7975 SetSym : RETURN( NoValue ) |
7976 ProcTypeSym : RETURN( NoValue ) |
7977 UnboundedSym : RETURN( NoValue ) |
7978 UndefinedSym : RETURN( NoValue )
7979
7980 ELSE
7981 InternalError ('not expecting this type')
7982 END
7983 END
7984 END GetMode ;
7985
7986
7987 (*
7988 RenameSym - renames a symbol, Sym, with SymName.
7989 It also checks the unknown tree for a symbol
7990 with this new name. Must only be renamed in
7991 the same scope of being declared.
7992 *)
7993
7994 PROCEDURE RenameSym (Sym: CARDINAL; SymName: Name) ;
7995 VAR
7996 pSym: PtrToSymbol ;
7997 BEGIN
7998 IF GetSymName(Sym)=NulName
7999 THEN
8000 pSym := GetPsym(Sym) ;
8001 WITH pSym^ DO
8002 CASE SymbolType OF
8003
8004 ErrorSym : ErrorAbort0('') |
8005 TypeSym : Type.name := SymName |
8006 VarSym : Var.name := SymName |
8007 ConstLitSym : ConstLit.name := SymName |
8008 ConstVarSym : ConstVar.name := SymName |
8009 UndefinedSym : Undefined.name := SymName |
8010 RecordSym : Record.name := SymName |
8011 PointerSym : Pointer.name := SymName
8012
8013 ELSE
8014 InternalError ('not implemented yet')
8015 END
8016 END ;
8017 AddSymToScope(Sym, SymName)
8018 ELSE
8019 InternalError ('old name of symbol must be nul')
8020 END
8021 END RenameSym ;
8022
8023
8024 (*
8025 IsUnknown - returns true is the symbol Sym is unknown.
8026 *)
8027
8028 PROCEDURE IsUnknown (Sym: WORD) : BOOLEAN ;
8029 VAR
8030 pSym: PtrToSymbol ;
8031 BEGIN
8032 CheckLegal (Sym) ;
8033 pSym := GetPsym(Sym) ;
8034 RETURN pSym^.SymbolType=UndefinedSym
8035 END IsUnknown ;
8036
8037
8038 (*
8039 CheckLegal - determines whether the Sym is a legal symbol.
8040 *)
8041
8042 PROCEDURE CheckLegal (Sym: CARDINAL) ;
8043 BEGIN
8044 IF (Sym<1) OR (Sym>FinalSymbol())
8045 THEN
8046 InternalError ('illegal symbol')
8047 END
8048 END CheckLegal ;
8049
8050
8051 (*
8052 CheckForHiddenType - scans the NeedToBeImplemented tree providing
8053 that we are currently compiling an implementation
8054 module. If a symbol is found with TypeName
8055 then its Sym is returned.
8056 Otherwise NulSym is returned.
8057 CheckForHiddenType is called before any type is
8058 created, therefore the compiler allows hidden
8059 types to be implemented using any type.
8060 *)
8061
8062 PROCEDURE CheckForHiddenType (TypeName: Name) : CARDINAL ;
8063 VAR
8064 pSym: PtrToSymbol ;
8065 Sym : CARDINAL ;
8066 BEGIN
8067 Sym := NulSym ;
8068 IF CompilingImplementationModule() AND
8069 IsDefImp(CurrentModule) AND
8070 IsHiddenTypeDeclared(CurrentModule) AND
8071 (TypeName#NulName)
8072 THEN
8073 (* Check to see whether we are declaring a HiddenType. *)
8074 pSym := GetPsym(CurrentModule) ;
8075 WITH pSym^ DO
8076 CASE SymbolType OF
8077
8078 DefImpSym: Sym := GetSymKey(DefImp.NeedToBeImplemented, TypeName)
8079
8080 ELSE
8081 InternalError ('expecting a DefImp symbol')
8082 END
8083 END
8084 END ;
8085 RETURN( Sym )
8086 END CheckForHiddenType ;
8087
8088
8089 (*
8090 IsReallyPointer - returns TRUE is sym is a pointer, address or a
8091 type declared as a pointer or address.
8092 *)
8093
8094 PROCEDURE IsReallyPointer (Sym: CARDINAL) : BOOLEAN ;
8095 BEGIN
8096 IF IsVar(Sym)
8097 THEN
8098 Sym := GetType(Sym)
8099 END ;
8100 Sym := SkipType(Sym) ;
8101 RETURN( IsPointer(Sym) OR (Sym=Address) )
8102 END IsReallyPointer ;
8103
8104
8105 (*
8106 SkipHiddenType - if sym is a TYPE foo = bar
8107 then call SkipType(bar)
8108 else return sym
8109
8110 it does skip over hidden type.
8111 *)
8112
8113 (*
8114 PROCEDURE SkipHiddenType (Sym: CARDINAL) : CARDINAL ;
8115 BEGIN
8116 IF (Sym#NulSym) AND IsType(Sym) AND (GetType(Sym)#NulSym)
8117 THEN
8118 RETURN( SkipType(GetType(Sym)) )
8119 ELSE
8120 RETURN( Sym )
8121 END
8122 END SkipHiddenType ;
8123 *)
8124
8125
8126 (*
8127 IsHiddenReallyPointer - returns TRUE is sym is a pointer, address or a
8128 type declared as a pointer or address.
8129 *)
8130
8131 PROCEDURE IsHiddenReallyPointer (Sym: CARDINAL) : BOOLEAN ;
8132 BEGIN
8133 IF IsVar (Sym)
8134 THEN
8135 Sym := GetType (Sym)
8136 END ;
8137 WHILE (Sym # NulSym) AND IsType (Sym) DO
8138 Sym := SkipType (GetType (Sym))
8139 END ;
8140 RETURN (Sym # NulSym) AND (IsPointer (Sym) OR (Sym = Address))
8141 END IsHiddenReallyPointer ;
8142
8143
8144 (*
8145 CheckHiddenTypeAreAddress - checks to see that any hidden types
8146 which we have declared are actually
8147 of type ADDRESS or map onto a POINTER type.
8148 *)
8149
8150 PROCEDURE CheckHiddenTypeAreAddress ;
8151 VAR
8152 name: Name ;
8153 e : Error ;
8154 sym,
8155 i, n: CARDINAL ;
8156 BEGIN
8157 i := 1 ;
8158 n := NoOfItemsInList(AddressTypes) ;
8159 WHILE i<=n DO
8160 sym := GetItemFromList(AddressTypes, i) ;
8161 IF NOT IsHiddenReallyPointer(sym)
8162 THEN
8163 name := GetSymName(sym) ;
8164 e := NewError(GetDeclaredDef(sym)) ;
8165 ErrorFormat1(e, 'opaque type (%a) should be equivalent to a POINTER or an ADDRESS', name) ;
8166 e := NewError(GetDeclaredMod(sym)) ;
8167 ErrorFormat0(e, 'if you really need a non POINTER type use the -fextended-opaque switch')
8168 END ;
8169 INC(i)
8170 END
8171 END CheckHiddenTypeAreAddress ;
8172
8173
8174 (*
8175 GetLastMainScopeId - returns the, id, containing the last main scope.
8176 *)
8177
8178 (*
8179 PROCEDURE GetLastMainScopeId (id: CARDINAL) : CARDINAL ;
8180 VAR
8181 pCall: PtrToCallFrame ;
8182 sym : CARDINAL ;
8183 BEGIN
8184 IF id>0
8185 THEN
8186 pCall := GetPcall(id) ;
8187 sym := pCall^.Main ;
8188 WHILE id>1 DO
8189 DEC(id) ;
8190 pCall := GetPcall(id) ;
8191 IF sym#pCall^.Main
8192 THEN
8193 RETURN( id )
8194 END
8195 END
8196 END ;
8197 RETURN( 0 )
8198 END GetLastMainScopeId ;
8199 *)
8200
8201
8202 (*
8203 GetDeclareSym - searches for a symbol with a name SymName in the
8204 current and previous scopes.
8205 If the symbol is found then it is returned
8206 else an unknown symbol is returned.
8207 This procedure assumes that SymName is being
8208 declared at this point and therefore it does
8209 not examine the base scope (for pervasive
8210 identifiers).
8211 *)
8212
8213 PROCEDURE GetDeclareSym (tok: CARDINAL; SymName: Name) : CARDINAL ;
8214 VAR
8215 Sym: CARDINAL ;
8216 BEGIN
8217 Sym := GetScopeSym (SymName, FALSE) ; (* must not be allowed to fetch a symbol through a procedure scope *)
8218 IF Sym=NulSym
8219 THEN
8220 Sym := GetSymFromUnknownTree (SymName) ;
8221 IF Sym=NulSym
8222 THEN
8223 (* Make unknown *)
8224 NewSym (Sym) ;
8225 FillInUnknownFields (tok, Sym, SymName) ;
8226 (* Add to unknown tree *)
8227 AddSymToUnknownTree (ScopePtr, SymName, Sym)
8228 (*
8229 ; WriteKey(SymName) ; WriteString(' unknown demanded') ; WriteLn
8230 *)
8231 END
8232 END ;
8233 RETURN Sym
8234 END GetDeclareSym ;
8235
8236
8237 (*
8238 RequestSym - searches for a symbol with a name SymName in the
8239 current and previous scopes.
8240 If the symbol is found then it is returned
8241 else an unknown symbol is returned create at token
8242 position, tok.
8243 This procedure does search the base scope (for
8244 pervasive identifiers).
8245 *)
8246
8247 PROCEDURE RequestSym (tok: CARDINAL; SymName: Name) : CARDINAL ;
8248 VAR
8249 Sym: CARDINAL ;
8250 BEGIN
8251 (*
8252 WriteString('RequestSym for: ') ; WriteKey(SymName) ; WriteLn ;
8253 *)
8254 Sym := GetSym (SymName) ;
8255 IF Sym=NulSym
8256 THEN
8257 Sym := GetSymFromUnknownTree (SymName) ;
8258 IF Sym=NulSym
8259 THEN
8260 (* Make unknown *)
8261 NewSym (Sym) ;
8262 FillInUnknownFields (tok, Sym, SymName) ;
8263 (* Add to unknown tree *)
8264 AddSymToUnknownTree (ScopePtr, SymName, Sym)
8265 (*
8266 ; WriteKey(SymName) ; WriteString(' unknown demanded') ; WriteLn
8267 *)
8268 END
8269 END ;
8270 RETURN( Sym )
8271 END RequestSym ;
8272
8273
8274 (*
8275 PutImported - places a symbol, Sym, into the current main scope.
8276 *)
8277
8278 PROCEDURE PutImported (Sym: CARDINAL) ;
8279 VAR
8280 pSym : PtrToSymbol ;
8281 ModSym: CARDINAL ;
8282 n : Name ;
8283 BEGIN
8284 (*
8285 We have currently imported Sym, now place it into the current module.
8286 *)
8287 ModSym := GetCurrentModuleScope() ;
8288 Assert(IsDefImp(ModSym) OR IsModule(ModSym)) ;
8289 pSym := GetPsym(ModSym) ;
8290 WITH pSym^ DO
8291 CASE SymbolType OF
8292
8293 ModuleSym: IF GetSymKey(Module.ImportTree, GetSymName(Sym))=Sym
8294 THEN
8295 IF Pedantic
8296 THEN
8297 n := GetSymName(Sym) ;
8298 WriteFormat1('symbol (%a) has already been imported', n)
8299 END
8300 ELSIF GetSymKey(Module.ImportTree, GetSymName(Sym))=NulKey
8301 THEN
8302 IF GetSymKey(Module.WhereImported, Sym)=NulKey
8303 THEN
8304 PutSymKey(Module.WhereImported, Sym, GetTokenNo())
8305 END ;
8306 PutSymKey(Module.ImportTree, GetSymName(Sym), Sym) ;
8307 AddSymToModuleScope(ModSym, Sym)
8308 ELSE
8309 n := GetSymName(Sym) ;
8310 WriteFormat1('name clash when trying to import (%a)', n)
8311 END |
8312 DefImpSym: IF GetSymKey(DefImp.ImportTree, GetSymName(Sym))=Sym
8313 THEN
8314 IF Pedantic
8315 THEN
8316 n := GetSymName(Sym) ;
8317 WriteFormat1('symbol (%a) has already been imported', n)
8318 END
8319 ELSIF GetSymKey(DefImp.ImportTree, GetSymName(Sym))=NulKey
8320 THEN
8321 IF GetSymKey(DefImp.WhereImported, Sym)=NulKey
8322 THEN
8323 PutSymKey(DefImp.WhereImported, Sym, GetTokenNo())
8324 END ;
8325 PutSymKey(DefImp.ImportTree, GetSymName(Sym), Sym) ;
8326 AddSymToModuleScope(ModSym, Sym)
8327 ELSE
8328 n := GetSymName(Sym) ;
8329 WriteFormat1('name clash when trying to import (%a)', n)
8330 END
8331
8332 ELSE
8333 InternalError ('expecting a Module or DefImp symbol')
8334 END
8335 END
8336 END PutImported ;
8337
8338
8339 (*
8340 PutIncluded - places a symbol, Sym, into the included list of the
8341 current module.
8342 Symbols that are placed in this list are indirectly declared
8343 by:
8344
8345 IMPORT modulename ;
8346
8347 modulename.identifier
8348 *)
8349
8350 PROCEDURE PutIncluded (Sym: CARDINAL) ;
8351 VAR
8352 pSym : PtrToSymbol ;
8353 ModSym: CARDINAL ;
8354 n1, n2: Name ;
8355 BEGIN
8356 (*
8357 We have referenced Sym, via modulename.Sym
8358 now place it into the current module include list.
8359 *)
8360 ModSym := GetCurrentModuleScope() ;
8361 Assert(IsDefImp(ModSym) OR IsModule(ModSym)) ;
8362 IF DebugUnknowns
8363 THEN
8364 n1 := GetSymName(Sym) ;
8365 n2 := GetSymName(ModSym) ;
8366 printf2('including %a into scope %a\n', n1, n2)
8367 END ;
8368 pSym := GetPsym(ModSym) ;
8369 WITH pSym^ DO
8370 CASE SymbolType OF
8371
8372 ModuleSym: IncludeItemIntoList(Module.IncludeList, Sym) |
8373 DefImpSym: IncludeItemIntoList(DefImp.IncludeList, Sym)
8374
8375 ELSE
8376 InternalError ('expecting a Module or DefImp symbol')
8377 END
8378 END
8379 END PutIncluded ;
8380
8381
8382 (*
8383 PutExported - places a symbol, Sym into the next level out module.
8384 Sym is also placed in the ExportTree of the current inner
8385 module.
8386 *)
8387
8388 PROCEDURE PutExported (Sym: CARDINAL) ;
8389 VAR
8390 pSym: PtrToSymbol ;
8391 BEGIN
8392 (*
8393 WriteString('PutExported') ; WriteLn ;
8394 *)
8395 AddSymToModuleScope(GetLastModuleOrProcedureScope(), Sym) ;
8396 pSym := GetPsym(GetCurrentModuleScope()) ;
8397 WITH pSym^ DO
8398 CASE SymbolType OF
8399
8400 ModuleSym: PutSymKey(Module.ExportTree, GetSymName(Sym), Sym) ;
8401 IF IsUnknown(Sym)
8402 THEN
8403 PutExportUndeclared(GetCurrentModuleScope(), Sym)
8404 END
8405 (*
8406 ; WriteKey(Module.name) ; WriteString(' exports ') ;
8407 ; WriteKey(GetSymName(Sym)) ; WriteLn ;
8408 *)
8409
8410 ELSE
8411 InternalError ('expecting a Module symbol')
8412 END
8413 END
8414 END PutExported ;
8415
8416
8417 (*
8418 PutExportQualified - places a symbol with the name, SymName,
8419 into the export tree of the
8420 Definition module being compiled.
8421 The symbol with name has been EXPORT QUALIFIED
8422 by the definition module and therefore any reference
8423 to this symbol in the code generation phase
8424 will be in the form _Module_Name.
8425 *)
8426
8427 PROCEDURE PutExportQualified (tokenno: CARDINAL; SymName: Name) ;
8428 VAR
8429 pSym : PtrToSymbol ;
8430 n : Name ;
8431 Sym,
8432 ModSym: CARDINAL ;
8433 BEGIN
8434 ModSym := GetCurrentModule () ;
8435 Assert (IsDefImp (ModSym)) ;
8436 Assert (CompilingDefinitionModule () OR
8437 (GetSymName(ModSym) = MakeKey ('SYSTEM'))) ;
8438 (* printf2('module %a exporting %a\n', GetSymName(ModSym), SymName) ; *)
8439 (*
8440 WriteString('1st MODULE ') ; WriteKey(GetSymName(ModSym)) ;
8441 WriteString(' identifier ') ; WriteKey(SymName) ; WriteLn ;
8442 *)
8443 pSym := GetPsym (ModSym) ;
8444 WITH pSym^ DO
8445 CASE SymbolType OF
8446
8447 DefImpSym: WITH DefImp DO
8448 IF (GetSymKey (ExportQualifiedTree, SymName) # NulKey) AND
8449 (GetSymKey (ExportRequest, SymName) = NulKey)
8450 THEN
8451 n := GetSymName(ModSym) ;
8452 WriteFormat2('identifier (%a) has already been exported from MODULE %a',
8453 SymName, n)
8454 ELSIF GetSymKey(ExportRequest, SymName)#NulKey
8455 THEN
8456 Sym := GetSymKey(ExportRequest, SymName) ;
8457 DelSymKey(ExportRequest, SymName) ;
8458 PutSymKey(ExportQualifiedTree, SymName, Sym) ;
8459 PutExportUndeclared (ModSym, Sym)
8460 ELSE
8461 Sym := GetDeclareSym(tokenno, SymName) ;
8462 PutSymKey(ExportQualifiedTree, SymName, Sym) ;
8463 PutExportUndeclared (ModSym, Sym)
8464 END
8465 END
8466
8467 ELSE
8468 InternalError ('expecting a DefImp symbol')
8469 END
8470 END
8471 END PutExportQualified ;
8472
8473
8474 (*
8475 PutExportUnQualified - places a symbol with the name, SymName,
8476 into the export tree of the
8477 Definition module being compiled.
8478 The symbol with Name has been EXPORT UNQUALIFIED
8479 by the definition module and therefore any reference
8480 to this symbol in the code generation phase
8481 will be in the form _Name.
8482 *)
8483
8484 PROCEDURE PutExportUnQualified (tokenno: CARDINAL; SymName: Name) ;
8485 VAR
8486 pSym : PtrToSymbol ;
8487 n : Name ;
8488 Sym,
8489 ModSym: CARDINAL ;
8490 BEGIN
8491 ModSym := GetCurrentModule() ;
8492 Assert(IsDefImp(ModSym)) ;
8493 Assert(CompilingDefinitionModule() OR (GetSymName(ModSym)=MakeKey('SYSTEM'))) ;
8494 pSym := GetPsym(ModSym) ;
8495 WITH pSym^ DO
8496 CASE SymbolType OF
8497
8498 DefImpSym: WITH DefImp DO
8499 IF (GetSymKey(ExportUnQualifiedTree, SymName)#NulKey) AND
8500 (GetSymKey(ExportRequest, SymName)=NulKey)
8501 THEN
8502 n := GetSymName(ModSym) ;
8503 WriteFormat2('identifier (%a) has already been exported from MODULE %a',
8504 SymName, n)
8505 ELSIF GetSymKey(ExportRequest, SymName)#NulKey
8506 THEN
8507 Sym := GetSymKey(ExportRequest, SymName) ;
8508 DelSymKey(ExportRequest, SymName) ;
8509 PutSymKey(ExportUnQualifiedTree, SymName, Sym) ;
8510 PutExportUndeclared(ModSym, Sym)
8511 ELSE
8512 Sym := GetDeclareSym(tokenno, SymName) ;
8513 PutSymKey(ExportUnQualifiedTree, SymName, Sym) ;
8514 PutExportUndeclared(ModSym, Sym)
8515 END
8516 END
8517
8518 ELSE
8519 InternalError ('expecting a DefImp symbol')
8520 END
8521 END
8522 END PutExportUnQualified ;
8523
8524
8525 (*
8526 GetExported - returns the symbol which has a name SymName,
8527 and is exported from the definition module ModSym.
8528
8529 *)
8530
8531 PROCEDURE GetExported (tokenno: CARDINAL;
8532 ModSym: CARDINAL;
8533 SymName: Name) : CARDINAL ;
8534 VAR
8535 pSym: PtrToSymbol ;
8536 Sym : CARDINAL ;
8537 BEGIN
8538 pSym := GetPsym(ModSym) ;
8539 WITH pSym^ DO
8540 CASE SymbolType OF
8541
8542 DefImpSym: Sym := RequestFromDefinition (tokenno, ModSym, SymName) |
8543 ModuleSym: Sym := RequestFromModule (tokenno, ModSym, SymName)
8544
8545 ELSE
8546 InternalError ('expecting a DefImp symbol')
8547 END
8548 END ;
8549 RETURN( Sym )
8550 END GetExported ;
8551
8552
8553 (*
8554 RequestFromModule - returns a symbol from module ModSym with name, SymName.
8555 *)
8556
8557 PROCEDURE RequestFromModule (tok: CARDINAL; ModSym: CARDINAL; SymName: Name) : CARDINAL ;
8558 VAR
8559 pSym: PtrToSymbol ;
8560 Sym : CARDINAL ;
8561 BEGIN
8562 pSym := GetPsym(ModSym) ;
8563 WITH pSym^ DO
8564 CASE SymbolType OF
8565
8566 DefImpSym: WITH DefImp DO
8567 Sym := GetSymKey (LocalSymbols, SymName) ;
8568 IF Sym=NulSym
8569 THEN
8570 Sym := FetchUnknownFromDefImp (tok, ModSym, SymName)
8571 END
8572 END |
8573
8574 ModuleSym: WITH Module DO
8575 Sym := GetSymKey (LocalSymbols, SymName) ;
8576 IF Sym=NulSym
8577 THEN
8578 Sym := FetchUnknownFromModule (tok, ModSym, SymName)
8579 END
8580 END
8581
8582 ELSE
8583 InternalError ('expecting a DefImp or Module symbol')
8584 END
8585 END ;
8586 RETURN( Sym )
8587 END RequestFromModule ;
8588
8589
8590 (*
8591 RequestFromDefinition - returns a symbol from module ModSym with name,
8592 SymName.
8593 *)
8594
8595 PROCEDURE RequestFromDefinition (tok: CARDINAL;
8596 ModSym: CARDINAL; SymName: Name) : CARDINAL ;
8597 VAR
8598 pSym : PtrToSymbol ;
8599 Sym : CARDINAL ;
8600 OldScopePtr: CARDINAL ;
8601 BEGIN
8602 pSym := GetPsym(ModSym) ;
8603 WITH pSym^ DO
8604 CASE SymbolType OF
8605
8606 DefImpSym: WITH DefImp DO
8607 Sym := GetSymKey (ExportQualifiedTree, SymName) ;
8608 IF Sym=NulSym
8609 THEN
8610 Sym := GetSymKey (ExportUnQualifiedTree, SymName) ;
8611 IF Sym=NulSym
8612 THEN
8613 Sym := GetSymKey (ExportRequest, SymName) ;
8614 IF Sym=NulSym
8615 THEN
8616 OldScopePtr := ScopePtr ;
8617 StartScope (ModSym) ;
8618 Sym := GetScopeSym (SymName, TRUE) ;
8619 EndScope ;
8620 Assert (OldScopePtr=ScopePtr) ;
8621 IF Sym=NulSym
8622 THEN
8623 Sym := FetchUnknownFromDefImp (tok, ModSym, SymName)
8624 ELSE
8625 IF IsFieldEnumeration (Sym)
8626 THEN
8627 IF IsExported (ModSym, GetType (Sym))
8628 THEN
8629 RETURN( Sym )
8630 END
8631 END
8632 END ;
8633 PutSymKey (ExportRequest, SymName, Sym)
8634 END
8635 END
8636 END
8637 END
8638
8639 ELSE
8640 InternalError ('expecting a DefImp symbol')
8641 END
8642 END ;
8643 RETURN( Sym )
8644 END RequestFromDefinition ;
8645
8646
8647 (*
8648 PutIncludedByDefinition - places a module symbol, Sym, into the
8649 included list of the current definition module.
8650 *)
8651
8652 PROCEDURE PutIncludedByDefinition (Sym: CARDINAL) ;
8653 VAR
8654 pSym : PtrToSymbol ;
8655 ModSym: CARDINAL ;
8656 BEGIN
8657 ModSym := GetCurrentModuleScope() ;
8658 Assert(IsDefImp(ModSym)) ;
8659 Assert(IsDefImp(Sym)) ;
8660 pSym := GetPsym(ModSym) ;
8661 WITH pSym^ DO
8662 CASE SymbolType OF
8663
8664 DefImpSym: IncludeItemIntoList(DefImp.DefIncludeList, Sym)
8665
8666 ELSE
8667 InternalError ('expecting a DefImp symbol')
8668 END
8669 END
8670 END PutIncludedByDefinition ;
8671
8672
8673 (*
8674 IsIncludedByDefinition - returns TRUE if definition module symbol, Sym, was included
8675 by ModSym's definition module.
8676 *)
8677
8678 PROCEDURE IsIncludedByDefinition (ModSym, Sym: CARDINAL) : BOOLEAN ;
8679 VAR
8680 pSym: PtrToSymbol ;
8681 BEGIN
8682 Assert(IsDefImp(ModSym)) ;
8683 Assert(IsDefImp(Sym)) ;
8684 pSym := GetPsym(ModSym) ;
8685 WITH pSym^ DO
8686 CASE SymbolType OF
8687
8688 DefImpSym: RETURN( IsItemInList(DefImp.DefIncludeList, Sym) )
8689
8690 ELSE
8691 InternalError ('expecting a DefImp symbol')
8692 END
8693 END
8694 END IsIncludedByDefinition ;
8695
8696
8697 (*
8698 GetWhereImported - returns the token number where this symbol
8699 was imported into the current module.
8700 *)
8701
8702 PROCEDURE GetWhereImported (Sym: CARDINAL) : CARDINAL ;
8703 VAR
8704 pSym: PtrToSymbol ;
8705 BEGIN
8706 pSym := GetPsym(GetCurrentModuleScope()) ;
8707 WITH pSym^ DO
8708 CASE SymbolType OF
8709
8710 DefImpSym: RETURN( GetSymKey(DefImp.WhereImported, Sym) ) |
8711 ModuleSym: RETURN( GetSymKey(Module.WhereImported, Sym) )
8712
8713 ELSE
8714 InternalError ('expecting DefImp or Module symbol')
8715 END
8716 END
8717 END GetWhereImported ;
8718
8719
8720 (*
8721 DisplayName - displays the name.
8722 *)
8723
8724 PROCEDURE DisplayName (sym: WORD) ;
8725 BEGIN
8726 printf1(' %a', sym)
8727 END DisplayName ;
8728
8729
8730 (*
8731 DisplaySymbol - displays the name of a symbol
8732 *)
8733
8734 PROCEDURE DisplaySymbol (sym: WORD) ;
8735 VAR
8736 s: String ;
8737 BEGIN
8738 s := Mark(InitStringCharStar(KeyToCharStar(GetSymName(sym)))) ;
8739 printf2(' %s (%d)', s, sym)
8740 END DisplaySymbol ;
8741
8742
8743 (*
8744 DisplayTrees - displays the SymbolTrees for Module symbol, ModSym.
8745 *)
8746
8747 PROCEDURE DisplayTrees (ModSym: CARDINAL) ;
8748 VAR
8749 pSym: PtrToSymbol ;
8750 n : Name ;
8751 BEGIN
8752 n := GetSymName(ModSym) ;
8753 printf1('Symbol trees for module/procedure: %a\n', n) ;
8754 pSym := GetPsym(ModSym) ;
8755 WITH pSym^ DO
8756 CASE SymbolType OF
8757
8758 DefImpSym: WITH DefImp DO
8759 n := GetSymName(ModSym) ;
8760 printf1('%a UndefinedTree', n) ;
8761 ForeachNodeDo(Unresolved, DisplaySymbol) ; printf0('\n') ;
8762 printf1('%a Local symbols', n) ;
8763 ForeachNodeDo(LocalSymbols, DisplaySymbol) ; printf0('\n') ;
8764 printf1('%a ExportRequest', n) ;
8765 ForeachNodeDo(ExportRequest, DisplaySymbol) ; printf0('\n') ;
8766 printf1('%a ExportQualified', n) ;
8767 ForeachNodeDo(ExportQualifiedTree, DisplaySymbol) ; printf0('\n') ;
8768 printf1('%a ExportUnQualified', n) ;
8769 ForeachNodeDo(ExportUnQualifiedTree, DisplaySymbol) ; printf0('\n') ;
8770 printf1('%a ExportUndeclared', n) ;
8771 ForeachNodeDo(ExportUndeclared, DisplaySymbol) ; printf0('\n') ;
8772 printf1('%a DeclaredObjects', n) ;
8773 ForeachNodeDo(NamedObjects, DisplaySymbol) ; printf0('\n') ;
8774 printf1('%a ImportedObjects', n) ;
8775 ForeachNodeDo(NamedImports, DisplayName) ; printf0('\n')
8776 END |
8777 ModuleSym: WITH Module DO
8778 n := GetSymName(ModSym) ;
8779 printf1('%a UndefinedTree', n) ;
8780 ForeachNodeDo(Unresolved, DisplaySymbol) ; printf0('\n') ;
8781 printf1('%a Local symbols', n) ;
8782 ForeachNodeDo(LocalSymbols, DisplaySymbol) ; printf0('\n') ;
8783 printf1('%a ImportTree', n) ;
8784 ForeachNodeDo(ImportTree, DisplaySymbol) ; printf0('\n') ;
8785 printf1('%a ExportTree', n) ;
8786 ForeachNodeDo(ExportTree, DisplaySymbol) ; printf0('\n') ;
8787 printf1('%a ExportUndeclared', n) ;
8788 ForeachNodeDo(ExportUndeclared, DisplaySymbol) ; printf0('\n') ;
8789 printf1('%a DeclaredObjects', n) ;
8790 ForeachNodeDo(NamedObjects, DisplaySymbol) ; printf0('\n') ;
8791 printf1('%a ImportedObjects', n) ;
8792 ForeachNodeDo(NamedImports, DisplayName) ; printf0('\n')
8793 END |
8794 ProcedureSym: WITH Procedure DO
8795 n := GetSymName(ModSym) ;
8796 printf1('%a UndefinedTree', n) ;
8797 ForeachNodeDo(Unresolved, DisplaySymbol) ; printf0('\n') ;
8798 printf1('%a Local symbols', n) ;
8799 ForeachNodeDo(LocalSymbols, DisplaySymbol) ; printf0('\n') ;
8800 printf1('%a DeclaredObjects', n) ;
8801 ForeachNodeDo(NamedObjects, DisplayName) ; printf0('\n')
8802 END
8803
8804 ELSE
8805 InternalError ('expecting DefImp symbol')
8806 END
8807 END
8808 END DisplayTrees ;
8809
8810
8811 (*
8812 FetchUnknownFromModule - returns an Unknown symbol from module, ModSym.
8813 *)
8814
8815 PROCEDURE FetchUnknownFromModule (tok: CARDINAL;
8816 ModSym: CARDINAL;
8817 SymName: Name) : CARDINAL ;
8818 VAR
8819 pSym: PtrToSymbol ;
8820 Sym : CARDINAL ;
8821 BEGIN
8822 pSym := GetPsym (ModSym) ;
8823 WITH pSym^ DO
8824 CASE SymbolType OF
8825 ModuleSym: WITH Module DO
8826 Sym := GetSymKey (Unresolved, SymName) ;
8827 IF Sym=NulSym
8828 THEN
8829 NewSym (Sym) ;
8830 FillInUnknownFields (tok, Sym, SymName) ;
8831 PutSymKey (Unresolved, SymName, Sym)
8832 END
8833 END
8834 ELSE
8835 InternalError ('expecting a Module symbol')
8836 END
8837 END ;
8838 RETURN( Sym )
8839 END FetchUnknownFromModule ;
8840
8841
8842 (*
8843 FetchUnknownFromDefImp - returns an Unknown symbol from module, ModSym.
8844 *)
8845
8846 PROCEDURE FetchUnknownFromDefImp (tok: CARDINAL;
8847 ModSym: CARDINAL;
8848 SymName: Name) : CARDINAL ;
8849 VAR
8850 pSym: PtrToSymbol ;
8851 Sym : CARDINAL ;
8852 BEGIN
8853 pSym := GetPsym (ModSym) ;
8854 WITH pSym^ DO
8855 CASE SymbolType OF
8856 DefImpSym: WITH DefImp DO
8857 Sym := GetSymKey (Unresolved , SymName) ;
8858 IF Sym=NulSym
8859 THEN
8860 NewSym(Sym) ;
8861 FillInUnknownFields (tok, Sym, SymName) ;
8862 PutSymKey (Unresolved, SymName, Sym)
8863 END
8864 END
8865 ELSE
8866 InternalError ('expecting a DefImp symbol')
8867 END
8868 END ;
8869 RETURN( Sym )
8870 END FetchUnknownFromDefImp ;
8871
8872
8873 PROCEDURE FetchUnknownFrom (tok: CARDINAL;
8874 scope: CARDINAL;
8875 SymName: Name) : CARDINAL ;
8876 VAR
8877 pSym: PtrToSymbol ;
8878 Sym : CARDINAL ;
8879 BEGIN
8880 pSym := GetPsym(scope) ;
8881 WITH pSym^ DO
8882 CASE SymbolType OF
8883 DefImpSym: WITH DefImp DO
8884 Sym := GetSymKey(Unresolved, SymName) ;
8885 IF Sym=NulSym
8886 THEN
8887 NewSym(Sym) ;
8888 FillInUnknownFields (tok, Sym, SymName) ;
8889 PutSymKey(Unresolved, SymName, Sym)
8890 END
8891 END |
8892 ModuleSym: WITH Module DO
8893 Sym := GetSymKey(Unresolved, SymName) ;
8894 IF Sym=NulSym
8895 THEN
8896 NewSym(Sym) ;
8897 FillInUnknownFields (tok, Sym, SymName) ;
8898 PutSymKey(Unresolved, SymName, Sym)
8899 END
8900 END |
8901 ProcedureSym: WITH Procedure DO
8902 Sym := GetSymKey(Unresolved, SymName) ;
8903 IF Sym=NulSym
8904 THEN
8905 NewSym(Sym) ;
8906 FillInUnknownFields (tok, Sym, SymName) ;
8907 PutSymKey(Unresolved, SymName, Sym)
8908 END
8909 END
8910
8911 ELSE
8912 InternalError ('expecting a DefImp or Module or Procedure symbol')
8913 END
8914 END ;
8915 RETURN( Sym )
8916 END FetchUnknownFrom ;
8917
8918
8919 (*
8920 GetFromOuterModule - returns a symbol with name, SymName, which comes
8921 from outside the current module.
8922 *)
8923
8924 PROCEDURE GetFromOuterModule (tokenno: CARDINAL; SymName: Name) : CARDINAL ;
8925 VAR
8926 pCall : PtrToCallFrame ;
8927 ScopeId : CARDINAL ;
8928 Sym,
8929 ScopeSym: CARDINAL ;
8930 BEGIN
8931 ScopeId := ScopePtr ;
8932 pCall := GetPcall(ScopeId) ;
8933 WHILE (NOT IsModule(pCall^.Search)) AND
8934 (NOT IsDefImp(pCall^.Search)) DO
8935 Assert (ScopeId>0) ;
8936 DEC (ScopeId) ;
8937 pCall := GetPcall (ScopeId)
8938 END ;
8939 DEC (ScopeId) ;
8940 (* we are now below the current module *)
8941 WHILE ScopeId>0 DO
8942 pCall := GetPcall(ScopeId) ;
8943 ScopeSym := pCall^.Search ;
8944 IF ScopeSym#NulSym
8945 THEN
8946 Sym := GetLocalSym(ScopeSym, SymName) ;
8947 IF Sym=NulSym
8948 THEN
8949 IF IsModule(ScopeSym) OR IsProcedure(ScopeSym) OR IsDefImp(ScopeSym)
8950 THEN
8951 IF Sym=NulSym
8952 THEN
8953 Sym := ExamineUnresolvedTree(ScopeSym, SymName) ;
8954 IF Sym#NulSym
8955 THEN
8956 RETURN( Sym )
8957 END
8958 END
8959 END
8960 ELSE
8961 RETURN( Sym )
8962 END
8963 END ;
8964 DEC(ScopeId) ;
8965 pCall := GetPcall(ScopeId)
8966 END ;
8967 (* at this point we force an unknown from the last module scope *)
8968 RETURN( RequestFromModule (tokenno, GetLastModuleScope(), SymName) )
8969 END GetFromOuterModule ;
8970
8971
8972 (*
8973 IsExportUnQualified - returns true if a symbol, Sym, was defined as
8974 being EXPORT UNQUALIFIED.
8975 *)
8976
8977 PROCEDURE IsExportUnQualified (Sym: CARDINAL) : BOOLEAN ;
8978 VAR
8979 pSym : PtrToSymbol ;
8980 OuterModule: CARDINAL ;
8981 BEGIN
8982 OuterModule := Sym ;
8983 REPEAT
8984 OuterModule := GetScope(OuterModule)
8985 UNTIL GetScope(OuterModule)=NulSym ;
8986 pSym := GetPsym(OuterModule) ;
8987 WITH pSym^ DO
8988 CASE SymbolType OF
8989
8990 ModuleSym: RETURN( FALSE ) |
8991 DefImpSym: RETURN( GetSymKey(
8992 DefImp.ExportUnQualifiedTree,
8993 GetSymName(Sym)
8994 )=Sym
8995 )
8996
8997 ELSE
8998 InternalError ('expecting a DefImp or Module symbol')
8999 END
9000 END
9001 END IsExportUnQualified ;
9002
9003
9004 (*
9005 IsExportQualified - returns true if a symbol, Sym, was defined as
9006 being EXPORT QUALIFIED.
9007 Sym is expected to be either a procedure or a
9008 variable.
9009 *)
9010
9011 PROCEDURE IsExportQualified (Sym: CARDINAL) : BOOLEAN ;
9012 VAR
9013 pSym : PtrToSymbol ;
9014 OuterModule: CARDINAL ;
9015 BEGIN
9016 OuterModule := Sym ;
9017 REPEAT
9018 OuterModule := GetScope(OuterModule)
9019 UNTIL GetScope(OuterModule)=NulSym ;
9020 pSym := GetPsym(OuterModule) ;
9021 WITH pSym^ DO
9022 CASE SymbolType OF
9023
9024 ModuleSym: RETURN( FALSE ) |
9025 DefImpSym: RETURN( GetSymKey(DefImp.ExportQualifiedTree, GetSymName(Sym))=Sym )
9026
9027 ELSE
9028 InternalError ('expecting a DefImp or Module symbol')
9029 END
9030 END
9031 END IsExportQualified ;
9032
9033
9034 (*
9035 ForeachImportedDo - calls a procedure, P, foreach imported symbol
9036 in module, ModSym.
9037 *)
9038
9039 PROCEDURE ForeachImportedDo (ModSym: CARDINAL; P: PerformOperation) ;
9040 VAR
9041 pSym: PtrToSymbol ;
9042 BEGIN
9043 pSym := GetPsym(ModSym) ;
9044 WITH pSym^ DO
9045 CASE SymbolType OF
9046
9047 DefImpSym: WITH DefImp DO
9048 ForeachNodeDo( ImportTree, P ) ;
9049 ForeachItemInListDo( IncludeList, P )
9050 END |
9051 ModuleSym: WITH Module DO
9052 ForeachNodeDo( ImportTree, P ) ;
9053 ForeachItemInListDo( IncludeList, P )
9054 END
9055
9056 ELSE
9057 InternalError ('expecting a DefImp or Module symbol')
9058 END
9059 END
9060 END ForeachImportedDo ;
9061
9062
9063 (*
9064 ForeachExportedDo - calls a procedure, P, foreach imported symbol
9065 in module, ModSym.
9066 *)
9067
9068 PROCEDURE ForeachExportedDo (ModSym: CARDINAL; P: PerformOperation) ;
9069 VAR
9070 pSym: PtrToSymbol ;
9071 BEGIN
9072 pSym := GetPsym(ModSym) ;
9073 WITH pSym^ DO
9074 CASE SymbolType OF
9075
9076 DefImpSym: WITH DefImp DO
9077 ForeachNodeDo( ExportQualifiedTree, P ) ;
9078 ForeachNodeDo( ExportUnQualifiedTree, P )
9079 END |
9080 ModuleSym: WITH Module DO
9081 ForeachNodeDo( ExportTree, P )
9082 END
9083
9084 ELSE
9085 InternalError ('expecting a DefImp or Module symbol')
9086 END
9087 END
9088 END ForeachExportedDo ;
9089
9090
9091 (*
9092 ForeachLocalSymDo - foreach local symbol in module, Sym, or procedure, Sym,
9093 perform the procedure, P.
9094 *)
9095
9096 PROCEDURE ForeachLocalSymDo (Sym: CARDINAL; P: PerformOperation) ;
9097 VAR
9098 pSym: PtrToSymbol ;
9099 BEGIN
9100 pSym := GetPsym(Sym) ;
9101 WITH pSym^ DO
9102 CASE SymbolType OF
9103
9104 DefImpSym: WITH DefImp DO
9105 ForeachNodeDo( LocalSymbols, P )
9106 END |
9107 ModuleSym: WITH Module DO
9108 ForeachNodeDo( LocalSymbols, P )
9109 END |
9110 ProcedureSym: WITH Procedure DO
9111 ForeachNodeDo( LocalSymbols, P )
9112 END |
9113 RecordSym: WITH Record DO
9114 ForeachNodeDo( LocalSymbols, P )
9115 END |
9116 EnumerationSym: WITH Enumeration DO
9117 ForeachNodeDo( LocalSymbols, P )
9118 END
9119
9120 ELSE
9121 InternalError ('expecting a DefImp, Module or Procedure symbol')
9122 END
9123 END
9124 END ForeachLocalSymDo ;
9125
9126
9127 (*
9128 ForeachParamSymDo - foreach parameter symbol in procedure, Sym,
9129 perform the procedure, P. Each symbol
9130 looked up will be VarParam or Param
9131 (not the shadow variable).
9132 *)
9133
9134 PROCEDURE ForeachParamSymDo (Sym: CARDINAL; P: PerformOperation) ;
9135 VAR
9136 param: CARDINAL ;
9137 p, i : CARDINAL ;
9138 BEGIN
9139 IF IsProcedure (Sym)
9140 THEN
9141 p := NoOfParam (Sym) ;
9142 i := p ;
9143 WHILE i>0 DO
9144 param := GetNthParam (Sym, i) ;
9145 P (param) ;
9146 DEC(i)
9147 END
9148 END
9149 END ForeachParamSymDo ;
9150
9151
9152 (*
9153 CheckForUnknownInModule - checks for any unknown symbols in the
9154 current module.
9155 If any unknown symbols are found then
9156 an error message is displayed.
9157 *)
9158
9159 PROCEDURE CheckForUnknownInModule ;
9160 VAR
9161 pSym: PtrToSymbol ;
9162 BEGIN
9163 pSym := GetPsym(GetCurrentModuleScope()) ;
9164 WITH pSym^ DO
9165 CASE SymbolType OF
9166
9167 DefImpSym: WITH DefImp DO
9168 CheckForUnknowns (name, ExportQualifiedTree,
9169 'EXPORT QUALIFIED') ;
9170 CheckForUnknowns (name, ExportUnQualifiedTree,
9171 'EXPORT UNQUALIFIED') ;
9172 CheckForSymbols (ExportRequest,
9173 'requested by another modules import (symbols have not been exported by the appropriate definition module)') ;
9174 CheckForUnknowns (name, Unresolved, 'unresolved') ;
9175 CheckForUnknowns (name, LocalSymbols, 'locally used')
9176 END |
9177 ModuleSym: WITH Module DO
9178 CheckForUnknowns (name, Unresolved, 'unresolved') ;
9179 CheckForUnknowns (name, ExportUndeclared, 'exported but undeclared') ;
9180 CheckForUnknowns (name, ExportTree, 'exported but undeclared') ;
9181 CheckForUnknowns (name, LocalSymbols, 'locally used')
9182 END
9183
9184 ELSE
9185 InternalError ('expecting a DefImp or Module symbol')
9186 END
9187 END
9188 END CheckForUnknownInModule ;
9189
9190
9191 (*
9192 UnknownSymbolError - displays symbol name for symbol, sym.
9193 *)
9194
9195 PROCEDURE UnknownSymbolError (sym: WORD) ;
9196 BEGIN
9197 IF IsUnreportedUnknown (sym)
9198 THEN
9199 IncludeElementIntoSet (ReportedUnknowns, sym) ;
9200 MetaErrorStringT1 (GetFirstUsed (sym), InitString ("unknown symbol {%1EUad}"), sym)
9201 END
9202 END UnknownSymbolError ;
9203
9204
9205 (*
9206 UnknownReported - if sym is an unknown symbol and has not been reported
9207 then include it into the set of reported unknowns.
9208 *)
9209
9210 PROCEDURE UnknownReported (sym: CARDINAL) ;
9211 BEGIN
9212 IF IsUnreportedUnknown (sym)
9213 THEN
9214 IncludeElementIntoSet (ReportedUnknowns, sym)
9215 END
9216 END UnknownReported ;
9217
9218
9219 (*
9220 IsUnreportedUnknown - returns TRUE if symbol, sym, has not been
9221 reported and is an unknown symbol.
9222 *)
9223
9224 PROCEDURE IsUnreportedUnknown (sym: CARDINAL) : BOOLEAN ;
9225 BEGIN
9226 RETURN IsUnknown (sym) AND (NOT IsElementInSet (ReportedUnknowns, sym))
9227 END IsUnreportedUnknown ;
9228
9229
9230 VAR
9231 ListifySentance : String ;
9232 ListifyTotal,
9233 ListifyWordCount: CARDINAL ;
9234
9235
9236 (*
9237 AddListify -
9238 *)
9239
9240 PROCEDURE AddListify (sym: CARDINAL) ;
9241 BEGIN
9242 INC (ListifyWordCount) ;
9243 (* printf ("AddListify: ListifyWordCount = %d, ListifyTotal = %d\n",
9244 ListifyWordCount, ListifyTotal) ; *)
9245 IF ListifyWordCount > 1
9246 THEN
9247 IF ListifyWordCount = ListifyTotal
9248 THEN
9249 ListifySentance := ConCat (ListifySentance, Mark (InitString (" and ")))
9250 ELSE
9251 ListifySentance := ConCat (ListifySentance, Mark (InitString (", ")))
9252 END
9253 END ;
9254 ListifySentance := ConCat (ListifySentance,
9255 Mark (InitStringCharStar (KeyToCharStar (GetSymName (sym)))))
9256 END AddListify ;
9257
9258
9259 (*
9260 Listify - convert tree into a string list and return the result.
9261 *)
9262
9263 PROCEDURE Listify (tree: SymbolTree; isCondition: IsSymbol) : String ;
9264 BEGIN
9265 ListifyTotal := NoOfNodes (tree, isCondition) ;
9266 ListifyWordCount := 0 ;
9267 ListifySentance := InitString ('') ;
9268 ForeachNodeConditionDo (tree, isCondition, AddListify) ;
9269 RETURN ListifySentance
9270 END Listify ;
9271
9272
9273 (*
9274 CheckForUnknowns - checks a binary tree, Tree, to see whether it contains
9275 an unknown symbol. All unknown symbols are displayed
9276 together with an error message.
9277 *)
9278
9279 PROCEDURE CheckForUnknowns (name: Name; Tree: SymbolTree;
9280 a: ARRAY OF CHAR) ;
9281 VAR
9282 s: String ;
9283 BEGIN
9284 IF DoesTreeContainAny(Tree, IsUnreportedUnknown)
9285 THEN
9286 CurrentError := NewError(GetTokenNo()) ;
9287 s := InitString("{%E} the following unknown symbols in module %<") ;
9288 s := ConCat(s, Mark(InitStringCharStar(KeyToCharStar(name)))) ;
9289 s := ConCat(s, Mark(InitString('%> were '))) ;
9290 s := ConCat(s, Mark(InitString(a))) ;
9291 s := ConCat (s, Mark (InitString (': '))) ;
9292 s := ConCat (s, Mark (Listify (Tree, IsUnreportedUnknown))) ;
9293 MetaErrorStringT0(GetTokenNo(), s) ;
9294 ForeachNodeDo(Tree, UnknownSymbolError)
9295 END
9296 END CheckForUnknowns ;
9297
9298
9299 (*
9300 SymbolError - displays symbol name for symbol, Sym.
9301 *)
9302
9303 PROCEDURE SymbolError (Sym: WORD) ;
9304 VAR
9305 e: Error ;
9306 n: Name ;
9307 BEGIN
9308 n := GetSymName(Sym) ;
9309 e := ChainError(GetFirstUsed(Sym), CurrentError) ;
9310 ErrorFormat1(e, "unknown symbol '%a' found", n)
9311 END SymbolError ;
9312
9313
9314 (*
9315 CheckForSymbols - checks a binary tree, Tree, to see whether it contains
9316 any symbol. The tree is expected to be empty, if not
9317 then an error has occurred.
9318 *)
9319
9320 PROCEDURE CheckForSymbols (Tree: SymbolTree; a: ARRAY OF CHAR) ;
9321 VAR
9322 s: String ;
9323 BEGIN
9324 IF NOT IsEmptyTree(Tree)
9325 THEN
9326 s := InitString ("the symbols are unknown at the end of module {%1Ea} when ") ;
9327 s := ConCat (s, Mark(InitString(a))) ;
9328 MetaErrorString1 (s, MainModule) ;
9329 ForeachNodeDo(Tree, SymbolError)
9330 END
9331 END CheckForSymbols ;
9332
9333
9334 (*
9335 PutExportUndeclared - places a symbol, Sym, into module, ModSym,
9336 ExportUndeclared list provided that Sym
9337 is unknown.
9338 *)
9339
9340 PROCEDURE PutExportUndeclared (ModSym: CARDINAL; Sym: CARDINAL) ;
9341 VAR
9342 pSym: PtrToSymbol ;
9343 BEGIN
9344 IF IsUnknown (Sym)
9345 THEN
9346 pSym := GetPsym (ModSym) ;
9347 WITH pSym^ DO
9348 CASE SymbolType OF
9349
9350 ModuleSym: PutSymKey (Module.ExportUndeclared, GetSymName (Sym), Sym) |
9351 DefImpSym: PutSymKey (DefImp.ExportUndeclared, GetSymName (Sym), Sym)
9352
9353 ELSE
9354 InternalError ('expecting a DefImp or Module symbol')
9355 END
9356 END
9357 END
9358 END PutExportUndeclared ;
9359
9360
9361 (*
9362 GetExportUndeclared - returns a symbol which has, name, from module, ModSym,
9363 which is in the ExportUndeclared list.
9364 *)
9365
9366 PROCEDURE GetExportUndeclared (ModSym: CARDINAL; name: Name) : CARDINAL ;
9367 VAR
9368 pSym: PtrToSymbol ;
9369 BEGIN
9370 pSym := GetPsym(ModSym) ;
9371 WITH pSym^ DO
9372 CASE SymbolType OF
9373
9374 ModuleSym: RETURN( GetSymKey(Module.ExportUndeclared, name) ) |
9375 DefImpSym: RETURN( GetSymKey(DefImp.ExportUndeclared, name) )
9376
9377 ELSE
9378 InternalError ('expecting a DefImp or Module symbol')
9379 END
9380 END
9381 END GetExportUndeclared ;
9382
9383
9384 (*
9385 RemoveExportUndeclared - removes a symbol, Sym, from the module, ModSym,
9386 ExportUndeclaredTree.
9387 *)
9388
9389 PROCEDURE RemoveExportUndeclared (ModSym: CARDINAL; Sym: CARDINAL) ;
9390 VAR
9391 pSym: PtrToSymbol ;
9392 BEGIN
9393 pSym := GetPsym(ModSym) ;
9394 WITH pSym^ DO
9395 CASE SymbolType OF
9396
9397 ModuleSym: IF GetSymKey(Module.ExportUndeclared, GetSymName(Sym))=Sym
9398 THEN
9399 DelSymKey(Module.ExportUndeclared, GetSymName(Sym))
9400 END |
9401 DefImpSym: IF GetSymKey(DefImp.ExportUndeclared, GetSymName(Sym))=Sym
9402 THEN
9403 DelSymKey(DefImp.ExportUndeclared, GetSymName(Sym))
9404 END
9405
9406 ELSE
9407 InternalError ('expecting a DefImp or Module symbol')
9408 END
9409 END
9410 END RemoveExportUndeclared ;
9411
9412
9413 (*
9414 CheckForExportedDeclaration - checks to see whether a definition module
9415 is currently being compiled, if so,
9416 symbol, Sym, is removed from the
9417 ExportUndeclared list.
9418 This procedure is called whenever a symbol
9419 is declared, thus attempting to reduce
9420 the ExportUndeclared list.
9421 *)
9422
9423 PROCEDURE CheckForExportedDeclaration (Sym: CARDINAL) ;
9424 BEGIN
9425 IF CompilingDefinitionModule ()
9426 THEN
9427 RemoveExportUndeclared(GetCurrentModule(), Sym)
9428 END
9429 END CheckForExportedDeclaration ;
9430
9431
9432 (*
9433 CheckForUndeclaredExports - displays an error and the offending symbols
9434 which have been exported but not declared
9435 from module, ModSym.
9436 *)
9437
9438 PROCEDURE CheckForUndeclaredExports (ModSym: CARDINAL) ;
9439 VAR
9440 pSym: PtrToSymbol ;
9441 BEGIN
9442 (* WriteString('Inside CheckForUndeclaredExports') ; WriteLn ; *)
9443 pSym := GetPsym(ModSym) ;
9444 WITH pSym^ DO
9445 CASE SymbolType OF
9446
9447 ModuleSym: IF NOT IsEmptyTree(Module.ExportUndeclared)
9448 THEN
9449 MetaError1('undeclared identifier(s) in EXPORT list of {%1ERd} {%1a}', ModSym) ;
9450 ForeachNodeDo(Module.ExportUndeclared, UndeclaredSymbolError)
9451 END |
9452 DefImpSym: IF NOT IsEmptyTree(DefImp.ExportUndeclared)
9453 THEN
9454 IF DoesNotNeedExportList(ModSym)
9455 THEN
9456 MetaError1('undeclared identifier(s) in {%1ERd} {%1a}', ModSym) ;
9457 ELSE
9458 MetaError1('undeclared identifier(s) in export list of {%1ERd} {%1a}', ModSym) ;
9459 END ;
9460 ForeachNodeDo(DefImp.ExportUndeclared, UndeclaredSymbolError)
9461 END
9462
9463 ELSE
9464 InternalError ('expecting a DefImp or Module symbol')
9465 END
9466 END
9467 END CheckForUndeclaredExports ;
9468
9469
9470 (*
9471 UndeclaredSymbolError - displays symbol name for symbol, Sym.
9472 *)
9473
9474 PROCEDURE UndeclaredSymbolError (Sym: WORD) ;
9475 BEGIN
9476 IF DebugUnknowns
9477 THEN
9478 printf1('undeclared symbol (%d)\n', Sym)
9479 END ;
9480 MetaError1('{%1UC} undeclared symbol {%1a}', Sym)
9481 END UndeclaredSymbolError ;
9482
9483
9484 (*
9485 PutExportUnImplemented - places a symbol, Sym, into the currently compiled
9486 DefImp module NeedToBeImplemented list.
9487 *)
9488
9489 PROCEDURE PutExportUnImplemented (tokenno: CARDINAL; Sym: CARDINAL) ;
9490 VAR
9491 pSym: PtrToSymbol ;
9492 BEGIN
9493 pSym := GetPsym (CurrentModule) ;
9494 WITH pSym^ DO
9495 CASE SymbolType OF
9496
9497 DefImpSym: IF GetSymKey (DefImp.NeedToBeImplemented, GetSymName (Sym)) = Sym
9498 THEN
9499 MetaErrorT2 (tokenno, 'symbol {%1a} is already exported from module {%2a}',
9500 Sym, CurrentModule)
9501 (*
9502 n1 := GetSymName (Sym) ;
9503 n2 := GetSymName (CurrentModule) ;
9504 WriteFormat2 ('symbol (%a) already exported from module (%a)', n1, n2)
9505 *)
9506 ELSE
9507 PutSymKey (DefImp.NeedToBeImplemented, GetSymName(Sym), Sym)
9508 END
9509
9510 ELSE
9511 InternalError ('expecting a DefImp symbol')
9512 END
9513 END
9514 END PutExportUnImplemented ;
9515
9516
9517 (*
9518 RemoveExportUnImplemented - removes a symbol, Sym, from the module, ModSym,
9519 NeedToBeImplemented list.
9520 *)
9521
9522 PROCEDURE RemoveExportUnImplemented (ModSym: CARDINAL; Sym: CARDINAL) ;
9523 VAR
9524 pSym: PtrToSymbol ;
9525 BEGIN
9526 pSym := GetPsym(ModSym) ;
9527 WITH pSym^ DO
9528 CASE SymbolType OF
9529
9530 DefImpSym: IF GetSymKey(DefImp.NeedToBeImplemented, GetSymName(Sym))=Sym
9531 THEN
9532 DelSymKey(DefImp.NeedToBeImplemented, GetSymName(Sym))
9533 END
9534
9535 ELSE
9536 InternalError ('expecting a DefImp symbol')
9537 END
9538 END
9539 END RemoveExportUnImplemented ;
9540
9541
9542 VAR
9543 ExportRequestModule: CARDINAL ;
9544
9545
9546 (*
9547 RemoveFromExportRequest -
9548 *)
9549
9550 PROCEDURE RemoveFromExportRequest (Sym: CARDINAL) ;
9551 VAR
9552 pSym: PtrToSymbol ;
9553 BEGIN
9554 pSym := GetPsym(ExportRequestModule) ;
9555 WITH pSym^ DO
9556 CASE SymbolType OF
9557
9558 DefImpSym: IF GetSymKey(DefImp.ExportRequest, GetSymName(Sym))=Sym
9559 THEN
9560 DelSymKey(DefImp.ExportRequest, GetSymName(Sym))
9561 END
9562
9563 ELSE
9564 InternalError ('expecting a DefImp symbol')
9565 END
9566 END
9567 END RemoveFromExportRequest ;
9568
9569
9570 (*
9571 RemoveEnumerationFromExportRequest - removes enumeration symbol, sym,
9572 (and its fields) from the ExportRequest tree.
9573 *)
9574
9575 PROCEDURE RemoveEnumerationFromExportRequest (ModSym: CARDINAL; Sym: CARDINAL) ;
9576 BEGIN
9577 IF IsEnumeration(Sym)
9578 THEN
9579 ExportRequestModule := ModSym ;
9580 RemoveFromExportRequest(Sym) ;
9581 ForeachLocalSymDo(Sym, RemoveFromExportRequest)
9582 END
9583 END RemoveEnumerationFromExportRequest ;
9584
9585
9586 (*
9587 CheckForExportedImplementation - checks to see whether an implementation
9588 module is currently being compiled, if so,
9589 symbol, Sym, is removed from the
9590 NeedToBeImplemented list.
9591 This procedure is called whenever a symbol
9592 is declared, thus attempting to reduce
9593 the NeedToBeImplemented list.
9594 Only needs to be called when a TYPE or
9595 PROCEDURE is built since the implementation
9596 module can only implement these objects
9597 declared in the definition module.
9598
9599 It also checks whether a definition module
9600 is currently being compiled and, if so,
9601 it will ensure that symbol, Sym, is removed
9602 from the ExportRequest list. If Sym is an
9603 enumerated type it ensures that its fields
9604 are also removed.
9605 *)
9606
9607 PROCEDURE CheckForExportedImplementation (Sym: CARDINAL) ;
9608 BEGIN
9609 IF CompilingImplementationModule()
9610 THEN
9611 RemoveExportUnImplemented(GetCurrentModule(), Sym)
9612 END ;
9613 IF CompilingDefinitionModule() AND IsEnumeration(Sym)
9614 THEN
9615 RemoveEnumerationFromExportRequest(GetCurrentModule(), Sym)
9616 END
9617 END CheckForExportedImplementation ;
9618
9619
9620 (*
9621 CheckForUnImplementedExports - displays an error and the offending symbols
9622 which have been exported but not implemented
9623 from the current compiled module.
9624 *)
9625
9626 PROCEDURE CheckForUnImplementedExports ;
9627 VAR
9628 pSym: PtrToSymbol ;
9629 BEGIN
9630 (* WriteString('Inside CheckForImplementedExports') ; WriteLn ; *)
9631 pSym := GetPsym (CurrentModule) ;
9632 WITH pSym^ DO
9633 CASE SymbolType OF
9634
9635 DefImpSym: IF NOT IsEmptyTree (DefImp.NeedToBeImplemented)
9636 THEN
9637 CurrentError := NewError (GetTokenNo ()) ;
9638 ErrorFormat1 (CurrentError, 'unimplemented identifier(s) in EXPORT list of DEFINITION MODULE %a\nthe implementation module fails to implement the following exported identifier(s)', DefImp.name) ;
9639 ForeachNodeDo (DefImp.NeedToBeImplemented, UnImplementedSymbolError)
9640 END
9641
9642 ELSE
9643 InternalError ('expecting a DefImp symbol')
9644 END
9645 END
9646 END CheckForUnImplementedExports ;
9647
9648
9649 (*
9650 UnImplementedSymbolError - displays symbol name for symbol, Sym.
9651 *)
9652
9653 PROCEDURE UnImplementedSymbolError (Sym: WORD) ;
9654 VAR
9655 n: Name ;
9656 BEGIN
9657 CurrentError := ChainError (GetFirstUsed (Sym), CurrentError) ;
9658 IF IsType (Sym)
9659 THEN
9660 n := GetSymName(Sym) ;
9661 ErrorFormat1 (CurrentError, 'hidden type is undeclared (%a)', n)
9662 ELSIF IsProcedure (Sym)
9663 THEN
9664 n := GetSymName(Sym) ;
9665 ErrorFormat1 (CurrentError, 'procedure is undeclared (%a)', n)
9666 ELSIF IsProcType (Sym)
9667 THEN
9668 n := GetSymName(Sym) ;
9669 ErrorFormat1 (CurrentError, 'procedure type is undeclared (%a)', n)
9670 ELSE
9671 ErrorFormat0 (CurrentError, 'undeclared symbol')
9672 END
9673 END UnImplementedSymbolError ;
9674
9675
9676 (*
9677 PutHiddenTypeDeclared - sets a flag in the current compiled module which
9678 indicates that a Hidden Type is declared within
9679 the implementation part of the module.
9680 This procedure is expected to be called while
9681 compiling the associated definition module.
9682 *)
9683
9684 PROCEDURE PutHiddenTypeDeclared ;
9685 VAR
9686 pSym: PtrToSymbol ;
9687 BEGIN
9688 pSym := GetPsym(CurrentModule) ;
9689 WITH pSym^ DO
9690 CASE SymbolType OF
9691
9692 DefImpSym: DefImp.ContainsHiddenType := TRUE
9693
9694 ELSE
9695 InternalError ('expecting a DefImp symbol')
9696 END
9697 END
9698 END PutHiddenTypeDeclared ;
9699
9700
9701 (*
9702 IsHiddenTypeDeclared - returns true if a Hidden Type was declared in
9703 the module, Sym.
9704 *)
9705
9706 PROCEDURE IsHiddenTypeDeclared (Sym: CARDINAL) : BOOLEAN ;
9707 VAR
9708 pSym: PtrToSymbol ;
9709 BEGIN
9710 pSym := GetPsym(Sym) ;
9711 WITH pSym^ DO
9712 CASE SymbolType OF
9713
9714 DefImpSym: RETURN( DefImp.ContainsHiddenType )
9715
9716 ELSE
9717 InternalError ('expecting a DefImp symbol')
9718 END
9719 END
9720 END IsHiddenTypeDeclared ;
9721
9722
9723 (*
9724 PutModuleContainsBuiltin - sets a flag in the current compiled module which
9725 indicates that a builtin procedure is being declared.
9726 This is only expected to be called when we are
9727 parsing the definition module.
9728 *)
9729
9730 PROCEDURE PutModuleContainsBuiltin ;
9731 VAR
9732 pSym: PtrToSymbol ;
9733 BEGIN
9734 PutHiddenTypeDeclared ;
9735 pSym := GetPsym(CurrentModule) ;
9736 WITH pSym^ DO
9737 CASE SymbolType OF
9738
9739 DefImpSym: DefImp.ContainsBuiltin := TRUE
9740
9741 ELSE
9742 InternalError ('expecting a DefImp symbol')
9743 END
9744 END
9745 END PutModuleContainsBuiltin ;
9746
9747
9748 (*
9749 IsBuiltinInModule - returns true if a module, Sym, has declared a builtin procedure.
9750 *)
9751
9752 PROCEDURE IsBuiltinInModule (Sym: CARDINAL) : BOOLEAN ;
9753 VAR
9754 pSym: PtrToSymbol ;
9755 BEGIN
9756 pSym := GetPsym(Sym) ;
9757 WITH pSym^ DO
9758 CASE SymbolType OF
9759
9760 DefImpSym: RETURN( DefImp.ContainsBuiltin )
9761
9762 ELSE
9763 InternalError ('expecting a DefImp symbol')
9764 END
9765 END
9766 END IsBuiltinInModule ;
9767
9768
9769 (*
9770 PutDefinitionForC - sets a flag in the current compiled module which
9771 indicates that this module is a wrapper for a C
9772 file. Parameters passes to procedures in this module
9773 will adopt the C calling convention.
9774 *)
9775
9776 PROCEDURE PutDefinitionForC (Sym: CARDINAL) ;
9777 VAR
9778 pSym: PtrToSymbol ;
9779 BEGIN
9780 pSym := GetPsym(Sym) ;
9781 WITH pSym^ DO
9782 CASE SymbolType OF
9783
9784 DefImpSym: DefImp.ForC := TRUE
9785
9786 ELSE
9787 InternalError ('expecting a DefImp symbol')
9788 END
9789 END
9790 END PutDefinitionForC ;
9791
9792
9793 (*
9794 IsDefinitionForC - returns true if this definition module was declared
9795 as a DEFINITION MODULE FOR "C".
9796 *)
9797
9798 PROCEDURE IsDefinitionForC (Sym: CARDINAL) : BOOLEAN ;
9799 VAR
9800 pSym: PtrToSymbol ;
9801 BEGIN
9802 pSym := GetPsym(Sym) ;
9803 WITH pSym^ DO
9804 CASE SymbolType OF
9805
9806 DefImpSym: RETURN( DefImp.ForC )
9807
9808 ELSE
9809 InternalError ('expecting a DefImp symbol')
9810 END
9811 END
9812 END IsDefinitionForC ;
9813
9814
9815 (*
9816 PutDoesNeedExportList - sets a flag in module, Sym, which
9817 indicates that this module requires an explicit
9818 EXPORT QUALIFIED or UNQUALIFIED list. PIM-2
9819 *)
9820
9821 PROCEDURE PutDoesNeedExportList (Sym: CARDINAL) ;
9822 VAR
9823 pSym: PtrToSymbol ;
9824 BEGIN
9825 pSym := GetPsym(Sym) ;
9826 WITH pSym^ DO
9827 CASE SymbolType OF
9828
9829 DefImpSym: DefImp.NeedExportList := TRUE
9830
9831 ELSE
9832 InternalError ('expecting a DefImp symbol')
9833 END
9834 END
9835 END PutDoesNeedExportList ;
9836
9837
9838 (*
9839 PutDoesNotNeedExportList - sets a flag in module, Sym, which
9840 indicates that this module does not require an explicit
9841 EXPORT QUALIFIED or UNQUALIFIED list. PIM-3|4
9842 *)
9843
9844 PROCEDURE PutDoesNotNeedExportList (Sym: CARDINAL) ;
9845 VAR
9846 pSym: PtrToSymbol ;
9847 BEGIN
9848 pSym := GetPsym(Sym) ;
9849 WITH pSym^ DO
9850 CASE SymbolType OF
9851
9852 DefImpSym: DefImp.NeedExportList := FALSE
9853
9854 ELSE
9855 InternalError ('expecting a DefImp symbol')
9856 END
9857 END
9858 END PutDoesNotNeedExportList ;
9859
9860
9861 (*
9862 DoesNotNeedExportList - returns TRUE if module, Sym, does not require an explicit
9863 EXPORT QUALIFIED list.
9864 *)
9865
9866 PROCEDURE DoesNotNeedExportList (Sym: CARDINAL) : BOOLEAN ;
9867 VAR
9868 pSym: PtrToSymbol ;
9869 BEGIN
9870 pSym := GetPsym(Sym) ;
9871 WITH pSym^ DO
9872 CASE SymbolType OF
9873
9874 DefImpSym: RETURN( NOT DefImp.NeedExportList )
9875
9876 ELSE
9877 InternalError ('expecting a DefImp symbol')
9878 END
9879 END
9880 END DoesNotNeedExportList ;
9881
9882
9883 (*
9884 CheckForEnumerationInCurrentModule - checks to see whether the enumeration
9885 type symbol, Sym, has been entered into
9886 the current modules scope list.
9887 *)
9888
9889 PROCEDURE CheckForEnumerationInCurrentModule (Sym: CARDINAL) ;
9890 VAR
9891 pSym : PtrToSymbol ;
9892 ModSym: CARDINAL ;
9893 BEGIN
9894 IF (SkipType(Sym)#NulSym) AND IsEnumeration(SkipType(Sym))
9895 THEN
9896 Sym := SkipType(Sym)
9897 END ;
9898
9899 IF IsEnumeration(Sym)
9900 THEN
9901 ModSym := GetCurrentModuleScope() ;
9902 pSym := GetPsym(ModSym) ;
9903 WITH pSym^ DO
9904 CASE SymbolType OF
9905
9906 DefImpSym: CheckEnumerationInList(DefImp.EnumerationScopeList, Sym) |
9907 ModuleSym: CheckEnumerationInList(Module.EnumerationScopeList, Sym)
9908
9909 ELSE
9910 InternalError ('expecting a DefImp or Module symbol')
9911 END
9912 END
9913 END
9914 END CheckForEnumerationInCurrentModule ;
9915
9916
9917 (*
9918 CheckEnumerationInList - places symbol, Sym, in the list, l,
9919 providing it does not already exist.
9920 PseudoScope(Sym) is called if Sym needs to
9921 be added to the enumeration list, l.
9922 *)
9923
9924 PROCEDURE CheckEnumerationInList (l: List; Sym: CARDINAL) ;
9925 BEGIN
9926 IF NOT IsItemInList(l, Sym)
9927 THEN
9928 PutItemIntoList(l, Sym) ;
9929 PseudoScope(Sym)
9930 END
9931 END CheckEnumerationInList ;
9932
9933
9934 (*
9935 CheckIfEnumerationExported - An outer module may use an enumeration that
9936 is declared inside an inner module. The usage
9937 may occur before definition. The first pass
9938 exports a symbol, later the symbol is declared
9939 as an emumeration type. At this stage the
9940 CheckIfEnumerationExported procedure should be
9941 called. This procedure ripples from the current
9942 (inner) module to outer module and every time
9943 it is exported it must be added to the outer
9944 module EnumerationScopeList.
9945 *)
9946
9947 PROCEDURE CheckIfEnumerationExported (Sym: CARDINAL; ScopeId: CARDINAL) ;
9948 VAR
9949 pCall : PtrToCallFrame ;
9950 InnerModId,
9951 OuterModId : CARDINAL ;
9952 InnerModSym,
9953 OuterModSym: CARDINAL ;
9954 BEGIN
9955 InnerModId := GetModuleScopeId(ScopeId) ;
9956 IF InnerModId>0
9957 THEN
9958 OuterModId := GetModuleScopeId(InnerModId-1) ;
9959 IF OuterModId>0
9960 THEN
9961 pCall := GetPcall(InnerModId) ;
9962 InnerModSym := pCall^.Search ;
9963 pCall := GetPcall(OuterModId) ;
9964 OuterModSym := pCall^.Search ;
9965 IF (InnerModSym#NulSym) AND (OuterModSym#NulSym)
9966 THEN
9967 IF IsExported(InnerModSym, Sym)
9968 THEN
9969 CheckForEnumerationInOuterModule(Sym, OuterModSym) ;
9970 CheckIfEnumerationExported(Sym, OuterModId)
9971 END
9972 END
9973 END
9974 END
9975 END CheckIfEnumerationExported ;
9976
9977
9978 (*
9979 CheckForEnumerationInOuterModule - checks to see whether the enumeration
9980 type symbol, Sym, has been entered into
9981 the outer module, OuterModule, scope list.
9982 OuterModule may be internal to the
9983 program module.
9984 *)
9985
9986 PROCEDURE CheckForEnumerationInOuterModule (Sym: CARDINAL;
9987 OuterModule: CARDINAL) ;
9988 VAR
9989 pSym: PtrToSymbol ;
9990 BEGIN
9991 pSym := GetPsym(OuterModule) ;
9992 WITH pSym^ DO
9993 CASE SymbolType OF
9994
9995 DefImpSym: IncludeItemIntoList(DefImp.EnumerationScopeList, Sym) |
9996 ModuleSym: IncludeItemIntoList(Module.EnumerationScopeList, Sym)
9997
9998 ELSE
9999 InternalError ('expecting a DefImp or Module symbol')
10000 END
10001 END
10002 END CheckForEnumerationInOuterModule ;
10003
10004
10005 (*
10006 IsExported - returns true if a symbol, Sym, is exported
10007 from module, ModSym.
10008 If ModSym is a DefImp symbol then its
10009 ExportQualified and ExportUnQualified lists are examined.
10010 *)
10011
10012 PROCEDURE IsExported (ModSym: CARDINAL; Sym: CARDINAL) : BOOLEAN ;
10013 VAR
10014 pSym : PtrToSymbol ;
10015 SymName: Name ;
10016 BEGIN
10017 SymName := GetSymName(Sym) ;
10018 pSym := GetPsym(ModSym) ;
10019 WITH pSym^ DO
10020 CASE SymbolType OF
10021
10022 DefImpSym: WITH DefImp DO
10023 RETURN(
10024 (GetSymKey(ExportQualifiedTree, SymName)=Sym) OR
10025 (GetSymKey(ExportUnQualifiedTree, SymName)=Sym)
10026 )
10027 END |
10028 ModuleSym: WITH Module DO
10029 RETURN( GetSymKey(ExportTree, SymName)=Sym )
10030 END
10031
10032 ELSE
10033 InternalError ('expecting a DefImp or Module symbol')
10034 END
10035 END
10036 END IsExported ;
10037
10038
10039 (*
10040 IsImported - returns true if a symbol, Sym, in module, ModSym,
10041 was imported.
10042 *)
10043
10044 PROCEDURE IsImported (ModSym: CARDINAL; Sym: CARDINAL) : BOOLEAN ;
10045 VAR
10046 pSym : PtrToSymbol ;
10047 SymName: Name ;
10048 BEGIN
10049 SymName := GetSymName(Sym) ;
10050 pSym := GetPsym(ModSym) ;
10051 WITH pSym^ DO
10052 CASE SymbolType OF
10053
10054 DefImpSym: WITH DefImp DO
10055 RETURN(
10056 (GetSymKey(ImportTree, SymName)=Sym) OR
10057 IsItemInList(IncludeList, Sym)
10058 )
10059 END |
10060 ModuleSym: WITH Module DO
10061 RETURN(
10062 (GetSymKey(ImportTree, SymName)=Sym) OR
10063 IsItemInList(IncludeList, Sym)
10064 )
10065 END
10066
10067 ELSE
10068 InternalError ('expecting a DefImp or Module symbol')
10069 END
10070 END
10071 END IsImported ;
10072
10073
10074 (*
10075 IsType - returns true if the Sym is a type symbol.
10076 *)
10077
10078 PROCEDURE IsType (Sym: CARDINAL) : BOOLEAN ;
10079 VAR
10080 pSym: PtrToSymbol ;
10081 BEGIN
10082 pSym := GetPsym(Sym) ;
10083 RETURN( pSym^.SymbolType=TypeSym )
10084 END IsType ;
10085
10086
10087 (*
10088 IsReturnOptional - returns TRUE if the return value for, sym, is
10089 optional.
10090 *)
10091
10092 PROCEDURE IsReturnOptional (sym: CARDINAL) : BOOLEAN ;
10093 VAR
10094 pSym: PtrToSymbol ;
10095 BEGIN
10096 pSym := GetPsym(sym) ;
10097 WITH pSym^ DO
10098 CASE SymbolType OF
10099
10100 ProcedureSym: RETURN( Procedure.ReturnOptional ) |
10101 ProcTypeSym : RETURN( ProcType.ReturnOptional )
10102
10103 ELSE
10104 InternalError ('expecting a Procedure or ProcType symbol')
10105 END
10106 END
10107 END IsReturnOptional ;
10108
10109
10110 (*
10111 SetReturnOptional - sets the ReturnOptional field in the Procedure or
10112 ProcType symboltable entry.
10113 *)
10114
10115 PROCEDURE SetReturnOptional (sym: CARDINAL; isopt: BOOLEAN) ;
10116 VAR
10117 pSym: PtrToSymbol ;
10118 BEGIN
10119 pSym := GetPsym(sym) ;
10120 WITH pSym^ DO
10121 CASE SymbolType OF
10122
10123 ProcedureSym: Procedure.ReturnOptional := isopt |
10124 ProcTypeSym : ProcType.ReturnOptional := isopt
10125
10126 ELSE
10127 InternalError ('expecting a Procedure or ProcType symbol')
10128 END
10129 END
10130 END SetReturnOptional ;
10131
10132
10133 (*
10134 CheckOptFunction - checks to see whether the optional return value
10135 has been set before and if it differs it will
10136 generate an error message. It will set the
10137 new value to, isopt.
10138 *)
10139
10140 PROCEDURE CheckOptFunction (sym: CARDINAL; isopt: BOOLEAN) ;
10141 VAR
10142 n: Name ;
10143 e: Error ;
10144 BEGIN
10145 IF GetType(sym)#NulSym
10146 THEN
10147 IF IsReturnOptional(sym) AND (NOT isopt)
10148 THEN
10149 n := GetSymName(sym) ;
10150 e := NewError(GetTokenNo()) ;
10151 ErrorFormat1(e, 'function (%a) has no optional return value here', n) ;
10152 e := ChainError(GetDeclaredMod(sym), e) ;
10153 ErrorFormat1(e, 'whereas the same function (%a) was declared to have an optional return value at this point', n)
10154 ELSIF (NOT IsReturnOptional(sym)) AND isopt
10155 THEN
10156 n := GetSymName(sym) ;
10157 e := NewError(GetTokenNo()) ;
10158 ErrorFormat1(e, 'function (%a) has an optional return value', n) ;
10159 e := ChainError(GetDeclaredMod(sym), e) ;
10160 ErrorFormat1(e, 'whereas the same function (%a) was declared to have no optional return value at this point', n)
10161 END
10162 END ;
10163 SetReturnOptional(sym, isopt)
10164 END CheckOptFunction ;
10165
10166
10167 (*
10168 PutFunction - Places a TypeSym as the return type to a procedure Sym.
10169 *)
10170
10171 PROCEDURE PutFunction (Sym: CARDINAL; TypeSym: CARDINAL) ;
10172 VAR
10173 pSym: PtrToSymbol ;
10174 BEGIN
10175 pSym := GetPsym(Sym) ;
10176 WITH pSym^ DO
10177 CASE SymbolType OF
10178
10179 ErrorSym: |
10180 ProcedureSym: CheckOptFunction(Sym, FALSE) ; Procedure.ReturnType := TypeSym |
10181 ProcTypeSym : CheckOptFunction(Sym, FALSE) ; ProcType.ReturnType := TypeSym
10182
10183 ELSE
10184 InternalError ('expecting a Procedure or ProcType symbol')
10185 END
10186 END
10187 END PutFunction ;
10188
10189
10190 (*
10191 PutOptFunction - places a TypeSym as the optional return type to a procedure Sym.
10192 *)
10193
10194 PROCEDURE PutOptFunction (Sym: CARDINAL; TypeSym: CARDINAL) ;
10195 VAR
10196 pSym: PtrToSymbol ;
10197 BEGIN
10198 pSym := GetPsym(Sym) ;
10199 WITH pSym^ DO
10200 CASE SymbolType OF
10201
10202 ErrorSym: |
10203 ProcedureSym: CheckOptFunction(Sym, TRUE) ; Procedure.ReturnType := TypeSym |
10204 ProcTypeSym : CheckOptFunction(Sym, TRUE) ; ProcType.ReturnType := TypeSym
10205
10206 ELSE
10207 InternalError ('expecting a Procedure or ProcType symbol')
10208 END
10209 END
10210 END PutOptFunction ;
10211
10212
10213 (*
10214 MakeVariableForParam -
10215 *)
10216
10217 PROCEDURE MakeVariableForParam (tok : CARDINAL;
10218 ParamName: Name;
10219 ProcSym : CARDINAL ;
10220 no : CARDINAL) : CARDINAL ;
10221 VAR
10222 pSym : PtrToSymbol ;
10223 VariableSym: CARDINAL ;
10224 BEGIN
10225 VariableSym := MakeVar (tok, ParamName) ;
10226 pSym := GetPsym (VariableSym) ;
10227 WITH pSym^ DO
10228 CASE SymbolType OF
10229
10230 ErrorSym: RETURN( NulSym ) |
10231 VarSym : Var.IsParam := TRUE (* Variable is really a parameter. *)
10232
10233 ELSE
10234 InternalError ('expecting a Var symbol')
10235 END
10236 END ;
10237 (* Note that the parameter is now treated as a local variable. *)
10238 PutVar (VariableSym, GetType(GetNthParam(ProcSym, no))) ;
10239 PutDeclared (tok, VariableSym) ;
10240 (*
10241 Normal VAR parameters have LeftValue,
10242 however Unbounded VAR parameters have RightValue.
10243 Non VAR parameters always have RightValue.
10244 *)
10245 IF IsVarParam (ProcSym, no) AND (NOT IsUnboundedParam (ProcSym, no))
10246 THEN
10247 PutMode (VariableSym, LeftValue)
10248 ELSE
10249 PutMode (VariableSym, RightValue)
10250 END ;
10251 RETURN( VariableSym )
10252 END MakeVariableForParam ;
10253
10254
10255 (*
10256 PutParam - Places a Non VAR parameter ParamName with type ParamType into
10257 procedure Sym. The parameter number is ParamNo.
10258 If the procedure Sym already has this parameter then
10259 the parameter is checked for consistancy and the
10260 consistancy test is returned.
10261 *)
10262
10263 PROCEDURE PutParam (tok: CARDINAL; Sym: CARDINAL; ParamNo: CARDINAL;
10264 ParamName: Name; ParamType: CARDINAL;
10265 isUnbounded: BOOLEAN) : BOOLEAN ;
10266 VAR
10267 pSym : PtrToSymbol ;
10268 ParSym : CARDINAL ;
10269 VariableSym: CARDINAL ;
10270 BEGIN
10271 IF ParamNo<=NoOfParam(Sym)
10272 THEN
10273 InternalError ('why are we trying to put parameters again')
10274 ELSE
10275 (* Add a new parameter *)
10276 NewSym(ParSym) ;
10277 pSym := GetPsym(ParSym) ;
10278 WITH pSym^ DO
10279 SymbolType := ParamSym ;
10280 WITH Param DO
10281 name := ParamName ;
10282 Type := ParamType ;
10283 IsUnbounded := isUnbounded ;
10284 ShadowVar := NulSym ;
10285 InitWhereDeclaredTok(tok, At)
10286 END
10287 END ;
10288 AddParameter(Sym, ParSym) ;
10289 IF ParamName#NulName
10290 THEN
10291 VariableSym := MakeVariableForParam(tok, ParamName, Sym, ParamNo) ;
10292 IF VariableSym=NulSym
10293 THEN
10294 RETURN( FALSE )
10295 ELSE
10296 pSym := GetPsym(ParSym) ;
10297 pSym^.Param.ShadowVar := VariableSym
10298 END
10299 END
10300 END ;
10301 RETURN( TRUE )
10302 END PutParam ;
10303
10304
10305 (*
10306 PutVarParam - Places a Non VAR parameter ParamName with type
10307 ParamType into procedure Sym.
10308 The parameter number is ParamNo.
10309 If the procedure Sym already has this parameter then
10310 the parameter is checked for consistancy and the
10311 consistancy test is returned.
10312 *)
10313
10314 PROCEDURE PutVarParam (tok: CARDINAL; Sym: CARDINAL; ParamNo: CARDINAL;
10315 ParamName: Name; ParamType: CARDINAL;
10316 isUnbounded: BOOLEAN) : BOOLEAN ;
10317 VAR
10318 pSym : PtrToSymbol ;
10319 ParSym : CARDINAL ;
10320 VariableSym: CARDINAL ;
10321 BEGIN
10322 IF ParamNo<=NoOfParam(Sym)
10323 THEN
10324 InternalError ('why are we trying to put parameters again')
10325 ELSE
10326 (* Add a new parameter *)
10327 NewSym(ParSym) ;
10328 pSym := GetPsym(ParSym) ;
10329 WITH pSym^ DO
10330 SymbolType := VarParamSym ;
10331 WITH VarParam DO
10332 name := ParamName ;
10333 Type := ParamType ;
10334 IsUnbounded := isUnbounded ;
10335 ShadowVar := NulSym ;
10336 HeapVar := NulSym ; (* Will contain a pointer value. *)
10337 InitWhereDeclaredTok(tok, At)
10338 END
10339 END ;
10340 AddParameter(Sym, ParSym) ;
10341 IF ParamName#NulName
10342 THEN
10343 VariableSym := MakeVariableForParam(tok, ParamName, Sym, ParamNo) ;
10344 IF VariableSym=NulSym
10345 THEN
10346 RETURN( FALSE )
10347 ELSE
10348 pSym := GetPsym(ParSym) ;
10349 pSym^.VarParam.ShadowVar := VariableSym
10350 END
10351 END ;
10352 RETURN( TRUE )
10353 END
10354 END PutVarParam ;
10355
10356
10357 (*
10358 PutParamName - assigns a name, name, to paramater, no, of procedure,
10359 ProcSym.
10360 *)
10361
10362 PROCEDURE PutParamName (tok: CARDINAL; ProcSym: CARDINAL; no: CARDINAL; name: Name) ;
10363 VAR
10364 pSym : PtrToSymbol ;
10365 ParSym: CARDINAL ;
10366 BEGIN
10367 pSym := GetPsym(ProcSym) ;
10368 ParSym := NulSym ;
10369 WITH pSym^ DO
10370 CASE SymbolType OF
10371
10372 ErrorSym : RETURN |
10373 ProcedureSym: ParSym := GetItemFromList(Procedure.ListOfParam, no) |
10374 ProcTypeSym : ParSym := GetItemFromList(ProcType.ListOfParam, no)
10375
10376 ELSE
10377 InternalError ('expecting a Procedure symbol')
10378 END
10379 END ;
10380 pSym := GetPsym(ParSym) ;
10381 WITH pSym^ DO
10382 CASE SymbolType OF
10383
10384 ParamSym: IF Param.name=NulName
10385 THEN
10386 Param.name := name ;
10387 Param.ShadowVar := MakeVariableForParam(tok, name, ProcSym, no)
10388 ELSE
10389 InternalError ('name of parameter has already been assigned')
10390 END |
10391 VarParamSym: IF VarParam.name=NulName
10392 THEN
10393 VarParam.name := name ;
10394 VarParam.ShadowVar := MakeVariableForParam(tok, name, ProcSym, no)
10395 ELSE
10396 InternalError ('name of parameter has already been assigned')
10397 END
10398
10399 ELSE
10400 InternalError ('expecting a VarParam or Param symbol')
10401 END
10402 END
10403 END PutParamName ;
10404
10405
10406 (*
10407 AddParameter - adds a parameter ParSym to a procedure Sym.
10408 *)
10409
10410 PROCEDURE AddParameter (Sym: CARDINAL; ParSym: CARDINAL) ;
10411 VAR
10412 pSym: PtrToSymbol ;
10413 BEGIN
10414 pSym := GetPsym(Sym) ;
10415 WITH pSym^ DO
10416 CASE SymbolType OF
10417
10418 ErrorSym: |
10419 ProcedureSym: PutItemIntoList(Procedure.ListOfParam, ParSym) |
10420 ProcTypeSym : PutItemIntoList(ProcType.ListOfParam, ParSym)
10421
10422 ELSE
10423 InternalError ('expecting a Procedure symbol')
10424 END
10425 END
10426 END AddParameter ;
10427
10428
10429 (*
10430 IsVarParam - Returns a conditional depending whether parameter ParamNo
10431 is a VAR parameter.
10432 *)
10433
10434 PROCEDURE IsVarParam (Sym: CARDINAL; ParamNo: CARDINAL) : BOOLEAN ;
10435 VAR
10436 pSym : PtrToSymbol ;
10437 IsVar: BOOLEAN ;
10438 BEGIN
10439 IsVar := FALSE ;
10440 pSym := GetPsym(Sym) ;
10441 WITH pSym^ DO
10442 CASE SymbolType OF
10443
10444 ErrorSym : |
10445 ProcedureSym: IsVar := IsNthParamVar(Procedure.ListOfParam, ParamNo) |
10446 ProcTypeSym : IsVar := IsNthParamVar(ProcType.ListOfParam, ParamNo)
10447
10448 ELSE
10449 InternalError ('expecting a Procedure or ProcType symbol')
10450 END
10451 END ;
10452 RETURN( IsVar )
10453 END IsVarParam ;
10454
10455
10456 (*
10457 IsNthParamVar - returns true if the n th parameter of the parameter list,
10458 List, is a VAR parameter.
10459 *)
10460
10461 PROCEDURE IsNthParamVar (Head: List; n: CARDINAL) : BOOLEAN ;
10462 VAR
10463 pSym: PtrToSymbol ;
10464 p : CARDINAL ;
10465 BEGIN
10466 p := GetItemFromList(Head, n) ;
10467 IF p=NulSym
10468 THEN
10469 InternalError ('parameter does not exist')
10470 ELSE
10471 pSym := GetPsym(p) ;
10472 WITH pSym^ DO
10473 CASE SymbolType OF
10474
10475 ErrorSym : RETURN( FALSE ) |
10476 VarParamSym: RETURN( TRUE ) |
10477 ParamSym : RETURN( FALSE )
10478
10479 ELSE
10480 InternalError ('expecting Param or VarParam symbol')
10481 END
10482 END
10483 END
10484 END IsNthParamVar ;
10485
10486
10487 (*
10488 NoOfParam - Returns the number of parameters that procedure Sym contains.
10489 *)
10490
10491 PROCEDURE NoOfParam (Sym: CARDINAL) : CARDINAL ;
10492 VAR
10493 pSym: PtrToSymbol ;
10494 n : CARDINAL ;
10495 BEGIN
10496 CheckLegal(Sym) ;
10497 pSym := GetPsym(Sym) ;
10498 WITH pSym^ DO
10499 CASE SymbolType OF
10500
10501 ErrorSym : n := 0 |
10502 ProcedureSym: n := NoOfItemsInList(Procedure.ListOfParam) |
10503 ProcTypeSym : n := NoOfItemsInList(ProcType.ListOfParam)
10504
10505 ELSE
10506 InternalError ('expecting a Procedure or ProcType symbol')
10507 END
10508 END ;
10509 RETURN( n )
10510 END NoOfParam ;
10511
10512
10513 (*
10514 HasVarParameters - returns TRUE if procedure, p, has any VAR parameters.
10515 *)
10516
10517 PROCEDURE HasVarParameters (p: CARDINAL) : BOOLEAN ;
10518 VAR
10519 i, n: CARDINAL ;
10520 BEGIN
10521 n := NoOfParam(p) ;
10522 i := 1 ;
10523 WHILE i<=n DO
10524 IF IsVarParam(p, i)
10525 THEN
10526 RETURN TRUE
10527 END ;
10528 INC(i)
10529 END ;
10530 RETURN FALSE
10531 END HasVarParameters ;
10532
10533
10534 (*
10535 PutUseVarArgs - tell the symbol table that this procedure, Sym,
10536 uses varargs.
10537 The procedure _must_ be declared inside a
10538 DEFINITION FOR "C"
10539
10540 *)
10541
10542 PROCEDURE PutUseVarArgs (Sym: CARDINAL) ;
10543 VAR
10544 pSym: PtrToSymbol ;
10545 BEGIN
10546 CheckLegal(Sym) ;
10547 pSym := GetPsym(Sym) ;
10548 WITH pSym^ DO
10549 CASE SymbolType OF
10550
10551 ErrorSym: |
10552 ProcedureSym: Procedure.HasVarArgs := TRUE |
10553 ProcTypeSym : ProcType.HasVarArgs := TRUE
10554
10555 ELSE
10556 InternalError ('expecting a Procedure or ProcType symbol')
10557 END
10558 END
10559 END PutUseVarArgs ;
10560
10561
10562 (*
10563 UsesVarArgs - returns TRUE if procedure, Sym, uses varargs.
10564 The procedure _must_ be declared inside a
10565 DEFINITION FOR "C"
10566 *)
10567
10568 PROCEDURE UsesVarArgs (Sym: CARDINAL) : BOOLEAN ;
10569 VAR
10570 pSym: PtrToSymbol ;
10571 BEGIN
10572 CheckLegal(Sym) ;
10573 pSym := GetPsym(Sym) ;
10574 WITH pSym^ DO
10575 CASE SymbolType OF
10576
10577 ErrorSym : RETURN( FALSE ) |
10578 ProcedureSym: RETURN( Procedure.HasVarArgs ) |
10579 ProcTypeSym : RETURN( ProcType.HasVarArgs )
10580
10581 ELSE
10582 InternalError ('expecting a Procedure or ProcType symbol')
10583 END
10584 END
10585 END UsesVarArgs ;
10586
10587
10588 (*
10589 PutUseOptArg - tell the symbol table that this procedure, Sym,
10590 uses an optarg.
10591 *)
10592
10593 PROCEDURE PutUseOptArg (Sym: CARDINAL) ;
10594 VAR
10595 pSym: PtrToSymbol ;
10596 BEGIN
10597 CheckLegal(Sym) ;
10598 pSym := GetPsym(Sym) ;
10599 WITH pSym^ DO
10600 CASE SymbolType OF
10601
10602 ErrorSym: |
10603 ProcedureSym: Procedure.HasOptArg := TRUE |
10604 ProcTypeSym : ProcType.HasOptArg := TRUE
10605
10606 ELSE
10607 InternalError ('expecting a Procedure or ProcType symbol')
10608 END
10609 END
10610 END PutUseOptArg ;
10611
10612
10613 (*
10614 UsesOptArg - returns TRUE if procedure, Sym, uses varargs.
10615 *)
10616
10617 PROCEDURE UsesOptArg (Sym: CARDINAL) : BOOLEAN ;
10618 VAR
10619 pSym: PtrToSymbol ;
10620 BEGIN
10621 CheckLegal(Sym) ;
10622 pSym := GetPsym(Sym) ;
10623 WITH pSym^ DO
10624 CASE SymbolType OF
10625
10626 ErrorSym : RETURN( FALSE ) |
10627 ProcedureSym: RETURN( Procedure.HasOptArg ) |
10628 ProcTypeSym : RETURN( ProcType.HasOptArg )
10629
10630 ELSE
10631 InternalError ('expecting a Procedure or ProcType symbol')
10632 END
10633 END
10634 END UsesOptArg ;
10635
10636
10637 (*
10638 PutOptArgInit - makes symbol, Sym, the initializer value to
10639 procedure, ProcSym.
10640 *)
10641
10642 PROCEDURE PutOptArgInit (ProcSym, Sym: CARDINAL) ;
10643 VAR
10644 pSym: PtrToSymbol ;
10645 BEGIN
10646 CheckLegal(Sym) ;
10647 IF NOT IsError(ProcSym)
10648 THEN
10649 IF UsesOptArg(ProcSym)
10650 THEN
10651 pSym := GetPsym(ProcSym) ;
10652 WITH pSym^ DO
10653 CASE SymbolType OF
10654
10655 ErrorSym : |
10656 ProcedureSym: Procedure.OptArgInit := Sym |
10657 ProcTypeSym : ProcType.OptArgInit := Sym
10658
10659 ELSE
10660 InternalError ('expecting a Procedure or ProcType symbol')
10661 END
10662 END
10663 END
10664 END
10665 END PutOptArgInit ;
10666
10667
10668 (*
10669 GetOptArgInit - returns the initializer value to the optional parameter in
10670 procedure, ProcSym.
10671 *)
10672
10673 PROCEDURE GetOptArgInit (ProcSym: CARDINAL) : CARDINAL ;
10674 VAR
10675 pSym: PtrToSymbol ;
10676 BEGIN
10677 IF NOT IsError(ProcSym)
10678 THEN
10679 IF UsesOptArg(ProcSym)
10680 THEN
10681 pSym := GetPsym(ProcSym) ;
10682 WITH pSym^ DO
10683 CASE SymbolType OF
10684
10685 ErrorSym : |
10686 ProcedureSym: RETURN( Procedure.OptArgInit ) |
10687 ProcTypeSym : RETURN( ProcType.OptArgInit )
10688
10689 ELSE
10690 InternalError ('expecting a Procedure or ProcType symbol')
10691 END
10692 END
10693 END
10694 END ;
10695 RETURN( NulSym )
10696 END GetOptArgInit ;
10697
10698
10699 (*
10700 MakeParameterHeapVar - create a heap variable if sym is a pointer.
10701 *)
10702
10703 PROCEDURE MakeParameterHeapVar (tok: CARDINAL; type: CARDINAL; mode: ModeOfAddr) : CARDINAL ;
10704 VAR
10705 heapvar: CARDINAL ;
10706 BEGIN
10707 heapvar := NulSym ;
10708 type := SkipType (type) ;
10709 IF IsPointer (type)
10710 THEN
10711 heapvar := MakeTemporary (tok, mode) ;
10712 PutVar (heapvar, type) ;
10713 PutVarHeap (heapvar, TRUE)
10714 END ;
10715 RETURN heapvar
10716 END MakeParameterHeapVar ;
10717
10718
10719 (*
10720 GetParameterHeapVar - return the heap variable associated with the
10721 parameter or NulSym.
10722 *)
10723
10724 PROCEDURE GetParameterHeapVar (ParSym: CARDINAL) : CARDINAL ;
10725 VAR
10726 pSym: PtrToSymbol ;
10727 BEGIN
10728 pSym := GetPsym (ParSym) ;
10729 WITH pSym^ DO
10730 CASE SymbolType OF
10731
10732 ParamSym : RETURN NulSym | (* Only VarParam has the pointer. *)
10733 VarParamSym: RETURN VarParam.HeapVar
10734
10735 ELSE
10736 InternalError ('expecting Param or VarParam symbol')
10737 END
10738 END
10739 END GetParameterHeapVar ;
10740
10741
10742 (*
10743 PutParameterHeapVar - creates a heap variable associated with parameter sym.
10744 *)
10745
10746 PROCEDURE PutParameterHeapVar (sym: CARDINAL) ;
10747 VAR
10748 pSym : PtrToSymbol ;
10749 BEGIN
10750 pSym := GetPsym (sym) ;
10751 WITH pSym^ DO
10752 CASE SymbolType OF
10753
10754 ParamSym : | (* Nothing to do for the non var parameter. *)
10755 VarParamSym: VarParam.HeapVar := MakeParameterHeapVar (GetDeclaredMod (sym),
10756 VarParam.Type, LeftValue)
10757
10758 ELSE
10759 InternalError ('Param or VarParam symbol expected')
10760 END
10761 END
10762 END PutParameterHeapVar ;
10763
10764
10765 (*
10766 PutProcedureParameterHeapVars - creates heap variables for parameter sym.
10767 *)
10768
10769 PROCEDURE PutProcedureParameterHeapVars (sym: CARDINAL) ;
10770 BEGIN
10771 Assert (IsProcedure (sym)) ;
10772 ForeachParamSymDo (sym, PutParameterHeapVar)
10773 END PutProcedureParameterHeapVars ;
10774
10775
10776 (*
10777 NoOfVariables - returns the number of variables in scope. The scope maybe
10778 a procedure, module or defimp scope.
10779 *)
10780
10781 PROCEDURE NoOfVariables (scope: CARDINAL) : CARDINAL ;
10782 VAR
10783 pSym: PtrToSymbol ;
10784 BEGIN
10785 IF IsProcedure (scope)
10786 THEN
10787 RETURN NoOfLocalVar (scope)
10788 ELSIF IsModule (scope)
10789 THEN
10790 pSym := GetPsym (scope) ;
10791 WITH pSym^ DO
10792 CASE SymbolType OF
10793
10794 ModuleSym: RETURN NoOfItemsInList (Module.ListOfVars)
10795
10796 ELSE
10797 InternalError ('expecting module symbol')
10798 END
10799 END
10800 ELSIF IsDefImp (scope)
10801 THEN
10802 pSym := GetPsym (scope) ;
10803 WITH pSym^ DO
10804 CASE SymbolType OF
10805
10806 DefImpSym: RETURN NoOfItemsInList (DefImp.ListOfVars)
10807
10808 ELSE
10809 InternalError ('expecting defimp symbol')
10810 END
10811 END
10812 ELSE
10813 InternalError ('expecting procedure, module or defimp symbol')
10814 END
10815 END NoOfVariables ;
10816
10817
10818 (*
10819 NoOfLocalVar - returns the number of local variables that exist in
10820 procedure Sym. Parameters are NOT included in the
10821 count.
10822 *)
10823
10824 PROCEDURE NoOfLocalVar (Sym: CARDINAL) : CARDINAL ;
10825 VAR
10826 pSym: PtrToSymbol ;
10827 n : CARDINAL ;
10828 BEGIN
10829 pSym := GetPsym(Sym) ;
10830 WITH pSym^ DO
10831 CASE SymbolType OF
10832
10833 ErrorSym : n := 0 |
10834 ProcedureSym: n := NoOfItemsInList(Procedure.ListOfVars)
10835
10836 ELSE
10837 InternalError ('expecting a Procedure symbol')
10838 END
10839 END ;
10840 (*
10841 Parameters are actually included in the list of local varaibles,
10842 therefore we must subtract the Parameter Number from local variable
10843 total.
10844 *)
10845 RETURN( n-NoOfParam(Sym) )
10846 END NoOfLocalVar ;
10847
10848
10849 (*
10850 IsParameterVar - returns true if parameter symbol Sym
10851 was declared as a VAR.
10852 *)
10853
10854 PROCEDURE IsParameterVar (Sym: CARDINAL) : BOOLEAN ;
10855 VAR
10856 pSym: PtrToSymbol ;
10857 BEGIN
10858 pSym := GetPsym(Sym) ;
10859 WITH pSym^ DO
10860 CASE SymbolType OF
10861
10862 ParamSym : RETURN( FALSE ) |
10863 VarParamSym: RETURN( TRUE )
10864
10865 ELSE
10866 InternalError ('expecting Param or VarParam symbol')
10867 END
10868 END
10869 END IsParameterVar ;
10870
10871
10872 (*
10873 IsParameterUnbounded - returns TRUE if parameter, Sym, is
10874 unbounded.
10875 *)
10876
10877 PROCEDURE IsParameterUnbounded (Sym: CARDINAL) : BOOLEAN ;
10878 VAR
10879 pSym: PtrToSymbol ;
10880 BEGIN
10881 pSym := GetPsym(Sym) ;
10882 WITH pSym^ DO
10883 CASE SymbolType OF
10884
10885 ParamSym : RETURN( Param.IsUnbounded ) |
10886 VarParamSym: RETURN( VarParam.IsUnbounded )
10887
10888 ELSE
10889 InternalError ('expecting Param or VarParam symbol')
10890 END
10891 END
10892 END IsParameterUnbounded ;
10893
10894
10895 (*
10896 IsUnboundedParam - Returns a conditional depending whether parameter
10897 ParamNo is an unbounded array procedure parameter.
10898 *)
10899
10900 PROCEDURE IsUnboundedParam (Sym: CARDINAL; ParamNo: CARDINAL) : BOOLEAN ;
10901 VAR
10902 param: CARDINAL ;
10903 BEGIN
10904 Assert(IsProcedure(Sym) OR IsProcType(Sym)) ;
10905 param := GetNthParam(Sym, ParamNo) ;
10906 RETURN( IsParameterUnbounded(param) )
10907 END IsUnboundedParam ;
10908
10909
10910 (*
10911 IsParameter - returns true if Sym is a parameter symbol.
10912 *)
10913
10914 PROCEDURE IsParameter (Sym: CARDINAL) : BOOLEAN ;
10915 VAR
10916 pSym: PtrToSymbol ;
10917 BEGIN
10918 pSym := GetPsym(Sym) ;
10919 WITH pSym^ DO
10920 CASE SymbolType OF
10921
10922 ParamSym,
10923 VarParamSym: RETURN( TRUE )
10924
10925 ELSE
10926 RETURN( FALSE )
10927 END
10928 END
10929 END IsParameter ;
10930
10931
10932 (*
10933 GetParameterShadowVar - returns the local variable associated with the
10934 parameter symbol, sym.
10935 *)
10936
10937 PROCEDURE GetParameterShadowVar (sym: CARDINAL) : CARDINAL ;
10938 VAR
10939 pSym: PtrToSymbol ;
10940 BEGIN
10941 pSym := GetPsym(sym) ;
10942 WITH pSym^ DO
10943 CASE SymbolType OF
10944
10945 ParamSym : RETURN( Param.ShadowVar ) |
10946 VarParamSym: RETURN( VarParam.ShadowVar )
10947
10948 ELSE
10949 InternalError ('expecting a ParamSym or VarParamSym')
10950 END
10951 END
10952 END GetParameterShadowVar ;
10953
10954
10955 (*
10956 IsProcedure - returns true if Sym is a procedure symbol.
10957 *)
10958
10959 PROCEDURE IsProcedure (Sym: CARDINAL) : BOOLEAN ;
10960 VAR
10961 pSym: PtrToSymbol ;
10962 BEGIN
10963 CheckLegal(Sym) ;
10964 pSym := GetPsym(Sym) ;
10965 RETURN( pSym^.SymbolType=ProcedureSym )
10966 END IsProcedure ;
10967
10968
10969 (*
10970 ProcedureParametersDefined - dictates to procedure symbol, Sym,
10971 that its parameters have been defined.
10972 *)
10973
10974 PROCEDURE ProcedureParametersDefined (Sym: CARDINAL) ;
10975 VAR
10976 pSym: PtrToSymbol ;
10977 BEGIN
10978 CheckLegal(Sym) ;
10979 pSym := GetPsym(Sym) ;
10980 WITH pSym^ DO
10981 CASE SymbolType OF
10982
10983 ErrorSym : |
10984 ProcedureSym: Assert(NOT Procedure.ParamDefined) ;
10985 Procedure.ParamDefined := TRUE
10986
10987 ELSE
10988 InternalError ('expecting a Procedure symbol')
10989 END
10990 END
10991 END ProcedureParametersDefined ;
10992
10993
10994 (*
10995 AreProcedureParametersDefined - returns true if the parameters to procedure
10996 symbol, Sym, have been defined.
10997 *)
10998
10999 PROCEDURE AreProcedureParametersDefined (Sym: CARDINAL) : BOOLEAN ;
11000 VAR
11001 pSym: PtrToSymbol ;
11002 BEGIN
11003 CheckLegal(Sym) ;
11004 pSym := GetPsym(Sym) ;
11005 WITH pSym^ DO
11006 CASE SymbolType OF
11007
11008 ErrorSym : RETURN( FALSE ) |
11009 ProcedureSym: RETURN( Procedure.ParamDefined )
11010
11011 ELSE
11012 InternalError ('expecting a Procedure symbol')
11013 END
11014 END
11015 END AreProcedureParametersDefined ;
11016
11017
11018 (*
11019 ParametersDefinedInDefinition - dictates to procedure symbol, Sym,
11020 that its parameters have been defined in
11021 a definition module.
11022 *)
11023
11024 PROCEDURE ParametersDefinedInDefinition (Sym: CARDINAL) ;
11025 VAR
11026 pSym: PtrToSymbol ;
11027 BEGIN
11028 CheckLegal(Sym) ;
11029 pSym := GetPsym(Sym) ;
11030 WITH pSym^ DO
11031 CASE SymbolType OF
11032
11033 ErrorSym : |
11034 ProcedureSym: Assert(NOT Procedure.DefinedInDef) ;
11035 Procedure.DefinedInDef := TRUE
11036
11037 ELSE
11038 InternalError ('expecting a Procedure symbol')
11039 END
11040 END
11041 END ParametersDefinedInDefinition ;
11042
11043
11044 (*
11045 AreParametersDefinedInDefinition - returns true if procedure symbol, Sym,
11046 has had its parameters been defined in
11047 a definition module.
11048 *)
11049
11050 PROCEDURE AreParametersDefinedInDefinition (Sym: CARDINAL) : BOOLEAN ;
11051 VAR
11052 pSym: PtrToSymbol ;
11053 BEGIN
11054 CheckLegal(Sym) ;
11055 pSym := GetPsym(Sym) ;
11056 WITH pSym^ DO
11057 CASE SymbolType OF
11058
11059 ErrorSym : RETURN( FALSE ) |
11060 ProcedureSym: RETURN( Procedure.DefinedInDef )
11061
11062 ELSE
11063 InternalError ('expecting a Procedure symbol')
11064 END
11065 END
11066 END AreParametersDefinedInDefinition ;
11067
11068
11069 (*
11070 ParametersDefinedInImplementation - dictates to procedure symbol, Sym,
11071 that its parameters have been defined in
11072 a implemtation module.
11073 *)
11074
11075 PROCEDURE ParametersDefinedInImplementation (Sym: CARDINAL) ;
11076 VAR
11077 pSym: PtrToSymbol ;
11078 BEGIN
11079 CheckLegal(Sym) ;
11080 pSym := GetPsym(Sym) ;
11081 WITH pSym^ DO
11082 CASE SymbolType OF
11083
11084 ErrorSym : |
11085 ProcedureSym: Assert(NOT Procedure.DefinedInImp) ;
11086 Procedure.DefinedInImp := TRUE
11087
11088 ELSE
11089 InternalError ('expecting a Procedure symbol')
11090 END
11091 END
11092 END ParametersDefinedInImplementation ;
11093
11094
11095 (*
11096 AreParametersDefinedInImplementation - returns true if procedure symbol, Sym,
11097 has had its parameters been defined in
11098 an implementation module.
11099 *)
11100
11101 PROCEDURE AreParametersDefinedInImplementation (Sym: CARDINAL) : BOOLEAN ;
11102 VAR
11103 pSym: PtrToSymbol ;
11104 BEGIN
11105 CheckLegal(Sym) ;
11106 pSym := GetPsym(Sym) ;
11107 WITH pSym^ DO
11108 CASE SymbolType OF
11109
11110 ErrorSym : RETURN( FALSE ) |
11111 ProcedureSym: RETURN( Procedure.DefinedInImp )
11112
11113 ELSE
11114 InternalError ('expecting a Procedure symbol')
11115 END
11116 END
11117 END AreParametersDefinedInImplementation ;
11118
11119
11120 (*
11121 FillInUnknownFields -
11122 *)
11123
11124 PROCEDURE FillInUnknownFields (tok: CARDINAL; sym: CARDINAL; SymName: Name) ;
11125 VAR
11126 pSym: PtrToSymbol ;
11127 BEGIN
11128 pSym := GetPsym(sym) ;
11129 WITH pSym^ DO
11130 SymbolType := UndefinedSym ;
11131 WITH Undefined DO
11132 name := SymName ;
11133 oafamily := NulSym ;
11134 errorScope := GetCurrentErrorScope () ;
11135 InitWhereFirstUsedTok (tok, At)
11136 END
11137 END
11138 END FillInUnknownFields ;
11139
11140
11141 (*
11142 FillInPointerFields - given a new symbol, sym, make it a pointer symbol
11143 and initialize its fields.
11144 *)
11145
11146 PROCEDURE FillInPointerFields (Sym: CARDINAL; PointerName: Name;
11147 scope: CARDINAL; oaf: CARDINAL) ;
11148 VAR
11149 pSym: PtrToSymbol ;
11150 BEGIN
11151 IF NOT IsError(Sym)
11152 THEN
11153 pSym := GetPsym(Sym) ;
11154 WITH pSym^ DO
11155 SymbolType := PointerSym ;
11156 CASE SymbolType OF
11157
11158 PointerSym: Pointer.Type := NulSym ;
11159 Pointer.name := PointerName ;
11160 Pointer.oafamily := oaf ; (* The unbounded for this *)
11161 InitTree(Pointer.ConstLitTree) ; (* constants of this type *)
11162 Pointer.Scope := scope ; (* Which scope created it *)
11163 Pointer.Size := InitValue() ;
11164 Pointer.Align := NulSym ; (* Alignment of this type *)
11165
11166 ELSE
11167 InternalError ('expecting a Pointer symbol')
11168 END
11169 END
11170 END
11171 END FillInPointerFields ;
11172
11173
11174 (*
11175 MakePointer - returns a pointer symbol with PointerName.
11176 *)
11177
11178 PROCEDURE MakePointer (tok: CARDINAL; PointerName: Name) : CARDINAL ;
11179 VAR
11180 oaf, sym: CARDINAL ;
11181 BEGIN
11182 sym := HandleHiddenOrDeclare(tok, PointerName, oaf) ;
11183 FillInPointerFields(sym, PointerName, GetCurrentScope(), oaf) ;
11184 ForeachOAFamily(oaf, doFillInOAFamily) ;
11185 RETURN( sym )
11186 END MakePointer ;
11187
11188
11189 (*
11190 PutPointer - gives a pointer symbol a type, PointerType.
11191 *)
11192
11193 PROCEDURE PutPointer (Sym: CARDINAL; PointerType: CARDINAL) ;
11194 VAR
11195 pSym: PtrToSymbol ;
11196 BEGIN
11197 pSym := GetPsym(Sym) ;
11198 WITH pSym^ DO
11199 CASE SymbolType OF
11200
11201 ErrorSym : |
11202 PointerSym: Pointer.Type := PointerType
11203
11204 ELSE
11205 InternalError ('expecting a Pointer symbol')
11206 END
11207 END
11208 END PutPointer ;
11209
11210
11211 (*
11212 IsPointer - returns true is Sym is a pointer type symbol.
11213 *)
11214
11215 PROCEDURE IsPointer (Sym: CARDINAL) : BOOLEAN ;
11216 VAR
11217 pSym: PtrToSymbol ;
11218 BEGIN
11219 CheckLegal(Sym) ;
11220 pSym := GetPsym(Sym) ;
11221 RETURN( pSym^.SymbolType=PointerSym )
11222 END IsPointer ;
11223
11224
11225 (*
11226 IsRecord - returns true is Sym is a record type symbol.
11227 *)
11228
11229 PROCEDURE IsRecord (Sym: CARDINAL) : BOOLEAN ;
11230 VAR
11231 pSym: PtrToSymbol ;
11232 BEGIN
11233 CheckLegal(Sym) ;
11234 pSym := GetPsym(Sym) ;
11235 RETURN( pSym^.SymbolType=RecordSym )
11236 END IsRecord ;
11237
11238
11239 (*
11240 IsArray - returns true is Sym is an array type symbol.
11241 *)
11242
11243 PROCEDURE IsArray (Sym: CARDINAL) : BOOLEAN ;
11244 VAR
11245 pSym: PtrToSymbol ;
11246 BEGIN
11247 CheckLegal(Sym) ;
11248 pSym := GetPsym(Sym) ;
11249 RETURN( pSym^.SymbolType=ArraySym )
11250 END IsArray ;
11251
11252
11253 (*
11254 IsEnumeration - returns true if Sym is an enumeration symbol.
11255 *)
11256
11257 PROCEDURE IsEnumeration (Sym: CARDINAL) : BOOLEAN ;
11258 VAR
11259 pSym: PtrToSymbol ;
11260 BEGIN
11261 CheckLegal(Sym) ;
11262 pSym := GetPsym(Sym) ;
11263 RETURN( pSym^.SymbolType=EnumerationSym )
11264 END IsEnumeration ;
11265
11266
11267 (*
11268 IsUnbounded - returns true if Sym is an unbounded symbol.
11269 *)
11270
11271 PROCEDURE IsUnbounded (Sym: CARDINAL) : BOOLEAN ;
11272 VAR
11273 pSym: PtrToSymbol ;
11274 BEGIN
11275 CheckLegal(Sym) ;
11276 pSym := GetPsym(Sym) ;
11277 RETURN( pSym^.SymbolType=UnboundedSym )
11278 END IsUnbounded ;
11279
11280
11281 (*
11282 GetVarScope - returns the symbol which is the scope of variable Sym.
11283 ie a Module, DefImp or Procedure Symbol.
11284 *)
11285
11286 PROCEDURE GetVarScope (Sym: CARDINAL) : CARDINAL ;
11287 VAR
11288 pSym: PtrToSymbol ;
11289 BEGIN
11290 pSym := GetPsym(Sym) ;
11291 WITH pSym^ DO
11292 CASE SymbolType OF
11293
11294 ErrorSym: RETURN( NulSym ) |
11295 VarSym : RETURN( Var.Scope )
11296
11297 ELSE
11298 InternalError ('expecting a Var symbol')
11299 END
11300 END
11301 END GetVarScope ;
11302
11303
11304 (*
11305 NoOfElements - Returns the number of elements in array Sym,
11306 or the number of elements in an enumeration Sym or
11307 the number of interface symbols in an Interface list.
11308 *)
11309
11310 PROCEDURE NoOfElements (Sym: CARDINAL) : CARDINAL ;
11311 VAR
11312 pSym: PtrToSymbol ;
11313 n : CARDINAL ;
11314 BEGIN
11315 pSym := GetPsym(Sym) ;
11316 WITH pSym^ DO
11317 CASE SymbolType OF
11318
11319 ErrorSym : n := 0 |
11320 (*
11321 ArraySym ,
11322 UnboundedSym : n := 1 | (* Standard language limitation *)
11323 *)
11324 EnumerationSym: n := pSym^.Enumeration.NoOfElements |
11325 InterfaceSym : n := HighIndice(Interface.Parameters)
11326
11327 ELSE
11328 InternalError ('expecting an Array or UnBounded symbol')
11329 END
11330 END ;
11331 RETURN( n )
11332 END NoOfElements ;
11333
11334
11335 (*
11336 PutArraySubscript - places an index field into the array Sym. The
11337 index field is a subscript sym.
11338 *)
11339
11340 PROCEDURE PutArraySubscript (Sym: CARDINAL; SubscriptSymbol: CARDINAL) ;
11341 VAR
11342 pSym: PtrToSymbol ;
11343 BEGIN
11344 pSym := GetPsym(Sym) ;
11345 WITH pSym^ DO
11346 CASE SymbolType OF
11347
11348 ErrorSym: |
11349 ArraySym: Array.Subscript := SubscriptSymbol
11350
11351 ELSE
11352 InternalError ('expecting an Array symbol')
11353 END
11354 END
11355 END PutArraySubscript ;
11356
11357
11358 (*
11359 GetArraySubscript - returns the subscript symbol for array, Sym.
11360 *)
11361
11362 PROCEDURE GetArraySubscript (Sym: CARDINAL) : CARDINAL ;
11363 VAR
11364 pSym: PtrToSymbol ;
11365 BEGIN
11366 pSym := GetPsym(Sym) ;
11367 WITH pSym^ DO
11368 CASE SymbolType OF
11369
11370 ErrorSym: RETURN( NulSym ) |
11371 ArraySym: RETURN( Array.Subscript )
11372
11373 ELSE
11374 InternalError ('expecting an Array symbol')
11375 END
11376 END
11377 END GetArraySubscript ;
11378
11379
11380 (*
11381 MakeSubscript - makes a subscript Symbol.
11382 No name is required.
11383 *)
11384
11385 PROCEDURE MakeSubscript () : CARDINAL ;
11386 VAR
11387 pSym: PtrToSymbol ;
11388 Sym : CARDINAL ;
11389 BEGIN
11390 NewSym(Sym) ;
11391 pSym := GetPsym(Sym) ;
11392 WITH pSym^ DO
11393 SymbolType := SubscriptSym ;
11394 WITH Subscript DO
11395 Type := NulSym ; (* Index to a subrange symbol. *)
11396 Size := InitValue() ; (* Size of this indice in*Size *)
11397 Offset := InitValue() ; (* Offset at runtime of symbol *)
11398 (* Pseudo ie: Offset+Size*i *)
11399 (* 1..n. The array offset is *)
11400 (* the real memory offset. *)
11401 (* This offset allows the a[i] *)
11402 (* to be calculated without *)
11403 (* the need to perform *)
11404 (* subtractions when a[4..10] *)
11405 (* needs to be indexed. *)
11406 InitWhereDeclared(At) (* Declared here *)
11407 END
11408 END ;
11409 RETURN( Sym )
11410 END MakeSubscript ;
11411
11412
11413 (*
11414 PutSubscript - gives a subscript symbol a type, SimpleType.
11415 *)
11416
11417 PROCEDURE PutSubscript (Sym: CARDINAL; SimpleType: CARDINAL) ;
11418 VAR
11419 pSym: PtrToSymbol ;
11420 BEGIN
11421 pSym := GetPsym(Sym) ;
11422 WITH pSym^ DO
11423 CASE SymbolType OF
11424
11425 ErrorSym: |
11426 SubscriptSym: Subscript.Type := SimpleType ;
11427
11428 ELSE
11429 InternalError ('expecting a SubScript symbol')
11430 END
11431 END
11432 END PutSubscript ;
11433
11434
11435 (*
11436 MakeSet - makes a set Symbol with name, SetName.
11437 *)
11438
11439 PROCEDURE MakeSet (tok: CARDINAL; SetName: Name) : CARDINAL ;
11440 VAR
11441 pSym : PtrToSymbol ;
11442 oaf, sym: CARDINAL ;
11443 BEGIN
11444 sym := HandleHiddenOrDeclare(tok, SetName, oaf) ;
11445 IF NOT IsError(sym)
11446 THEN
11447 pSym := GetPsym(sym) ;
11448 WITH pSym^ DO
11449 SymbolType := SetSym ;
11450 WITH Set DO
11451 name := SetName ; (* The name of the set. *)
11452 Type := NulSym ; (* Index to a subrange symbol. *)
11453 Size := InitValue() ; (* Size of this set *)
11454 InitPacked(packedInfo) ; (* not packed and no *)
11455 (* equivalent (yet). *)
11456 ispacked := FALSE ; (* Not yet known to be packed. *)
11457 oafamily := oaf ; (* The unbounded sym for this *)
11458 Scope := GetCurrentScope() ; (* Which scope created it *)
11459 InitWhereDeclaredTok(tok, At) (* Declared here *)
11460 END
11461 END
11462 END ;
11463 ForeachOAFamily(oaf, doFillInOAFamily) ;
11464 RETURN( sym )
11465 END MakeSet ;
11466
11467
11468 (*
11469 PutSet - places SimpleType as the type for set, Sym.
11470 *)
11471
11472 PROCEDURE PutSet (Sym: CARDINAL; SimpleType: CARDINAL; packed: BOOLEAN) ;
11473 VAR
11474 pSym: PtrToSymbol ;
11475 BEGIN
11476 pSym := GetPsym(Sym) ;
11477 WITH pSym^ DO
11478 CASE SymbolType OF
11479
11480 ErrorSym: |
11481 SetSym: WITH Set DO
11482 Type := SimpleType ; (* Index to a subrange symbol *)
11483 (* or an enumeration type. *)
11484 ispacked := packed
11485 END
11486 ELSE
11487 InternalError ('expecting a Set symbol')
11488 END
11489 END
11490 END PutSet ;
11491
11492
11493 (*
11494 IsSet - returns TRUE if Sym is a set symbol.
11495 *)
11496
11497 PROCEDURE IsSet (Sym: CARDINAL) : BOOLEAN ;
11498 VAR
11499 pSym: PtrToSymbol ;
11500 BEGIN
11501 CheckLegal(Sym) ;
11502 pSym := GetPsym(Sym) ;
11503 RETURN( pSym^.SymbolType=SetSym )
11504 END IsSet ;
11505
11506
11507 (*
11508 IsSetPacked - returns TRUE if Sym is packed.
11509 *)
11510
11511 PROCEDURE IsSetPacked (Sym: CARDINAL) : BOOLEAN ;
11512 VAR
11513 pSym: PtrToSymbol ;
11514 BEGIN
11515 CheckLegal (Sym) ;
11516 pSym := GetPsym (Sym) ;
11517 RETURN (pSym^.SymbolType=SetSym) AND pSym^.Set.ispacked
11518 END IsSetPacked ;
11519
11520
11521 (*
11522 ForeachParameterDo -
11523 *)
11524
11525 PROCEDURE ForeachParameterDo (p: CheckProcedure) ;
11526 VAR
11527 l, h: CARDINAL ;
11528 BEGIN
11529 l := LowIndice(Symbols) ;
11530 h := HighIndice(Symbols) ;
11531 WHILE l<=h DO
11532 IF IsParameter(l)
11533 THEN
11534 p(l)
11535 END ;
11536 INC(l)
11537 END
11538 END ForeachParameterDo ;
11539
11540
11541 (*
11542 CheckUnbounded - checks to see if parameter, Sym, is now an unbounded parameter.
11543 *)
11544
11545 PROCEDURE CheckUnbounded (Sym: CARDINAL) ;
11546 VAR
11547 pSym: PtrToSymbol ;
11548 BEGIN
11549 CheckLegal(Sym) ;
11550 pSym := GetPsym(Sym) ;
11551 WITH pSym^ DO
11552 CASE SymbolType OF
11553
11554 ParamSym : IF IsUnbounded(Param.Type)
11555 THEN
11556 Param.IsUnbounded := TRUE
11557 END |
11558 VarParamSym: IF IsUnbounded(VarParam.Type)
11559 THEN
11560 VarParam.IsUnbounded := TRUE
11561 END
11562
11563 ELSE
11564 HALT
11565 END
11566 END
11567 END CheckUnbounded ;
11568
11569
11570 (*
11571 IsOAFamily - returns TRUE if, Sym, is an OAFamily symbol.
11572 *)
11573
11574 PROCEDURE IsOAFamily (Sym: CARDINAL) : BOOLEAN ;
11575 VAR
11576 pSym: PtrToSymbol ;
11577 BEGIN
11578 CheckLegal(Sym) ;
11579 pSym := GetPsym(Sym) ;
11580 RETURN( pSym^.SymbolType=OAFamilySym )
11581 END IsOAFamily ;
11582
11583
11584 (*
11585 MakeOAFamily - makes an OAFamily symbol based on SimpleType.
11586 It returns the OAFamily symbol. A new symbol
11587 is created if one does not already exist for
11588 SimpleType.
11589 *)
11590
11591 PROCEDURE MakeOAFamily (SimpleType: CARDINAL) : CARDINAL ;
11592 VAR
11593 pSym: PtrToSymbol ;
11594 sym : CARDINAL ;
11595 BEGIN
11596 sym := GetOAFamily(SimpleType) ;
11597 IF sym=NulSym
11598 THEN
11599 NewSym(sym) ;
11600 pSym := GetPsym(sym) ;
11601 WITH pSym^ DO
11602 SymbolType := OAFamilySym ;
11603 OAFamily.MaxDimensions := 0 ;
11604 OAFamily.SimpleType := SimpleType ;
11605 OAFamily.Dimensions := Indexing.InitIndex(1)
11606 END ;
11607 PutOAFamily(SimpleType, sym)
11608 END ;
11609 RETURN( sym )
11610 END MakeOAFamily ;
11611
11612
11613 (*
11614 GetOAFamily - returns the oafamily symbol associated with
11615 SimpleType.
11616 *)
11617
11618 PROCEDURE GetOAFamily (SimpleType: CARDINAL) : CARDINAL ;
11619 VAR
11620 pSym: PtrToSymbol ;
11621 BEGIN
11622 pSym := GetPsym(SimpleType) ;
11623 WITH pSym^ DO
11624 CASE SymbolType OF
11625
11626 ErrorSym : RETURN( NulSym ) |
11627 RecordSym : RETURN( Record.oafamily ) |
11628 SubrangeSym : RETURN( Subrange.oafamily ) |
11629 EnumerationSym: RETURN( Enumeration.oafamily ) |
11630 ArraySym : RETURN( Array.oafamily ) |
11631 ProcTypeSym : RETURN( ProcType.oafamily ) |
11632 TypeSym : RETURN( Type.oafamily ) |
11633 PointerSym : RETURN( Pointer.oafamily ) |
11634 SetSym : RETURN( Set.oafamily ) |
11635 UndefinedSym : RETURN( Undefined.oafamily )
11636
11637 ELSE
11638 RETURN( NulSym )
11639 END
11640 END
11641 END GetOAFamily ;
11642
11643
11644 (*
11645 PutOAFamily - places the, oaf, into, SimpleType, oafamily field.
11646 *)
11647
11648 PROCEDURE PutOAFamily (SimpleType: CARDINAL; oaf: CARDINAL) ;
11649 VAR
11650 pSym: PtrToSymbol ;
11651 BEGIN
11652 pSym := GetPsym(SimpleType) ;
11653 WITH pSym^ DO
11654 CASE SymbolType OF
11655
11656 ErrorSym : |
11657 RecordSym : Record.oafamily := oaf |
11658 SubrangeSym : Subrange.oafamily := oaf |
11659 EnumerationSym: Enumeration.oafamily := oaf |
11660 ArraySym : Array.oafamily := oaf |
11661 ProcTypeSym : ProcType.oafamily := oaf |
11662 TypeSym : Type.oafamily := oaf |
11663 PointerSym : Pointer.oafamily := oaf |
11664 SetSym : Set.oafamily := oaf |
11665 UndefinedSym : Undefined.oafamily := oaf
11666
11667 ELSE
11668 InternalError ('not expecting this SimpleType')
11669 END
11670 END
11671 END PutOAFamily ;
11672
11673
11674 (*
11675 ForeachOAFamily - call, p[oaf, ndim, symbol] for every unbounded symbol,
11676 sym, in the oaf.
11677 *)
11678
11679 PROCEDURE ForeachOAFamily (sym: CARDINAL; p: FamilyOperation) ;
11680 VAR
11681 pSym: PtrToSymbol ;
11682 h, i: CARDINAL ;
11683 pc : POINTER TO CARDINAL ;
11684 BEGIN
11685 IF sym#NulSym
11686 THEN
11687 pSym := GetPsym(sym) ;
11688 WITH pSym^ DO
11689 CASE SymbolType OF
11690
11691 OAFamilySym: h := Indexing.HighIndice(OAFamily.Dimensions) ;
11692 i := 1 ;
11693 WHILE i<=h DO
11694 pc := Indexing.GetIndice(OAFamily.Dimensions, i) ;
11695 IF pc#NIL
11696 THEN
11697 p(sym, i, pc^)
11698 END ;
11699 INC(i)
11700 END
11701
11702 ELSE
11703 InternalError ('expecting OAFamily symbol')
11704 END
11705 END
11706 END
11707 END ForeachOAFamily ;
11708
11709
11710 (*
11711 doFillInOAFamily -
11712 *)
11713
11714 PROCEDURE doFillInOAFamily (oaf: CARDINAL; i: CARDINAL; unbounded: CARDINAL) ;
11715 VAR
11716 SimpleType: CARDINAL ;
11717 BEGIN
11718 SimpleType := GetType(oaf) ;
11719 IF unbounded#NulSym
11720 THEN
11721 FillInUnboundedFields(GetTokenNo(), unbounded, SimpleType, i)
11722 END
11723 END doFillInOAFamily ;
11724
11725
11726 (*
11727 FillInUnboundedFields -
11728 *)
11729
11730 PROCEDURE FillInUnboundedFields (tok: CARDINAL;
11731 sym: CARDINAL; SimpleType: CARDINAL; ndim: CARDINAL) ;
11732 VAR
11733 pSym : PtrToSymbol ;
11734 Contents: CARDINAL ;
11735 i : CARDINAL ;
11736 BEGIN
11737 IF sym#NulSym
11738 THEN
11739 pSym := GetPsym(sym) ;
11740 WITH pSym^ DO
11741 SymbolType := UnboundedSym ;
11742 WITH Unbounded DO
11743 Type := SimpleType ; (* Index to a simple type. *)
11744 Size := InitValue() ; (* Size in bytes for this sym *)
11745 Scope := GetScope(SimpleType) ; (* Which scope will create it *)
11746 InitWhereDeclaredTok(tok, At) ; (* Declared here *)
11747 NewSym(RecordType) ;
11748 FillInRecordFields(tok, RecordType, NulName, GetScope(SimpleType), NulSym) ;
11749 NewSym(Contents) ;
11750 FillInPointerFields(Contents, NulName, GetScope(SimpleType), NulSym) ;
11751 PutPointer(Contents, SimpleType) ;
11752 (* create the contents field for the unbounded array. *)
11753 Assert (PutFieldRecord(RecordType,
11754 MakeKey(UnboundedAddressName),
11755 Contents, NulSym) # NulSym) ;
11756 (* create all the high fields for the unbounded array. *)
11757 i := 1 ;
11758 WHILE i<=ndim DO
11759 Assert (PutFieldRecord(RecordType,
11760 makekey(string(Mark(Sprintf1(Mark(InitString(UnboundedHighName)), i)))),
11761 Cardinal, NulSym) # NulSym) ;
11762 INC(i)
11763 END ;
11764 Dimensions := ndim
11765 END
11766 END ;
11767 ForeachParameterDo(CheckUnbounded)
11768 END
11769 END FillInUnboundedFields ;
11770
11771
11772 (*
11773 MakeUnbounded - makes an unbounded array Symbol.
11774 ndim is the number of dimensions required.
11775 No name is required.
11776 *)
11777
11778 PROCEDURE MakeUnbounded (tok: CARDINAL;
11779 SimpleType: CARDINAL; ndim: CARDINAL) : CARDINAL ;
11780 VAR
11781 sym, oaf: CARDINAL ;
11782 BEGIN
11783 oaf := MakeOAFamily(SimpleType) ;
11784 sym := GetUnbounded(oaf, ndim) ;
11785 IF sym=NulSym
11786 THEN
11787 NewSym(sym) ;
11788 IF IsUnknown (SimpleType)
11789 THEN
11790 PutPartialUnbounded(sym, SimpleType, ndim)
11791 ELSE
11792 FillInUnboundedFields(tok, sym, SimpleType, ndim)
11793 END ;
11794 PutUnbounded(oaf, sym, ndim)
11795 END ;
11796 RETURN( sym )
11797 END MakeUnbounded ;
11798
11799
11800 (*
11801 GetUnbounded - returns the unbounded symbol associated with
11802 the OAFamily symbol, oaf, and the number of
11803 dimensions, ndim, of the open array.
11804 *)
11805
11806 PROCEDURE GetUnbounded (oaf: CARDINAL; ndim: CARDINAL) : CARDINAL ;
11807 VAR
11808 pSym: PtrToSymbol ;
11809 BEGIN
11810 pSym := GetPsym(oaf) ;
11811 WITH pSym^ DO
11812 CASE SymbolType OF
11813
11814 OAFamilySym: WITH OAFamily DO
11815 IF ndim>MaxDimensions
11816 THEN
11817 RETURN( NulSym )
11818 ELSE
11819 RETURN( GetFromIndex(Dimensions, ndim) )
11820 END
11821 END
11822
11823 ELSE
11824 InternalError ('expecting OAFamily symbol')
11825 END
11826 END
11827 END GetUnbounded ;
11828
11829
11830 (*
11831 PutUnbounded - associates the unbounded symbol, open, with
11832 SimpleType.
11833 *)
11834
11835 PROCEDURE PutUnbounded (oaf: CARDINAL; sym: CARDINAL; ndim: CARDINAL) ;
11836 VAR
11837 pSym: PtrToSymbol ;
11838 BEGIN
11839 pSym := GetPsym(oaf) ;
11840 WITH pSym^ DO
11841 CASE SymbolType OF
11842
11843 OAFamilySym: WITH OAFamily DO
11844 (* need to check to see if we need to add NulSym for all dimensions < ndim
11845 which have not been used. *)
11846 WHILE MaxDimensions<ndim DO
11847 INC(MaxDimensions) ;
11848 IF MaxDimensions<ndim
11849 THEN
11850 (* add NulSym to an unused dimension. *)
11851 PutIntoIndex(Dimensions, MaxDimensions, NulSym)
11852 END
11853 END ;
11854 (* and finally add the known sym. *)
11855 PutIntoIndex(Dimensions, ndim, sym)
11856 END
11857
11858 ELSE
11859 InternalError ('expecting OAFamily symbol')
11860 END
11861 END
11862 END PutUnbounded ;
11863
11864
11865 (*
11866 GetUnboundedRecordType - returns the record type used to
11867 implement the unbounded array.
11868 *)
11869
11870 PROCEDURE GetUnboundedRecordType (Sym: CARDINAL) : CARDINAL ;
11871 VAR
11872 pSym: PtrToSymbol ;
11873 BEGIN
11874 pSym := GetPsym(Sym) ;
11875 WITH pSym^ DO
11876 CASE SymbolType OF
11877
11878 UnboundedSym: RETURN( Unbounded.RecordType )
11879
11880 ELSE
11881 InternalError ('expecting an UnBounded symbol')
11882 END
11883 END
11884 END GetUnboundedRecordType ;
11885
11886
11887 (*
11888 GetUnboundedAddressOffset - returns the offset of the address field
11889 inside the record used to implement the
11890 unbounded type.
11891 *)
11892
11893 PROCEDURE GetUnboundedAddressOffset (sym: CARDINAL) : CARDINAL ;
11894 VAR
11895 field,
11896 rec : CARDINAL ;
11897 BEGIN
11898 rec := GetUnboundedRecordType(sym) ;
11899 IF rec=NulSym
11900 THEN
11901 InternalError ('expecting record type to be declared')
11902 ELSE
11903 field := GetLocalSym(rec, MakeKey(UnboundedAddressName)) ;
11904 IF field=NulSym
11905 THEN
11906 InternalError ('expecting address field to be present inside unbounded record')
11907 ELSE
11908 RETURN( field )
11909 END
11910 END
11911 END GetUnboundedAddressOffset ;
11912
11913
11914 (*
11915 GetUnboundedHighOffset - returns the offset of the high field
11916 inside the record used to implement the
11917 unbounded type.
11918 *)
11919
11920 PROCEDURE GetUnboundedHighOffset (sym: CARDINAL; ndim: CARDINAL) : CARDINAL ;
11921 VAR
11922 rec: CARDINAL ;
11923 BEGIN
11924 rec := GetUnboundedRecordType(sym) ;
11925 IF rec=NulSym
11926 THEN
11927 InternalError ('expecting record type to be declared')
11928 ELSE
11929 RETURN GetLocalSym(rec,
11930 makekey(string(Mark(Sprintf1(Mark(InitString(UnboundedHighName)),
11931 ndim)))))
11932 END
11933 END GetUnboundedHighOffset ;
11934
11935
11936 (*
11937 GetArrayDimension - returns the number of dimensions defined.
11938 *)
11939
11940 PROCEDURE GetArrayDimension (sym: CARDINAL) : CARDINAL ;
11941 VAR
11942 n: CARDINAL ;
11943 BEGIN
11944 n := 0 ;
11945 WHILE IsArray(sym) DO
11946 sym := SkipType(GetType(sym)) ;
11947 INC(n)
11948 END ;
11949 RETURN( n )
11950 END GetArrayDimension ;
11951
11952
11953 (*
11954 GetDimension - return the number of dimensions associated with
11955 this unbounded ARRAY parameter.
11956 *)
11957
11958 PROCEDURE GetDimension (sym: CARDINAL) : CARDINAL ;
11959 VAR
11960 pSym: PtrToSymbol ;
11961 BEGIN
11962 pSym := GetPsym(sym) ;
11963 WITH pSym^ DO
11964 CASE SymbolType OF
11965
11966 PartialUnboundedSym: RETURN( PartialUnbounded.NDim ) |
11967 UnboundedSym : RETURN( Unbounded.Dimensions ) |
11968 OAFamilySym : RETURN( OAFamily.MaxDimensions ) |
11969 ParamSym : IF Param.IsUnbounded
11970 THEN
11971 RETURN( GetDimension(GetType(sym)) )
11972 ELSE
11973 InternalError ('expecting unbounded paramater')
11974 END |
11975 VarParamSym : IF VarParam.IsUnbounded
11976 THEN
11977 RETURN( GetDimension(GetType(sym)) )
11978 ELSE
11979 InternalError ('expecting unbounded paramater')
11980 END |
11981 ArraySym : RETURN( GetArrayDimension(sym) ) |
11982 TypeSym : RETURN( GetDimension(GetType(sym)) ) |
11983 VarSym : RETURN( GetDimension(GetType(sym)) )
11984
11985 ELSE
11986 InternalError ('expecting PartialUnbounded')
11987 END
11988 END
11989 END GetDimension ;
11990
11991
11992 (*
11993 PutArray - places a type symbol into an Array.
11994 *)
11995
11996 PROCEDURE PutArray (Sym, TypeSymbol: CARDINAL) ;
11997 VAR
11998 pSym: PtrToSymbol ;
11999 BEGIN
12000 pSym := GetPsym(Sym) ;
12001 WITH pSym^ DO
12002 CASE SymbolType OF
12003
12004 ErrorSym: |
12005 ArraySym: WITH Array DO
12006 Type := TypeSymbol (* The Array Type. ARRAY OF Type. *)
12007 END
12008 ELSE
12009 InternalError ('expecting an Array symbol')
12010 END
12011 END
12012 END PutArray ;
12013
12014
12015 (*
12016 ResolveConstructorType - if, sym, has an unresolved constructor type
12017 then attempt to resolve it by examining the
12018 from, type.
12019 *)
12020
12021 PROCEDURE ResolveConstructorType (sym: CARDINAL;
12022 VAR type: CARDINAL;
12023 VAR from: CARDINAL;
12024 VAR unres: BOOLEAN) ;
12025 BEGIN
12026 IF unres
12027 THEN
12028 IF IsConstructor(from)
12029 THEN
12030 IF IsConstructorResolved(from)
12031 THEN
12032 unres := FALSE ;
12033 type := GetType(from) ;
12034 IF (type#NulSym) AND IsSet(SkipType(type))
12035 THEN
12036 PutConstSet(sym)
12037 END
12038 END
12039 ELSIF (from#NulSym) AND IsSet(SkipType(from))
12040 THEN
12041 unres := FALSE ;
12042 type := from ;
12043 PutConstSet(sym)
12044 ELSIF (from#NulSym) AND (IsRecord(SkipType(from)) OR IsArray(SkipType(from)))
12045 THEN
12046 unres := FALSE ;
12047 type := from
12048 END
12049 END
12050 END ResolveConstructorType ;
12051
12052
12053 (*
12054 IsConstructorResolved - returns TRUE if the constructor does not
12055 have an unresolved type.
12056 *)
12057
12058 PROCEDURE IsConstructorResolved (sym: CARDINAL) : BOOLEAN ;
12059 VAR
12060 pSym: PtrToSymbol ;
12061 BEGIN
12062 pSym := GetPsym(sym) ;
12063 WITH pSym^ DO
12064 CASE SymbolType OF
12065
12066 ConstVarSym: RETURN( NOT ConstVar.UnresFromType ) |
12067 ConstLitSym: RETURN( NOT ConstLit.UnresFromType )
12068
12069 ELSE
12070 InternalError ('expecting ConstVar or ConstLit symbol')
12071 END
12072 END
12073 END IsConstructorResolved ;
12074
12075
12076 (*
12077 CanResolveConstructor - returns TRUE if the type of the constructor,
12078 sym, is known.
12079 *)
12080
12081 PROCEDURE CanResolveConstructor (sym: CARDINAL) : BOOLEAN ;
12082 VAR
12083 pSym: PtrToSymbol ;
12084 BEGIN
12085 IF NOT IsConstructorResolved(sym)
12086 THEN
12087 pSym := GetPsym(sym) ;
12088 WITH pSym^ DO
12089 CASE SymbolType OF
12090
12091 ConstVarSym: WITH ConstVar DO
12092 ResolveConstructorType(sym, Type, FromType, UnresFromType)
12093 END |
12094 ConstLitSym: WITH ConstLit DO
12095 ResolveConstructorType(sym, Type, FromType, UnresFromType)
12096 END |
12097
12098 ELSE
12099 InternalError ('expecting ConstVar or ConstLit symbol')
12100 END
12101 END
12102 END ;
12103 RETURN( IsConstructorResolved(sym) )
12104 END CanResolveConstructor ;
12105
12106
12107 (*
12108 CheckAllConstructorsResolved - checks to see that the
12109 UnresolvedConstructorType list is
12110 empty and if it is not then it
12111 generates error messages.
12112 *)
12113
12114 PROCEDURE CheckAllConstructorsResolved ;
12115 VAR
12116 i, n, s: CARDINAL ;
12117 e : Error ;
12118 BEGIN
12119 n := NoOfItemsInList(UnresolvedConstructorType) ;
12120 IF n>0
12121 THEN
12122 FOR i := 1 TO n DO
12123 s := GetItemFromList(UnresolvedConstructorType, i) ;
12124 e := NewError(GetDeclaredMod(s)) ;
12125 ErrorFormat0(e, 'constructor has an unknown type')
12126 END ;
12127 FlushErrors
12128 END
12129 END CheckAllConstructorsResolved ;
12130
12131
12132 (*
12133 ResolveConstructorTypes - to be called at the end of pass three. Its
12134 purpose is to fix up all constructors whose
12135 types are unknown.
12136 *)
12137
12138 PROCEDURE ResolveConstructorTypes ;
12139 VAR
12140 finished: BOOLEAN ;
12141 i, n, s : CARDINAL ;
12142 BEGIN
12143 REPEAT
12144 n := NoOfItemsInList(UnresolvedConstructorType) ;
12145 finished := TRUE ;
12146 i := 1 ;
12147 WHILE i<=n DO
12148 s := GetItemFromList(UnresolvedConstructorType, i) ;
12149 Assert(IsConstructor(s)) ;
12150 IF CanResolveConstructor(s)
12151 THEN
12152 finished := FALSE ;
12153 RemoveItemFromList(UnresolvedConstructorType, s) ;
12154 i := n
12155 END ;
12156 INC(i)
12157 END
12158 UNTIL finished ;
12159 CheckAllConstructorsResolved
12160 END ResolveConstructorTypes ;
12161
12162
12163 (*
12164 SanityCheckParameters -
12165 *)
12166
12167 PROCEDURE SanityCheckParameters (sym: CARDINAL) ;
12168 VAR
12169 p : CARDINAL ;
12170 i, n: CARDINAL ;
12171 BEGIN
12172 i := 1 ;
12173 n := NoOfParam(sym) ;
12174 WHILE i<=n DO
12175 p := GetType(GetParam(sym, i)) ;
12176 IF IsConst(p)
12177 THEN
12178 MetaError3('the {%1N} formal parameter in procedure {%2Dad} should have a type rather than a constant {%3Dad}',
12179 i, sym, p)
12180 END ;
12181 INC(i)
12182 END
12183 END SanityCheckParameters ;
12184
12185
12186 (*
12187 SanityCheckArray - checks to see that an array has a correct subrange type.
12188 *)
12189
12190 PROCEDURE SanityCheckArray (sym: CARDINAL) ;
12191 VAR
12192 type : CARDINAL ;
12193 subscript: CARDINAL ;
12194 BEGIN
12195 IF IsArray(sym)
12196 THEN
12197 subscript := GetArraySubscript(sym) ;
12198 IF subscript#NulSym
12199 THEN
12200 type := SkipType(GetType(subscript)) ;
12201 IF IsAModula2Type(type)
12202 THEN
12203 (* ok all is good *)
12204 ELSE
12205 MetaError2('the array {%1Dad} must be declared with a simpletype in the [..] component rather than a {%2d}',
12206 sym, type)
12207 END
12208 END
12209 END
12210 END SanityCheckArray ;
12211
12212
12213 (*
12214 ForeachSymbolDo - foreach symbol, call, P(sym).
12215 *)
12216
12217 PROCEDURE ForeachSymbolDo (P: PerformOperation) ;
12218 VAR
12219 i, n: CARDINAL ;
12220 BEGIN
12221 i := Indexing.LowIndice(Symbols) ;
12222 n := Indexing.HighIndice(Symbols) ;
12223 WHILE i<=n DO
12224 P(i) ;
12225 INC(i)
12226 END
12227 END ForeachSymbolDo ;
12228
12229
12230 (*
12231 SanityCheckProcedure - check to see that procedure parameters do not use constants
12232 instead of types in their formal parameter section.
12233 *)
12234
12235 PROCEDURE SanityCheckProcedure (sym: CARDINAL) ;
12236 BEGIN
12237 SanityCheckParameters(sym)
12238 END SanityCheckProcedure ;
12239
12240
12241 (*
12242 SanityCheckModule -
12243 *)
12244
12245 PROCEDURE SanityCheckModule (sym: CARDINAL) ;
12246 BEGIN
12247 ForeachInnerModuleDo(sym, SanityCheckModule) ;
12248 ForeachProcedureDo(sym, SanityCheckProcedure) ;
12249 ForeachLocalSymDo(sym, SanityCheckArray)
12250 END SanityCheckModule ;
12251
12252
12253 (*
12254 SanityCheckConstants - must only be called once all constants, types, procedures
12255 have been declared. It checks to see that constants are
12256 not used as procedure parameter types.
12257 *)
12258
12259 PROCEDURE SanityCheckConstants ;
12260 BEGIN
12261 ForeachModuleDo(SanityCheckModule) ;
12262 ForeachSymbolDo(SanityCheckArray)
12263 END SanityCheckConstants ;
12264
12265
12266 (*
12267 AddNameTo - adds Name, n, to tree, s.
12268 *)
12269
12270 PROCEDURE AddNameTo (s: SymbolTree; o: CARDINAL) ;
12271 BEGIN
12272 IF GetSymKey(s, GetSymName(o))=NulKey
12273 THEN
12274 PutSymKey(s, GetSymName(o), o)
12275 END
12276 END AddNameTo ;
12277
12278
12279 (*
12280 AddNameToScope - adds a Name, n, to the list of objects declared at the
12281 current scope.
12282 *)
12283
12284 PROCEDURE AddNameToScope (n: Name) ;
12285 VAR
12286 pSym : PtrToSymbol ;
12287 scope: CARDINAL ;
12288 BEGIN
12289 scope := GetCurrentScope() ;
12290 pSym := GetPsym(scope) ;
12291 WITH pSym^ DO
12292 CASE SymbolType OF
12293
12294 ProcedureSym: AddNameTo(Procedure.NamedObjects, MakeObject(n)) |
12295 ModuleSym : AddNameTo(Module.NamedObjects, MakeObject(n)) |
12296 DefImpSym : AddNameTo(DefImp.NamedObjects, MakeObject(n))
12297
12298 ELSE
12299 InternalError ('expecting - DefImp')
12300 END
12301 END
12302 END AddNameToScope ;
12303
12304
12305 (*
12306 AddNameToImportList - adds a Name, n, to the import list of the current
12307 module.
12308 *)
12309
12310 PROCEDURE AddNameToImportList (n: Name) ;
12311 VAR
12312 pSym : PtrToSymbol ;
12313 scope: CARDINAL ;
12314 BEGIN
12315 scope := GetCurrentScope() ;
12316 pSym := GetPsym(scope) ;
12317 WITH pSym^ DO
12318 CASE SymbolType OF
12319
12320 ModuleSym: AddNameTo(Module.NamedImports, MakeObject(n)) |
12321 DefImpSym: AddNameTo(DefImp.NamedImports, MakeObject(n))
12322
12323 ELSE
12324 InternalError ('expecting - DefImp or Module symbol')
12325 END
12326 END
12327 END AddNameToImportList ;
12328
12329
12330 VAR
12331 ResolveModule: CARDINAL ;
12332
12333
12334 (*
12335 CollectSymbolFrom -
12336 *)
12337
12338 PROCEDURE CollectSymbolFrom (tok: CARDINAL; scope: CARDINAL; n: Name) : CARDINAL ;
12339 VAR
12340 n1 : Name ;
12341 sym: CARDINAL ;
12342 BEGIN
12343 n1 := GetSymName (scope) ;
12344 IF DebugUnknowns
12345 THEN
12346 printf2('declaring %a in %a', n, n1)
12347 END ;
12348 sym := CheckScopeForSym (scope, n) ;
12349 IF sym=NulSym
12350 THEN
12351 sym := FetchUnknownFrom (tok, scope, n)
12352 END ;
12353 IF DebugUnknowns
12354 THEN
12355 printf1(' symbol created (%d)\n', sym)
12356 END ;
12357 RETURN( sym )
12358 END CollectSymbolFrom ;
12359
12360
12361 (*
12362 CollectUnknown -
12363 *)
12364
12365 PROCEDURE CollectUnknown (tok: CARDINAL; sym: CARDINAL; n: Name) : CARDINAL ;
12366 VAR
12367 pSym: PtrToSymbol ;
12368 s : CARDINAL ;
12369 BEGIN
12370 s := NulSym ;
12371 IF IsModule (sym) OR IsDefImp (sym)
12372 THEN
12373 RETURN( CollectSymbolFrom (tok, sym, n) )
12374 ELSIF IsProcedure(sym)
12375 THEN
12376 s := CheckScopeForSym (sym, n) ;
12377 IF s=NulSym
12378 THEN
12379 pSym := GetPsym (sym) ;
12380 WITH pSym^ DO
12381 CASE SymbolType OF
12382
12383 ProcedureSym: IF GetSymKey (Procedure.NamedObjects, n) # NulKey
12384 THEN
12385 RETURN( CollectSymbolFrom (tok, sym, n) )
12386 END
12387
12388 ELSE
12389 InternalError ('expecting - Procedure symbol')
12390 END
12391 END ;
12392 s := CollectUnknown (tok, GetScope (sym), n)
12393 END
12394 END ;
12395 RETURN( s )
12396 END CollectUnknown ;
12397
12398
12399 (*
12400 ResolveImport -
12401 *)
12402
12403 PROCEDURE ResolveImport (o: WORD) ;
12404 VAR
12405 n1, n2: Name ;
12406 tok : CARDINAL ;
12407 sym : CARDINAL ;
12408 BEGIN
12409 IF DebugUnknowns
12410 THEN
12411 n1 := GetSymName(o) ;
12412 printf1('attempting to find out where %a was declared\n', n1) ;
12413 n1 := GetSymName(ResolveModule) ;
12414 n2 := GetSymName(GetScope(ResolveModule)) ;
12415 printf2('scope of module %a is %a\n', n1, n2)
12416 END ;
12417 tok := GetFirstUsed (o) ;
12418 sym := CollectUnknown (tok, GetScope(ResolveModule), GetSymName(o)) ;
12419 IF sym=NulSym
12420 THEN
12421 MetaError2('unknown symbol {%1Uad} found in import list of module {%2a}',
12422 o, ResolveModule)
12423 ELSE
12424 AddSymToModuleScope(ResolveModule, sym)
12425 END
12426 END ResolveImport ;
12427
12428
12429 (*
12430 ResolveRelativeImport -
12431 *)
12432
12433 PROCEDURE ResolveRelativeImport (sym: CARDINAL) ;
12434 VAR
12435 pSym: PtrToSymbol ;
12436 BEGIN
12437 IF IsModule(sym)
12438 THEN
12439 ResolveModule := sym ;
12440 pSym := GetPsym(sym) ;
12441 WITH pSym^ DO
12442 CASE SymbolType OF
12443
12444 ModuleSym: ForeachNodeDo(Module.NamedImports,
12445 ResolveImport)
12446
12447 ELSE
12448 InternalError ('expecting - Module symbol')
12449 END
12450 END
12451 END ;
12452 ForeachProcedureDo(sym, ResolveRelativeImport) ;
12453 ForeachInnerModuleDo(sym, ResolveRelativeImport)
12454 END ResolveRelativeImport ;
12455
12456
12457 (*
12458 ResolveImports - it examines the import list of all inner modules
12459 and resolves all relative imports.
12460 *)
12461
12462 PROCEDURE ResolveImports ;
12463 VAR
12464 scope: CARDINAL ;
12465 BEGIN
12466 scope := GetCurrentScope() ;
12467 IF DebugUnknowns
12468 THEN
12469 DisplayTrees(scope)
12470 END ;
12471 ForeachProcedureDo(scope, ResolveRelativeImport) ;
12472 ForeachInnerModuleDo(scope, ResolveRelativeImport)
12473 END ResolveImports ;
12474
12475
12476 (*
12477 GetScope - returns the declaration scope of the symbol.
12478 *)
12479
12480 PROCEDURE GetScope (Sym: CARDINAL) : CARDINAL ;
12481 VAR
12482 pSym: PtrToSymbol ;
12483 BEGIN
12484 pSym := GetPsym(Sym) ;
12485 WITH pSym^ DO
12486 CASE SymbolType OF
12487
12488 ErrorSym : ErrorAbort0('') |
12489 DefImpSym : RETURN( NulSym ) |
12490 ModuleSym : RETURN( Module.Scope ) |
12491 VarSym : RETURN( Var.Scope ) |
12492 ProcedureSym : RETURN( Procedure.Scope ) |
12493 ProcTypeSym : RETURN( ProcType.Scope ) |
12494 RecordFieldSym : RETURN( RecordField.Scope ) |
12495 VarientSym : RETURN( Varient.Scope ) |
12496 VarientFieldSym : RETURN( VarientField.Scope ) |
12497 EnumerationSym : RETURN( Enumeration.Scope ) |
12498 EnumerationFieldSym: RETURN( EnumerationField.Scope ) |
12499 SubrangeSym : RETURN( Subrange.Scope ) |
12500 ArraySym : RETURN( Array.Scope ) |
12501 TypeSym : RETURN( Type.Scope ) |
12502 PointerSym : RETURN( Pointer.Scope ) |
12503 RecordSym : RETURN( Record.Scope ) |
12504 SetSym : RETURN( Set.Scope ) |
12505 UnboundedSym : RETURN( Unbounded.Scope ) |
12506 ConstLitSym : RETURN( ConstLit.Scope ) |
12507 ConstStringSym : RETURN( ConstString.Scope ) |
12508 ConstVarSym : RETURN( ConstVar.Scope ) |
12509 PartialUnboundedSym: InternalError ('should not be requesting the scope of a PartialUnbounded symbol')
12510
12511 ELSE
12512 InternalError ('not implemented yet')
12513 END
12514 END
12515 END GetScope ;
12516
12517
12518 (*
12519 GetModuleScope - returns the module scope of symbol, sym.
12520 If sym was declared within a nested procedure
12521 then return the module which defines the
12522 procedure.
12523 *)
12524
12525 PROCEDURE GetModuleScope (sym: CARDINAL) : CARDINAL ;
12526 VAR
12527 mod: CARDINAL ;
12528 BEGIN
12529 mod := GetScope(sym) ;
12530 WHILE (mod#NulSym) AND (NOT IsDefImp(mod)) AND (NOT IsModule(mod)) DO
12531 mod := GetScope(mod)
12532 END ;
12533 RETURN( mod )
12534 END GetModuleScope ;
12535
12536
12537 (*
12538 GetProcedureScope - returns the innermost procedure (if any)
12539 in which the symbol, sym, resides.
12540 A module inside the procedure is skipped
12541 over.
12542 *)
12543
12544 PROCEDURE GetProcedureScope (sym: CARDINAL) : CARDINAL ;
12545 BEGIN
12546 WHILE (sym#NulSym) AND (NOT IsProcedure(sym)) DO
12547 sym := GetScope(sym)
12548 END ;
12549 IF (sym#NulSym) AND IsProcedure(sym)
12550 THEN
12551 RETURN( sym )
12552 ELSE
12553 RETURN( NulSym )
12554 END
12555 END GetProcedureScope ;
12556
12557
12558 (*
12559 IsModuleWithinProcedure - returns TRUE if module, sym, is
12560 inside a procedure.
12561 *)
12562
12563 PROCEDURE IsModuleWithinProcedure (sym: CARDINAL) : BOOLEAN ;
12564 BEGIN
12565 RETURN( GetProcedureScope(sym)#NulSym )
12566 END IsModuleWithinProcedure ;
12567
12568
12569 (*
12570 GetParent - returns the parent of symbol, Sym.
12571 *)
12572
12573 PROCEDURE GetParent (Sym: CARDINAL) : CARDINAL ;
12574 VAR
12575 pSym: PtrToSymbol ;
12576 BEGIN
12577 pSym := GetPsym(Sym) ;
12578 WITH pSym^ DO
12579 CASE SymbolType OF
12580
12581 ErrorSym : ErrorAbort0('') |
12582 VarientSym : RETURN( Varient.Parent ) |
12583 VarientFieldSym : RETURN( VarientField.Parent ) |
12584 RecordFieldSym : RETURN( RecordField.Parent ) |
12585 EnumerationFieldSym: RETURN( EnumerationField.Type )
12586
12587 ELSE
12588 InternalError ('not implemented yet')
12589 END
12590 END
12591 END GetParent ;
12592
12593
12594 (*
12595 IsRecordField - returns true if Sym is a record field.
12596 *)
12597
12598 PROCEDURE IsRecordField (Sym: CARDINAL) : BOOLEAN ;
12599 VAR
12600 pSym: PtrToSymbol ;
12601 BEGIN
12602 pSym := GetPsym(Sym) ;
12603 RETURN( pSym^.SymbolType=RecordFieldSym )
12604 END IsRecordField ;
12605
12606
12607 (*
12608 MakeProcType - returns a procedure type symbol with ProcTypeName.
12609 *)
12610
12611 PROCEDURE MakeProcType (tok: CARDINAL; ProcTypeName: Name) : CARDINAL ;
12612 VAR
12613 pSym : PtrToSymbol ;
12614 oaf, sym: CARDINAL ;
12615 BEGIN
12616 sym := HandleHiddenOrDeclare (tok, ProcTypeName, oaf) ;
12617 IF NOT IsError(sym)
12618 THEN
12619 pSym := GetPsym(sym) ;
12620 WITH pSym^ DO
12621 SymbolType := ProcTypeSym ;
12622 CASE SymbolType OF
12623
12624 ProcTypeSym: ProcType.ReturnType := NulSym ;
12625 ProcType.name := ProcTypeName ;
12626 InitList(ProcType.ListOfParam) ;
12627 ProcType.HasVarArgs := FALSE ; (* Does this proc type use ... ? *)
12628 ProcType.HasOptArg := FALSE ; (* Does this proc type use [ ] ? *)
12629 ProcType.OptArgInit := NulSym ; (* The optarg initial value. *)
12630 ProcType.ReturnOptional := FALSE ; (* Is the return value optional? *)
12631 ProcType.Scope := GetCurrentScope() ;
12632 (* scope of procedure. *)
12633 ProcType.Size := InitValue() ;
12634 ProcType.TotalParamSize := InitValue() ; (* size of all parameters *)
12635 ProcType.oafamily := oaf ; (* The oa family for this symbol *)
12636 InitWhereDeclaredTok(tok, ProcType.At) (* Declared here *)
12637
12638 ELSE
12639 InternalError ('expecting ProcType symbol')
12640 END
12641 END
12642 END ;
12643 ForeachOAFamily(oaf, doFillInOAFamily) ;
12644 RETURN( sym )
12645 END MakeProcType ;
12646
12647
12648 (*
12649 PutProcTypeParam - Places a Non VAR parameter ParamName with type
12650 ParamType into ProcType Sym.
12651 *)
12652
12653 PROCEDURE PutProcTypeParam (Sym: CARDINAL;
12654 ParamType: CARDINAL; isUnbounded: BOOLEAN) ;
12655 VAR
12656 pSym : PtrToSymbol ;
12657 ParSym: CARDINAL ;
12658 BEGIN
12659 NewSym(ParSym) ;
12660 pSym := GetPsym(ParSym) ;
12661 WITH pSym^ DO
12662 SymbolType := ParamSym ;
12663 WITH Param DO
12664 name := NulName ;
12665 Type := ParamType ;
12666 IsUnbounded := isUnbounded ;
12667 ShadowVar := NulSym ;
12668 InitWhereDeclared(At)
12669 END
12670 END ;
12671 AddParameter(Sym, ParSym)
12672 END PutProcTypeParam ;
12673
12674
12675 (*
12676 PutProcTypeVarParam - Places a Non VAR parameter ParamName with type
12677 ParamType into ProcType Sym.
12678 *)
12679
12680 PROCEDURE PutProcTypeVarParam (Sym: CARDINAL;
12681 ParamType: CARDINAL; isUnbounded: BOOLEAN) ;
12682 VAR
12683 pSym : PtrToSymbol ;
12684 ParSym: CARDINAL ;
12685 BEGIN
12686 NewSym(ParSym) ;
12687 pSym := GetPsym(ParSym) ;
12688 WITH pSym^ DO
12689 SymbolType := VarParamSym ;
12690 WITH Param DO
12691 name := NulName ;
12692 Type := ParamType ;
12693 IsUnbounded := isUnbounded ;
12694 ShadowVar := NulSym ;
12695 InitWhereDeclared(At)
12696 END
12697 END ;
12698 AddParameter(Sym, ParSym)
12699 END PutProcTypeVarParam ;
12700
12701
12702 (*
12703 PutProcedureReachable - Sets the procedure, Sym, to be reachable by the
12704 main Module.
12705 *)
12706
12707 PROCEDURE PutProcedureReachable (Sym: CARDINAL) ;
12708 VAR
12709 pSym: PtrToSymbol ;
12710 BEGIN
12711 pSym := GetPsym(Sym) ;
12712 WITH pSym^ DO
12713 CASE SymbolType OF
12714
12715 ErrorSym: |
12716 ProcedureSym: Procedure.Reachable := TRUE
12717
12718 ELSE
12719 InternalError ('expecting Procedure symbol')
12720 END
12721 END
12722 END PutProcedureReachable ;
12723
12724
12725 (*
12726 PutModuleStartQuad - Places QuadNumber into the Module symbol, Sym.
12727 QuadNumber is the start quad of Module,
12728 Sym.
12729 *)
12730
12731 PROCEDURE PutModuleStartQuad (Sym: CARDINAL; QuadNumber: CARDINAL) ;
12732 VAR
12733 pSym: PtrToSymbol ;
12734 BEGIN
12735 pSym := GetPsym(Sym) ;
12736 WITH pSym^ DO
12737 CASE SymbolType OF
12738
12739 ModuleSym: Module.StartQuad := QuadNumber |
12740 DefImpSym: DefImp.StartQuad := QuadNumber
12741
12742 ELSE
12743 InternalError ('expecting a Module or DefImp symbol')
12744 END
12745 END
12746 END PutModuleStartQuad ;
12747
12748
12749 (*
12750 PutModuleEndQuad - Places QuadNumber into the Module symbol, Sym.
12751 QuadNumber is the end quad of Module,
12752 Sym.
12753 *)
12754
12755 PROCEDURE PutModuleEndQuad (Sym: CARDINAL; QuadNumber: CARDINAL) ;
12756 VAR
12757 pSym: PtrToSymbol ;
12758 BEGIN
12759 pSym := GetPsym(Sym) ;
12760 WITH pSym^ DO
12761 CASE SymbolType OF
12762
12763 ModuleSym: Module.EndQuad := QuadNumber |
12764 DefImpSym: DefImp.EndQuad := QuadNumber
12765
12766 ELSE
12767 InternalError ('expecting a Module or DefImp symbol')
12768 END
12769 END
12770 END PutModuleEndQuad ;
12771
12772
12773 (*
12774 PutModuleFinallyStartQuad - Places QuadNumber into the Module symbol, Sym.
12775 QuadNumber is the finally start quad of
12776 Module, Sym.
12777 *)
12778
12779 PROCEDURE PutModuleFinallyStartQuad (Sym: CARDINAL; QuadNumber: CARDINAL) ;
12780 VAR
12781 pSym: PtrToSymbol ;
12782 BEGIN
12783 pSym := GetPsym(Sym) ;
12784 WITH pSym^ DO
12785 CASE SymbolType OF
12786
12787 ModuleSym: Module.StartFinishQuad := QuadNumber |
12788 DefImpSym: DefImp.StartFinishQuad := QuadNumber
12789
12790 ELSE
12791 InternalError ('expecting a Module or DefImp symbol')
12792 END
12793 END
12794 END PutModuleFinallyStartQuad ;
12795
12796
12797 (*
12798 PutModuleFinallyEndQuad - Places QuadNumber into the Module symbol, Sym.
12799 QuadNumber is the end quad of the finally block
12800 in Module, Sym.
12801 *)
12802
12803 PROCEDURE PutModuleFinallyEndQuad (Sym: CARDINAL; QuadNumber: CARDINAL) ;
12804 VAR
12805 pSym: PtrToSymbol ;
12806 BEGIN
12807 pSym := GetPsym(Sym) ;
12808 WITH pSym^ DO
12809 CASE SymbolType OF
12810
12811 ModuleSym: Module.EndFinishQuad := QuadNumber |
12812 DefImpSym: DefImp.EndFinishQuad := QuadNumber
12813
12814 ELSE
12815 InternalError ('expecting a Module or DefImp symbol')
12816 END
12817 END
12818 END PutModuleFinallyEndQuad ;
12819
12820
12821 (*
12822 GetModuleQuads - Returns, StartInit EndInit StartFinish EndFinish,
12823 Quads of a Module, Sym.
12824 Start and End represent the initialization code
12825 of the Module, Sym.
12826 *)
12827
12828 PROCEDURE GetModuleQuads (Sym: CARDINAL;
12829 VAR StartInit, EndInit,
12830 StartFinish, EndFinish: CARDINAL) ;
12831 VAR
12832 pSym: PtrToSymbol ;
12833 BEGIN
12834 pSym := GetPsym(Sym) ;
12835 WITH pSym^ DO
12836 CASE SymbolType OF
12837
12838 ModuleSym: WITH Module DO
12839 StartInit := StartQuad ;
12840 EndInit := EndQuad ;
12841 StartFinish := StartFinishQuad ;
12842 EndFinish := EndFinishQuad
12843 END |
12844 DefImpSym: WITH DefImp DO
12845 StartInit := StartQuad ;
12846 EndInit := EndQuad ;
12847 StartFinish := StartFinishQuad ;
12848 EndFinish := EndFinishQuad
12849 END
12850
12851 ELSE
12852 InternalError ('expecting a Module or DefImp symbol')
12853 END
12854 END
12855 END GetModuleQuads ;
12856
12857
12858 (*
12859 PutModuleFinallyFunction - Places Tree, finally, into the Module symbol, Sym.
12860 *)
12861
12862 PROCEDURE PutModuleFinallyFunction (Sym: CARDINAL; finally: Tree) ;
12863 VAR
12864 pSym: PtrToSymbol ;
12865 BEGIN
12866 pSym := GetPsym(Sym) ;
12867 WITH pSym^ DO
12868 CASE SymbolType OF
12869
12870 ModuleSym: Module.FinallyFunction := finally |
12871 DefImpSym: DefImp.FinallyFunction := finally
12872
12873 ELSE
12874 InternalError ('expecting a Module or DefImp symbol')
12875 END
12876 END
12877 END PutModuleFinallyFunction ;
12878
12879
12880 (*
12881 GetModuleFinallyFunction - returns the finally tree from the Module symbol, Sym.
12882 *)
12883
12884 PROCEDURE GetModuleFinallyFunction (Sym: CARDINAL) : Tree ;
12885 VAR
12886 pSym: PtrToSymbol ;
12887 BEGIN
12888 pSym := GetPsym(Sym) ;
12889 WITH pSym^ DO
12890 CASE SymbolType OF
12891
12892 ModuleSym: RETURN( Module.FinallyFunction) |
12893 DefImpSym: RETURN( DefImp.FinallyFunction)
12894
12895 ELSE
12896 InternalError ('expecting a Module or DefImp symbol')
12897 END
12898 END
12899 END GetModuleFinallyFunction ;
12900
12901
12902 (*
12903 PutProcedureScopeQuad - Places QuadNumber into the Procedure symbol, Sym.
12904 QuadNumber is the start quad of scope for procedure,
12905 Sym.
12906 *)
12907
12908 PROCEDURE PutProcedureScopeQuad (Sym: CARDINAL; QuadNumber: CARDINAL) ;
12909 VAR
12910 pSym: PtrToSymbol ;
12911 BEGIN
12912 pSym := GetPsym(Sym) ;
12913 WITH pSym^ DO
12914 CASE SymbolType OF
12915
12916 ProcedureSym: Procedure.ScopeQuad := QuadNumber
12917
12918 ELSE
12919 InternalError ('expecting a Procedure symbol')
12920 END
12921 END
12922 END PutProcedureScopeQuad ;
12923
12924
12925 (*
12926 PutProcedureStartQuad - Places QuadNumber into the Procedure symbol, Sym.
12927 QuadNumber is the start quad of procedure,
12928 Sym.
12929 *)
12930
12931 PROCEDURE PutProcedureStartQuad (Sym: CARDINAL; QuadNumber: CARDINAL) ;
12932 VAR
12933 pSym: PtrToSymbol ;
12934 BEGIN
12935 pSym := GetPsym(Sym) ;
12936 WITH pSym^ DO
12937 CASE SymbolType OF
12938
12939 ProcedureSym: Procedure.StartQuad := QuadNumber
12940
12941 ELSE
12942 InternalError ('expecting a Procedure symbol')
12943 END
12944 END
12945 END PutProcedureStartQuad ;
12946
12947
12948 (*
12949 PutProcedureEndQuad - Places QuadNumber into the Procedure symbol, Sym.
12950 QuadNumber is the end quad of procedure,
12951 Sym.
12952 *)
12953
12954 PROCEDURE PutProcedureEndQuad (Sym: CARDINAL; QuadNumber: CARDINAL) ;
12955 VAR
12956 pSym: PtrToSymbol ;
12957 BEGIN
12958 pSym := GetPsym(Sym) ;
12959 WITH pSym^ DO
12960 CASE SymbolType OF
12961
12962 ProcedureSym: Procedure.EndQuad := QuadNumber
12963
12964 ELSE
12965 InternalError ('expecting a Procedure symbol')
12966 END
12967 END
12968 END PutProcedureEndQuad ;
12969
12970
12971 (*
12972 GetProcedureQuads - Returns, Start and End, Quads of a procedure, Sym.
12973 *)
12974
12975 PROCEDURE GetProcedureQuads (Sym: CARDINAL; VAR scope, start, end: CARDINAL) ;
12976 VAR
12977 pSym: PtrToSymbol ;
12978 BEGIN
12979 pSym := GetPsym(Sym) ;
12980 WITH pSym^ DO
12981 CASE SymbolType OF
12982
12983 ProcedureSym: WITH Procedure DO
12984 scope := ScopeQuad ;
12985 start := StartQuad ;
12986 end := EndQuad
12987 END
12988
12989 ELSE
12990 InternalError ('expecting a Procedure symbol')
12991 END
12992 END
12993 END GetProcedureQuads ;
12994
12995
12996 (*
12997 GetReadQuads - assigns Start and End to the beginning and end of
12998 symbol, Sym, read history usage.
12999 *)
13000
13001 PROCEDURE GetReadQuads (Sym: CARDINAL; m: ModeOfAddr;
13002 VAR Start, End: CARDINAL) ;
13003 BEGIN
13004 GetReadLimitQuads(Sym, m, 0, 0, Start, End)
13005 END GetReadQuads ;
13006
13007
13008 (*
13009 GetWriteQuads - assigns Start and End to the beginning and end of
13010 symbol, Sym, usage.
13011 *)
13012
13013 PROCEDURE GetWriteQuads (Sym: CARDINAL; m: ModeOfAddr;
13014 VAR Start, End: CARDINAL) ;
13015 BEGIN
13016 GetWriteLimitQuads(Sym, m, 0, 0, Start, End)
13017 END GetWriteQuads ;
13018
13019
13020 (*
13021 PutProcedureBegin - assigns begin as the token number matching the
13022 procedure BEGIN.
13023 *)
13024
13025 PROCEDURE PutProcedureBegin (Sym: CARDINAL; begin: CARDINAL) ;
13026 VAR
13027 pSym: PtrToSymbol ;
13028 BEGIN
13029 pSym := GetPsym(Sym) ;
13030 WITH pSym^ DO
13031 CASE SymbolType OF
13032
13033 ProcedureSym: Procedure.Begin := begin
13034
13035 ELSE
13036 InternalError ('expecting a Procedure symbol')
13037 END
13038 END
13039 END PutProcedureBegin ;
13040
13041
13042 (*
13043 PutProcedureEnd - assigns end as the token number matching the
13044 procedure END.
13045 *)
13046
13047 PROCEDURE PutProcedureEnd (Sym: CARDINAL; end: CARDINAL) ;
13048 VAR
13049 pSym: PtrToSymbol ;
13050 BEGIN
13051 pSym := GetPsym(Sym) ;
13052 WITH pSym^ DO
13053 CASE SymbolType OF
13054
13055 ProcedureSym: Procedure.End := end
13056
13057 ELSE
13058 InternalError ('expecting a Procedure symbol')
13059 END
13060 END
13061 END PutProcedureEnd ;
13062
13063
13064 (*
13065 GetProcedureBeginEnd - assigns, begin, end, to the stored token values.
13066 *)
13067
13068 PROCEDURE GetProcedureBeginEnd (Sym: CARDINAL; VAR begin, end: CARDINAL) ;
13069 VAR
13070 pSym: PtrToSymbol ;
13071 BEGIN
13072 pSym := GetPsym(Sym) ;
13073 WITH pSym^ DO
13074 CASE SymbolType OF
13075
13076 ProcedureSym: begin := Procedure.Begin ;
13077 end := Procedure.End
13078
13079 ELSE
13080 InternalError ('expecting a Procedure symbol')
13081 END
13082 END
13083 END GetProcedureBeginEnd ;
13084
13085
13086 (*
13087 Max -
13088 *)
13089
13090 PROCEDURE Max (a, b: CARDINAL) : CARDINAL ;
13091 BEGIN
13092 IF a>b
13093 THEN
13094 RETURN( a )
13095 ELSE
13096 RETURN( b )
13097 END
13098 END Max ;
13099
13100
13101 (*
13102 Min -
13103 *)
13104
13105 PROCEDURE Min (a, b: CARDINAL) : CARDINAL ;
13106 BEGIN
13107 IF a<b
13108 THEN
13109 RETURN( a )
13110 ELSE
13111 RETURN( b )
13112 END
13113 END Min ;
13114
13115
13116 (*
13117 GetQuads - assigns Start and End to the beginning and end of
13118 symbol, Sym, usage.
13119 *)
13120
13121 PROCEDURE GetQuads (Sym: CARDINAL; m: ModeOfAddr; VAR Start, End: CARDINAL) ;
13122 VAR
13123 StartRead, EndRead,
13124 StartWrite, EndWrite: CARDINAL ;
13125 BEGIN
13126 GetReadQuads(Sym, m, StartRead, EndRead) ;
13127 GetWriteQuads(Sym, m, StartWrite, EndWrite) ;
13128 IF StartRead=0
13129 THEN
13130 Start := StartWrite
13131 ELSIF StartWrite=0
13132 THEN
13133 Start := StartRead
13134 ELSE
13135 Start := Min(StartRead, StartWrite)
13136 END ;
13137 IF EndRead=0
13138 THEN
13139 End := EndWrite
13140 ELSIF EndWrite=0
13141 THEN
13142 End := EndRead
13143 ELSE
13144 End := Max(EndRead, EndWrite)
13145 END
13146 END GetQuads ;
13147
13148
13149 (*
13150 PutReadQuad - places Quad into the list of symbol usage.
13151 *)
13152
13153 PROCEDURE PutReadQuad (Sym: CARDINAL; m: ModeOfAddr; Quad: CARDINAL) ;
13154 VAR
13155 pSym: PtrToSymbol ;
13156 BEGIN
13157 pSym := GetPsym(Sym) ;
13158 WITH pSym^ DO
13159 CASE SymbolType OF
13160
13161 VarSym: IncludeItemIntoList(Var.ReadUsageList[m], Quad)
13162
13163 ELSE
13164 InternalError ('expecting a Var symbol')
13165 END
13166 END
13167 END PutReadQuad ;
13168
13169
13170 (*
13171 RemoveReadQuad - places Quad into the list of symbol usage.
13172 *)
13173
13174 PROCEDURE RemoveReadQuad (Sym: CARDINAL; m: ModeOfAddr; Quad: CARDINAL) ;
13175 VAR
13176 pSym: PtrToSymbol ;
13177 BEGIN
13178 pSym := GetPsym(Sym) ;
13179 WITH pSym^ DO
13180 CASE SymbolType OF
13181
13182 VarSym: RemoveItemFromList(Var.ReadUsageList[m], Quad)
13183
13184 ELSE
13185 InternalError ('expecting a Var symbol')
13186 END
13187 END
13188 END RemoveReadQuad ;
13189
13190
13191 (*
13192 PutWriteQuad - places Quad into the list of symbol usage.
13193 *)
13194
13195 PROCEDURE PutWriteQuad (Sym: CARDINAL; m: ModeOfAddr; Quad: CARDINAL) ;
13196 VAR
13197 pSym: PtrToSymbol ;
13198 BEGIN
13199 pSym := GetPsym(Sym) ;
13200 WITH pSym^ DO
13201 CASE SymbolType OF
13202
13203 VarSym: IncludeItemIntoList(Var.WriteUsageList[m], Quad)
13204
13205 ELSE
13206 InternalError ('expecting a Var symbol')
13207 END
13208 END
13209 END PutWriteQuad ;
13210
13211
13212 (*
13213 RemoveWriteQuad - places Quad into the list of symbol usage.
13214 *)
13215
13216 PROCEDURE RemoveWriteQuad (Sym: CARDINAL; m: ModeOfAddr; Quad: CARDINAL) ;
13217 VAR
13218 pSym: PtrToSymbol ;
13219 BEGIN
13220 pSym := GetPsym(Sym) ;
13221 WITH pSym^ DO
13222 CASE SymbolType OF
13223
13224 VarSym: RemoveItemFromList(Var.WriteUsageList[m], Quad)
13225
13226 ELSE
13227 InternalError ('expecting a Var symbol')
13228 END
13229 END
13230 END RemoveWriteQuad ;
13231
13232
13233 (*
13234 DoFindLimits - assigns, Start, and, End, to the start and end
13235 limits contained in the list, l. It ensures that
13236 Start and End are within StartLimit..EndLimit.
13237 If StartLimit or EndLimit are 0 then Start is
13238 is set to the first value and End to the last.
13239 *)
13240
13241 PROCEDURE DoFindLimits (StartLimit, EndLimit: CARDINAL;
13242 VAR Start, End: CARDINAL; l: List) ;
13243 VAR
13244 i, j, n: CARDINAL ;
13245 BEGIN
13246 End := 0 ;
13247 Start := 0 ;
13248 i := 1 ;
13249 n := NoOfItemsInList(l) ;
13250 WHILE i<=n DO
13251 j := GetItemFromList(l, i) ;
13252 IF (j>End) AND (j>=StartLimit) AND ((j<=EndLimit) OR (EndLimit=0))
13253 THEN
13254 End := j
13255 END ;
13256 IF ((Start=0) OR (j<Start)) AND (j#0) AND (j>=StartLimit) AND
13257 ((j<=EndLimit) OR (EndLimit=0))
13258 THEN
13259 Start := j
13260 END ;
13261 INC(i)
13262 END
13263 END DoFindLimits ;
13264
13265
13266 (*
13267 GetReadLimitQuads - returns Start and End which have been assigned
13268 the start and end of when the symbol was read
13269 to within: StartLimit..EndLimit.
13270 *)
13271
13272 PROCEDURE GetReadLimitQuads (Sym: CARDINAL; m: ModeOfAddr;
13273 StartLimit, EndLimit: CARDINAL;
13274 VAR Start, End: CARDINAL) ;
13275 VAR
13276 pSym: PtrToSymbol ;
13277 BEGIN
13278 pSym := GetPsym(Sym) ;
13279 WITH pSym^ DO
13280 CASE SymbolType OF
13281
13282 VarSym: DoFindLimits(StartLimit, EndLimit, Start, End,
13283 Var.ReadUsageList[m])
13284
13285 ELSE
13286 InternalError ('expecting a Var symbol')
13287 END
13288 END
13289 END GetReadLimitQuads ;
13290
13291
13292 (*
13293 GetWriteLimitQuads - returns Start and End which have been assigned
13294 the start and end of when the symbol was written
13295 to within: StartLimit..EndLimit.
13296 *)
13297
13298 PROCEDURE GetWriteLimitQuads (Sym: CARDINAL; m: ModeOfAddr;
13299 StartLimit, EndLimit: CARDINAL;
13300 VAR Start, End: CARDINAL) ;
13301 VAR
13302 pSym: PtrToSymbol ;
13303 BEGIN
13304 pSym := GetPsym(Sym) ;
13305 WITH pSym^ DO
13306 CASE SymbolType OF
13307
13308 VarSym : DoFindLimits(StartLimit, EndLimit, Start, End,
13309 Var.WriteUsageList[m])
13310
13311 ELSE
13312 InternalError ('expecting a Var symbol')
13313 END
13314 END
13315 END GetWriteLimitQuads ;
13316
13317
13318 (*
13319 GetNthProcedure - Returns the Nth procedure in Module, Sym.
13320 *)
13321
13322 PROCEDURE GetNthProcedure (Sym: CARDINAL; n: CARDINAL) : CARDINAL ;
13323 VAR
13324 pSym: PtrToSymbol ;
13325 BEGIN
13326 pSym := GetPsym(Sym) ;
13327 WITH pSym^ DO
13328 CASE SymbolType OF
13329
13330 DefImpSym: RETURN( GetItemFromList(DefImp.ListOfProcs, n) ) |
13331 ModuleSym: RETURN( GetItemFromList(Module.ListOfProcs, n) )
13332
13333 ELSE
13334 InternalError ('expecting a DefImp or Module symbol')
13335 END
13336 END
13337 END GetNthProcedure ;
13338
13339
13340 (*
13341 GetDeclaredDefinition - returns the token where this symbol
13342 was declared in the definition module.
13343 *)
13344
13345 PROCEDURE GetDeclaredDefinition (Sym: CARDINAL) : CARDINAL ;
13346 VAR
13347 pSym: PtrToSymbol ;
13348 BEGIN
13349 pSym := GetPsym(Sym) ;
13350 WITH pSym^ DO
13351 CASE SymbolType OF
13352
13353 ErrorSym : RETURN( Error.At.DefDeclared ) |
13354 ObjectSym : RETURN( Object.At.DefDeclared ) |
13355 VarientSym : RETURN( Varient.At.DefDeclared ) |
13356 RecordSym : RETURN( Record.At.DefDeclared ) |
13357 SubrangeSym : RETURN( Subrange.At.DefDeclared ) |
13358 EnumerationSym : RETURN( Enumeration.At.DefDeclared ) |
13359 ArraySym : RETURN( Array.At.DefDeclared ) |
13360 SubscriptSym : RETURN( Subscript.At.DefDeclared ) |
13361 UnboundedSym : RETURN( Unbounded.At.DefDeclared ) |
13362 ProcedureSym : RETURN( Procedure.At.DefDeclared ) |
13363 ProcTypeSym : RETURN( ProcType.At.DefDeclared ) |
13364 ParamSym : RETURN( Param.At.DefDeclared ) |
13365 VarParamSym : RETURN( VarParam.At.DefDeclared ) |
13366 ConstStringSym : RETURN( ConstString.At.DefDeclared ) |
13367 ConstLitSym : RETURN( ConstLit.At.DefDeclared ) |
13368 ConstVarSym : RETURN( ConstVar.At.DefDeclared ) |
13369 VarSym : RETURN( Var.At.DefDeclared ) |
13370 TypeSym : RETURN( Type.At.DefDeclared ) |
13371 PointerSym : RETURN( Pointer.At.DefDeclared ) |
13372 RecordFieldSym : RETURN( RecordField.At.DefDeclared ) |
13373 VarientFieldSym : RETURN( VarientField.At.DefDeclared ) |
13374 EnumerationFieldSym: RETURN( EnumerationField.At.DefDeclared ) |
13375 SetSym : RETURN( Set.At.DefDeclared ) |
13376 DefImpSym : RETURN( DefImp.At.DefDeclared ) |
13377 ModuleSym : RETURN( Module.At.DefDeclared ) |
13378 UndefinedSym : RETURN( GetFirstUsed(Sym) ) |
13379 ImportSym : RETURN( Import.at.DefDeclared ) |
13380 ImportStatementSym : RETURN( ImportStatement.at.DefDeclared ) |
13381 PartialUnboundedSym: RETURN( GetDeclaredDefinition(PartialUnbounded.Type) )
13382
13383 ELSE
13384 InternalError ('not expecting this type of symbol')
13385 END
13386 END
13387 END GetDeclaredDefinition ;
13388
13389
13390 (*
13391 GetDeclaredModule - returns the token where this symbol was declared
13392 in an implementation or program module.
13393 *)
13394
13395 PROCEDURE GetDeclaredModule (Sym: CARDINAL) : CARDINAL ;
13396 VAR
13397 pSym: PtrToSymbol ;
13398 BEGIN
13399 pSym := GetPsym(Sym) ;
13400 WITH pSym^ DO
13401 CASE SymbolType OF
13402
13403 ErrorSym : RETURN( Error.At.ModDeclared ) |
13404 ObjectSym : RETURN( Object.At.ModDeclared ) |
13405 VarientSym : RETURN( Varient.At.ModDeclared ) |
13406 RecordSym : RETURN( Record.At.ModDeclared ) |
13407 SubrangeSym : RETURN( Subrange.At.ModDeclared ) |
13408 EnumerationSym : RETURN( Enumeration.At.ModDeclared ) |
13409 ArraySym : RETURN( Array.At.ModDeclared ) |
13410 SubscriptSym : RETURN( Subscript.At.ModDeclared ) |
13411 UnboundedSym : RETURN( Unbounded.At.ModDeclared ) |
13412 ProcedureSym : RETURN( Procedure.At.ModDeclared ) |
13413 ProcTypeSym : RETURN( ProcType.At.ModDeclared ) |
13414 ParamSym : RETURN( Param.At.ModDeclared ) |
13415 VarParamSym : RETURN( VarParam.At.ModDeclared ) |
13416 ConstStringSym : RETURN( ConstString.At.ModDeclared ) |
13417 ConstLitSym : RETURN( ConstLit.At.ModDeclared ) |
13418 ConstVarSym : RETURN( ConstVar.At.ModDeclared ) |
13419 VarSym : RETURN( Var.At.ModDeclared ) |
13420 TypeSym : RETURN( Type.At.ModDeclared ) |
13421 PointerSym : RETURN( Pointer.At.ModDeclared ) |
13422 RecordFieldSym : RETURN( RecordField.At.ModDeclared ) |
13423 VarientFieldSym : RETURN( VarientField.At.ModDeclared ) |
13424 EnumerationFieldSym: RETURN( EnumerationField.At.ModDeclared ) |
13425 SetSym : RETURN( Set.At.ModDeclared ) |
13426 DefImpSym : RETURN( DefImp.At.ModDeclared ) |
13427 ModuleSym : RETURN( Module.At.ModDeclared ) |
13428 UndefinedSym : RETURN( GetFirstUsed(Sym) ) |
13429 ImportSym : RETURN( Import.at.ModDeclared ) |
13430 ImportStatementSym : RETURN( ImportStatement.at.ModDeclared ) |
13431 PartialUnboundedSym: RETURN( GetDeclaredModule(PartialUnbounded.Type) )
13432
13433 ELSE
13434 InternalError ('not expecting this type of symbol')
13435 END
13436 END
13437 END GetDeclaredModule ;
13438
13439
13440 (*
13441 PutDeclaredDefinition - associates the current tokenno with
13442 the symbols declaration in the definition
13443 module.
13444 *)
13445
13446 PROCEDURE PutDeclaredDefinition (tok: CARDINAL; Sym: CARDINAL) ;
13447 VAR
13448 pSym: PtrToSymbol ;
13449 BEGIN
13450 pSym := GetPsym(Sym) ;
13451 WITH pSym^ DO
13452 CASE SymbolType OF
13453
13454 ErrorSym : Error.At.DefDeclared := tok |
13455 ObjectSym : Object.At.DefDeclared := tok |
13456 VarientSym : Varient.At.DefDeclared := tok |
13457 RecordSym : Record.At.DefDeclared := tok |
13458 SubrangeSym : Subrange.At.DefDeclared := tok |
13459 EnumerationSym : Enumeration.At.DefDeclared := tok |
13460 ArraySym : Array.At.DefDeclared := tok |
13461 SubscriptSym : Subscript.At.DefDeclared := tok |
13462 UnboundedSym : Unbounded.At.DefDeclared := tok |
13463 ProcedureSym : Procedure.At.DefDeclared := tok |
13464 ProcTypeSym : ProcType.At.DefDeclared := tok |
13465 ParamSym : Param.At.DefDeclared := tok |
13466 VarParamSym : VarParam.At.DefDeclared := tok |
13467 ConstStringSym : ConstString.At.DefDeclared := tok |
13468 ConstLitSym : ConstLit.At.DefDeclared := tok |
13469 ConstVarSym : ConstVar.At.DefDeclared := tok |
13470 VarSym : Var.At.DefDeclared := tok |
13471 TypeSym : Type.At.DefDeclared := tok |
13472 PointerSym : Pointer.At.DefDeclared := tok |
13473 RecordFieldSym : RecordField.At.DefDeclared := tok |
13474 VarientFieldSym : VarientField.At.DefDeclared := tok |
13475 EnumerationFieldSym: EnumerationField.At.DefDeclared := tok |
13476 SetSym : Set.At.DefDeclared := tok |
13477 DefImpSym : DefImp.At.DefDeclared := tok |
13478 ModuleSym : Module.At.DefDeclared := tok |
13479 UndefinedSym : |
13480 PartialUnboundedSym: PutDeclaredDefinition(tok, PartialUnbounded.Type)
13481
13482 ELSE
13483 InternalError ('not expecting this type of symbol')
13484 END
13485 END
13486 END PutDeclaredDefinition ;
13487
13488
13489 (*
13490 PutDeclaredModule - returns the token where this symbol was declared
13491 in an implementation or program module.
13492 *)
13493
13494 PROCEDURE PutDeclaredModule (tok: CARDINAL; Sym: CARDINAL) ;
13495 VAR
13496 pSym: PtrToSymbol ;
13497 BEGIN
13498 pSym := GetPsym(Sym) ;
13499 WITH pSym^ DO
13500 CASE SymbolType OF
13501
13502 ErrorSym : Error.At.ModDeclared := tok |
13503 ObjectSym : Object.At.ModDeclared := tok |
13504 VarientSym : Varient.At.ModDeclared := tok |
13505 RecordSym : Record.At.ModDeclared := tok |
13506 SubrangeSym : Subrange.At.ModDeclared := tok |
13507 EnumerationSym : Enumeration.At.ModDeclared := tok |
13508 ArraySym : Array.At.ModDeclared := tok |
13509 SubscriptSym : Subscript.At.ModDeclared := tok |
13510 UnboundedSym : Unbounded.At.ModDeclared := tok |
13511 ProcedureSym : Procedure.At.ModDeclared := tok |
13512 ProcTypeSym : ProcType.At.ModDeclared := tok |
13513 ParamSym : Param.At.ModDeclared := tok |
13514 VarParamSym : VarParam.At.ModDeclared := tok |
13515 ConstStringSym : ConstString.At.ModDeclared := tok |
13516 ConstLitSym : ConstLit.At.ModDeclared := tok |
13517 ConstVarSym : ConstVar.At.ModDeclared := tok |
13518 VarSym : Var.At.ModDeclared := tok |
13519 TypeSym : Type.At.ModDeclared := tok |
13520 PointerSym : Pointer.At.ModDeclared := tok |
13521 RecordFieldSym : RecordField.At.ModDeclared := tok |
13522 VarientFieldSym : VarientField.At.ModDeclared := tok |
13523 EnumerationFieldSym: EnumerationField.At.ModDeclared := tok |
13524 SetSym : Set.At.ModDeclared := tok |
13525 DefImpSym : DefImp.At.ModDeclared := tok |
13526 ModuleSym : Module.At.ModDeclared := tok |
13527 UndefinedSym : |
13528 PartialUnboundedSym: PutDeclaredModule(tok, PartialUnbounded.Type)
13529
13530 ELSE
13531 InternalError ('not expecting this type of symbol')
13532 END
13533 END
13534 END PutDeclaredModule ;
13535
13536
13537 (*
13538 PutDeclared - adds an entry to symbol, Sym, indicating that it
13539 was declared at, tok. This routine
13540 may be called twice, once for definition module
13541 partial declaration and once when parsing the
13542 implementation module.
13543 *)
13544
13545 PROCEDURE PutDeclared (tok: CARDINAL; Sym: CARDINAL) ;
13546 BEGIN
13547 IF CompilingDefinitionModule ()
13548 THEN
13549 PutDeclaredDefinition (tok, Sym)
13550 ELSE
13551 PutDeclaredModule (tok, Sym)
13552 END
13553 END PutDeclared ;
13554
13555
13556 (*
13557 GetDeclaredDef - returns the tokenno where the symbol was declared.
13558 The priority of declaration is definition, implementation
13559 and program module.
13560 *)
13561
13562 PROCEDURE GetDeclaredDef (Sym: CARDINAL) : CARDINAL ;
13563 VAR
13564 declared: CARDINAL ;
13565 BEGIN
13566 declared := GetDeclaredDefinition (Sym) ;
13567 IF declared = UnknownTokenNo
13568 THEN
13569 RETURN GetDeclaredModule (Sym)
13570 END ;
13571 RETURN declared
13572 END GetDeclaredDef ;
13573
13574
13575 (*
13576 GetDeclaredMod - returns the tokenno where the symbol was declared.
13577 The priority of declaration is program,
13578 implementation and definition module.
13579 *)
13580
13581 PROCEDURE GetDeclaredMod (Sym: CARDINAL) : CARDINAL ;
13582 VAR
13583 declared: CARDINAL ;
13584 BEGIN
13585 declared := GetDeclaredModule (Sym) ;
13586 IF declared = UnknownTokenNo
13587 THEN
13588 RETURN GetDeclaredDefinition (Sym)
13589 END ;
13590 RETURN declared
13591 END GetDeclaredMod ;
13592
13593
13594 (*
13595 GetFirstUsed - returns the token where this symbol was first used.
13596 *)
13597
13598 PROCEDURE GetFirstUsed (Sym: CARDINAL) : CARDINAL ;
13599 VAR
13600 pSym: PtrToSymbol ;
13601 BEGIN
13602 pSym := GetPsym (Sym) ;
13603 WITH pSym^ DO
13604 CASE SymbolType OF
13605
13606 ErrorSym : RETURN( Error.At.FirstUsed ) |
13607 ObjectSym : RETURN( Object.At.FirstUsed ) |
13608 UndefinedSym : RETURN( Undefined.At.FirstUsed ) |
13609 VarientSym : RETURN( Varient.At.FirstUsed ) |
13610 RecordSym : RETURN( Record.At.FirstUsed ) |
13611 SubrangeSym : RETURN( Subrange.At.FirstUsed ) |
13612 EnumerationSym : RETURN( Enumeration.At.FirstUsed ) |
13613 ArraySym : RETURN( Array.At.FirstUsed ) |
13614 SubscriptSym : RETURN( Subscript.At.FirstUsed ) |
13615 UnboundedSym : RETURN( Unbounded.At.FirstUsed ) |
13616 ProcedureSym : RETURN( Procedure.At.FirstUsed ) |
13617 ProcTypeSym : RETURN( ProcType.At.FirstUsed ) |
13618 ParamSym : RETURN( Param.At.FirstUsed ) |
13619 VarParamSym : RETURN( VarParam.At.FirstUsed ) |
13620 ConstStringSym : RETURN( ConstString.At.FirstUsed ) |
13621 ConstLitSym : RETURN( ConstLit.At.FirstUsed ) |
13622 ConstVarSym : RETURN( ConstVar.At.FirstUsed ) |
13623 VarSym : RETURN( Var.At.FirstUsed ) |
13624 TypeSym : RETURN( Type.At.FirstUsed ) |
13625 PointerSym : RETURN( Pointer.At.FirstUsed ) |
13626 RecordFieldSym : RETURN( RecordField.At.FirstUsed ) |
13627 VarientFieldSym : RETURN( VarientField.At.FirstUsed ) |
13628 EnumerationFieldSym: RETURN( EnumerationField.At.FirstUsed ) |
13629 SetSym : RETURN( Set.At.FirstUsed ) |
13630 DefImpSym : RETURN( DefImp.At.FirstUsed ) |
13631 ModuleSym : RETURN( Module.At.FirstUsed )
13632
13633 ELSE
13634 InternalError ('not expecting this type of symbol')
13635 END
13636 END
13637 END GetFirstUsed ;
13638
13639
13640 (*
13641 ForeachProcedureDo - for each procedure in module, Sym, do procedure, P.
13642 *)
13643
13644 PROCEDURE ForeachProcedureDo (Sym: CARDINAL; P: PerformOperation) ;
13645 VAR
13646 pSym: PtrToSymbol ;
13647 BEGIN
13648 pSym := GetPsym(Sym) ;
13649 WITH pSym^ DO
13650 CASE SymbolType OF
13651
13652 DefImpSym : ForeachItemInListDo( DefImp.ListOfProcs, P) |
13653 ModuleSym : ForeachItemInListDo( Module.ListOfProcs, P) |
13654 ProcedureSym: ForeachItemInListDo( Procedure.ListOfProcs, P)
13655
13656 ELSE
13657 InternalError ('expecting DefImp or Module symbol')
13658 END
13659 END
13660 END ForeachProcedureDo ;
13661
13662
13663 (*
13664 ForeachInnerModuleDo - for each inner module in module, Sym,
13665 do procedure, P.
13666 *)
13667
13668 PROCEDURE ForeachInnerModuleDo (Sym: CARDINAL; P: PerformOperation) ;
13669 VAR
13670 pSym: PtrToSymbol ;
13671 BEGIN
13672 pSym := GetPsym(Sym) ;
13673 WITH pSym^ DO
13674 CASE SymbolType OF
13675
13676 DefImpSym : ForeachItemInListDo( DefImp.ListOfModules, P) |
13677 ModuleSym : ForeachItemInListDo( Module.ListOfModules, P) |
13678 ProcedureSym: ForeachItemInListDo( Procedure.ListOfModules, P)
13679
13680 ELSE
13681 InternalError ('expecting DefImp or Module symbol')
13682 END
13683 END
13684 END ForeachInnerModuleDo ;
13685
13686
13687 (*
13688 ForeachModuleDo - for each module do procedure, P.
13689 *)
13690
13691 PROCEDURE ForeachModuleDo (P: PerformOperation) ;
13692 BEGIN
13693 ForeachNodeDo (ModuleTree, P)
13694 END ForeachModuleDo ;
13695
13696
13697 (*
13698 ForeachFieldEnumerationDo - for each field in enumeration, Sym,
13699 do procedure, P. Each call to P contains
13700 an enumeration field, the order is alphabetical.
13701 Use ForeachLocalSymDo for declaration order.
13702 *)
13703
13704 PROCEDURE ForeachFieldEnumerationDo (Sym: CARDINAL; P: PerformOperation) ;
13705 VAR
13706 pSym: PtrToSymbol ;
13707 BEGIN
13708 pSym := GetPsym(Sym) ;
13709 WITH pSym^ DO
13710 CASE SymbolType OF
13711
13712 EnumerationSym: ForeachNodeDo (Enumeration.LocalSymbols, P)
13713
13714 ELSE
13715 InternalError ('expecting Enumeration symbol')
13716 END
13717 END
13718 END ForeachFieldEnumerationDo ;
13719
13720
13721 (*
13722 IsProcedureReachable - Returns true if the procedure, Sym, is
13723 reachable from the main Module.
13724 *)
13725
13726 PROCEDURE IsProcedureReachable (Sym: CARDINAL) : BOOLEAN ;
13727 VAR
13728 pSym: PtrToSymbol ;
13729 BEGIN
13730 pSym := GetPsym(Sym) ;
13731 WITH pSym^ DO
13732 CASE SymbolType OF
13733
13734 ProcedureSym: RETURN( Procedure.Reachable )
13735
13736 ELSE
13737 InternalError ('expecting Procedure symbol')
13738 END
13739 END
13740 END IsProcedureReachable ;
13741
13742
13743 (*
13744 IsProcType - returns true if Sym is a ProcType Symbol.
13745 *)
13746
13747 PROCEDURE IsProcType (Sym: CARDINAL) : BOOLEAN ;
13748 VAR
13749 pSym: PtrToSymbol ;
13750 BEGIN
13751 pSym := GetPsym(Sym) ;
13752 RETURN( pSym^.SymbolType=ProcTypeSym )
13753 END IsProcType ;
13754
13755
13756 (*
13757 IsVar - returns true if Sym is a Var Symbol.
13758 *)
13759
13760 PROCEDURE IsVar (Sym: CARDINAL) : BOOLEAN ;
13761 VAR
13762 pSym: PtrToSymbol ;
13763 BEGIN
13764 pSym := GetPsym(Sym) ;
13765 RETURN( pSym^.SymbolType=VarSym )
13766 END IsVar ;
13767
13768
13769 (*
13770 DoIsConst - returns TRUE if Sym is defined as a constant
13771 or is an enumeration field or string.
13772 *)
13773
13774 PROCEDURE DoIsConst (Sym: CARDINAL) : BOOLEAN ;
13775 VAR
13776 pSym: PtrToSymbol ;
13777 BEGIN
13778 pSym := GetPsym(Sym) ;
13779 WITH pSym^ DO
13780 RETURN( (SymbolType=ConstVarSym) OR
13781 (SymbolType=ConstLitSym) OR
13782 (SymbolType=ConstStringSym) OR
13783 ((SymbolType=VarSym) AND (Var.AddrMode=ImmediateValue)) OR
13784 (SymbolType=EnumerationFieldSym)
13785 )
13786 END
13787 END DoIsConst ;
13788
13789
13790 (*
13791 IsConst - returns true if Sym contains a constant value.
13792 *)
13793
13794 PROCEDURE IsConst (Sym: CARDINAL) : BOOLEAN ;
13795 BEGIN
13796 IF IsConstructor(Sym)
13797 THEN
13798 RETURN( IsConstructorConstant(Sym) )
13799 ELSE
13800 RETURN( DoIsConst(Sym) )
13801 END
13802 END IsConst ;
13803
13804
13805 (*
13806 IsConstString - returns whether sym is a conststring of any variant.
13807 *)
13808
13809 PROCEDURE IsConstString (sym: CARDINAL) : BOOLEAN ;
13810 VAR
13811 pSym: PtrToSymbol ;
13812 BEGIN
13813 pSym := GetPsym (sym) ;
13814 WITH pSym^ DO
13815 RETURN SymbolType = ConstStringSym
13816 END
13817 END IsConstString ;
13818
13819
13820 (*
13821 IsConstLit - returns true if Sym is a literal constant.
13822 *)
13823
13824 PROCEDURE IsConstLit (Sym: CARDINAL) : BOOLEAN ;
13825 VAR
13826 pSym: PtrToSymbol ;
13827 BEGIN
13828 pSym := GetPsym(Sym) ;
13829 WITH pSym^ DO
13830 RETURN( SymbolType=ConstLitSym )
13831 END
13832 END IsConstLit ;
13833
13834
13835 (*
13836 IsDummy - returns true if Sym is a Dummy symbol.
13837 *)
13838
13839 PROCEDURE IsDummy (Sym: CARDINAL) : BOOLEAN ;
13840 VAR
13841 pSym: PtrToSymbol ;
13842 BEGIN
13843 pSym := GetPsym(Sym) ;
13844 RETURN( pSym^.SymbolType=DummySym )
13845 END IsDummy ;
13846
13847
13848 (*
13849 IsTemporary - returns true if Sym is a Temporary symbol.
13850 *)
13851
13852 PROCEDURE IsTemporary (Sym: CARDINAL) : BOOLEAN ;
13853 VAR
13854 pSym: PtrToSymbol ;
13855 BEGIN
13856 pSym := GetPsym(Sym) ;
13857 WITH pSym^ DO
13858 CASE SymbolType OF
13859
13860 VarSym : RETURN( Var.IsTemp ) |
13861 ConstVarSym: RETURN( ConstVar.IsTemp )
13862
13863 ELSE
13864 RETURN( FALSE )
13865 END
13866 END
13867 END IsTemporary ;
13868
13869
13870 (*
13871 IsVarAParam - returns true if Sym is a variable declared as a parameter.
13872 *)
13873
13874 PROCEDURE IsVarAParam (Sym: CARDINAL) : BOOLEAN ;
13875 VAR
13876 pSym: PtrToSymbol ;
13877 BEGIN
13878 pSym := GetPsym(Sym) ;
13879 WITH pSym^ DO
13880 CASE SymbolType OF
13881
13882 VarSym: RETURN( Var.IsParam )
13883
13884 ELSE
13885 RETURN( FALSE )
13886 END
13887 END
13888 END IsVarAParam ;
13889
13890
13891 (*
13892 IsSubscript - returns true if Sym is a subscript symbol.
13893 *)
13894
13895 PROCEDURE IsSubscript (Sym: CARDINAL) : BOOLEAN ;
13896 VAR
13897 pSym: PtrToSymbol ;
13898 BEGIN
13899 pSym := GetPsym(Sym) ;
13900 RETURN( pSym^.SymbolType=SubscriptSym )
13901 END IsSubscript ;
13902
13903
13904 (*
13905 IsSubrange - returns true if Sym is a subrange symbol.
13906 *)
13907
13908 PROCEDURE IsSubrange (Sym: CARDINAL) : BOOLEAN ;
13909 VAR
13910 pSym: PtrToSymbol ;
13911 BEGIN
13912 pSym := GetPsym(Sym) ;
13913 RETURN( pSym^.SymbolType=SubrangeSym )
13914 END IsSubrange ;
13915
13916
13917 (*
13918 IsProcedureVariable - returns true if a Sym is a variable and
13919 it was declared within a procedure.
13920 *)
13921
13922 PROCEDURE IsProcedureVariable (Sym: CARDINAL) : BOOLEAN ;
13923 BEGIN
13924 CheckLegal(Sym) ;
13925 RETURN( IsVar(Sym) AND IsProcedure(GetVarScope(Sym)) )
13926 END IsProcedureVariable ;
13927
13928
13929 (*
13930 IsProcedureNested - returns TRUE if procedure, Sym, was
13931 declared as a nested procedure.
13932 *)
13933
13934 PROCEDURE IsProcedureNested (Sym: CARDINAL) : BOOLEAN ;
13935 BEGIN
13936 RETURN( IsProcedure(Sym) AND (IsProcedure(GetScope(Sym))) )
13937 END IsProcedureNested ;
13938
13939
13940 (*
13941 IsAModula2Type - returns true if Sym, is a:
13942 IsType, IsPointer, IsRecord, IsEnumeration,
13943 IsSubrange, IsArray, IsUnbounded, IsProcType.
13944 NOTE that it different from IsType.
13945 *)
13946
13947 PROCEDURE IsAModula2Type (Sym: CARDINAL) : BOOLEAN ;
13948 BEGIN
13949 CheckLegal(Sym) ;
13950 RETURN(
13951 IsType(Sym) OR IsRecord(Sym) OR IsPointer(Sym) OR
13952 IsEnumeration(Sym) OR IsSubrange(Sym) OR IsArray(Sym) OR
13953 IsUnbounded(Sym) OR IsProcType(Sym) OR IsSet(Sym)
13954 )
13955 END IsAModula2Type ;
13956
13957
13958 (*
13959 IsGnuAsmVolatile - returns TRUE if a GnuAsm symbol was defined as VOLATILE.
13960 *)
13961
13962 PROCEDURE IsGnuAsmVolatile (Sym: CARDINAL) : BOOLEAN ;
13963 VAR
13964 pSym: PtrToSymbol ;
13965 BEGIN
13966 pSym := GetPsym(Sym) ;
13967 WITH pSym^ DO
13968 CASE SymbolType OF
13969
13970 GnuAsmSym: RETURN( GnuAsm.Volatile )
13971
13972 ELSE
13973 InternalError ('expecting GnuAsm symbol')
13974 END
13975 END
13976 END IsGnuAsmVolatile ;
13977
13978
13979 (*
13980 IsGnuAsmSimple - returns TRUE if a GnuAsm symbol is a simple kind.
13981 *)
13982
13983 PROCEDURE IsGnuAsmSimple (Sym: CARDINAL) : BOOLEAN ;
13984 VAR
13985 pSym: PtrToSymbol ;
13986 BEGIN
13987 pSym := GetPsym(Sym) ;
13988 WITH pSym^ DO
13989 CASE SymbolType OF
13990
13991 GnuAsmSym: RETURN( GnuAsm.Simple )
13992
13993 ELSE
13994 InternalError ('expecting GnuAsm symbol')
13995 END
13996 END
13997 END IsGnuAsmSimple ;
13998
13999
14000 (*
14001 IsGnuAsm - returns TRUE if Sym is a GnuAsm symbol.
14002 *)
14003
14004 PROCEDURE IsGnuAsm (Sym: CARDINAL) : BOOLEAN ;
14005 VAR
14006 pSym: PtrToSymbol ;
14007 BEGIN
14008 pSym := GetPsym(Sym) ;
14009 WITH pSym^ DO
14010 RETURN( SymbolType=GnuAsmSym )
14011 END
14012 END IsGnuAsm ;
14013
14014
14015 (*
14016 IsRegInterface - returns TRUE if Sym is a RegInterface symbol.
14017 *)
14018
14019 PROCEDURE IsRegInterface (Sym: CARDINAL) : BOOLEAN ;
14020 VAR
14021 pSym: PtrToSymbol ;
14022 BEGIN
14023 pSym := GetPsym(Sym) ;
14024 WITH pSym^ DO
14025 RETURN( SymbolType=InterfaceSym )
14026 END
14027 END IsRegInterface ;
14028
14029
14030 (*
14031 GetParam - returns the ParamNo parameter from procedure ProcSym
14032 *)
14033
14034 PROCEDURE GetParam (Sym: CARDINAL; ParamNo: CARDINAL) : CARDINAL ;
14035 BEGIN
14036 CheckLegal(Sym) ;
14037 IF ParamNo=0
14038 THEN
14039 (* Parameter Zero is the return argument for the Function *)
14040 RETURN(GetType(Sym))
14041 ELSE
14042 RETURN(GetNthParam(Sym, ParamNo))
14043 END
14044 END GetParam ;
14045
14046
14047 (*
14048 GetFromIndex - return a value from list, i, at position, n.
14049 *)
14050
14051 PROCEDURE GetFromIndex (i: Indexing.Index; n: CARDINAL) : CARDINAL ;
14052 VAR
14053 p: POINTER TO CARDINAL ;
14054 BEGIN
14055 p := Indexing.GetIndice(i, n) ;
14056 RETURN( p^ )
14057 END GetFromIndex ;
14058
14059
14060 (*
14061 PutIntoIndex - places value, v, into list, i, at position, n.
14062 *)
14063
14064 PROCEDURE PutIntoIndex (VAR i: Indexing.Index; n: CARDINAL; v: CARDINAL) ;
14065 VAR
14066 p: POINTER TO CARDINAL ;
14067 BEGIN
14068 NEW(p) ;
14069 p^ := v ;
14070 Indexing.PutIndice(i, n, p)
14071 END PutIntoIndex ;
14072
14073
14074 (*
14075 Make2Tuple - creates and returns a 2 tuple from, a, and, b.
14076 *)
14077
14078 PROCEDURE Make2Tuple (a, b: CARDINAL) : CARDINAL ;
14079 VAR
14080 pSym: PtrToSymbol ;
14081 Sym : CARDINAL ;
14082 BEGIN
14083 NewSym(Sym) ;
14084 pSym := GetPsym(Sym) ;
14085 WITH pSym^ DO
14086 SymbolType := TupleSym ;
14087 WITH Tuple DO
14088 nTuple := 2 ;
14089 list := Indexing.InitIndex(1) ;
14090 PutIntoIndex(list, 1, a) ;
14091 PutIntoIndex(list, 2, b) ;
14092 InitWhereDeclared(At) ;
14093 InitWhereFirstUsed(At)
14094 END
14095 END ;
14096 RETURN( Sym )
14097 END Make2Tuple ;
14098
14099
14100 (*
14101 IsSizeSolved - returns true if the size of Sym is solved.
14102 *)
14103
14104 PROCEDURE IsSizeSolved (Sym: CARDINAL) : BOOLEAN ;
14105 VAR
14106 pSym: PtrToSymbol ;
14107 BEGIN
14108 CheckLegal(Sym) ;
14109 pSym := GetPsym(Sym) ;
14110 WITH pSym^ DO
14111 CASE SymbolType OF
14112
14113 ProcedureSym : RETURN( IsSolved(Procedure.Size) ) |
14114 VarSym : RETURN( IsSolved(Var.Size) ) |
14115 TypeSym : RETURN( IsSolved(Type.Size) ) |
14116 SetSym : RETURN( IsSolved(Set.Size) ) |
14117 RecordSym : RETURN( IsSolved(Record.Size) ) |
14118 VarientSym : RETURN( IsSolved(Varient.Size) ) |
14119 EnumerationSym : RETURN( IsSolved(Enumeration.Size) ) |
14120 PointerSym : RETURN( IsSolved(Pointer.Size) ) |
14121 ArraySym : RETURN( IsSolved(Array.Size) ) |
14122 RecordFieldSym : RETURN( IsSolved(RecordField.Size) ) |
14123 VarientFieldSym : RETURN( IsSolved(VarientField.Size) ) |
14124 SubrangeSym : RETURN( IsSolved(Subrange.Size) ) |
14125 SubscriptSym : RETURN( IsSolved(Subscript.Size) ) |
14126 ProcTypeSym : RETURN( IsSolved(ProcType.Size) ) |
14127 UnboundedSym : RETURN( IsSolved(Unbounded.Size) )
14128
14129 ELSE
14130 InternalError ('not expecting this kind of symbol')
14131 END
14132 END
14133 END IsSizeSolved ;
14134
14135
14136 (*
14137 IsOffsetSolved - returns true if the Offset of Sym is solved.
14138 *)
14139
14140 PROCEDURE IsOffsetSolved (Sym: CARDINAL) : BOOLEAN ;
14141 VAR
14142 pSym: PtrToSymbol ;
14143 BEGIN
14144 CheckLegal(Sym) ;
14145 pSym := GetPsym(Sym) ;
14146 WITH pSym^ DO
14147 CASE SymbolType OF
14148
14149 VarSym : RETURN( IsSolved(Var.Offset) ) |
14150 RecordFieldSym : RETURN( IsSolved(RecordField.Offset) ) |
14151 VarientFieldSym : RETURN( IsSolved(VarientField.Offset) )
14152
14153 ELSE
14154 InternalError ('not expecting this kind of symbol')
14155 END
14156 END
14157 END IsOffsetSolved ;
14158
14159
14160 (*
14161 IsValueSolved - returns true if the value of Sym is solved.
14162 *)
14163
14164 PROCEDURE IsValueSolved (Sym: CARDINAL) : BOOLEAN ;
14165 VAR
14166 pSym: PtrToSymbol ;
14167 BEGIN
14168 CheckLegal(Sym) ;
14169 pSym := GetPsym(Sym) ;
14170 WITH pSym^ DO
14171 CASE SymbolType OF
14172
14173 ConstLitSym : RETURN( IsSolved(ConstLit.Value) ) |
14174 ConstVarSym : RETURN( IsSolved(ConstVar.Value) ) |
14175 EnumerationFieldSym : RETURN( IsSolved(EnumerationField.Value) ) |
14176 ConstStringSym : RETURN( TRUE )
14177
14178 ELSE
14179 InternalError ('not expecting this kind of symbol')
14180 END
14181 END
14182 END IsValueSolved ;
14183
14184
14185 (*
14186 IsConstructorConstant - returns TRUE if constructor, Sym, is
14187 defined by only constants.
14188 *)
14189
14190 PROCEDURE IsConstructorConstant (Sym: CARDINAL) : BOOLEAN ;
14191 VAR
14192 pSym: PtrToSymbol ;
14193 BEGIN
14194 IF IsConstructor(Sym) OR IsConstSet(Sym)
14195 THEN
14196 pSym := GetPsym(Sym) ;
14197 WITH pSym^ DO
14198 CASE SymbolType OF
14199
14200 ConstVarSym: RETURN( IsValueConst(ConstVar.Value) ) |
14201 ConstLitSym: RETURN( IsValueConst(ConstLit.Value) )
14202
14203 ELSE
14204 InternalError ('expecting Constructor')
14205 END
14206 END
14207 ELSE
14208 InternalError ('expecting Constructor')
14209 END
14210 END IsConstructorConstant ;
14211
14212
14213 (*
14214 IsComposite - returns TRUE if symbol, sym, is a composite
14215 type: ie an ARRAY or RECORD.
14216 *)
14217
14218 PROCEDURE IsComposite (sym: CARDINAL) : BOOLEAN ;
14219 BEGIN
14220 IF sym=NulSym
14221 THEN
14222 RETURN( FALSE )
14223 ELSE
14224 sym := SkipType(sym) ;
14225 RETURN( IsArray(sym) OR IsRecord(sym) )
14226 END
14227 END IsComposite ;
14228
14229
14230 (*
14231 IsSumOfParamSizeSolved - has the sum of parameters been solved yet?
14232 *)
14233
14234 PROCEDURE IsSumOfParamSizeSolved (Sym: CARDINAL) : BOOLEAN ;
14235 VAR
14236 pSym: PtrToSymbol ;
14237 BEGIN
14238 CheckLegal(Sym) ;
14239 pSym := GetPsym(Sym) ;
14240 WITH pSym^ DO
14241 CASE SymbolType OF
14242
14243 ProcedureSym: RETURN( IsSolved(Procedure.TotalParamSize) ) |
14244 ProcTypeSym : RETURN( IsSolved(ProcType.TotalParamSize) )
14245
14246 ELSE
14247 InternalError ('expecting Procedure or ProcType symbol')
14248 END
14249 END
14250 END IsSumOfParamSizeSolved ;
14251
14252
14253 (*
14254 PushSize - pushes the size of Sym.
14255 *)
14256
14257 PROCEDURE PushSize (Sym: CARDINAL) ;
14258 VAR
14259 pSym: PtrToSymbol ;
14260 BEGIN
14261 CheckLegal(Sym) ;
14262 pSym := GetPsym(Sym) ;
14263 WITH pSym^ DO
14264 CASE SymbolType OF
14265
14266 ProcedureSym : PushFrom(Procedure.Size) |
14267 VarSym : PushFrom(Var.Size) |
14268 TypeSym : PushFrom(Type.Size) |
14269 SetSym : PushFrom(Set.Size) |
14270 VarientSym : PushFrom(Varient.Size) |
14271 RecordSym : PushFrom(Record.Size) |
14272 EnumerationSym : PushFrom(Enumeration.Size) |
14273 PointerSym : PushFrom(Pointer.Size) |
14274 ArraySym : PushFrom(Array.Size) |
14275 RecordFieldSym : PushFrom(RecordField.Size) |
14276 VarientFieldSym : PushFrom(VarientField.Size) |
14277 SubrangeSym : PushFrom(Subrange.Size) |
14278 SubscriptSym : PushFrom(Subscript.Size) |
14279 ProcTypeSym : PushFrom(ProcType.Size) |
14280 UnboundedSym : PushFrom(Unbounded.Size)
14281
14282 ELSE
14283 InternalError ('not expecting this kind of symbol')
14284 END
14285 END
14286 END PushSize ;
14287
14288
14289 (*
14290 PushOffset - pushes the Offset of Sym.
14291 *)
14292
14293 PROCEDURE PushOffset (Sym: CARDINAL) ;
14294 VAR
14295 pSym: PtrToSymbol ;
14296 BEGIN
14297 CheckLegal(Sym) ;
14298 pSym := GetPsym(Sym) ;
14299 WITH pSym^ DO
14300 CASE SymbolType OF
14301
14302 VarSym : PushFrom(Var.Offset) |
14303 RecordFieldSym : PushFrom(RecordField.Offset) |
14304 VarientFieldSym : PushFrom(VarientField.Offset)
14305
14306 ELSE
14307 InternalError ('not expecting this kind of symbol')
14308 END
14309 END
14310 END PushOffset ;
14311
14312
14313 (*
14314 PushValue - pushes the Value of Sym onto the ALU stack.
14315 *)
14316
14317 PROCEDURE PushValue (Sym: CARDINAL) ;
14318 VAR
14319 pSym: PtrToSymbol ;
14320 BEGIN
14321 CheckLegal(Sym) ;
14322 pSym := GetPsym(Sym) ;
14323 WITH pSym^ DO
14324 CASE SymbolType OF
14325
14326 ConstLitSym : PushFrom(ConstLit.Value) |
14327 ConstVarSym : PushFrom(ConstVar.Value) |
14328 EnumerationFieldSym : PushFrom(EnumerationField.Value) |
14329 ConstStringSym : PushConstString(Sym)
14330
14331 ELSE
14332 InternalError ('not expecting this kind of symbol')
14333 END
14334 END
14335 END PushValue ;
14336
14337
14338 (*
14339 PushConstString - pushes the character string onto the ALU stack.
14340 It assumes that the character string is only
14341 one character long.
14342 *)
14343
14344 PROCEDURE PushConstString (Sym: CARDINAL) ;
14345 VAR
14346 pSym: PtrToSymbol ;
14347 a : ARRAY [0..10] OF CHAR ;
14348 BEGIN
14349 CheckLegal (Sym) ;
14350 pSym := GetPsym (Sym) ;
14351 WITH pSym^ DO
14352 CASE SymbolType OF
14353
14354 ConstStringSym: WITH ConstString DO
14355 IF Length = 1
14356 THEN
14357 GetKey (Contents, a) ;
14358 PushChar (a[0])
14359 ELSE
14360 WriteFormat0 ('ConstString must be length 1')
14361 END
14362 END
14363
14364 ELSE
14365 InternalError ('expecting ConstString symbol')
14366 END
14367 END
14368 END PushConstString ;
14369
14370
14371 (*
14372 PushParamSize - push the size of parameter, ParamNo,
14373 of procedure Sym onto the ALU stack.
14374 *)
14375
14376 PROCEDURE PushParamSize (Sym: CARDINAL; ParamNo: CARDINAL) ;
14377 VAR
14378 p, Type: CARDINAL ;
14379 BEGIN
14380 CheckLegal(Sym) ;
14381 Assert(IsProcedure(Sym) OR IsProcType(Sym)) ;
14382 IF ParamNo=0
14383 THEN
14384 PushSize(GetType(Sym))
14385 ELSE
14386 (*
14387 can use GetNthParam but 1..n returns parameter.
14388 But 0 yields the function return type.
14389
14390 Note that VAR Unbounded parameters and non VAR Unbounded parameters
14391 contain the unbounded descriptor. VAR unbounded parameters
14392 do NOT JUST contain an address re: other VAR parameters.
14393 *)
14394 IF IsVarParam(Sym, ParamNo) AND (NOT IsUnboundedParam(Sym, ParamNo))
14395 THEN
14396 PushSize(Address) (* VAR parameters point to the variable *)
14397 ELSE
14398 p := GetNthParam(Sym, ParamNo) ; (* nth Parameter *)
14399 (*
14400 N.B. chose to get the Type of the parameter rather than the Var
14401 because ProcType's have Type but no Var associated with them.
14402 *)
14403 Type := GetType(p) ; (* ie Variable from Procedure Sym *)
14404 Assert(p#NulSym) ; (* If this fails then ParamNo is out of range *)
14405 PushSize(Type)
14406 END
14407 END
14408 END PushParamSize ;
14409
14410
14411 (*
14412 PushSumOfLocalVarSize - push the total size of all local variables
14413 onto the ALU stack.
14414 *)
14415
14416 PROCEDURE PushSumOfLocalVarSize (Sym: CARDINAL) ;
14417 VAR
14418 pSym: PtrToSymbol ;
14419 BEGIN
14420 CheckLegal(Sym) ;
14421 pSym := GetPsym(Sym) ;
14422 WITH pSym^ DO
14423 CASE SymbolType OF
14424
14425 ProcedureSym,
14426 DefImpSym,
14427 ModuleSym : PushSize(Sym)
14428
14429 ELSE
14430 InternalError ('expecting Procedure, DefImp or Module symbol')
14431 END
14432 END
14433 END PushSumOfLocalVarSize ;
14434
14435
14436 (*
14437 PushSumOfParamSize - push the total size of all parameters onto
14438 the ALU stack.
14439 *)
14440
14441 PROCEDURE PushSumOfParamSize (Sym: CARDINAL) ;
14442 VAR
14443 pSym: PtrToSymbol ;
14444 BEGIN
14445 CheckLegal(Sym) ;
14446 pSym := GetPsym(Sym) ;
14447 WITH pSym^ DO
14448 CASE SymbolType OF
14449
14450 ProcedureSym: PushFrom(Procedure.TotalParamSize) |
14451 ProcTypeSym : PushFrom(ProcType.TotalParamSize)
14452
14453 ELSE
14454 InternalError ('expecting Procedure or ProcType symbol')
14455 END
14456 END
14457 END PushSumOfParamSize ;
14458
14459
14460 (*
14461 PushVarSize - pushes the size of a variable, Sym.
14462 The runtime size of Sym will depend upon its addressing mode,
14463 RightValue has size PushSize(GetType(Sym)) and
14464 LeftValue has size PushSize(Address) since it points to a
14465 variable.
14466 *)
14467
14468 PROCEDURE PushVarSize (Sym: CARDINAL) ;
14469 BEGIN
14470 CheckLegal(Sym) ;
14471 Assert(IsVar(Sym)) ;
14472 IF GetMode(Sym)=LeftValue
14473 THEN
14474 PushSize(Address)
14475 ELSE
14476 Assert(GetMode(Sym)=RightValue) ;
14477 PushSize(GetType(Sym))
14478 END
14479 END PushVarSize ;
14480
14481
14482 (*
14483 PopValue - pops the ALU stack into Value of Sym.
14484 *)
14485
14486 PROCEDURE PopValue (Sym: CARDINAL) ;
14487 VAR
14488 pSym: PtrToSymbol ;
14489 BEGIN
14490 CheckLegal(Sym) ;
14491 pSym := GetPsym(Sym) ;
14492 WITH pSym^ DO
14493 CASE SymbolType OF
14494
14495 ConstLitSym : PopInto(ConstLit.Value) |
14496 ConstVarSym : PopInto(ConstVar.Value) |
14497 EnumerationFieldSym : InternalError ('cannot pop into an enumeration field')
14498
14499 ELSE
14500 InternalError ('symbol type not expected')
14501 END
14502 END
14503 END PopValue ;
14504
14505
14506 (*
14507 PopSize - pops the ALU stack into Size of Sym.
14508 *)
14509
14510 PROCEDURE PopSize (Sym: CARDINAL) ;
14511 VAR
14512 pSym: PtrToSymbol ;
14513 BEGIN
14514 CheckLegal(Sym) ;
14515 pSym := GetPsym(Sym) ;
14516 WITH pSym^ DO
14517 CASE SymbolType OF
14518
14519 ProcedureSym : PopInto(Procedure.Size) |
14520 VarSym : PopInto(Var.Size) |
14521 TypeSym : PopInto(Type.Size) |
14522 RecordSym : PopInto(Record.Size) |
14523 VarientSym : PopInto(Varient.Size) |
14524 EnumerationSym : PopInto(Enumeration.Size) |
14525 PointerSym : PopInto(Pointer.Size) |
14526 ArraySym : PopInto(Array.Size) |
14527 RecordFieldSym : PopInto(RecordField.Size) |
14528 VarientFieldSym : PopInto(VarientField.Size) |
14529 SubrangeSym : PopInto(Subrange.Size) |
14530 SubscriptSym : PopInto(Subscript.Size) |
14531 ProcTypeSym : PopInto(ProcType.Size) |
14532 UnboundedSym : PopInto(Unbounded.Size) |
14533 SetSym : PopInto(Set.Size)
14534
14535 ELSE
14536 InternalError ('not expecting this kind of symbol')
14537 END
14538 END
14539 END PopSize ;
14540
14541
14542 (*
14543 PopOffset - pops the ALU stack into Offset of Sym.
14544 *)
14545
14546 PROCEDURE PopOffset (Sym: CARDINAL) ;
14547 VAR
14548 pSym: PtrToSymbol ;
14549 BEGIN
14550 CheckLegal(Sym) ;
14551 pSym := GetPsym(Sym) ;
14552 WITH pSym^ DO
14553 CASE SymbolType OF
14554
14555 VarSym : PopInto(Var.Offset) |
14556 RecordFieldSym : PopInto(RecordField.Offset) |
14557 VarientFieldSym : PopInto(VarientField.Offset)
14558
14559 ELSE
14560 InternalError ('not expecting this kind of symbol')
14561 END
14562 END
14563 END PopOffset ;
14564
14565
14566 (*
14567 PopSumOfParamSize - pop the total value on the ALU stack as the
14568 sum of all parameters.
14569 *)
14570
14571 PROCEDURE PopSumOfParamSize (Sym: CARDINAL) ;
14572 VAR
14573 pSym: PtrToSymbol ;
14574 BEGIN
14575 CheckLegal(Sym) ;
14576 pSym := GetPsym(Sym) ;
14577 WITH pSym^ DO
14578 CASE SymbolType OF
14579
14580 ProcedureSym: PopInto(Procedure.TotalParamSize) |
14581 ProcTypeSym : PopInto(ProcType.TotalParamSize)
14582
14583 ELSE
14584 InternalError ('expecting Procedure or ProcType symbol')
14585 END
14586 END
14587 END PopSumOfParamSize ;
14588
14589
14590 (*
14591 PutAlignment - assigns the alignment constant associated with,
14592 type, with, align.
14593 *)
14594
14595 PROCEDURE PutAlignment (type: CARDINAL; align: CARDINAL) ;
14596 VAR
14597 pSym: PtrToSymbol ;
14598 BEGIN
14599 pSym := GetPsym(type) ;
14600 WITH pSym^ DO
14601 CASE SymbolType OF
14602
14603 RecordSym : Record.Align := align |
14604 RecordFieldSym: RecordField.Align := align |
14605 TypeSym : Type.Align := align |
14606 ArraySym : Array.Align := align |
14607 PointerSym : Pointer.Align := align |
14608 SubrangeSym : Subrange.Align := align
14609
14610 ELSE
14611 InternalError ('expecting record, field, pointer, type, subrange or an array symbol')
14612 END
14613 END
14614 END PutAlignment ;
14615
14616
14617 (*
14618 GetAlignment - returns the alignment constant associated with,
14619 type.
14620 *)
14621
14622 PROCEDURE GetAlignment (type: CARDINAL) : CARDINAL ;
14623 VAR
14624 pSym: PtrToSymbol ;
14625 BEGIN
14626 pSym := GetPsym(type) ;
14627 WITH pSym^ DO
14628 CASE SymbolType OF
14629
14630 RecordSym : RETURN( Record.Align ) |
14631 RecordFieldSym : RETURN( RecordField.Align ) |
14632 TypeSym : RETURN( Type.Align ) |
14633 ArraySym : RETURN( Array.Align ) |
14634 PointerSym : RETURN( Pointer.Align ) |
14635 VarientFieldSym: RETURN( GetAlignment(VarientField.Parent) ) |
14636 VarientSym : RETURN( GetAlignment(Varient.Parent) ) |
14637 SubrangeSym : RETURN( Subrange.Align )
14638
14639 ELSE
14640 InternalError ('expecting record, field, pointer, type, subrange or an array symbol')
14641 END
14642 END
14643 END GetAlignment ;
14644
14645
14646 (*
14647 PutDefaultRecordFieldAlignment - assigns, align, as the default alignment
14648 to record, sym.
14649 *)
14650
14651 PROCEDURE PutDefaultRecordFieldAlignment (sym: CARDINAL; align: CARDINAL) ;
14652 VAR
14653 pSym: PtrToSymbol ;
14654 BEGIN
14655 pSym := GetPsym(sym) ;
14656 WITH pSym^ DO
14657 CASE SymbolType OF
14658
14659 RecordSym: Record.DefaultAlign := align
14660
14661 ELSE
14662 InternalError ('expecting record symbol')
14663 END
14664 END
14665 END PutDefaultRecordFieldAlignment ;
14666
14667
14668 (*
14669 GetDefaultRecordFieldAlignment - assigns, align, as the default alignment
14670 to record, sym.
14671 *)
14672
14673 PROCEDURE GetDefaultRecordFieldAlignment (sym: CARDINAL) : CARDINAL ;
14674 VAR
14675 pSym: PtrToSymbol ;
14676 BEGIN
14677 pSym := GetPsym(sym) ;
14678 WITH pSym^ DO
14679 CASE SymbolType OF
14680
14681 RecordSym : RETURN( Record.DefaultAlign ) |
14682 VarientFieldSym: RETURN( GetDefaultRecordFieldAlignment(GetParent(sym)) ) |
14683 VarientSym : RETURN( GetDefaultRecordFieldAlignment(GetParent(sym)) )
14684
14685 ELSE
14686 InternalError ('expecting record symbol')
14687 END
14688 END
14689 END GetDefaultRecordFieldAlignment ;
14690
14691
14692 (*
14693 VarCheckReadInit - returns TRUE if sym has been initialized.
14694 *)
14695
14696 PROCEDURE VarCheckReadInit (sym: CARDINAL; mode: ModeOfAddr) : BOOLEAN ;
14697 VAR
14698 pSym: PtrToSymbol ;
14699 BEGIN
14700 IF IsVar (sym)
14701 THEN
14702 pSym := GetPsym (sym) ;
14703 WITH pSym^ DO
14704 CASE SymbolType OF
14705
14706 VarSym: RETURN GetInitialized (Var.InitState[mode])
14707
14708 ELSE
14709 END
14710 END
14711 END ;
14712 RETURN FALSE
14713 END VarCheckReadInit ;
14714
14715
14716 (*
14717 VarInitState - initializes the init state for variable sym.
14718 *)
14719
14720 PROCEDURE VarInitState (sym: CARDINAL) ;
14721 VAR
14722 pSym: PtrToSymbol ;
14723 BEGIN
14724 IF IsVar (sym)
14725 THEN
14726 pSym := GetPsym (sym) ;
14727 WITH pSym^ DO
14728 CASE SymbolType OF
14729
14730 VarSym: ConfigSymInit (Var.InitState[LeftValue], sym) ;
14731 ConfigSymInit (Var.InitState[RightValue], sym)
14732
14733 ELSE
14734 END
14735 END
14736 END
14737 END VarInitState ;
14738
14739
14740 (*
14741 PutVarInitialized - set sym as initialized.
14742 *)
14743
14744 PROCEDURE PutVarInitialized (sym: CARDINAL; mode: ModeOfAddr) ;
14745 VAR
14746 pSym: PtrToSymbol ;
14747 BEGIN
14748 IF IsVar (sym)
14749 THEN
14750 pSym := GetPsym (sym) ;
14751 WITH pSym^ DO
14752 CASE SymbolType OF
14753
14754 VarSym: WITH Var DO
14755 SetInitialized (InitState[mode])
14756 END
14757
14758 ELSE
14759 END
14760 END
14761 END
14762 END PutVarInitialized ;
14763
14764
14765 (*
14766 PutVarFieldInitialized - records that field has been initialized with
14767 variable sym. TRUE is returned if the field
14768 is detected and changed to initialized.
14769 *)
14770
14771 PROCEDURE PutVarFieldInitialized (sym: CARDINAL; mode: ModeOfAddr;
14772 fieldlist: List) : BOOLEAN ;
14773 VAR
14774 pSym: PtrToSymbol ;
14775 BEGIN
14776 IF IsVar (sym)
14777 THEN
14778 pSym := GetPsym (sym) ;
14779 WITH pSym^ DO
14780 CASE SymbolType OF
14781
14782 VarSym: WITH Var DO
14783 RETURN SetFieldInitialized (InitState[mode], fieldlist)
14784 END
14785
14786 ELSE
14787 END
14788 END
14789 END ;
14790 RETURN FALSE
14791 END PutVarFieldInitialized ;
14792
14793
14794 (*
14795 GetVarFieldInitialized - return TRUE if fieldlist has been initialized
14796 within variable sym.
14797 *)
14798
14799 PROCEDURE GetVarFieldInitialized (sym: CARDINAL; mode: ModeOfAddr;
14800 fieldlist: List) : BOOLEAN ;
14801 VAR
14802 pSym: PtrToSymbol ;
14803 BEGIN
14804 IF IsVar (sym)
14805 THEN
14806 pSym := GetPsym (sym) ;
14807 WITH pSym^ DO
14808 CASE SymbolType OF
14809
14810 VarSym: WITH Var DO
14811 RETURN GetFieldInitialized (InitState[mode], fieldlist)
14812 END
14813
14814 ELSE
14815 END
14816 END
14817 END ;
14818 RETURN FALSE
14819 END GetVarFieldInitialized ;
14820
14821
14822 (*
14823 PrintInitialized - display variable sym initialization state.
14824 *)
14825
14826 PROCEDURE PrintInitialized (sym: CARDINAL) ;
14827 VAR
14828 pSym: PtrToSymbol ;
14829 BEGIN
14830 IF IsVar (sym)
14831 THEN
14832 pSym := GetPsym (sym) ;
14833 WITH pSym^ DO
14834 CASE SymbolType OF
14835
14836 VarSym: printf0 ("LeftMode init: ") ;
14837 PrintSymInit (Var.InitState[LeftValue]) ;
14838 printf0 ("RightMode init: ") ;
14839 PrintSymInit (Var.InitState[RightValue])
14840
14841 ELSE
14842 END
14843 END
14844 END
14845 END PrintInitialized ;
14846
14847
14848 (*
14849 DumpSymbols - display all symbol numbers and their type.
14850 *)
14851
14852 (*
14853 PROCEDURE DumpSymbols ;
14854 VAR
14855 pSym: PtrToSymbol ;
14856 sym : CARDINAL ;
14857 BEGIN
14858 sym := 1 ;
14859 WHILE sym <= FinalSymbol () DO
14860 pSym := GetPsym(sym) ;
14861 printf ("%d ", sym) ;
14862 WITH pSym^ DO
14863 CASE SymbolType OF
14864
14865 RecordSym: printf ("RecordSym") |
14866 VarientSym: printf ("VarientSym") |
14867 DummySym: printf ("DummySym") |
14868 VarSym: printf ("VarSym") |
14869 EnumerationSym: printf ("EnumerationSym") |
14870 SubrangeSym: printf ("SubrangeSym") |
14871 ArraySym: printf ("ArraySym") |
14872 ConstStringSym: printf ("ConstStringSym") |
14873 ConstVarSym: printf ("ConstVarSym") |
14874 ConstLitSym: printf ("ConstLitSym") |
14875 VarParamSym: printf ("VarParamSym") |
14876 ParamSym: printf ("ParamSym") |
14877 PointerSym: printf ("PointerSym") |
14878 UndefinedSym: printf ("UndefinedSym") |
14879 TypeSym: printf ("TypeSym") |
14880 RecordFieldSym: printf ("RecordFieldSym") |
14881 VarientFieldSym: printf ("VarientFieldSym") |
14882 EnumerationFieldSym: printf ("EnumerationFieldSym") |
14883 DefImpSym: printf ("DefImpSym") |
14884 ModuleSym: printf ("ModuleSym") |
14885 SetSym: printf ("SetSym") |
14886 ProcedureSym: printf ("ProcedureSym") |
14887 ProcTypeSym: printf ("ProcTypeSym") |
14888 SubscriptSym: printf ("SubscriptSym") |
14889 UnboundedSym: printf ("UnboundedSym") |
14890 GnuAsmSym: printf ("GnuAsmSym") |
14891 InterfaceSym: printf ("InterfaceSym") |
14892 ObjectSym: printf ("ObjectSym") |
14893 PartialUnboundedSym: printf ("PartialUnboundedSym") |
14894 TupleSym: printf ("TupleSym") |
14895 OAFamilySym: printf ("OAFamilySym") |
14896 EquivSym: printf ("EquivSym") |
14897 ErrorSym: printf ("ErrorSym")
14898
14899 END
14900 END ;
14901 printf ("\n") ;
14902 INC (sym)
14903 END
14904 END DumpSymbols ;
14905 *)
14906
14907
14908 (*
14909 GetErrorScope - returns the error scope for a symbol.
14910 The error scope is the title scope which is used to
14911 announce the symbol in the GCC error message.
14912 *)
14913
14914 PROCEDURE GetErrorScope (sym: CARDINAL) : ErrorScope ;
14915 VAR
14916 pSym: PtrToSymbol ;
14917 BEGIN
14918 pSym := GetPsym (sym) ;
14919 WITH pSym^ DO
14920 CASE SymbolType OF
14921
14922 ProcedureSym: RETURN Procedure.errorScope |
14923 ModuleSym : RETURN Module.errorScope |
14924 DefImpSym : RETURN DefImp.errorScope |
14925 UndefinedSym: RETURN Undefined.errorScope
14926
14927 ELSE
14928 InternalError ('expecting procedure, module or defimp symbol')
14929 END
14930 END
14931 END GetErrorScope ;
14932
14933
14934 (*
14935 PutErrorScope - sets the error scope for a symbol.
14936 The error scope is the title scope which is used to
14937 announce the symbol in the GCC error message.
14938 *)
14939
14940 (*
14941 PROCEDURE PutErrorScope (sym: CARDINAL; errorScope: ErrorScope) ;
14942 VAR
14943 pSym: PtrToSymbol ;
14944 BEGIN
14945 pSym := GetPsym (type) ;
14946 WITH pSym^ DO
14947 CASE SymbolType OF
14948
14949 ProcedureSym: Procedure.errorScope := errorScope |
14950 ModuleSym : Module.errorScope := errorScope |
14951 DefImpSym : DefImp.errorScope := errorScope
14952
14953 ELSE
14954 InternalError ('expecting procedure, module or defimp symbol')
14955 END
14956 END
14957 END PutErrorScope ;
14958 *)
14959
14960
14961 (*
14962 IsLegal - returns TRUE if, sym, is a legal symbol.
14963 *)
14964
14965 PROCEDURE IsLegal (sym: CARDINAL) : BOOLEAN ;
14966 BEGIN
14967 RETURN sym < FreeSymbol
14968 END IsLegal ;
14969
14970
14971 BEGIN
14972 Init
14973 END SymbolTable.