📄 conscomp.c
字号:
/* file was successfully written. */
/*========================================*/
return(TRUE);
}
/**************************************************/
/* NewCFile: Opens a new file for writing C code. */
/**************************************************/
globle FILE *NewCFile(
void *theEnv,
char *fileName,
int id,
int version,
int reopenOldFile)
{
char fname[FILENAME_MAX+1];
FILE *newFP;
sprintf(fname,"%s%d_%d.c",fileName,id,version);
newFP = GenOpen(theEnv,fname,(char *) (reopenOldFile ? "a" : "w"));
if (newFP == NULL)
{
OpenErrorMessage(theEnv,"constructs-to-c",fname);
return(NULL);
}
if (reopenOldFile == FALSE)
{
fprintf(newFP,"#include \"%s.h\"\n",fileName);
fprintf(newFP,"\n");
}
return(newFP);
}
/**********************************************************/
/* HashedExpressionsToCode: Traverses the expression hash */
/* table and calls ExpressionToCode to write the C */
/* code representation to a file of every expression in */
/* the table. */
/**********************************************************/
static void HashedExpressionsToCode(
void *theEnv)
{
unsigned i;
EXPRESSION_HN *exphash;
for (i = 0; i < EXPRESSION_HASH_SIZE; i++)
{
for (exphash = ExpressionData(theEnv)->ExpressionHashTable[i];
exphash != NULL;
exphash = exphash->next)
{
exphash->bsaveID = ConstructCompilerData(theEnv)->ExpressionCount + (ConstructCompilerData(theEnv)->MaxIndices * ConstructCompilerData(theEnv)->ExpressionVersion);
ExpressionToCode(theEnv,NULL,exphash->exp);
}
}
}
/*****************************************************/
/* PrintHashedExpressionReference: Writes the C code */
/* representation of a pointer to an expression */
/* stored in the expression hash table. */
/*****************************************************/
globle void PrintHashedExpressionReference(
void *theEnv,
FILE *theFile,
struct expr *theExpression,
int imageID,
int maxIndices)
{
long theIDValue;
if (theExpression == NULL)
{ fprintf(theFile,"NULL"); }
else
{
theIDValue = HashedExpressionIndex(theEnv,theExpression);
fprintf(theFile,"&E%d_%ld[%ld]",
imageID,
theIDValue / maxIndices,
theIDValue % maxIndices);
}
}
/**************************************************************/
/* ExpressionToCode: Writes the C code reference of a pointer */
/* to an expression and then calls DumpExpression to write */
/* the C code for the expression to the expression file. */
/**************************************************************/
globle int ExpressionToCode(
void *theEnv,
FILE *fp,
struct expr *exprPtr)
{
/*========================================*/
/* Print the reference to the expression. */
/*========================================*/
if (exprPtr == NULL)
{
if (fp != NULL) fprintf(fp,"NULL");
return(FALSE);
}
else if (fp != NULL)
{ fprintf(fp,"&E%d_%d[%ld]",ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->ExpressionVersion,ConstructCompilerData(theEnv)->ExpressionCount); }
/*==================================================*/
/* Create a new expression code file, if necessary. */
/*==================================================*/
if (ConstructCompilerData(theEnv)->ExpressionHeader == TRUE)
{
if ((ConstructCompilerData(theEnv)->ExpressionFP = NewCFile(theEnv,ConstructCompilerData(theEnv)->FilePrefix,3,ConstructCompilerData(theEnv)->ExpressionVersion,FALSE)) == NULL)
{ return(-1); }
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"struct expr E%d_%d[] = {\n",ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->ExpressionVersion);
fprintf(ConstructCompilerData(theEnv)->HeaderFP,"extern struct expr E%d_%d[];\n",ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->ExpressionVersion);
ConstructCompilerData(theEnv)->ExpressionHeader = FALSE;
}
else
{ fprintf(ConstructCompilerData(theEnv)->ExpressionFP,",\n"); }
/*===========================*/
/* Dump the expression code. */
/*===========================*/
DumpExpression(theEnv,exprPtr);
/*=========================================*/
/* Close the expression file if necessary. */
/*=========================================*/
if (ConstructCompilerData(theEnv)->ExpressionCount >= ConstructCompilerData(theEnv)->MaxIndices)
{
ConstructCompilerData(theEnv)->ExpressionCount = 0;
ConstructCompilerData(theEnv)->ExpressionVersion++;
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"};\n");
GenClose(theEnv,ConstructCompilerData(theEnv)->ExpressionFP);
ConstructCompilerData(theEnv)->ExpressionFP = NULL;
ConstructCompilerData(theEnv)->ExpressionHeader = TRUE;
}
/*==========================================*/
/* Return TRUE to indicate the expression */
/* reference and expression data structures */
/* were succcessfully written to the file. */
/*==========================================*/
return(TRUE);
}
/**********************************************************/
/* DumpExpression: Writes the C code representation of an */
/* expression data structure to the expression file. */
/**********************************************************/
static void DumpExpression(
void *theEnv,
struct expr *exprPtr)
{
while (exprPtr != NULL)
{
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"{");
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"%d,",exprPtr->type);
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"VS ");
switch (exprPtr->type)
{
case FCALL:
PrintFunctionReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(struct FunctionDefinition *) exprPtr->value);
break;
case INTEGER:
PrintIntegerReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(INTEGER_HN *) exprPtr->value);
break;
case FLOAT:
PrintFloatReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(FLOAT_HN *) exprPtr->value);
break;
case PCALL:
#if DEFFUNCTION_CONSTRUCT
PrintDeffunctionReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(DEFFUNCTION *) exprPtr->value,
ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->MaxIndices);
#else
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
#endif
break;
case GCALL:
#if DEFGENERIC_CONSTRUCT
PrintGenericFunctionReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(DEFGENERIC *) exprPtr->value,
ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->MaxIndices);
#else
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
#endif
break;
case DEFTEMPLATE_PTR:
#if DEFTEMPLATE_CONSTRUCT
DeftemplateCConstructReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,exprPtr->value,ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->MaxIndices);
#else
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
#endif
break;
case DEFGLOBAL_PTR:
#if DEFGLOBAL_CONSTRUCT
DefglobalCConstructReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,exprPtr->value,ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->MaxIndices);
#else
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
#endif
break;
case DEFCLASS_PTR:
#if OBJECT_SYSTEM
PrintClassReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(DEFCLASS *) exprPtr->value,ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->MaxIndices);
#else
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
#endif
break;
case FACT_ADDRESS:
#if DEFTEMPLATE_CONSTRUCT
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
fprintf(ConstructCompilerData(theEnv)->FixupFP,
" E%d_%d[%ld].value = &FactData(theEnv)->DummyFact;\n",
ConstructCompilerData(theEnv)->ImageID,
ConstructCompilerData(theEnv)->ExpressionVersion,
ConstructCompilerData(theEnv)->ExpressionCount);
#else
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
#endif
break;
case INSTANCE_ADDRESS:
#if OBJECT_SYSTEM
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
fprintf(ConstructCompilerData(theEnv)->FixupFP,
" E%d_%d[%ld].value = &InstanceData(theEnv)->DummyInstance;\n",
ConstructCompilerData(theEnv)->ImageID,
ConstructCompilerData(theEnv)->ExpressionVersion,
ConstructCompilerData(theEnv)->ExpressionCount);
#else
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
#endif
break;
case STRING:
case SYMBOL:
case INSTANCE_NAME:
case GBL_VARIABLE:
PrintSymbolReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(SYMBOL_HN *) exprPtr->value);
break;
case RVOID:
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL");
break;
default:
if (EvaluationData(theEnv)->PrimitivesArray[exprPtr->type] == NULL)
{ fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL"); }
else if (EvaluationData(theEnv)->PrimitivesArray[exprPtr->type]->bitMap)
{ PrintBitMapReference(theEnv,ConstructCompilerData(theEnv)->ExpressionFP,(BITMAP_HN *) exprPtr->value); }
else
{ fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL"); }
break;
}
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,",");
ConstructCompilerData(theEnv)->ExpressionCount++;
if (exprPtr->argList == NULL)
{ fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL,"); }
else
{
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"&E%d_%d[%ld],",ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->ExpressionVersion,
ConstructCompilerData(theEnv)->ExpressionCount);
}
if (exprPtr->nextArg == NULL)
{ fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"NULL}"); }
else
{
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,"&E%d_%d[%ld]}",ConstructCompilerData(theEnv)->ImageID,ConstructCompilerData(theEnv)->ExpressionVersion,
ConstructCompilerData(theEnv)->ExpressionCount + ExpressionSize(exprPtr->argList));
}
if (exprPtr->argList != NULL)
{
fprintf(ConstructCompilerData(theEnv)->ExpressionFP,",\n");
DumpExpression(theEnv,exprPtr->argList);
}
exprPtr = exprPtr->nextArg;
if (exprPtr != NULL) fprintf(ConstructCompilerData(theEnv)->ExpressionFP,",\n");
}
}
/***********************************************/
/* ConstructsToCCommandDefinition: Initializes */
/* the constructs-to-c command. */
/***********************************************/
globle void ConstructsToCCommandDefinition(
void *theEnv)
{
EnvDefineFunction2(theEnv,"constructs-to-c",'v',
PTIEF ConstructsToCCommand,
"ConstructsToCCommand", "23*kii");
}
/*********************************************************/
/* AddCodeGeneratorItem: Adds another code generator */
/* item to the list of items for which code is */
/* generated bythe constructs-to-c function. Typically */
/* each construct has its own code generator item. */
/*********************************************************/
globle struct CodeGeneratorItem *AddCodeGeneratorItem(
void *theEnv,
char *name,
int priority,
void (*beforeFunction)(void *),
void (*initFunction)(void *,FILE *,int,int),
int (*generateFunction)(void *,char *,int,FILE *,int,int),
int arrayCount)
{
struct CodeGeneratorItem *newPtr, *currentPtr, *lastPtr = NULL;
register int i;
char theBuffer[3];
/*======================================*/
/* Create the code generator item data */
/* structure and initialize its values. */
/*======================================*/
newPtr = get_struct(theEnv,CodeGeneratorItem);
newPtr->name = name;
newPtr->beforeFunction = beforeFunction;
newPtr->initFunction = initFunction;
newPtr->generateFunction = generateFunction;
newPtr->priority = priority;
newPtr->arrayCount = arrayCount;
/*================================================*/
/* Create the primary and secondary codes used to */
/* provide names for the C data structure arrays. */
/* (The maximum number of arrays is currently */
/* limited to 47. */
/*================================================*/
if (arrayCount != 0)
{
if ((arrayCount + ConstructCompilerData(theEnv)->CodeGeneratorCount) > (PRIMARY_LEN + SECONDARY_LEN))
{
SystemError(theEnv,"CONSCOMP",2);
EnvExitRouter(theEnv,EXIT_FAILURE);
}
newPtr->arrayNames = (char **) gm2(theEnv,(sizeof(char *) * arrayCount));
for (i = 0 ; i < arrayCount ; i++)
{
if (ConstructCompilerData(theEnv)->CodeGeneratorCount < PRIMARY_LEN)
{ sprintf(theBuffer,"%c",PRIMARY_CODES[ConstructCompilerData(theEnv)->CodeGeneratorCount]); }
else
{ sprintf(theBuffer,"%c_",SECONDARY_CODES[ConstructCompilerData(theEnv)->CodeGeneratorCount - PRIMARY_LEN]); }
ConstructCompilerData(theEnv)->CodeGeneratorCount++;
newPtr->arrayNames[i] = (char *) gm2(theEnv,(strlen(theBuffer) + 1));
strcpy(newPtr->arrayNames[i],theBuffer);
}
}
else
{ newPtr->arrayNames = NULL; }
/*===========================================*/
/* Add the new item in the appropriate place */
/* in the code generator item list. */
/*===========================================*/
if (ConstructCompilerData(theEnv)->ListOfCodeGeneratorItems == NULL)
{
newPtr->next = NULL;
ConstructCompilerData(theEnv)->ListOfCodeGeneratorItems = newPtr;
return(newPtr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -