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 + -
显示快捷键?