]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/gm2-compiler/P3SymBuild.mod
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / gm2-compiler / P3SymBuild.mod
CommitLineData
1eee94d3
GM
1(* P3SymBuild.mod pass 3 symbol creation.
2
a945c346 3Copyright (C) 2001-2024 Free Software Foundation, Inc.
1eee94d3
GM
4Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
5
6This file is part of GNU Modula-2.
7
8GNU Modula-2 is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 3, or (at your option)
11any later version.
12
13GNU Modula-2 is distributed in the hope that it will be useful, but
14WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU Modula-2; see the file COPYING3. If not see
20<http://www.gnu.org/licenses/>. *)
21
22IMPLEMENTATION MODULE P3SymBuild ;
23
24
25FROM NameKey IMPORT Name, WriteKey, NulName ;
26FROM StrIO IMPORT WriteString, WriteLn ;
27FROM NumberIO IMPORT WriteCard ;
28FROM M2Debug IMPORT Assert, WriteDebug ;
29FROM M2Error IMPORT WriteFormat0, WriteFormat1, WriteFormat2, FlushErrors, InternalError ;
30FROM M2LexBuf IMPORT GetTokenNo ;
31
32FROM SymbolTable IMPORT NulSym, ModeOfAddr,
33 StartScope, EndScope, GetScope, GetCurrentScope,
34 GetModuleScope,
35 SetCurrentModule, GetCurrentModule, SetFileModule,
36 GetExported, IsExported, IsImplicityExported,
37 IsDefImp, IsModule, IsImported, IsIncludedByDefinition,
38 RequestSym,
39 IsProcedure, PutOptArgInit,
40 IsFieldEnumeration, GetType,
41 CheckForUnknownInModule,
42 GetFromOuterModule,
43 GetMode, PutVariableAtAddress, ModeOfAddr, SkipType,
44 IsSet, PutConstSet,
45 IsConst, IsConstructor, PutConst, PutConstructor,
46 PopValue, PushValue,
47 MakeTemporary, PutVar,
48 PutSubrange,
49 GetSymName ;
50
51FROM M2Batch IMPORT MakeDefinitionSource,
52 MakeImplementationSource,
53 MakeProgramSource,
54 LookupOuterModule ;
55
56FROM M2Quads IMPORT PushT, PopT, OperandT, PopN, PopTF, PushTF,
57 PopTtok, PopTFtok, PushTtok, PushTFtok, OperandTok ;
58
59FROM M2Comp IMPORT CompilingDefinitionModule,
60 CompilingImplementationModule,
61 CompilingProgramModule ;
62
63FROM FifoQueue IMPORT GetSubrangeFromFifoQueue ;
64FROM M2Reserved IMPORT NulTok, ImportTok ;
65IMPORT M2Error ;
66
67
68(*
69 StartBuildDefinitionModule - Creates a definition module and starts
70 a new scope.
71
72 The Stack is expected:
73
74 Entry Exit
75
76 Ptr -> <- Ptr
77 +------------+ +-----------+
78 | NameStart | | NameStart |
79 |------------| |-----------|
80
81*)
82
83PROCEDURE P3StartBuildDefModule ;
84VAR
85 tok : CARDINAL ;
86 name : Name ;
87 ModuleSym: CARDINAL ;
88BEGIN
89 PopTtok (name, tok) ;
90 ModuleSym := MakeDefinitionSource (tok, name) ;
91 SetCurrentModule (ModuleSym) ;
92 SetFileModule (ModuleSym) ;
93 StartScope (ModuleSym) ;
94 Assert (IsDefImp (ModuleSym)) ;
95 Assert (CompilingDefinitionModule ()) ;
96 PushT (name) ;
97 M2Error.EnterDefinitionScope (name)
98END P3StartBuildDefModule ;
99
100
101(*
102 EndBuildDefinitionModule - Destroys the definition module scope and
103 checks for correct name.
104
105 The Stack is expected:
106
107 Entry Exit
108
109 Ptr ->
110 +------------+ +-----------+
111 | NameEnd | | |
112 |------------| |-----------|
113 | NameStart | | | <- Ptr
114 |------------| |-----------|
115*)
116
117PROCEDURE P3EndBuildDefModule ;
118VAR
119 NameStart,
120 NameEnd : CARDINAL ;
121BEGIN
122 Assert(CompilingDefinitionModule()) ;
123 CheckForUnknownInModule ;
124 EndScope ;
125 PopT(NameEnd) ;
126 PopT(NameStart) ;
127 IF NameStart#NameEnd
128 THEN
129 WriteFormat2('inconsistant definition module was named (%a) and concluded as (%a)',
130 NameStart, NameEnd)
131 END ;
132 M2Error.LeaveErrorScope
133END P3EndBuildDefModule ;
134
135
136(*
137 StartBuildImplementationModule - Creates an implementation module and starts
138 a new scope.
139
140 The Stack is expected:
141
142 Entry Exit
143
144 Ptr -> <- Ptr
145 +------------+ +-----------+
146 | NameStart | | NameStart |
147 |------------| |-----------|
148
149*)
150
151PROCEDURE P3StartBuildImpModule ;
152VAR
153 tok : CARDINAL ;
154 name : Name ;
155 ModuleSym: CARDINAL ;
156BEGIN
157 PopTtok (name, tok) ;
158 ModuleSym := MakeImplementationSource (tok, name) ;
159 SetCurrentModule (ModuleSym) ;
160 SetFileModule (ModuleSym) ;
161 StartScope (ModuleSym) ;
162 Assert (IsDefImp(ModuleSym)) ;
163 Assert (CompilingImplementationModule()) ;
164 PushT (name) ;
165 M2Error.EnterImplementationScope (name)
166END P3StartBuildImpModule ;
167
168
169(*
170 EndBuildImplementationModule - Destroys the implementation module scope and
171 checks for correct name.
172
173 The Stack is expected:
174
175 Entry Exit
176
177 Ptr ->
178 +------------+ +-----------+
179 | NameEnd | | |
180 |------------| |-----------|
181 | NameStart | | | <- Ptr
182 |------------| |-----------|
183*)
184
185PROCEDURE P3EndBuildImpModule ;
186VAR
187 NameStart,
188 NameEnd : Name ;
189BEGIN
190 Assert(CompilingImplementationModule()) ;
191 CheckForUnknownInModule ;
192 EndScope ;
193 PopT(NameEnd) ;
194 PopT(NameStart) ;
195 IF NameStart#NameEnd
196 THEN
197 (* we dont issue an error based around incorrect module names as this is done in P1 and P2.
198 If we get here then something has gone wrong with our error recovery in P3, so we bail out.
199 *)
200 WriteFormat0('too many errors in pass 3') ;
201 FlushErrors
202 END ;
203 M2Error.LeaveErrorScope
204END P3EndBuildImpModule ;
205
206
207(*
208 StartBuildProgramModule - Creates a program module and starts
209 a new scope.
210
211 The Stack is expected:
212
213 Entry Exit
214
215 Ptr -> <- Ptr
216 +------------+ +-----------+
217 | NameStart | | NameStart |
218 |------------| |-----------|
219
220*)
221
222PROCEDURE P3StartBuildProgModule ;
223VAR
224 tok : CARDINAL ;
225 name : Name ;
226 ModuleSym: CARDINAL ;
227BEGIN
228 (* WriteString('StartBuildProgramModule') ; WriteLn ; *)
229 PopTtok(name, tok) ;
230 ModuleSym := MakeProgramSource(tok, name) ;
231 SetCurrentModule(ModuleSym) ;
232 SetFileModule(ModuleSym) ;
233 (* WriteString('MODULE - ') ; WriteKey(GetSymName(ModuleSym)) ; WriteLn ; *)
234 StartScope(ModuleSym) ;
235 Assert(CompilingProgramModule()) ;
236 Assert(NOT IsDefImp(ModuleSym)) ;
237 PushT(name) ;
238 M2Error.EnterProgramScope (name)
239END P3StartBuildProgModule ;
240
241
242(*
243 EndBuildProgramModule - Destroys the program module scope and
244 checks for correct name.
245
246 The Stack is expected:
247
248 Entry Exit
249
250 Ptr ->
251 +------------+ +-----------+
252 | NameEnd | | |
253 |------------| |-----------|
254 | NameStart | | | <- Ptr
255 |------------| |-----------|
256*)
257
258PROCEDURE P3EndBuildProgModule ;
259VAR
260 NameStart,
261 NameEnd : Name ;
262BEGIN
263 Assert(CompilingProgramModule()) ;
264 CheckForUnknownInModule ;
265 EndScope ;
266 PopT(NameEnd) ;
267 PopT(NameStart) ;
268 IF NameStart#NameEnd
269 THEN
270 (* we dont issue an error based around incorrect module names this would be done in P1 and P2.
271 If we get here then something has gone wrong with our error recovery in P3, so we bail out.
272 *)
273 WriteFormat0('too many errors in pass 3') ;
274 FlushErrors
275 END ;
276 M2Error.LeaveErrorScope
277END P3EndBuildProgModule ;
278
279
280(*
281 StartBuildInnerModule - Creates an Inner module and starts
282 a new scope.
283
284 The Stack is expected:
285
286 Entry Exit
287
288 Ptr -> <- Ptr
289 +------------+ +-----------+
290 | NameStart | | NameStart |
291 |------------| |-----------|
292
293*)
294
295PROCEDURE StartBuildInnerModule ;
296VAR
297 name : Name ;
298 tok : CARDINAL ;
299 ModuleSym: CARDINAL ;
300BEGIN
301 PopTtok (name, tok) ;
302 ModuleSym := RequestSym (tok, name) ;
303 Assert(IsModule(ModuleSym)) ;
304 StartScope(ModuleSym) ;
305 Assert(NOT IsDefImp(ModuleSym)) ;
306 SetCurrentModule(ModuleSym) ;
307 PushT(name) ;
308 M2Error.EnterModuleScope (name)
309END StartBuildInnerModule ;
310
311
312(*
313 EndBuildInnerModule - Destroys the Inner module scope and
314 checks for correct name.
315
316 The Stack is expected:
317
318 Entry Exit
319
320 Ptr ->
321 +------------+ +-----------+
322 | NameEnd | | |
323 |------------| |-----------|
324 | NameStart | | | <- Ptr
325 |------------| |-----------|
326*)
327
328PROCEDURE EndBuildInnerModule ;
329VAR
330 NameStart,
331 NameEnd : Name ;
332BEGIN
333 CheckForUnknownInModule ;
334 EndScope ;
335 PopT(NameEnd) ;
336 PopT(NameStart) ;
337 IF NameStart#NameEnd
338 THEN
339 (* we dont issue an error based around incorrect module names this would be done in P1 and P2.
340 If we get here then something has gone wrong with our error recovery in P3, so we bail out.
341 *)
342 WriteFormat0('too many errors in pass 3') ;
343 FlushErrors
344 END ;
345 SetCurrentModule(GetModuleScope(GetCurrentModule())) ;
346 M2Error.LeaveErrorScope
347END EndBuildInnerModule ;
348
349
350(*
351 CheckImportListOuterModule - checks to see that all identifiers are
352 exported from the definition module.
353
354 The Stack is expected:
355
356 Entry OR Entry
357
358 Ptr -> Ptr ->
359 +------------+ +-----------+
360 | # | | # |
361 |------------| |-----------|
362 | Id1 | | Id1 |
363 |------------| |-----------|
364 . . . .
365 . . . .
366 . . . .
367 |------------| |-----------|
368 | Id# | | Id# |
369 |------------| |-----------|
370 | ImportTok | | Ident |
371 |------------| |-----------|
372
373 IMPORT Id1, .. Id# ; FROM Ident IMPORT Id1 .. Id# ;
374
375
376 Error Condition
377 Exit
378
379 All above stack discarded
380*)
381
382PROCEDURE CheckImportListOuterModule ;
383VAR
384 n1, n2 : Name ;
385 tok : CARDINAL ;
386 ModSym,
387 i, n : CARDINAL ;
388BEGIN
389 PopT(n) ; (* n = # of the Ident List *)
390 IF OperandT(n+1)#ImportTok
391 THEN
392 (* Ident List contains list of objects *)
393 ModSym := LookupOuterModule(OperandTok(n+1), OperandT(n+1)) ;
394 i := 1 ;
395 WHILE i<=n DO
396 tok := OperandTok (i) ;
397 IF (NOT IsExported(ModSym, RequestSym (tok, OperandT (i)))) AND
398 (NOT IsImplicityExported(ModSym, RequestSym (tok, OperandT(i))))
399 THEN
400 n1 := OperandT(n+1) ;
401 n2 := OperandT(i) ;
402 WriteFormat2 ('symbol %a is not exported from definition or inner module %a', n2, n1)
403 END ;
404 INC(i)
405 END
406 END ;
407 PopN(n+1) (* clear stack *)
408END CheckImportListOuterModule ;
409
410
411(*
412 CheckCanBeImported - checks to see that it is legal to import, Sym, from, ModSym.
413*)
414
415PROCEDURE CheckCanBeImported (ModSym, Sym: CARDINAL) ;
416VAR
417 n1, n2: Name ;
418BEGIN
419 IF IsDefImp(ModSym)
420 THEN
421 IF IsExported(ModSym, Sym)
422 THEN
423 (* great all done *)
424 RETURN
425 ELSE
426 IF IsImplicityExported(ModSym, Sym)
427 THEN
428 (* this is also legal *)
429 RETURN
430 ELSIF IsDefImp(Sym) AND IsIncludedByDefinition(ModSym, Sym)
431 THEN
432 (* this is also legal (for a definition module) *)
433 RETURN
434 END ;
435 n1 := GetSymName(ModSym) ;
436 n2 := GetSymName(Sym) ;
437 WriteFormat2('symbol %a is not exported from definition module %a', n2, n1)
438 END
439 END
440END CheckCanBeImported ;
441
442
443(*
444 StartBuildProcedure - Builds a Procedure.
445
446 The Stack:
447
448 Entry Exit
449
450 <- Ptr
451 +------------+
452 Ptr -> | ProcSym |
453 +------------+ |------------|
454 | Name | | Name |
455 |------------| |------------|
456*)
457
458PROCEDURE StartBuildProcedure ;
459VAR
460 tok : CARDINAL ;
461 name : Name ;
462 ProcSym : CARDINAL ;
463BEGIN
464 PopTtok (name, tok) ;
465 PushTtok (name, tok) ; (* Name saved for the EndBuildProcedure name check *)
466 ProcSym := RequestSym (tok, name) ;
467 Assert (IsProcedure (ProcSym)) ;
468 PushTtok (ProcSym, tok) ;
469 StartScope (ProcSym) ;
470 M2Error.EnterProcedureScope (name)
471END StartBuildProcedure ;
472
473
474(*
475 EndBuildProcedure - Ends building a Procedure.
476 It checks the start procedure name matches the end
477 procedure name.
478
479 The Stack:
480
481 (Procedure Not Defined in definition module)
482
483 Entry Exit
484
485 Ptr ->
486 +------------+
487 | NameEnd |
488 |------------|
489 | ProcSym |
490 |------------|
491 | NameStart |
492 |------------|
493 Empty
494*)
495
496PROCEDURE EndBuildProcedure ;
497VAR
498 ProcSym : CARDINAL ;
499 NameEnd,
500 NameStart: Name ;
501BEGIN
502 PopT(NameEnd) ;
503 PopT(ProcSym) ;
504 PopT(NameStart) ;
505 IF NameEnd#NameStart
506 THEN
507 (* we dont issue an error based around incorrect module names this would be done in P1 and P2.
508 If we get here then something has gone wrong with our error recovery in P3, so we bail out.
509 *)
510 WriteFormat0('too many errors in pass 3') ;
511 FlushErrors
512 END ;
513 EndScope ;
514 M2Error.LeaveErrorScope
515END EndBuildProcedure ;
516
517
518(*
519 BuildProcedureHeading - Builds a procedure heading for the definition
520 module procedures.
521
522 Operation only performed if compiling a
523 definition module.
524
525 The Stack:
526
527 Entry Exit
528
529 Ptr ->
530 +------------+
531 | ProcSym |
532 |------------|
533 | NameStart |
534 |------------|
535 Empty
536
537*)
538
539PROCEDURE BuildProcedureHeading ;
540VAR
541 ProcSym : CARDINAL ;
542 NameStart: Name ;
543BEGIN
544 IF CompilingDefinitionModule()
545 THEN
546 PopT(ProcSym) ;
547 PopT(NameStart) ;
548 EndScope
549 END
550END BuildProcedureHeading ;
551
552
553(*
554 BuildSubrange - Builds a Subrange type Symbol.
555
556
557 Stack
558
559 Entry Exit
560
561 Ptr ->
562 +------------+
563 | High |
564 |------------|
565 | Low | <- Ptr
566 |------------|
567*)
568
569PROCEDURE BuildSubrange ;
570VAR
571 Base,
572 Type,
573 Low,
574 High: CARDINAL ;
575BEGIN
576 PopT(High) ;
577 PopT(Low) ;
578 GetSubrangeFromFifoQueue(Type) ; (* Collect subrange type from pass 2 and fill in *)
579 (* bounds. *)
580 GetSubrangeFromFifoQueue(Base) ; (* Get base of subrange (maybe NulSym) *)
581(*
582 WriteString('Subrange type name is: ') ; WriteKey(GetSymName(Type)) ; WriteLn ;
583 WriteString('Subrange High is: ') ; WriteKey(GetSymName(High)) ;
584 WriteString(' Low is: ') ; WriteKey(GetSymName(Low)) ; WriteLn ;
585*)
586 PutSubrange(Type, Low, High, Base) (* if Base is NulSym then it is *)
587 (* worked out later in M2GCCDeclare *)
588END BuildSubrange ;
589
590
591(*
592 BuildNulName - Pushes a NulKey onto the top of the stack.
593 The Stack:
594
595
596 Entry Exit
597
598 <- Ptr
599 Empty +------------+
600 | NulKey |
601 |------------|
602*)
603
604PROCEDURE BuildNulName ;
605BEGIN
606 PushT(NulName)
607END BuildNulName ;
608
609
610(*
611 BuildConst - builds a constant.
612 Stack
613
614 Entry Exit
615
616 Ptr -> <- Ptr
617 +------------+ +------------+
618 | Name | | Sym |
619 |------------+ |------------|
620*)
621
622PROCEDURE BuildConst ;
623VAR
624 name: Name ;
625 tok : CARDINAL ;
626 Sym : CARDINAL ;
627BEGIN
628 PopTtok (name, tok) ;
629 Sym := RequestSym (tok, name) ;
630 PushTtok (Sym, tok)
631END BuildConst ;
632
633
634(*
635 BuildVarAtAddress - updates the symbol table entry of, variable sym, to be declared
636 at address, address.
637
638 Stack
639
640 Entry Exit
641
642 Ptr ->
643 +--------------+
644 | Expr | EType | <- Ptr
645 |--------------+ +--------------+
646 | name | SType | | name | SType |
647 |--------------+ |--------------|
648*)
649
650PROCEDURE BuildVarAtAddress ;
651VAR
652 nametok : CARDINAL ;
653 name : Name ;
654 Sym, SType,
655 Exp, EType: CARDINAL ;
656BEGIN
657 PopTF(Exp, EType) ;
658 PopTFtok (name, SType, nametok) ;
659 PushTF(name, SType) ;
660 Sym := RequestSym (nametok, name) ;
661 IF GetMode(Sym)=LeftValue
662 THEN
663 PutVariableAtAddress(Sym, Exp)
664 ELSE
665 InternalError ('expecting lvalue for this variable which is declared at an explicit address')
666 END
667END BuildVarAtAddress ;
668
669
670(*
671 BuildOptArgInitializer - assigns the constant value symbol, const, to be the
672 initial value of the optional parameter should it be
673 absent.
674
675 Ptr ->
676 +------------+
677 | const |
678 |------------| <- Ptr
679*)
680
681PROCEDURE BuildOptArgInitializer ;
682VAR
683 const: CARDINAL ;
684BEGIN
685 PopT(const) ;
686 PutOptArgInit(GetCurrentScope(), const)
687END BuildOptArgInitializer ;
688
689
690END P3SymBuild.