]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/m2/mc/mcComp.mod
Update copyright years.
[thirdparty/gcc.git] / gcc / m2 / mc / mcComp.mod
CommitLineData
a945c346 1(* Copyright (C) 2015-2024 Free Software Foundation, Inc.
1eee94d3
GM
2 This file is part of GNU Modula-2.
3
4GNU Modula-2 is free software; you can redistribute it and/or modify it under
5the terms of the GNU General Public License as published by the Free
6Software Foundation; either version 3, or (at your option) any later
7version.
8
9GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY
10WARRANTY; without even the implied warranty of MERCHANTABILITY or
11FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12for more details.
13
14You should have received a copy of the GNU General Public License along
15with gm2; see the file COPYING. If not, write to the Free Software
16Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *)
17
18IMPLEMENTATION MODULE mcComp ;
19
20
21FROM FIO IMPORT StdErr ;
22FROM libc IMPORT exit ;
23
24FROM decl IMPORT node, isNodeF, isDef, isImp, isModule, isMainModule,
25 setMainModule, setCurrentModule, getSource, isImpOrModule,
26 lookupDef, lookupModule, lookupImp, setSource, getSymName,
27 foreachDefModuleDo, foreachModModuleDo,
28 getMainModule, out, hasHidden,
29 setVisited, unsetVisited, isVisited ;
30
31FROM symbolKey IMPORT performOperation ;
32
33FROM SYSTEM IMPORT ADDRESS ;
34FROM mcReserved IMPORT toktype ;
35FROM mcSearch IMPORT findSourceDefFile, findSourceModFile ;
36FROM mcLexBuf IMPORT openSource, closeSource, currenttoken, getToken, reInitialize, currentstring ;
37FROM mcFileName IMPORT calculateFileName ;
38FROM mcPreprocess IMPORT preprocessModule ;
39
40FROM FormatStrings IMPORT Sprintf1 ;
41
42IMPORT mcflex ;
43IMPORT mcp1 ;
44IMPORT mcp2 ;
45IMPORT mcp3 ;
46IMPORT mcp4 ;
47IMPORT mcp5 ;
48IMPORT mcComment ;
49
50
51FROM mcError IMPORT writeFormat0, flushErrors, flushWarnings ;
52FROM nameKey IMPORT Name, NulName, getKey, keyToCharStar, makekey ;
53FROM mcPrintf IMPORT fprintf1 ;
54FROM mcQuiet IMPORT qprintf0, qprintf1, qprintf2 ;
55FROM DynamicStrings IMPORT String, InitString, KillString, InitStringCharStar, Dup, Mark, string ;
56FROM mcOptions IMPORT getExtendedOpaque ;
57
58CONST
59 Debugging = FALSE ;
60
61TYPE
62 parserFunction = PROCEDURE () : BOOLEAN ;
63 openFunction = PROCEDURE (node, BOOLEAN) : BOOLEAN ;
64
65VAR
66 currentPass: CARDINAL ;
67
68
69(*
70 doCompile - translate file, s, using a 6 pass technique.
71*)
72
73PROCEDURE doCompile (s: String) ;
74VAR
75 n: node ;
76BEGIN
77 n := initParser (s) ;
78 doPass (TRUE, TRUE, 1, p1, 'lexical analysis, modules, root decls and C preprocessor') ;
79 doPass (TRUE, TRUE, 2, p2, '[all modules] type equivalence and enumeration types') ;
80 doPass (TRUE, TRUE, 3, p3, '[all modules] import lists, types, variables and procedure declarations') ;
81 doPass (TRUE, TRUE, 4, p4, '[all modules] constant expressions') ;
82
83 IF NOT isDef (n)
84 THEN
85 IF isImp (n)
86 THEN
87 qprintf0 ('Parse implementation module\n') ;
88 doPass (FALSE, TRUE, 5, p5, '[implementation module] build code tree for all procedures and module initializations')
89 ELSE
90 qprintf0 ('Parse program module\n') ;
91 doPass (FALSE, TRUE, 5, p5, '[program module] build code tree for all procedures and module initializations')
92 END ;
93 END ;
94
95 qprintf0 ('walk tree converting it to C/C++\n') ;
96 out
97END doCompile ;
98
99
100(*
101 compile - check, s, is non NIL before calling doCompile.
102*)
103
104PROCEDURE compile (s: String) ;
105BEGIN
106 IF s#NIL
107 THEN
108 doCompile (s)
109 END
110END compile ;
111
112
113(*
114 examineCompilationUnit - opens the source file to obtain the module name and kind of module.
115*)
116
117PROCEDURE examineCompilationUnit () : node ;
118BEGIN
119 (* stop if we see eof, ';' or '[' *)
120 WHILE (currenttoken#eoftok) AND (currenttoken#semicolontok) AND (currenttoken#lsbratok) DO
121 IF currenttoken=definitiontok
122 THEN
123 getToken ;
124 IF currenttoken=moduletok
125 THEN
126 getToken ;
127 IF currenttoken=fortok
128 THEN
129 getToken ;
130 IF currenttoken=stringtok
131 THEN
132 getToken
133 ELSE
134 mcflex.mcError (string (InitString ('expecting language string after FOR keyword'))) ;
135 exit (1)
136 END
137 END ;
138 IF currenttoken=identtok
139 THEN
140 RETURN lookupDef (makekey (currentstring))
141 END
142 ELSE
143 mcflex.mcError (string (InitString ('MODULE missing after DEFINITION keyword')))
144 END
145 ELSIF currenttoken=implementationtok
146 THEN
147 getToken ;
148 IF currenttoken=moduletok
149 THEN
150 getToken ;
151 IF currenttoken=identtok
152 THEN
153 RETURN lookupImp (makekey (currentstring))
154 END
155 ELSE
156 mcflex.mcError (string (InitString ('MODULE missing after IMPLEMENTATION keyword')))
157 END
158 ELSIF currenttoken=moduletok
159 THEN
160 getToken ;
161 IF currenttoken=identtok
162 THEN
163 RETURN lookupModule (makekey (currentstring))
164 END
165 END ;
166 getToken
167 END ;
168 mcflex.mcError (string (InitString ('failed to find module name'))) ;
169 exit (1)
170END examineCompilationUnit ;
171
172
173(*
174 peepInto - peeps into source, s, and initializes a definition/implementation or
175 program module accordingly.
176*)
177
178PROCEDURE peepInto (s: String) : node ;
179VAR
180 n : node ;
181 fileName: String ;
182BEGIN
183 fileName := preprocessModule (s) ;
184 IF openSource (fileName)
185 THEN
186 n := examineCompilationUnit () ;
187 setSource (n, makekey (string (fileName))) ;
188 setMainModule (n) ;
189 closeSource ;
190 reInitialize ;
191 RETURN n
192 ELSE
193 fprintf1 (StdErr, 'failed to open %s\n', s) ;
194 exit (1)
195 END
196END peepInto ;
197
198
199(*
200 initParser - returns the node of the module found in the source file.
201*)
202
203PROCEDURE initParser (s: String) : node ;
204BEGIN
205 qprintf1 ('Compiling: %s\n', s) ;
206 RETURN peepInto (s)
207END initParser ;
208
209
210(*
211 p1 - wrap the pass procedure with the correct parameter values.
212*)
213
214PROCEDURE p1 (n: node) ;
215BEGIN
216 IF isDef (n)
217 THEN
218 pass (1, n, mcp1.CompilationUnit, isDef, openDef) ;
219 IF hasHidden (n) AND getExtendedOpaque ()
220 THEN
221 pass (1, lookupImp (getSymName (n)), mcp1.CompilationUnit, isImp, openMod)
222 END
223 ELSE
224 pass (1, n, mcp1.CompilationUnit, isImpOrModule, openMod)
225 END
226END p1 ;
227
228
229(*
230 p2 - wrap the pass procedure with the correct parameter values.
231*)
232
233PROCEDURE p2 (n: node) ;
234BEGIN
235 IF isDef (n)
236 THEN
237 pass (2, n, mcp2.CompilationUnit, isDef, openDef) ;
238 IF hasHidden (n) AND getExtendedOpaque ()
239 THEN
240 pass (2, lookupImp (getSymName (n)), mcp2.CompilationUnit, isImp, openMod)
241 END
242 ELSE
243 pass (2, n, mcp2.CompilationUnit, isImpOrModule, openMod)
244 END
245END p2 ;
246
247
248(*
249 p3 - wrap the pass procedure with the correct parameter values.
250*)
251
252PROCEDURE p3 (n: node) ;
253BEGIN
254 IF isDef (n)
255 THEN
256 pass (3, n, mcp3.CompilationUnit, isDef, openDef) ;
257 IF hasHidden (n) AND getExtendedOpaque ()
258 THEN
259 pass (3, lookupImp (getSymName (n)), mcp3.CompilationUnit, isImp, openMod)
260 END
261 ELSE
262 pass (3, n, mcp3.CompilationUnit, isImpOrModule, openMod)
263 END
264END p3 ;
265
266
267(*
268 p4 - wrap the pass procedure with the correct parameter values.
269*)
270
271PROCEDURE p4 (n: node) ;
272BEGIN
273 IF isDef (n)
274 THEN
275 pass (4, n, mcp4.CompilationUnit, isDef, openDef) ;
276 IF hasHidden (n) AND getExtendedOpaque ()
277 THEN
278 pass (4, lookupImp (getSymName (n)), mcp4.CompilationUnit, isImp, openMod)
279 END
280 ELSE
281 pass (4, n, mcp4.CompilationUnit, isImpOrModule, openMod)
282 END
283END p4 ;
284
285
286(*
287 p5 - wrap the pass procedure with the correct parameter values.
288*)
289
290PROCEDURE p5 (n: node) ;
291BEGIN
292 pass (5, n, mcp5.CompilationUnit, isImpOrModule, openMod)
293END p5 ;
294
295
296(*
297 doOpen -
298*)
299
300PROCEDURE doOpen (n: node; symName, fileName: String; exitOnFailure: BOOLEAN) : BOOLEAN ;
301VAR
302 postProcessed: String ;
303BEGIN
304 qprintf2(' Module %-20s : %s\n', symName, fileName) ;
305 postProcessed := preprocessModule (fileName) ;
306 setSource (n, makekey (string (postProcessed))) ;
307 setCurrentModule (n) ;
308 IF openSource (postProcessed)
309 THEN
310 RETURN TRUE
311 END ;
312 fprintf1 (StdErr, 'failed to open %s\n', fileName) ;
313 IF exitOnFailure
314 THEN
315 exit (1)
316 END ;
317 RETURN FALSE
318END doOpen ;
319
320
321(*
322 openDef - try and open the definition module source file.
323 Returns true/false if successful/unsuccessful or
324 exitOnFailure.
325*)
326
327PROCEDURE openDef (n: node; exitOnFailure: BOOLEAN) : BOOLEAN ;
328VAR
329 sourceName: Name ;
330 symName,
331 fileName : String ;
332BEGIN
333 sourceName := getSource (n) ;
334 symName := InitStringCharStar (keyToCharStar (getSymName (n))) ;
335 IF sourceName=NulName
336 THEN
337 IF NOT findSourceDefFile (symName, fileName)
338 THEN
339 fprintf1 (StdErr, 'failed to find definition module %s.def\n', symName) ;
340 IF exitOnFailure
341 THEN
342 exit (1)
343 END
344 END
345 ELSE
346 fileName := InitStringCharStar (keyToCharStar (sourceName))
347 END ;
348 RETURN doOpen (n, symName, fileName, exitOnFailure)
349END openDef ;
350
351
352(*
353 openMod - try and open the implementation/program module source file.
354 Returns true/false if successful/unsuccessful or
355 exitOnFailure.
356*)
357
358PROCEDURE openMod (n: node; exitOnFailure: BOOLEAN) : BOOLEAN ;
359VAR
360 sourceName: Name ;
361 symName,
362 fileName : String ;
363BEGIN
364 sourceName := getSource (n) ;
365 symName := InitStringCharStar (keyToCharStar (getSymName (n))) ;
366 IF sourceName=NulName
367 THEN
368 IF NOT findSourceModFile (symName, fileName)
369 THEN
370 IF isImp (n)
371 THEN
372 fprintf1 (StdErr, 'failed to find implementation module %s.mod\n', symName)
373 ELSE
374 fprintf1 (StdErr, 'failed to find program module %s.mod\n', symName)
375 END ;
376 IF exitOnFailure
377 THEN
378 exit (1)
379 END
380 END
381 ELSE
382 fileName := InitStringCharStar (keyToCharStar (sourceName))
383 END ;
384 RETURN doOpen (n, symName, fileName, exitOnFailure)
385END openMod ;
386
387
388(*
389 pass -
390*)
391
392PROCEDURE pass (no: CARDINAL; n: node; f: parserFunction;
393 isnode: isNodeF; open: openFunction) ;
394BEGIN
395 IF isnode (n) AND (NOT isVisited (n))
396 THEN
397 setVisited (n) ;
398 IF open (n, TRUE)
399 THEN
400 IF NOT f ()
401 THEN
402 writeFormat0 ('compilation failed') ;
403 closeSource ;
404 RETURN
405 END ;
406 closeSource
407 END
408 END
409END pass ;
410
411
412(*
413 doPass -
414*)
415
416PROCEDURE doPass (parseDefs, parseMain: BOOLEAN;
417 no: CARDINAL; p: performOperation; desc: ARRAY OF CHAR) ;
418VAR
419 descs: String ;
420BEGIN
421 setToPassNo (no) ;
422 descs := InitString (desc) ;
423 qprintf2 ('Pass %d: %s\n', no, descs) ;
424 foreachDefModuleDo (unsetVisited) ;
425 foreachModModuleDo (unsetVisited) ;
426 IF parseMain
427 THEN
428 unsetVisited (getMainModule ()) ;
429 IF parseDefs AND isImp (getMainModule ())
430 THEN
431 (* we need to parse the definition module of a corresponding implementation module. *)
432 p (lookupDef (getSymName (getMainModule ())))
433 END ;
434 p (getMainModule ())
435 END ;
436 IF parseDefs
437 THEN
438 foreachDefModuleDo (p)
439 END ;
440 flushWarnings ; flushErrors ;
441 setToPassNo (0)
442END doPass ;
443
444
445(*
446 setToPassNo -
447*)
448
449PROCEDURE setToPassNo (n: CARDINAL) ;
450BEGIN
451 currentPass := n
452END setToPassNo ;
453
454
455(*
456 getPassNo - return the pass no.
457*)
458
459PROCEDURE getPassNo () : CARDINAL ;
460BEGIN
461 RETURN currentPass
462END getPassNo ;
463
464
465(*
466 init - initialise data structures for this module.
467*)
468
469PROCEDURE init ;
470BEGIN
471 setToPassNo (0)
472END init ;
473
474
475BEGIN
476 init
477END mcComp.