📄 modulpsr.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* DEFMODULE PARSER MODULE */ /*******************************************************//*************************************************************//* Purpose: Parses a defmodule construct. *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* *//* Contributing Programmer(s): *//* Brian L. Donnell *//* *//* Revision History: *//* *//*************************************************************/#define _MODULPSR_SOURCE_#include "setup.h"#if DEFMODULE_CONSTRUCT && (! RUN_TIME) && (! BLOAD_ONLY)#include <stdio.h>#include <string.h>#define _CLIPS_STDIO_#include "clipsmem.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"#if BLOAD || BLOAD_AND_BSAVE#include "bload.h"#endif#include "modulpsr.h"/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static struct portConstructItem *ListOfPortConstructItems = NULL; static long NumberOfDefmodules; static struct callFunctionItem *AfterModuleDefinedFunctions = NULL; /***************************************//* LOCAL INTERNAL FUNCTION DEFINITIONS *//***************************************/#if ANSI_COMPILER static int ParsePortSpecifications(char *,struct token *, struct defmodule *); static int ParseImportSpec(char *,struct token *, struct defmodule *); static int ParseExportSpec(char *,struct token *, struct defmodule *, struct defmodule *); static BOOLEAN DeleteDefmodule(VOID *); static int FindMultiImportConflict(struct defmodule *); static VOID NotExportedErrorMessage(char *,char *,char *);#else static int ParsePortSpecifications(); static int ParseImportSpec(); static int ParseExportSpec(); static BOOLEAN DeleteDefmodule(); static int FindMultiImportConflict(); static VOID NotExportedErrorMessage();#endif/*********************************************//* GetNumberOfDefmodules: Returns the number *//* of defmodules currently defined. *//*********************************************/globle long GetNumberOfDefmodules() { return(NumberOfDefmodules); }/******************************************//* SetNumberOfDefmodules: Sets the number *//* of defmodules currently defined. *//******************************************/globle VOID SetNumberOfDefmodules(value) long value; { NumberOfDefmodules = value; } /****************************************************//* AddAfterModuleChangeFunction: Adds a function to *//* the list of functions that are to be called *//* after a module change occurs. *//****************************************************/globle VOID AddAfterModuleDefinedFunction(name,func,priority) char *name; VOID (*func)(VOID_ARG); int priority; { AfterModuleDefinedFunctions = AddFunctionToCallList(name,priority,func,AfterModuleDefinedFunctions); } /******************************************************//* AddPortConstructItem: Adds an item to the list of *//* items that can be imported/exported by a module. *//******************************************************/globle VOID AddPortConstructItem(theName,theType) char *theName; int theType; { struct portConstructItem *newItem; newItem = get_struct(portConstructItem); newItem->constructName = theName; newItem->typeExpected = theType; newItem->next = ListOfPortConstructItems; ListOfPortConstructItems = newItem; }/******************************************************//* ParseDefmodule: Coordinates all actions necessary *//* for the parsing and creation of a defmodule into *//* the current environment. *//******************************************************/globle int ParseDefmodule(readSource) 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; /*================================================*/ /* Flush the buffer which stores the pretty print */ /* representation for a module. Add the already */ /* parsed keyword defmodule to this buffer. */ /*================================================*/ SetPPBufferStatus(ON); FlushPPBuffer(); SetIndentDepth(3); SavePPBuffer("(defmodule "); /*===============================*/ /* Modules cannot be loaded when */ /* a binary load is in effect. */ /*===============================*/#if BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE if (Bloaded() == CLIPS_TRUE) { CannotLoadWithBloadMessage("defmodule"); return(CLIPS_TRUE); }#endif /*=====================================================*/ /* Parse the name and comment fields of the defmodule. */ /* Remove the defmodule if it already exists. */ /*=====================================================*/ defmoduleName = GetConstructNameAndComment(readSource,&inputToken,"defmodule", FindDefmodule,DeleteDefmodule,"+", CLIPS_TRUE,CLIPS_TRUE,CLIPS_FALSE); if (defmoduleName == NULL) { return(CLIPS_TRUE); } if (strcmp(ValueToString(defmoduleName),"MAIN") == 0) { redefiningMainModule = (struct defmodule *) FindDefmodule("MAIN"); } /*==============================================*/ /* Create the defmodule structure if necessary. */ /*==============================================*/ if (redefiningMainModule == NULL) { newDefmodule = get_struct(defmodule); newDefmodule->name = defmoduleName; newDefmodule->next = NULL; } else newDefmodule = redefiningMainModule; newDefmodule->importList = NULL; newDefmodule->exportList = NULL; /*===================================*/ /* Finish parsing the defmodule (its */ /* import/export specifications). */ /*===================================*/ parseError = ParsePortSpecifications(readSource,&inputToken,newDefmodule); /*====================================*/ /* Check for import/export conflicts. */ /*====================================*/ if (! parseError) parseError = FindMultiImportConflict(newDefmodule); /*=============================================*/ /* If an error occured in parsing or an import */ /* conflict was detected, abort the definition */ /* of the defmodule. */ /*=============================================*/ if (parseError) { while (newDefmodule->importList != NULL) { nextSpec = newDefmodule->importList->next; rtn_struct(portItem,newDefmodule->importList); newDefmodule->importList = nextSpec; } while (newDefmodule->exportList != NULL) { nextSpec = newDefmodule->exportList->next; rtn_struct(portItem,newDefmodule->exportList); newDefmodule->exportList = nextSpec; } if (redefiningMainModule == NULL) rtn_struct(defmodule,newDefmodule); return(CLIPS_TRUE); } /*===============================================*/ /* 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)) { MainModuleRedefinable = CLIPS_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 (NumberOfModuleItems == 0) newDefmodule->itemsArray = NULL; else { newDefmodule->itemsArray = (struct defmoduleItemHeader **) gm2((int) sizeof(VOID *) * NumberOfModuleItems); for (i = 0, theItem = ListOfModuleItems; (i < NumberOfModuleItems) && (theItem != NULL); i++, theItem = theItem->next) { if (theItem->allocateFunction == NULL) { newDefmodule->itemsArray[i] = NULL; } else { newDefmodule->itemsArray[i] = (struct defmoduleItemHeader *) (*theItem->allocateFunction)(); theHeader = (struct defmoduleItemHeader *) newDefmodule->itemsArray[i]; theHeader->theModule = newDefmodule; theHeader->firstItem = NULL; theHeader->lastItem = NULL; } } } /*=======================================*/ /* Save the pretty print representation. */ /*=======================================*/ SavePPBuffer("\n"); if (GetConserveMemory() == CLIPS_TRUE) { newDefmodule->ppForm = NULL; } else { newDefmodule->ppForm = CopyPPBuffer(); } /*==============================================*/ /* Add the defmodule to the list of defmodules. */ /*==============================================*/ if (redefiningMainModule == NULL) { if (LastDefmodule == NULL) ListOfDefmodules = newDefmodule; else LastDefmodule->next = newDefmodule; LastDefmodule = newDefmodule; newDefmodule->bsaveID = NumberOfDefmodules++; } SetCurrentModule((VOID *) newDefmodule); /*=========================================*/ /* Call any functions required by other */ /* constructs when a new module is defined */ /*=========================================*/ for (defineFunctions = AfterModuleDefinedFunctions; defineFunctions != NULL; defineFunctions = defineFunctions->next) { (* (VOID (*)(VOID_ARG)) defineFunctions->func)(); } /*===============================================*/ /* Defmodule successfully parsed with no errors. */ /*===============================================*/ return(CLIPS_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 BOOLEAN DeleteDefmodule(theConstruct) VOID *theConstruct; { if (strcmp(GetDefmoduleName(theConstruct),"MAIN") == 0) { return(MainModuleRedefinable); } return(CLIPS_FALSE); } /*********************************************************//* ParsePortSpecifications: Parses the import and export *//* specifications found in a defmodule construct. *//*********************************************************/static int ParsePortSpecifications(readSource,theToken,theDefmodule) char *readSource; struct token *theToken; struct defmodule *theDefmodule; { int error; /*=============================*/ /* The import and export lists */ /* are initially empty. */ /*=============================*/ theDefmodule->importList = NULL; theDefmodule->exportList = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -