/* do not edit automatically generated by mc from mcComp. */
/* Copyright (C) 2015-2025 Free Software Foundation, Inc.
This file is part of GNU Modula-2.
GNU Modula-2 is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GNU Modula-2 is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
. */
#include "config.h"
#include "system.h"
#include
# if !defined (PROC_D)
# define PROC_D
typedef void (*PROC_t) (void);
typedef struct { PROC_t proc; } PROC;
# endif
# if !defined (TRUE)
# define TRUE (1==1)
# endif
# if !defined (FALSE)
# define FALSE (1==0)
# endif
# include "Gmcrts.h"
#if defined(__cplusplus)
# undef NULL
# define NULL 0
#endif
#define _mcComp_C
#include "GmcComp.h"
# include "GFIO.h"
# include "Glibc.h"
# include "Gdecl.h"
# include "GsymbolKey.h"
# include "GSYSTEM.h"
# include "GmcReserved.h"
# include "GmcSearch.h"
# include "GmcLexBuf.h"
# include "GmcFileName.h"
# include "GmcPreprocess.h"
# include "GFormatStrings.h"
# include "Gmcflex.h"
# include "Gmcp1.h"
# include "Gmcp2.h"
# include "Gmcp3.h"
# include "Gmcp4.h"
# include "Gmcp5.h"
# include "GmcComment.h"
# include "GmcError.h"
# include "GnameKey.h"
# include "GmcPrintf.h"
# include "GmcQuiet.h"
# include "GDynamicStrings.h"
# include "GmcOptions.h"
# define Debugging false
typedef struct mcComp_parserFunction_p mcComp_parserFunction;
typedef struct mcComp_openFunction_p mcComp_openFunction;
typedef bool (*mcComp_parserFunction_t) (void);
struct mcComp_parserFunction_p { mcComp_parserFunction_t proc; };
typedef bool (*mcComp_openFunction_t) (decl_node, bool);
struct mcComp_openFunction_p { mcComp_openFunction_t proc; };
static unsigned int currentPass;
/*
compile - check, s, is non NIL before calling doCompile.
*/
extern "C" void mcComp_compile (DynamicStrings_String s);
/*
getPassNo - return the pass no.
*/
extern "C" unsigned int mcComp_getPassNo (void);
/*
doCompile - translate file, s, using a 6 pass technique.
*/
static void doCompile (DynamicStrings_String s);
/*
examineCompilationUnit - opens the source file to obtain the module name and kind of module.
*/
static decl_node examineCompilationUnit (void);
/*
peepInto - peeps into source, s, and initializes a definition/implementation or
program module accordingly.
*/
static decl_node peepInto (DynamicStrings_String s);
/*
initParser - returns the node of the module found in the source file.
*/
static decl_node initParser (DynamicStrings_String s);
/*
p1 - wrap the pass procedure with the correct parameter values.
*/
static void p1 (decl_node n);
/*
p2 - wrap the pass procedure with the correct parameter values.
*/
static void p2 (decl_node n);
/*
p3 - wrap the pass procedure with the correct parameter values.
*/
static void p3 (decl_node n);
/*
p4 - wrap the pass procedure with the correct parameter values.
*/
static void p4 (decl_node n);
/*
p5 - wrap the pass procedure with the correct parameter values.
*/
static void p5 (decl_node n);
/*
doOpen -
*/
static bool doOpen (decl_node n, DynamicStrings_String symName, DynamicStrings_String fileName, bool exitOnFailure);
/*
openDef - try and open the definition module source file.
Returns true/false if successful/unsuccessful or
exitOnFailure.
*/
static bool openDef (decl_node n, bool exitOnFailure);
/*
openMod - try and open the implementation/program module source file.
Returns true/false if successful/unsuccessful or
exitOnFailure.
*/
static bool openMod (decl_node n, bool exitOnFailure);
/*
pass -
*/
static void pass (unsigned int no, decl_node n, mcComp_parserFunction f, decl_isNodeF isnode, mcComp_openFunction open);
/*
doPass -
*/
static void doPass (bool parseDefs, bool parseMain, unsigned int no, symbolKey_performOperation p, const char *desc_, unsigned int _desc_high);
/*
setToPassNo -
*/
static void setToPassNo (unsigned int n);
/*
init - initialise data structures for this module.
*/
static void init (void);
/*
doCompile - translate file, s, using a 6 pass technique.
*/
static void doCompile (DynamicStrings_String s)
{
decl_node n;
n = initParser (s);
doPass (true, true, 1, (symbolKey_performOperation) {(symbolKey_performOperation_t) p1}, (const char *) "lexical analysis, modules, root decls and C preprocessor", 56);
doPass (true, true, 2, (symbolKey_performOperation) {(symbolKey_performOperation_t) p2}, (const char *) "[all modules] type equivalence and enumeration types", 52);
doPass (true, true, 3, (symbolKey_performOperation) {(symbolKey_performOperation_t) p3}, (const char *) "[all modules] import lists, types, variables and procedure declarations", 71);
doPass (true, true, 4, (symbolKey_performOperation) {(symbolKey_performOperation_t) p4}, (const char *) "[all modules] constant expressions", 34);
if (! (decl_isDef (n)))
{
/* avoid gcc warning by using compound statement even if not strictly necessary. */
if (decl_isImp (n))
{
mcQuiet_qprintf0 ((const char *) "Parse implementation module\\n", 29);
doPass (false, true, 5, (symbolKey_performOperation) {(symbolKey_performOperation_t) p5}, (const char *) "[implementation module] build code tree for all procedures and module initializations", 85);
}
else
{
mcQuiet_qprintf0 ((const char *) "Parse program module\\n", 22);
doPass (false, true, 5, (symbolKey_performOperation) {(symbolKey_performOperation_t) p5}, (const char *) "[program module] build code tree for all procedures and module initializations", 78);
}
}
mcQuiet_qprintf0 ((const char *) "walk tree converting it to C/C++\\n", 34);
decl_out ();
}
/*
examineCompilationUnit - opens the source file to obtain the module name and kind of module.
*/
static decl_node examineCompilationUnit (void)
{
/* stop if we see eof, ';' or '[' */
while (((mcLexBuf_currenttoken != mcReserved_eoftok) && (mcLexBuf_currenttoken != mcReserved_semicolontok)) && (mcLexBuf_currenttoken != mcReserved_lsbratok))
{
if (mcLexBuf_currenttoken == mcReserved_definitiontok)
{
mcLexBuf_getToken ();
if (mcLexBuf_currenttoken == mcReserved_moduletok)
{
/* avoid dangling else. */
mcLexBuf_getToken ();
if (mcLexBuf_currenttoken == mcReserved_fortok)
{
mcLexBuf_getToken ();
if (mcLexBuf_currenttoken == mcReserved_stringtok)
{
mcLexBuf_getToken ();
}
else
{
mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "expecting language string after FOR keyword", 43)));
libc_exit (1);
}
}
if (mcLexBuf_currenttoken == mcReserved_identtok)
{
return decl_lookupDef (nameKey_makekey (mcLexBuf_currentstring));
}
}
else
{
mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after DEFINITION keyword", 39)));
}
}
else if (mcLexBuf_currenttoken == mcReserved_implementationtok)
{
/* avoid dangling else. */
mcLexBuf_getToken ();
if (mcLexBuf_currenttoken == mcReserved_moduletok)
{
/* avoid dangling else. */
mcLexBuf_getToken ();
if (mcLexBuf_currenttoken == mcReserved_identtok)
{
return decl_lookupImp (nameKey_makekey (mcLexBuf_currentstring));
}
}
else
{
mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "MODULE missing after IMPLEMENTATION keyword", 43)));
}
}
else if (mcLexBuf_currenttoken == mcReserved_moduletok)
{
/* avoid dangling else. */
mcLexBuf_getToken ();
if (mcLexBuf_currenttoken == mcReserved_identtok)
{
return decl_lookupModule (nameKey_makekey (mcLexBuf_currentstring));
}
}
mcLexBuf_getToken ();
}
mcflex_mcError (DynamicStrings_string (DynamicStrings_InitString ((const char *) "failed to find module name", 26)));
libc_exit (1);
ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1);
__builtin_unreachable ();
}
/*
peepInto - peeps into source, s, and initializes a definition/implementation or
program module accordingly.
*/
static decl_node peepInto (DynamicStrings_String s)
{
decl_node n;
DynamicStrings_String fileName;
fileName = mcPreprocess_preprocessModule (s);
if (mcLexBuf_openSource (fileName))
{
n = examineCompilationUnit ();
decl_setSource (n, nameKey_makekey (DynamicStrings_string (fileName)));
decl_setMainModule (n);
mcLexBuf_closeSource ();
mcLexBuf_reInitialize ();
return n;
}
else
{
mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &s, (sizeof (s)-1));
libc_exit (1);
}
ReturnException ("../../gcc/m2/mc/mcComp.def", 20, 1);
__builtin_unreachable ();
}
/*
initParser - returns the node of the module found in the source file.
*/
static decl_node initParser (DynamicStrings_String s)
{
mcQuiet_qprintf1 ((const char *) "Compiling: %s\\n", 15, (const unsigned char *) &s, (sizeof (s)-1));
return peepInto (s);
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
p1 - wrap the pass procedure with the correct parameter values.
*/
static void p1 (decl_node n)
{
if (decl_isDef (n))
{
/* avoid dangling else. */
pass (1, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp1_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
{
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});
}
}
else
{
pass (1, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp1_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
}
}
/*
p2 - wrap the pass procedure with the correct parameter values.
*/
static void p2 (decl_node n)
{
if (decl_isDef (n))
{
/* avoid dangling else. */
pass (2, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp2_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
{
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});
}
}
else
{
pass (2, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp2_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
}
}
/*
p3 - wrap the pass procedure with the correct parameter values.
*/
static void p3 (decl_node n)
{
if (decl_isDef (n))
{
/* avoid dangling else. */
pass (3, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp3_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
{
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});
}
}
else
{
pass (3, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp3_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
}
}
/*
p4 - wrap the pass procedure with the correct parameter values.
*/
static void p4 (decl_node n)
{
if (decl_isDef (n))
{
/* avoid dangling else. */
pass (4, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp4_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isDef}, (mcComp_openFunction) {(mcComp_openFunction_t) openDef});
if ((decl_hasHidden (n)) && (mcOptions_getExtendedOpaque ()))
{
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});
}
}
else
{
pass (4, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp4_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
}
}
/*
p5 - wrap the pass procedure with the correct parameter values.
*/
static void p5 (decl_node n)
{
pass (5, n, (mcComp_parserFunction) {(mcComp_parserFunction_t) mcp5_CompilationUnit}, (decl_isNodeF) {(decl_isNodeF_t) decl_isImpOrModule}, (mcComp_openFunction) {(mcComp_openFunction_t) openMod});
}
/*
doOpen -
*/
static bool doOpen (decl_node n, DynamicStrings_String symName, DynamicStrings_String fileName, bool exitOnFailure)
{
DynamicStrings_String postProcessed;
mcQuiet_qprintf2 ((const char *) " Module %-20s : %s\\n", 22, (const unsigned char *) &symName, (sizeof (symName)-1), (const unsigned char *) &fileName, (sizeof (fileName)-1));
postProcessed = mcPreprocess_preprocessModule (fileName);
decl_setSource (n, nameKey_makekey (DynamicStrings_string (postProcessed)));
decl_setCurrentModule (n);
if (mcLexBuf_openSource (postProcessed))
{
return true;
}
mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to open %s\\n", 19, (const unsigned char *) &fileName, (sizeof (fileName)-1));
if (exitOnFailure)
{
libc_exit (1);
}
return false;
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
openDef - try and open the definition module source file.
Returns true/false if successful/unsuccessful or
exitOnFailure.
*/
static bool openDef (decl_node n, bool exitOnFailure)
{
nameKey_Name sourceName;
DynamicStrings_String symName;
DynamicStrings_String fileName;
sourceName = decl_getSource (n);
symName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n)));
if (sourceName == nameKey_NulName)
{
/* avoid dangling else. */
if (! (mcSearch_findSourceDefFile (symName, &fileName)))
{
mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find definition module %s.def\\n", 41, (const unsigned char *) &symName, (sizeof (symName)-1));
if (exitOnFailure)
{
libc_exit (1);
}
}
}
else
{
fileName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName));
}
return doOpen (n, symName, fileName, exitOnFailure);
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
openMod - try and open the implementation/program module source file.
Returns true/false if successful/unsuccessful or
exitOnFailure.
*/
static bool openMod (decl_node n, bool exitOnFailure)
{
nameKey_Name sourceName;
DynamicStrings_String symName;
DynamicStrings_String fileName;
sourceName = decl_getSource (n);
symName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (n)));
if (sourceName == nameKey_NulName)
{
/* avoid dangling else. */
if (! (mcSearch_findSourceModFile (symName, &fileName)))
{
if (decl_isImp (n))
{
mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find implementation module %s.mod\\n", 45, (const unsigned char *) &symName, (sizeof (symName)-1));
}
else
{
mcPrintf_fprintf1 (FIO_StdErr, (const char *) "failed to find program module %s.mod\\n", 38, (const unsigned char *) &symName, (sizeof (symName)-1));
}
if (exitOnFailure)
{
libc_exit (1);
}
}
}
else
{
fileName = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (sourceName));
}
return doOpen (n, symName, fileName, exitOnFailure);
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
pass -
*/
static void pass (unsigned int no, decl_node n, mcComp_parserFunction f, decl_isNodeF isnode, mcComp_openFunction open)
{
if (((*isnode.proc) (n)) && (! (decl_isVisited (n))))
{
decl_setVisited (n);
if ((*open.proc) (n, true))
{
if (! ((*f.proc) ()))
{
mcError_writeFormat0 ((const char *) "compilation failed", 18);
mcLexBuf_closeSource ();
return;
}
mcLexBuf_closeSource ();
}
}
}
/*
doPass -
*/
static void doPass (bool parseDefs, bool parseMain, unsigned int no, symbolKey_performOperation p, const char *desc_, unsigned int _desc_high)
{
DynamicStrings_String descs;
char desc[_desc_high+1];
/* make a local copy of each unbounded array. */
memcpy (desc, desc_, _desc_high+1);
setToPassNo (no);
descs = DynamicStrings_InitString ((const char *) desc, _desc_high);
mcQuiet_qprintf2 ((const char *) "Pass %d: %s\\n", 13, (const unsigned char *) &no, (sizeof (no)-1), (const unsigned char *) &descs, (sizeof (descs)-1));
decl_foreachDefModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) decl_unsetVisited});
decl_foreachModModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) decl_unsetVisited});
if (parseMain)
{
decl_unsetVisited (decl_getMainModule ());
if (parseDefs && (decl_isImp (decl_getMainModule ())))
{
/* we need to parse the definition module of a corresponding implementation module. */
(*p.proc) (reinterpret_cast (decl_lookupDef (decl_getSymName (decl_getMainModule ()))));
}
(*p.proc) (reinterpret_cast (decl_getMainModule ()));
}
if (parseDefs)
{
decl_foreachDefModuleDo (p);
}
mcError_flushWarnings ();
mcError_flushErrors ();
setToPassNo (0);
}
/*
setToPassNo -
*/
static void setToPassNo (unsigned int n)
{
currentPass = n;
}
/*
init - initialise data structures for this module.
*/
static void init (void)
{
setToPassNo (0);
}
/*
compile - check, s, is non NIL before calling doCompile.
*/
extern "C" void mcComp_compile (DynamicStrings_String s)
{
if (s != NULL)
{
doCompile (s);
}
}
/*
getPassNo - return the pass no.
*/
extern "C" unsigned int mcComp_getPassNo (void)
{
return currentPass;
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
extern "C" void _M2_mcComp_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
init ();
}
extern "C" void _M2_mcComp_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
}