📄 factcmp.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.20 01/31/02 */
/* */
/* FACT PATTERN NETWORK CONSTRUCTS-TO-C MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Implements the constructs-to-c feature for the */
/* fact pattern network. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* */
/*************************************************************/
#define _FACTCMP_SOURCE_
#include "setup.h"
#if DEFRULE_CONSTRUCT && (! RUN_TIME) && DEFTEMPLATE_CONSTRUCT && CONSTRUCT_COMPILER
#define FactPrefix() ArbitraryPrefix(FactData(theEnv)->FactCodeItem,0)
#include <stdio.h>
#define _STDIO_INCLUDED_
#include "factbld.h"
#include "conscomp.h"
#include "factcmp.h"
#include "tmpltdef.h"
#include "envrnmnt.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static int PatternNetworkToCode(void *,char *,int,FILE *,int,int);
static void BeforePatternNetworkToCode(void *);
static struct factPatternNode *GetNextPatternNode(struct factPatternNode *);
static void CloseNetworkFiles(void *,FILE *,int);
static void PatternNodeToCode(void *,FILE *,struct factPatternNode *,int,int);
/**************************************************************/
/* FactPatternsCompilerSetup: Initializes the constructs-to-c */
/* command for use with the fact pattern network. */
/**************************************************************/
globle void FactPatternsCompilerSetup(
void *theEnv)
{
FactData(theEnv)->FactCodeItem = AddCodeGeneratorItem(theEnv,"facts",0,BeforePatternNetworkToCode,
NULL,PatternNetworkToCode,1);
}
/****************************************************************/
/* BeforePatternNetworkToCode: Assigns each pattern node with a */
/* unique ID which will be used for pointer references when */
/* the data structures are written to a file as C code */
/****************************************************************/
static void BeforePatternNetworkToCode(
void *theEnv)
{
int whichPattern = 0;
int whichDeftemplate = 0;
struct defmodule *theModule;
struct deftemplate *theDeftemplate;
struct factPatternNode *thePattern;
/*===========================*/
/* Loop through each module. */
/*===========================*/
for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
theModule != NULL;
theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
{
/*=========================*/
/* Set the current module. */
/*=========================*/
EnvSetCurrentModule(theEnv,(void *) theModule);
/*======================================================*/
/* Loop through each deftemplate in the current module. */
/*======================================================*/
for (theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,NULL);
theDeftemplate != NULL;
theDeftemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,theDeftemplate))
{
/*=================================================*/
/* Assign each pattern node in the pattern network */
/* for the deftemplate a unique integer ID. */
/*=================================================*/
theDeftemplate->header.bsaveID = whichDeftemplate++;
for (thePattern = theDeftemplate->patternNetwork;
thePattern != NULL;
thePattern = GetNextPatternNode(thePattern))
{ thePattern->bsaveID = whichPattern++; }
}
}
}
/********************************************************************/
/* GetNextPatternNode: Returns the next node in a pattern network */
/* tree. The next node is computed using a depth first traversal. */
/********************************************************************/
static struct factPatternNode *GetNextPatternNode(
struct factPatternNode *thePattern)
{
/*=========================================*/
/* If it's possible to go deeper into the */
/* tree, then move down to the next level. */
/*=========================================*/
if (thePattern->nextLevel != NULL) return(thePattern->nextLevel);
/*========================================*/
/* Keep backing up toward the root of the */
/* tree until a side branch can be taken. */
/*========================================*/
while (thePattern->rightNode == NULL)
{
/*========================================*/
/* Back up to check the next side branch. */
/*========================================*/
thePattern = thePattern->lastLevel;
/*======================================*/
/* If we branched up from the root, the */
/* entire tree has been traversed. */
/*======================================*/
if (thePattern == NULL) return(NULL);
}
/*==================================*/
/* Move on to the next side branch. */
/*==================================*/
return(thePattern->rightNode);
}
/********************************************************************/
/* PatternNetworkToCode: Produces the fact pattern network code for */
/* a run-time module created using the constructs-to-c function. */
/********************************************************************/
static int PatternNetworkToCode(
void *theEnv,
char *fileName,
int fileID,
FILE *headerFP,
int imageID,
int maxIndices)
{
int fileCount = 1;
struct defmodule *theModule;
struct deftemplate *theTemplate;
struct factPatternNode *thePatternNode;
int networkArrayCount = 0, networkArrayVersion = 1;
FILE *networkFile = NULL;
/*===========================================================*/
/* Include the appropriate fact pattern network header file. */
/*===========================================================*/
fprintf(headerFP,"#include \"factbld.h\"\n");
/*===============================*/
/* Loop through all the modules. */
/*===============================*/
for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
theModule != NULL;
theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule))
{
/*=========================*/
/* Set the current module. */
/*=========================*/
EnvSetCurrentModule(theEnv,(void *) theModule);
/*======================================*/
/* Loop through all of the deftemplates */
/* in the current module. */
/*======================================*/
for (theTemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,NULL);
theTemplate != NULL;
theTemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,theTemplate))
{
/*======================================================*/
/* Loop through each pattern node in the deftemplate's */
/* pattern network writing its C code representation to */
/* the file as it is traversed. */
/*======================================================*/
for (thePatternNode = theTemplate->patternNetwork;
thePatternNode != NULL;
thePatternNode = GetNextPatternNode(thePatternNode))
{
networkFile = OpenFileIfNeeded(theEnv,networkFile,fileName,fileID,imageID,&fileCount,
networkArrayVersion,headerFP,
"struct factPatternNode",FactPrefix(),FALSE,NULL);
if (networkFile == NULL)
{
CloseNetworkFiles(theEnv,networkFile,maxIndices);
return(0);
}
PatternNodeToCode(theEnv,networkFile,thePatternNode,imageID,maxIndices);
networkArrayCount++;
networkFile = CloseFileIfNeeded(theEnv,networkFile,&networkArrayCount,
&networkArrayVersion,maxIndices,NULL,NULL);
}
}
}
/*==============================*/
/* Close any C files left open. */
/*==============================*/
CloseNetworkFiles(theEnv,networkFile,maxIndices);
/*===============================*/
/* Return TRUE to indicate the C */
/* code was successfully saved. */
/*===============================*/
return(TRUE);
}
/****************************************************************/
/* CloseNetworkFiles: Closes all of the C files created for the */
/* fact pattern network. Called when an error occurs or when */
/* the fact pattern network data structures have all been */
/* written to the files. */
/****************************************************************/
static void CloseNetworkFiles(
void *theEnv,
FILE *networkFile,
int maxIndices)
{
int count = maxIndices;
int arrayVersion = 0;
if (networkFile != NULL)
{
CloseFileIfNeeded(theEnv,networkFile,&count,&arrayVersion,maxIndices,NULL,NULL);
}
}
/************************************************************/
/* PatternNodeToCode: Writes the C code representation of a */
/* single fact pattern node slot to the specified file. */
/************************************************************/
static void PatternNodeToCode(
void *theEnv,
FILE *theFile,
struct factPatternNode *thePatternNode,
int imageID,
int maxIndices)
{
fprintf(theFile,"{");
/*=====================*/
/* Pattern Node Header */
/*=====================*/
PatternNodeHeaderToCode(theEnv,theFile,&thePatternNode->header,imageID,maxIndices);
/*========================*/
/* Field and Slot Indices */
/*========================*/
fprintf(theFile,",0,%d,%d,%d,",thePatternNode->whichField,
thePatternNode->whichSlot,
thePatternNode->leaveFields);
/*===============*/
/* Network Tests */
/*===============*/
PrintHashedExpressionReference(theEnv,theFile,thePatternNode->networkTest,imageID,maxIndices);
/*============*/
/* Next Level */
/*============*/
if (thePatternNode->nextLevel == NULL)
{ fprintf(theFile,",NULL,"); }
else
{
fprintf(theFile,",&%s%d_%ld[%ld],",FactPrefix(),
imageID,(thePatternNode->nextLevel->bsaveID / maxIndices) + 1,
thePatternNode->nextLevel->bsaveID % maxIndices);
}
/*============*/
/* Last Level */
/*============*/
if (thePatternNode->lastLevel == NULL)
{ fprintf(theFile,"NULL,"); }
else
{
fprintf(theFile,"&%s%d_%ld[%ld],",FactPrefix(),
imageID,(thePatternNode->lastLevel->bsaveID / maxIndices) + 1,
thePatternNode->lastLevel->bsaveID % maxIndices);
}
/*===========*/
/* Left Node */
/*===========*/
if (thePatternNode->leftNode == NULL)
{ fprintf(theFile,"NULL,"); }
else
{
fprintf(theFile,"&%s%d_%ld[%ld],",FactPrefix(),
imageID,(thePatternNode->leftNode->bsaveID / maxIndices) + 1,
thePatternNode->leftNode->bsaveID % maxIndices);
}
/*============*/
/* Right Node */
/*============*/
if (thePatternNode->rightNode == NULL)
{ fprintf(theFile,"NULL}"); }
else
{
fprintf(theFile,"&%s%d_%ld[%ld]}",FactPrefix(),
imageID,(thePatternNode->rightNode->bsaveID / maxIndices) + 1,
thePatternNode->rightNode->bsaveID % maxIndices);
}
}
/**********************************************************/
/* FactPatternNodeReference: Prints C code representation */
/* of a fact pattern node data structure reference. */
/**********************************************************/
globle void FactPatternNodeReference(
void *theEnv,
void *theVPattern,
FILE *theFile,
int imageID,
int maxIndices)
{
struct factPatternNode *thePattern = (struct factPatternNode *) theVPattern;
if (thePattern == NULL) fprintf(theFile,"NULL");
else
{
fprintf(theFile,"&%s%d_%ld[%ld]",FactPrefix(),
imageID,(thePattern->bsaveID / maxIndices) + 1,
thePattern->bsaveID % maxIndices);
}
}
#endif /* DEFRULE_CONSTRUCT && (! RUN_TIME) && DEFTEMPLATE_CONSTRUCT && CONSTRUCT_COMPILER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -