📄 modulpsr.c
字号:
struct token *theToken,
struct defmodule *theDefmodule)
{
int error;
/*=============================*/
/* The import and export lists */
/* are initially empty. */
/*=============================*/
theDefmodule->importList = NULL;
theDefmodule->exportList = NULL;
/*==========================================*/
/* Parse import/export specifications until */
/* a right parenthesis is encountered. */
/*==========================================*/
while (theToken->type != RPAREN)
{
/*========================================*/
/* Look for the opening left parenthesis. */
/*========================================*/
if (theToken->type != LPAREN)
{
SyntaxErrorMessage(theEnv,"defmodule");
return(TRUE);
}
/*====================================*/
/* Look for the import/export keyword */
/* and call the appropriate functions */
/* for parsing the specification. */
/*====================================*/
GetToken(theEnv,readSource,theToken);
if (theToken->type != SYMBOL)
{
SyntaxErrorMessage(theEnv,"defmodule");
return(TRUE);
}
if (strcmp(ValueToString(theToken->value),"import") == 0)
{
error = ParseImportSpec(theEnv,readSource,theToken,theDefmodule);
}
else if (strcmp(ValueToString(theToken->value),"export") == 0)
{
error = ParseExportSpec(theEnv,readSource,theToken,theDefmodule,NULL);
}
else
{
SyntaxErrorMessage(theEnv,"defmodule");
return(TRUE);
}
if (error) return(TRUE);
/*============================================*/
/* Begin parsing the next port specification. */
/*============================================*/
PPCRAndIndent(theEnv);
GetToken(theEnv,readSource,theToken);
if (theToken->type == RPAREN)
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,")");
}
}
/*===================================*/
/* Return FALSE to indicate no error */
/* occurred while parsing the */
/* import/export specifications. */
/*===================================*/
return(FALSE);
}
/**********************************************************/
/* ParseImportSpec: Parses import specifications found in */
/* a defmodule construct. */
/* */
/* <import-spec> ::= (import <module-name> <port-item>) */
/* */
/* <port-item> ::= ?ALL | */
/* ?NONE | */
/* <construct-name> ?ALL | */
/* <construct-name> ?NONE | */
/* <construct-name> <names>* */
/**********************************************************/
static int ParseImportSpec(
void *theEnv,
char *readSource,
struct token *theToken,
struct defmodule *newModule)
{
struct defmodule *theModule;
struct portItem *thePort, *oldImportSpec;
int found, count;
/*===========================*/
/* Look for the module name. */
/*===========================*/
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
if (theToken->type != SYMBOL)
{
SyntaxErrorMessage(theEnv,"defmodule import specification");
return(TRUE);
}
/*=====================================*/
/* Verify the existence of the module. */
/*=====================================*/
if ((theModule = (struct defmodule *)
EnvFindDefmodule(theEnv,ValueToString(theToken->value))) == NULL)
{
CantFindItemErrorMessage(theEnv,"defmodule",ValueToString(theToken->value));
return(TRUE);
}
/*========================================*/
/* If the specified module doesn't export */
/* any constructs, then the import */
/* specification is meaningless. */
/*========================================*/
if (theModule->exportList == NULL)
{
NotExportedErrorMessage(theEnv,EnvGetDefmoduleName(theEnv,theModule),NULL,NULL);
return(TRUE);
}
/*==============================================*/
/* Parse the remaining portion of the import */
/* specification and return if an error occurs. */
/*==============================================*/
oldImportSpec = newModule->importList;
if (ParseExportSpec(theEnv,readSource,theToken,newModule,theModule)) return(TRUE);
/*========================================================*/
/* If the ?NONE keyword was used with the import spec, */
/* then no constructs were actually imported and the */
/* import spec does not need to be checked for conflicts. */
/*========================================================*/
if (newModule->importList == oldImportSpec) return(FALSE);
/*======================================================*/
/* Check to see if the construct being imported can be */
/* by the specified module. This check exported doesn't */
/* guarantee that a specific named construct actually */
/* exists. It just checks that it could be exported if */
/* it does exists. */
/*======================================================*/
if (newModule->importList->constructType != NULL)
{
/*=============================*/
/* Look for the construct in */
/* the module that exports it. */
/*=============================*/
found = FALSE;
for (thePort = theModule->exportList;
(thePort != NULL) && (! found);
thePort = thePort->next)
{
if (thePort->constructType == NULL) found = TRUE;
else if (thePort->constructType == newModule->importList->constructType)
{
if (newModule->importList->constructName == NULL) found = TRUE;
else if (thePort->constructName == NULL) found = TRUE;
else if (thePort->constructName == newModule->importList->constructName)
{ found = TRUE; }
}
}
/*=======================================*/
/* If it's not exported by the specified */
/* module, print an error message. */
/*=======================================*/
if (! found)
{
if (newModule->importList->constructName == NULL)
{
NotExportedErrorMessage(theEnv,EnvGetDefmoduleName(theEnv,theModule),
ValueToString(newModule->importList->constructType),
NULL);
}
else
{
NotExportedErrorMessage(theEnv,EnvGetDefmoduleName(theEnv,theModule),
ValueToString(newModule->importList->constructType),
ValueToString(newModule->importList->constructName));
}
return(TRUE);
}
}
/*======================================================*/
/* Verify that specific named constructs actually exist */
/* and can be seen from the module importing them. */
/*======================================================*/
SaveCurrentModule(theEnv);
EnvSetCurrentModule(theEnv,(void *) newModule);
for (thePort = newModule->importList;
thePort != NULL;
thePort = thePort->next)
{
if ((thePort->constructType == NULL) || (thePort->constructName == NULL))
{ continue; }
theModule = (struct defmodule *)
EnvFindDefmodule(theEnv,ValueToString(thePort->moduleName));
EnvSetCurrentModule(theEnv,theModule);
if (FindImportedConstruct(theEnv,ValueToString(thePort->constructType),NULL,
ValueToString(thePort->constructName),&count,
TRUE,FALSE) == NULL)
{
NotExportedErrorMessage(theEnv,EnvGetDefmoduleName(theEnv,theModule),
ValueToString(thePort->constructType),
ValueToString(thePort->constructName));
RestoreCurrentModule(theEnv);
return(TRUE);
}
}
RestoreCurrentModule(theEnv);
/*===============================================*/
/* The import list has been successfully parsed. */
/*===============================================*/
return(FALSE);
}
/**********************************************************/
/* ParseExportSpec: Parses export specifications found in */
/* a defmodule construct. This includes parsing the */
/* remaining specification found in an import */
/* specification after the module name. */
/**********************************************************/
static int ParseExportSpec(
void *theEnv,
char *readSource,
struct token *theToken,
struct defmodule *newModule,
struct defmodule *importModule)
{
struct portItem *newPort;
SYMBOL_HN *theConstruct, *moduleName;
struct portConstructItem *thePortConstruct;
char *errorMessage;
/*===========================================*/
/* Set up some variables for error messages. */
/*===========================================*/
if (importModule != NULL)
{
errorMessage = "defmodule import specification";
moduleName = importModule->name;
}
else
{
errorMessage = "defmodule export specification";
moduleName = NULL;
}
/*=============================================*/
/* Handle the special variables ?ALL and ?NONE */
/* in the import/export specification. */
/*=============================================*/
SavePPBuffer(theEnv," ");
GetToken(theEnv,readSource,theToken);
if (theToken->type == SF_VARIABLE)
{
/*==============================*/
/* Check to see if the variable */
/* is either ?ALL or ?NONE. */
/*==============================*/
if (strcmp(ValueToString(theToken->value),"ALL") == 0)
{
newPort = (struct portItem *) get_struct(theEnv,portItem);
newPort->moduleName = moduleName;
newPort->constructType = NULL;
newPort->constructName = NULL;
newPort->next = NULL;
}
else if (strcmp(ValueToString(theToken->value),"NONE") == 0)
{ newPort = NULL; }
else
{
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
/*=======================================================*/
/* The export/import specification must end with a right */
/* parenthesis after ?ALL or ?NONE at this point. */
/*=======================================================*/
GetToken(theEnv,readSource,theToken);
if (theToken->type != RPAREN)
{
if (newPort != NULL) rtn_struct(theEnv,portItem,newPort);
PPBackup(theEnv);
SavePPBuffer(theEnv," ");
SavePPBuffer(theEnv,theToken->printForm);
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
/*=====================================*/
/* Add the new specification to either */
/* the import or export list. */
/*=====================================*/
if (newPort != NULL)
{
if (importModule != NULL)
{
newPort->next = newModule->importList;
newModule->importList = newPort;
}
else
{
newPort->next = newModule->exportList;
newModule->exportList = newPort;
}
}
/*============================================*/
/* Return FALSE to indicate the import/export */
/* specification was successfully parsed. */
/*============================================*/
return(FALSE);
}
/*========================================================*/
/* If the ?ALL and ?NONE keywords were not used, then the */
/* token must be the name of an importable construct. */
/*========================================================*/
if (theToken->type != SYMBOL)
{
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
theConstruct = (SYMBOL_HN *) theToken->value;
if ((thePortConstruct = ValidPortConstructItem(theEnv,ValueToString(theConstruct))) == NULL)
{
SyntaxErrorMessage(theEnv,errorMessage);
return(TRUE);
}
/*=============================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -