📄 modulpsr.c
字号:
/*******************************************************/
/* "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 + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -