1 /* do not edit automatically generated by mc from mcComp. */
2 /* Copyright (C) 2015-2025 Free Software Foundation, Inc.
3 This file is part of GNU Modula-2.
5 GNU Modula-2 is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
10 GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 You should have received a copy of the GNU General Public License
16 along with GCC; see the file COPYING3. If not see
17 <http://www.gnu.org/licenses/>. */
22 # if !defined (PROC_D)
24 typedef void (*PROC_t
) (void);
25 typedef struct { PROC_t proc
; } PROC
;
37 #if defined(__cplusplus)
47 # include "GsymbolKey.h"
49 # include "GmcReserved.h"
50 # include "GmcSearch.h"
51 # include "GmcLexBuf.h"
52 # include "GmcFileName.h"
53 # include "GmcPreprocess.h"
54 # include "GFormatStrings.h"
61 # include "GmcComment.h"
62 # include "GmcError.h"
63 # include "GnameKey.h"
64 # include "GmcPrintf.h"
65 # include "GmcQuiet.h"
66 # include "GDynamicStrings.h"
67 # include "GmcOptions.h"
69 # define Debugging false
70 typedef struct mcComp_parserFunction_p mcComp_parserFunction
;
72 typedef struct mcComp_openFunction_p mcComp_openFunction
;
74 typedef bool (*mcComp_parserFunction_t
) (void);
75 struct mcComp_parserFunction_p
{ mcComp_parserFunction_t proc
; };
77 typedef bool (*mcComp_openFunction_t
) (decl_node
, bool);
78 struct mcComp_openFunction_p
{ mcComp_openFunction_t proc
; };
80 static unsigned int currentPass
;
83 compile - check, s, is non NIL before calling doCompile.
86 extern "C" void mcComp_compile (DynamicStrings_String s
);
89 getPassNo - return the pass no.
92 extern "C" unsigned int mcComp_getPassNo (void);
95 doCompile - translate file, s, using a 6 pass technique.
98 static void doCompile (DynamicStrings_String s
);
101 examineCompilationUnit - opens the source file to obtain the module name and kind of module.
104 static decl_node
examineCompilationUnit (void);
107 peepInto - peeps into source, s, and initializes a definition/implementation or
108 program module accordingly.
111 static decl_node
peepInto (DynamicStrings_String s
);
114 initParser - returns the node of the module found in the source file.
117 static decl_node
initParser (DynamicStrings_String s
);
120 p1 - wrap the pass procedure with the correct parameter values.
123 static void p1 (decl_node n
);
126 p2 - wrap the pass procedure with the correct parameter values.
129 static void p2 (decl_node n
);
132 p3 - wrap the pass procedure with the correct parameter values.
135 static void p3 (decl_node n
);
138 p4 - wrap the pass procedure with the correct parameter values.
141 static void p4 (decl_node n
);
144 p5 - wrap the pass procedure with the correct parameter values.
147 static void p5 (decl_node n
);
153 static bool doOpen (decl_node n
, DynamicStrings_String symName
, DynamicStrings_String fileName
, bool exitOnFailure
);
156 openDef - try and open the definition module source file.
157 Returns true/false if successful/unsuccessful or
161 static bool openDef (decl_node n
, bool exitOnFailure
);
164 openMod - try and open the implementation/program module source file.
165 Returns true/false if successful/unsuccessful or
169 static bool openMod (decl_node n
, bool exitOnFailure
);
175 static void pass (unsigned int no
, decl_node n
, mcComp_parserFunction f
, decl_isNodeF isnode
, mcComp_openFunction open
);
181 static void doPass (bool parseDefs
, bool parseMain
, unsigned int no
, symbolKey_performOperation p
, const char *desc_
, unsigned int _desc_high
);
187 static void setToPassNo (unsigned int n
);
190 init - initialise data structures for this module.
193 static void init (void);
197 doCompile - translate file, s, using a 6 pass technique.
200 static void doCompile (DynamicStrings_String s
)
205 doPass (true, true, 1, (symbolKey_performOperation
) {(symbolKey_performOperation_t
) p1
}, (const char *) "lexical analysis, modules, root decls and C preprocessor", 56);
206 doPass (true, true, 2, (symbolKey_performOperation
) {(symbolKey_performOperation_t
) p2
}, (const char *) "[all modules] type equivalence and enumeration types", 52);
207 doPass (true, true, 3, (symbolKey_performOperation
) {(symbolKey_performOperation_t
) p3
}, (const char *) "[all modules] import lists, types, variables and procedure declarations", 71);
208 doPass (true, true, 4, (symbolKey_performOperation
) {(symbolKey_performOperation_t
) p4
}, (const char *) "[all modules] constant expressions", 34);
209 if (! (decl_isDef (n
)))
211 /* avoid gcc warning by using compound statement even if not strictly necessary. */
214 mcQuiet_qprintf0 ((const char *) "Parse implementation module\\n", 29);
215 doPass (false, true, 5, (symbolKey_performOperation
) {(symbolKey_performOperation_t
) p5
}, (const char *) "[implementation module] build code tree for all procedures and module initializations", 85);
219 mcQuiet_qprintf0 ((const char *) "Parse program module\\n", 22);
220 doPass (false, true, 5, (symbolKey_performOperation
) {(symbolKey_performOperation_t
) p5
}, (const char *) "[program module] build code tree for all procedures and module initializations", 78);
223 mcQuiet_qprintf0 ((const char *) "walk tree converting it to C/C++\\n", 34);
229 examineCompilationUnit - opens the source file to obtain the module name and kind of module.
232 static decl_node
examineCompilationUnit (void)
234 /* stop if we see eof, ';' or '[' */
235 while (((mcLexBuf_currenttoken
!= mcReserved_eoftok
) && (mcLexBuf_currenttoken
!= mcReserved_semicolontok
)) && (mcLexBuf_currenttoken
!= mcReserved_lsbratok
))
237 if (mcLexBuf_currenttoken
== mcReserved_definitiontok
)
239 mcLexBuf_getToken ();
240 if (mcLexBuf_currenttoken
== mcReserved_moduletok
)
242 /* avoid dangling else. */
243 mcLexBuf_getToken ();
244 if (mcLexBuf_currenttoken
== mcReserved_fortok
)
246 mcLexBuf_getToken ();
247 if (mcLexBuf_currenttoken
== mcReserved_stringtok
)
249 mcLexBuf_getToken ();
253 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "expecting language string after FOR keyword", 43)));
257 if (mcLexBuf_currenttoken
== mcReserved_identtok
)
259 return decl_lookupDef (nameKey_makekey (mcLexBuf_currentstring
));
264 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after DEFINITION keyword", 39)));
267 else if (mcLexBuf_currenttoken
== mcReserved_implementationtok
)
269 /* avoid dangling else. */
270 mcLexBuf_getToken ();
271 if (mcLexBuf_currenttoken
== mcReserved_moduletok
)
273 /* avoid dangling else. */
274 mcLexBuf_getToken ();
275 if (mcLexBuf_currenttoken
== mcReserved_identtok
)
277 return decl_lookupImp (nameKey_makekey (mcLexBuf_currentstring
));
282 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after IMPLEMENTATION keyword", 43)));
285 else if (mcLexBuf_currenttoken
== mcReserved_moduletok
)
287 /* avoid dangling else. */
288 mcLexBuf_getToken ();
289 if (mcLexBuf_currenttoken
== mcReserved_identtok
)
291 return decl_lookupModule (nameKey_makekey (mcLexBuf_currentstring
));
294 mcLexBuf_getToken ();
296 mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "failed to find module name", 26)));
298 ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1);
299 __builtin_unreachable ();
304 peepInto - peeps into source, s, and initializes a definition/implementation or
305 program module accordingly.
308 static decl_node
peepInto (DynamicStrings_String s
)
311 DynamicStrings_String fileName
;
313 fileName
= mcPreprocess_preprocessModule (s
);
314 if (mcLexBuf_openSource (fileName
))
316 n
= examineCompilationUnit ();
317 decl_setSource (n
, nameKey_makekey (DynamicStrings_string (fileName
)));
318 decl_setMainModule (n
);
319 mcLexBuf_closeSource ();
320 mcLexBuf_reInitialize ();
325 mcPrintf_fprintf1 (FIO_StdErr
, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &s
, (sizeof (s
)-1));
328 ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1);
329 __builtin_unreachable ();
334 initParser - returns the node of the module found in the source file.
337 static decl_node
initParser (DynamicStrings_String s
)
339 mcQuiet_qprintf1 ((const char *) "Compiling: %s\\n", 15, (const unsigned char *) &s
, (sizeof (s
)-1));
341 /* static analysis guarentees a RETURN statement will be used before here. */
342 __builtin_unreachable ();
347 p1 - wrap the pass procedure with the correct parameter values.
350 static void p1 (decl_node n
)
354 /* avoid dangling else. */
355 pass (1, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp1_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isDef
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openDef
});
356 if ((decl_hasHidden (n
)) && (mcOptions_getExtendedOpaque ()))
358 pass (1, decl_lookupImp (decl_getSymName (n
)), (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp1_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImp
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
363 pass (1, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp1_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImpOrModule
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
369 p2 - wrap the pass procedure with the correct parameter values.
372 static void p2 (decl_node n
)
376 /* avoid dangling else. */
377 pass (2, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp2_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isDef
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openDef
});
378 if ((decl_hasHidden (n
)) && (mcOptions_getExtendedOpaque ()))
380 pass (2, decl_lookupImp (decl_getSymName (n
)), (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp2_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImp
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
385 pass (2, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp2_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImpOrModule
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
391 p3 - wrap the pass procedure with the correct parameter values.
394 static void p3 (decl_node n
)
398 /* avoid dangling else. */
399 pass (3, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp3_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isDef
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openDef
});
400 if ((decl_hasHidden (n
)) && (mcOptions_getExtendedOpaque ()))
402 pass (3, decl_lookupImp (decl_getSymName (n
)), (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp3_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImp
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
407 pass (3, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp3_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImpOrModule
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
413 p4 - wrap the pass procedure with the correct parameter values.
416 static void p4 (decl_node n
)
420 /* avoid dangling else. */
421 pass (4, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp4_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isDef
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openDef
});
422 if ((decl_hasHidden (n
)) && (mcOptions_getExtendedOpaque ()))
424 pass (4, decl_lookupImp (decl_getSymName (n
)), (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp4_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImp
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
429 pass (4, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp4_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImpOrModule
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
435 p5 - wrap the pass procedure with the correct parameter values.
438 static void p5 (decl_node n
)
440 pass (5, n
, (mcComp_parserFunction
) {(mcComp_parserFunction_t
) mcp5_CompilationUnit
}, (decl_isNodeF
) {(decl_isNodeF_t
) decl_isImpOrModule
}, (mcComp_openFunction
) {(mcComp_openFunction_t
) openMod
});
448 static bool doOpen (decl_node n
, DynamicStrings_String symName
, DynamicStrings_String fileName
, bool exitOnFailure
)
450 DynamicStrings_String postProcessed
;
452 mcQuiet_qprintf2 ((const char *) " Module %-20s : %s\\n", 22, (const unsigned char *) &symName
, (sizeof (symName
)-1), (const unsigned char *) &fileName
, (sizeof (fileName
)-1));
453 postProcessed
= mcPreprocess_preprocessModule (fileName
);
454 decl_setSource (n
, nameKey_makekey (DynamicStrings_string (postProcessed
)));
455 decl_setCurrentModule (n
);
456 if (mcLexBuf_openSource (postProcessed
))
460 mcPrintf_fprintf1 (FIO_StdErr
, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &fileName
, (sizeof (fileName
)-1));
466 /* static analysis guarentees a RETURN statement will be used before here. */
467 __builtin_unreachable ();
472 openDef - try and open the definition module source file.
473 Returns true/false if successful/unsuccessful or
477 static bool openDef (decl_node n
, bool exitOnFailure
)
479 nameKey_Name sourceName
;
480 DynamicStrings_String symName
;
481 DynamicStrings_String fileName
;
483 sourceName
= decl_getSource (n
);
484 symName
= DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n
)));
485 if (sourceName
== nameKey_NulName
)
487 /* avoid dangling else. */
488 if (! (mcSearch_findSourceDefFile (symName
, &fileName
)))
490 mcPrintf_fprintf1 (FIO_StdErr
, (const char *) "failed to find definition module %s.def\\n", 41, (const unsigned char *) &symName
, (sizeof (symName
)-1));
499 fileName
= DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName
));
501 return doOpen (n
, symName
, fileName
, exitOnFailure
);
502 /* static analysis guarentees a RETURN statement will be used before here. */
503 __builtin_unreachable ();
508 openMod - try and open the implementation/program module source file.
509 Returns true/false if successful/unsuccessful or
513 static bool openMod (decl_node n
, bool exitOnFailure
)
515 nameKey_Name sourceName
;
516 DynamicStrings_String symName
;
517 DynamicStrings_String fileName
;
519 sourceName
= decl_getSource (n
);
520 symName
= DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n
)));
521 if (sourceName
== nameKey_NulName
)
523 /* avoid dangling else. */
524 if (! (mcSearch_findSourceModFile (symName
, &fileName
)))
528 mcPrintf_fprintf1 (FIO_StdErr
, (const char *) "failed to find implementation module %s.mod\\n", 45, (const unsigned char *) &symName
, (sizeof (symName
)-1));
532 mcPrintf_fprintf1 (FIO_StdErr
, (const char *) "failed to find program module %s.mod\\n", 38, (const unsigned char *) &symName
, (sizeof (symName
)-1));
542 fileName
= DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName
));
544 return doOpen (n
, symName
, fileName
, exitOnFailure
);
545 /* static analysis guarentees a RETURN statement will be used before here. */
546 __builtin_unreachable ();
554 static void pass (unsigned int no
, decl_node n
, mcComp_parserFunction f
, decl_isNodeF isnode
, mcComp_openFunction open
)
556 if (((*isnode
.proc
) (n
)) && (! (decl_isVisited (n
))))
559 if ((*open
.proc
) (n
, true))
561 if (! ((*f
.proc
) ()))
563 mcError_writeFormat0 ((const char *) "compilation failed", 18);
564 mcLexBuf_closeSource ();
567 mcLexBuf_closeSource ();
577 static void doPass (bool parseDefs
, bool parseMain
, unsigned int no
, symbolKey_performOperation p
, const char *desc_
, unsigned int _desc_high
)
579 DynamicStrings_String descs
;
580 char desc
[_desc_high
+1];
582 /* make a local copy of each unbounded array. */
583 memcpy (desc
, desc_
, _desc_high
+1);
586 descs
= DynamicStrings_InitString ((const char *) desc
, _desc_high
);
587 mcQuiet_qprintf2 ((const char *) "Pass %d: %s\\n", 13, (const unsigned char *) &no
, (sizeof (no
)-1), (const unsigned char *) &descs
, (sizeof (descs
)-1));
588 decl_foreachDefModuleDo ((symbolKey_performOperation
) {(symbolKey_performOperation_t
) decl_unsetVisited
});
589 decl_foreachModModuleDo ((symbolKey_performOperation
) {(symbolKey_performOperation_t
) decl_unsetVisited
});
592 decl_unsetVisited (decl_getMainModule ());
593 if (parseDefs
&& (decl_isImp (decl_getMainModule ())))
595 /* we need to parse the definition module of a corresponding implementation module. */
596 (*p
.proc
) (reinterpret_cast <void *> (decl_lookupDef (decl_getSymName (decl_getMainModule ()))));
598 (*p
.proc
) (reinterpret_cast <void *> (decl_getMainModule ()));
602 decl_foreachDefModuleDo (p
);
604 mcError_flushWarnings ();
605 mcError_flushErrors ();
614 static void setToPassNo (unsigned int n
)
621 init - initialise data structures for this module.
624 static void init (void)
631 compile - check, s, is non NIL before calling doCompile.
634 extern "C" void mcComp_compile (DynamicStrings_String s
)
644 getPassNo - return the pass no.
647 extern "C" unsigned int mcComp_getPassNo (void)
650 /* static analysis guarentees a RETURN statement will be used before here. */
651 __builtin_unreachable ();
654 extern "C" void _M2_mcComp_init (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])
659 extern "C" void _M2_mcComp_fini (__attribute__((unused
)) int argc
, __attribute__((unused
)) char *argv
[], __attribute__((unused
)) char *envp
[])