modulpsr.c

来自「clips源代码」· C语言 代码 · 共 1,135 行 · 第 1/3 页

C
1,135
字号
  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 + =
减小字号Ctrl + -
显示快捷键?