modulpsr.c

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

C
1,135
字号
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*             CLIPS Version 6.24  06/05/06            */   /*                                                     */   /*              DEFMODULE PARSER MODULE                */   /*******************************************************//*************************************************************//* Purpose: Parses a defmodule construct.                    *//*                                                           *//* Principal Programmer(s):                                  *//*      Gary D. Riley                                        *//*                                                           *//* Contributing Programmer(s):                               *//*      Brian L. Donnell                                     *//*                                                           *//* Revision History:                                         *//*                                                           *//*      6.24: Renamed BOOLEAN macro type to intBool.         *//*                                                           *//*************************************************************/#define _MODULPSR_SOURCE_#include "setup.h"#if DEFMODULE_CONSTRUCT && (! RUN_TIME) && (! BLOAD_ONLY)#include <stdio.h>#include <string.h>#define _STDIO_INCLUDED_#include "memalloc.h"#include "constant.h"#include "router.h"#include "extnfunc.h"#include "argacces.h"#include "cstrcpsr.h"#include "constrct.h"#include "modulutl.h"#include "utility.h"#include "envrnmnt.h"#if BLOAD || BLOAD_AND_BSAVE#include "bload.h"#endif#include "modulpsr.h"/***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/   static int                        ParsePortSpecifications(void *,                                                             char *,struct token *,                                                             struct defmodule *);   static int                        ParseImportSpec(void *,char *,struct token *,                                                     struct defmodule *);   static int                        ParseExportSpec(void *,char *,struct token *,                                                     struct defmodule *,                                                     struct defmodule *);   static intBool                    DeleteDefmodule(void *,void *);   static int                        FindMultiImportConflict(void *,struct defmodule *);   static void                       NotExportedErrorMessage(void *,char *,char *,char *);/*********************************************//* GetNumberOfDefmodules: Returns the number *//*   of defmodules currently defined.        *//*********************************************/globle long GetNumberOfDefmodules(  void *theEnv)  {   return(DefmoduleData(theEnv)->NumberOfDefmodules);  }/******************************************//* SetNumberOfDefmodules: Sets the number *//*   of defmodules currently defined.     *//******************************************/globle void SetNumberOfDefmodules(  void *theEnv,  long value)  {   DefmoduleData(theEnv)->NumberOfDefmodules = value;  }/****************************************************//* AddAfterModuleChangeFunction: Adds a function to *//*   the list of functions that are to be called    *//*   after a module change occurs.                  *//****************************************************/globle void AddAfterModuleDefinedFunction(  void *theEnv,  char *name,  void (*func)(void *),  int priority)  {   DefmoduleData(theEnv)->AfterModuleDefinedFunctions =     AddFunctionToCallList(theEnv,name,priority,func,DefmoduleData(theEnv)->AfterModuleDefinedFunctions,TRUE);  }/******************************************************//* AddPortConstructItem: Adds an item to the list of  *//*   items that can be imported/exported by a module. *//******************************************************/globle void AddPortConstructItem(  void *theEnv,  char *theName,  int theType)  {   struct portConstructItem *newItem;   newItem = get_struct(theEnv,portConstructItem);   newItem->constructName = theName;   newItem->typeExpected = theType;   newItem->next = DefmoduleData(theEnv)->ListOfPortConstructItems;   DefmoduleData(theEnv)->ListOfPortConstructItems = newItem;  }/******************************************************//* ParseDefmodule: Coordinates all actions necessary  *//*   for the parsing and creation of a defmodule into *//*   the current environment.                         *//******************************************************/globle int ParseDefmodule(  void *theEnv,  char *readSource)  {   SYMBOL_HN *defmoduleName;   struct defmodule *newDefmodule;   struct token inputToken;   int i;   struct moduleItem *theItem;   struct portItem *portSpecs, *nextSpec;   struct defmoduleItemHeader *theHeader;   struct callFunctionItem *defineFunctions;   struct defmodule *redefiningMainModule = NULL;   int parseError;   struct portItem *oldImportList = NULL, *oldExportList = NULL;   short overwrite = FALSE;   /*================================================*/   /* Flush the buffer which stores the pretty print */   /* representation for a module.  Add the already  */   /* parsed keyword defmodule to this buffer.       */   /*================================================*/   SetPPBufferStatus(theEnv,ON);   FlushPPBuffer(theEnv);   SetIndentDepth(theEnv,3);   SavePPBuffer(theEnv,"(defmodule ");   /*===============================*/   /* Modules cannot be loaded when */   /* a binary load is in effect.   */   /*===============================*/#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE   if ((Bloaded(theEnv) == TRUE) && (! ConstructData(theEnv)->CheckSyntaxMode))     {      CannotLoadWithBloadMessage(theEnv,"defmodule");      return(TRUE);     }#endif   /*=====================================================*/   /* Parse the name and comment fields of the defmodule. */   /* Remove the defmodule if it already exists.          */   /*=====================================================*/   defmoduleName = GetConstructNameAndComment(theEnv,readSource,&inputToken,"defmodule",                                              EnvFindDefmodule,DeleteDefmodule,"+",                                              TRUE,TRUE,FALSE);   if (defmoduleName == NULL) { return(TRUE); }   if (strcmp(ValueToString(defmoduleName),"MAIN") == 0)     { redefiningMainModule = (struct defmodule *) EnvFindDefmodule(theEnv,"MAIN"); }   /*==============================================*/   /* Create the defmodule structure if necessary. */   /*==============================================*/   if (redefiningMainModule == NULL)     {      newDefmodule = (struct defmodule *) EnvFindDefmodule(theEnv,ValueToString(defmoduleName));      if (newDefmodule)        { overwrite = TRUE; }      else        {         newDefmodule = get_struct(theEnv,defmodule);         newDefmodule->name = defmoduleName;         newDefmodule->usrData = NULL;         newDefmodule->next = NULL;        }     }   else     {      overwrite = TRUE;      newDefmodule = redefiningMainModule;     }   if (overwrite)     {      oldImportList = newDefmodule->importList;      oldExportList = newDefmodule->exportList;     }   newDefmodule->importList = NULL;   newDefmodule->exportList = NULL;   /*===================================*/   /* Finish parsing the defmodule (its */   /* import/export specifications).    */   /*===================================*/   parseError = ParsePortSpecifications(theEnv,readSource,&inputToken,newDefmodule);   /*====================================*/   /* Check for import/export conflicts. */   /*====================================*/   if (! parseError) parseError = FindMultiImportConflict(theEnv,newDefmodule);   /*======================================================*/   /* If an error occured in parsing or an import conflict */   /* was detected, abort the definition of the defmodule. */   /* If we're only checking syntax, then we want to exit  */   /* at this point as well.                               */   /*======================================================*/   if (parseError || ConstructData(theEnv)->CheckSyntaxMode)     {      while (newDefmodule->importList != NULL)        {         nextSpec = newDefmodule->importList->next;         rtn_struct(theEnv,portItem,newDefmodule->importList);         newDefmodule->importList = nextSpec;        }      while (newDefmodule->exportList != NULL)        {         nextSpec = newDefmodule->exportList->next;         rtn_struct(theEnv,portItem,newDefmodule->exportList);         newDefmodule->exportList = nextSpec;        }      if ((redefiningMainModule == NULL) && (! overwrite))        { rtn_struct(theEnv,defmodule,newDefmodule); }      if (overwrite)        {         newDefmodule->importList = oldImportList;         newDefmodule->exportList = oldExportList;        }      if (parseError) return(TRUE);      return(FALSE);     }   /*===============================================*/   /* Increment the symbol table counts for symbols */   /* used in the defmodule data structures.        */   /*===============================================*/   if (redefiningMainModule == NULL)     { IncrementSymbolCount(newDefmodule->name); }   else     {      if ((newDefmodule->importList != NULL) ||          (newDefmodule->exportList != NULL))        { DefmoduleData(theEnv)->MainModuleRedefinable = FALSE; }     }   for (portSpecs = newDefmodule->importList; portSpecs != NULL; portSpecs = portSpecs->next)     {      if (portSpecs->moduleName != NULL) IncrementSymbolCount(portSpecs->moduleName);      if (portSpecs->constructType != NULL) IncrementSymbolCount(portSpecs->constructType);      if (portSpecs->constructName != NULL) IncrementSymbolCount(portSpecs->constructName);     }   for (portSpecs = newDefmodule->exportList; portSpecs != NULL; portSpecs = portSpecs->next)     {      if (portSpecs->moduleName != NULL) IncrementSymbolCount(portSpecs->moduleName);      if (portSpecs->constructType != NULL) IncrementSymbolCount(portSpecs->constructType);      if (portSpecs->constructName != NULL) IncrementSymbolCount(portSpecs->constructName);     }   /*====================================================*/   /* Allocate storage for the module's construct lists. */   /*====================================================*/   if (redefiningMainModule != NULL) { /* Do nothing */ }   else if (DefmoduleData(theEnv)->NumberOfModuleItems == 0) newDefmodule->itemsArray = NULL;   else     {      newDefmodule->itemsArray = (struct defmoduleItemHeader **) gm2(theEnv,sizeof(void *) * DefmoduleData(theEnv)->NumberOfModuleItems);      for (i = 0, theItem = DefmoduleData(theEnv)->ListOfModuleItems;           (i < DefmoduleData(theEnv)->NumberOfModuleItems) && (theItem != NULL);           i++, theItem = theItem->next)        {         if (theItem->allocateFunction == NULL)           { newDefmodule->itemsArray[i] = NULL; }         else           {            newDefmodule->itemsArray[i] = (struct defmoduleItemHeader *)                                          (*theItem->allocateFunction)(theEnv);            theHeader = (struct defmoduleItemHeader *) newDefmodule->itemsArray[i];            theHeader->theModule = newDefmodule;            theHeader->firstItem = NULL;            theHeader->lastItem = NULL;           }        }     }   /*=======================================*/   /* Save the pretty print representation. */   /*=======================================*/   SavePPBuffer(theEnv,"\n");   if (EnvGetConserveMemory(theEnv) == TRUE)     { newDefmodule->ppForm = NULL; }   else     { newDefmodule->ppForm = CopyPPBuffer(theEnv); }   /*==============================================*/   /* Add the defmodule to the list of defmodules. */   /*==============================================*/   if (redefiningMainModule == NULL)     {      if (DefmoduleData(theEnv)->LastDefmodule == NULL) DefmoduleData(theEnv)->ListOfDefmodules = newDefmodule;      else DefmoduleData(theEnv)->LastDefmodule->next = newDefmodule;      DefmoduleData(theEnv)->LastDefmodule = newDefmodule;      newDefmodule->bsaveID = DefmoduleData(theEnv)->NumberOfDefmodules++;     }   EnvSetCurrentModule(theEnv,(void *) newDefmodule);   /*=========================================*/   /* Call any functions required by other    */   /* constructs when a new module is defined */   /*=========================================*/   for (defineFunctions = DefmoduleData(theEnv)->AfterModuleDefinedFunctions;        defineFunctions != NULL;        defineFunctions = defineFunctions->next)     { (* (void (*)(void *)) defineFunctions->func)(theEnv); }   /*===============================================*/   /* Defmodule successfully parsed with no errors. */   /*===============================================*/   return(FALSE);  }/*************************************************************//* DeleteDefmodule: Used by the parsing routine to determine *//*   if a module can be redefined. Only the MAIN module can  *//*   be redefined (and it can only be redefined once).       *//*************************************************************/static intBool DeleteDefmodule(  void *theEnv,  void *theConstruct)  {   if (strcmp(EnvGetDefmoduleName(theEnv,theConstruct),"MAIN") == 0)     { return(DefmoduleData(theEnv)->MainModuleRedefinable); }   return(FALSE);  }/*********************************************************//* ParsePortSpecifications: Parses the import and export *//*   specifications found in a defmodule construct.      *//*********************************************************/static int ParsePortSpecifications(  void *theEnv,  char *readSource,

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?