📄 conscomp.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/04/06 */
/* */
/* CONSTRUCT COMPILER MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides core routines for the constructs-to-c */
/* command. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* Brian L. Donnell */
/* Barry Cameron */
/* */
/* Contributing Programmer(s): */
/* */
/* Revision History: */
/* 6.23: Modifications to use the system constant */
/* FILENAME_MAX to check file name lengths. */
/* DR0856 */
/* */
/* Corrected compilation errors for files */
/* generated by constructs-to-c. DR0861 */
/* */
/* 6.24: Used EnvClear rather than Clear in */
/* InitCImage initialization code. */
/* */
/* Added environment parameter to GenClose. */
/* Added environment parameter to GenOpen. */
/* */
/* Removed SHORT_LINK_NAMES code as this option */
/* is no longer supported. */
/* */
/* Support for run-time programs directly passing */
/* the hash tables for initialization. */
/* */
/*************************************************************/
#define _CONSCOMP_SOURCE_
#include "setup.h"
#if CONSTRUCT_COMPILER && (! RUN_TIME)
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <stdlib.h>
#include <string.h>
#include "symbol.h"
#include "memalloc.h"
#include "constant.h"
#include "exprnpsr.h"
#include "cstrccom.h"
#include "constrct.h"
#include "argacces.h"
#include "cstrncmp.h"
#include "router.h"
#include "sysdep.h"
#include "utility.h"
#include "modulcmp.h"
#include "envrnmnt.h"
#if DEFRULE_CONSTRUCT
#include "network.h"
#endif
#if DEFFUNCTION_CONSTRUCT
#include "dffnxcmp.h"
#endif
#if DEFTEMPLATE_CONSTRUCT
#include "tmpltcmp.h"
#endif
#if DEFGLOBAL_CONSTRUCT
#include "globlcmp.h"
#endif
#if DEFGENERIC_CONSTRUCT
#include "genrccmp.h"
#endif
#if OBJECT_SYSTEM
#include "objcmp.h"
#endif
#include "conscomp.h"
/***************/
/* DEFINITIONS */
/***************/
#define FSIZE 80
/**********************************************/
/* CONSTRUCT CODES DEFINITIONS: The codes F, */
/* I, B, S, E, P, L, and C are not included */
/* because those are already taken. */
/* */
/* B: BitMap hash nodes */
/* C: Constraint hash nodes */
/* E: Expression hash nodes */
/* F: Float hash nodes */
/* I: Integer hash nodes */
/* L: Bitmaps */
/* P: Functions */
/* S: Symbol hash nodes */
/**********************************************/
#define PRIMARY_CODES "ADGHJKMNOQRTUVWXYZ"
#define PRIMARY_LEN 18
#define SECONDARY_CODES "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
#define SECONDARY_LEN 26
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
void ConstructsToCCommand(void *);
static int ConstructsToC(void *,char *,int,int);
static void WriteFunctionExternDeclarations(void *,FILE *);
static int FunctionsToCode(void *theEnv,char *);
static int WriteInitializationFunction(void *,char *);
static void DumpExpression(void *,struct expr *);
static void MarkConstruct(void *,struct constructHeader *,void *);
static void HashedExpressionsToCode(void *);
static void DeallocateConstructCompilerData(void *);
/**********************************************************/
/* InitializeConstructCompilerData: Allocates environment */
/* data for the constructs-to-c command. */
/**********************************************************/
globle void InitializeConstructCompilerData(
void *theEnv)
{
AllocateEnvironmentData(theEnv,CONSTRUCT_COMPILER_DATA,sizeof(struct constructCompilerData),DeallocateConstructCompilerData);
ConstructCompilerData(theEnv)->MaxIndices = 2000;
ConstructCompilerData(theEnv)->CodeGeneratorCount = 0;
}
/************************************************************/
/* DeallocateConstructCompilerData: Deallocates environment */
/* data for the constructs-to-c command. */
/************************************************************/
static void DeallocateConstructCompilerData(
void *theEnv)
{
struct CodeGeneratorItem *tmpPtr, *nextPtr;
int i;
tmpPtr = ConstructCompilerData(theEnv)->ListOfCodeGeneratorItems;
while (tmpPtr != NULL)
{
nextPtr = tmpPtr->next;
for (i = 0; i < tmpPtr->arrayCount ; i++)
{ rm(theEnv,tmpPtr->arrayNames[i],strlen(tmpPtr->arrayNames[i]) + 1); }
if (tmpPtr->arrayCount != 0)
{ rm(theEnv,tmpPtr->arrayNames,sizeof(char *) * tmpPtr->arrayCount); }
rtn_struct(theEnv,CodeGeneratorItem,tmpPtr);
tmpPtr = nextPtr;
}
}
/**********************************************/
/* ConstructsToCCommand: H/L access routine */
/* for the constructs-to-c command. */
/**********************************************/
globle void ConstructsToCCommand(
void *theEnv)
{
char *fileName;
DATA_OBJECT theArg;
int argCount;
int id, max, nameLength;
#if VAX_VMS || IBM_MSC || IBM_TBC || IBM_ICB || IBM_ZTC || IBM_SC
int i;
#endif
/*============================================*/
/* Check for appropriate number of arguments. */
/*============================================*/
if ((argCount = EnvArgRangeCheck(theEnv,"constructs-to-c",2,3)) == -1) return;
/*====================================================*/
/* Get the name of the file in which to place C code. */
/*====================================================*/
if (EnvArgTypeCheck(theEnv,"constructs-to-c",1,SYMBOL_OR_STRING,&theArg) == FALSE)
{ return; }
fileName = DOToString(theArg);
nameLength = (int) strlen(fileName);
/*================================*/
/* File names for the VAX and IBM */
/* PCs can't contain a period. */
/*================================*/
#if VAX_VMS || IBM_MSC || IBM_TBC || IBM_ICB || IBM_ZTC || IBM_SC
for (i = 0 ; *(fileName+i) ; i++)
{
if (*(fileName+i) == '.')
{
PrintErrorID(theEnv,"CONSCOMP",1,FALSE);
EnvPrintRouter(theEnv,WERROR,"Invalid file name ");
EnvPrintRouter(theEnv,WERROR,fileName);
EnvPrintRouter(theEnv,WERROR," contains \'.\'\n");
return;
}
}
#endif
/*==========================================================*/
/* The maximum file name size that can be passed into fopen */
/* is specified by FILENAME_MAX. Assume that the most */
/* characters that will be appended to the file prefix will */
/* be 20 and check that the prefix plus the additional */
/* characters is less than the supported maximum. */
/*==========================================================*/
if ((nameLength + 20) > FILENAME_MAX)
{
PrintErrorID(theEnv,"CONSCOMP",1,FALSE);
EnvPrintRouter(theEnv,WERROR,"Aborting because the base file name may cause the fopen maximum of ");
PrintLongInteger(theEnv,WERROR,FILENAME_MAX);
EnvPrintRouter(theEnv,WERROR," to be violated when file names are generated.\n");
return;
}
/*===========================================*/
/* If the base file name is greater than 3 */
/* characters, issue a warning that the file */
/* name lengths may exceed what is allowed */
/* under some operating systems. */
/*===========================================*/
if (nameLength > 3)
{
PrintWarningID(theEnv,"CONSCOMP",1,FALSE);
EnvPrintRouter(theEnv,WWARNING,"Base file name exceeds 3 characters.\n");
EnvPrintRouter(theEnv,WWARNING," This may cause files to be overwritten if file name length\n");
EnvPrintRouter(theEnv,WWARNING," is limited on your platform.\n");
}
/*====================================*/
/* Get the runtime image ID argument. */
/*====================================*/
if (EnvArgTypeCheck(theEnv,"constructs-to-c",2,INTEGER,&theArg) == FALSE)
{ return; }
id = DOToInteger(theArg);
if (id < 0)
{
ExpectedTypeError1(theEnv,"constructs-to-c",2,"positive integer");
return;
}
/*===========================================*/
/* Get the maximum number of data structures */
/* to store per file argument (if supplied). */
/*===========================================*/
if (argCount == 3)
{
if (EnvArgTypeCheck(theEnv,"constructs-to-c",3,INTEGER,&theArg) == FALSE)
{ return; }
max = DOToInteger(theArg);
if (max < 0)
{
ExpectedTypeError1(theEnv,"constructs-to-c",3,"positive integer");
return;
}
}
else
{ max = 10000; }
/*============================*/
/* Call the driver routine to */
/* generate the C code. */
/*============================*/
ConstructsToC(theEnv,fileName,id,max);
}
/***************************************/
/* ConstructsToC: C access routine for */
/* the constructs-to-c command. */
/***************************************/
static int ConstructsToC(
void *theEnv,
char *fileName,
int theImageID,
int max)
{
char fname[FILENAME_MAX+1];
int fileVersion;
struct CodeGeneratorItem *cgPtr;
/*===============================================*/
/* Set the global MaxIndices variable indicating */
/* the maximum number of data structures to save */
/* in each file. */
/*===============================================*/
ConstructCompilerData(theEnv)->MaxIndices = max;
/*==================================*/
/* Call the list of functions to be */
/* executed before generating code. */
/*==================================*/
for (cgPtr = ConstructCompilerData(theEnv)->ListOfCodeGeneratorItems;
cgPtr != NULL;
cgPtr = cgPtr->next)
{ if (cgPtr->beforeFunction != NULL) (*cgPtr->beforeFunction)(theEnv); }
/*=================================================*/
/* Do a periodic cleanup without using heuristics */
/* to get rid of as much garbage as possible so */
/* that it isn't written out as C data structures. */
/*=================================================*/
PeriodicCleanup(theEnv,FALSE,FALSE);
/*=====================================*/
/* Initialize some global information. */
/*=====================================*/
ConstructCompilerData(theEnv)->FilePrefix = fileName;
ConstructCompilerData(theEnv)->ImageID = theImageID;
ConstructCompilerData(theEnv)->ExpressionFP = NULL;
ConstructCompilerData(theEnv)->ExpressionVersion = 1;
ConstructCompilerData(theEnv)->ExpressionHeader = TRUE;
ConstructCompilerData(theEnv)->ExpressionCount = 0;
/*=====================================================*/
/* Open a header file for dumping general information. */
/*=====================================================*/
sprintf(fname,"%s.h",fileName);
if ((ConstructCompilerData(theEnv)->HeaderFP = GenOpen(theEnv,fname,"w")) == NULL)
{
OpenErrorMessage(theEnv,"constructs-to-c",fname);
return(0);
}
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"#ifndef _CONSTRUCT_COMPILER_HEADER_\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"#define _CONSTRUCT_COMPILER_HEADER_\n\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"#include <stdio.h>\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"#include \"setup.h\"\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"#include \"expressn.h\"\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"#include \"extnfunc.h\"\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"#include \"%s\"\n",API_HEADER);
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"\n#define VS (void *)\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"\n");
/*=========================================================*/
/* Give extern declarations for user and system functions. */
/*=========================================================*/
WriteFunctionExternDeclarations(theEnv,ConstructCompilerData(theEnv)->HeaderFP);
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"\n#endif\n\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"/****************************/\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"/* EXTERN ARRAY DEFINITIONS */\n");
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"/****************************/\n\n");
/*============================================*/
/* Open a file for dumping fixup information. */
/*============================================*/
sprintf(fname,"%s_init.c",fileName);
if ((ConstructCompilerData(theEnv)->FixupFP = GenOpen(theEnv,fname,"w")) == NULL)
{
OpenErrorMessage(theEnv,"constructs-to-c",fname);
return(0);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -