📄 tmpltrhs.c
字号:
if (newField == NULL)
{
*error = TRUE;
SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents);
return(NULL);
}
/*==============================================*/
/* A function returning a multifield value can */
/* not be called to get the value for the slot. */
/*==============================================*/
if ((newField->type == FCALL) ? (ExpressionFunctionType(newField) == 'm') :
(newField->type == MF_VARIABLE))
{
*error = TRUE;
SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents);
ReturnExpression(theEnv,newField);
return(NULL);
}
/*============================*/
/* Move on to the next token. */
/*============================*/
GetToken(theEnv,inputSource,tempToken);
}
/*========================================*/
/* Handle a multifield slot. Build a list */
/* of the values stored in the slot. */
/*========================================*/
else
{
SavePPBuffer(theEnv," ");
valueList = GetAssertArgument(theEnv,inputSource,tempToken,
error,RPAREN,constantsOnly,&printError);
if (*error)
{
if (printError) SyntaxErrorMessage(theEnv,"deftemplate pattern");
return(NULL);
}
if (valueList == NULL)
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,")");
}
lastValue = valueList;
while (lastValue != NULL) /* (tempToken->type != RPAREN) */
{
if (tempToken->type == RPAREN)
{ SavePPBuffer(theEnv," "); }
else
{
/* PPBackup(theEnv); */
SavePPBuffer(theEnv," ");
/* SavePPBuffer(theEnv,tempToken->printForm); */
}
newField = GetAssertArgument(theEnv,inputSource,tempToken,error,RPAREN,constantsOnly,&printError);
if (*error)
{
if (printError) SyntaxErrorMessage(theEnv,"deftemplate pattern");
ReturnExpression(theEnv,valueList);
return(NULL);
}
if (newField == NULL)
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,")");
}
lastValue->nextArg = newField;
lastValue = newField;
}
newField = valueList;
}
/*==========================================================*/
/* Slot definition must be closed with a right parenthesis. */
/*==========================================================*/
if (tempToken->type != RPAREN)
{
SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents);
*error = TRUE;
ReturnExpression(theEnv,newField);
return(NULL);
}
/*=========================================================*/
/* Build and return a structure describing the slot value. */
/*=========================================================*/
nextSlot = GenConstant(theEnv,SYMBOL,slotPtr->slotName);
nextSlot->argList = newField;
return(nextSlot);
}
/*************************************************************************/
/* ReorderAssertSlotValues: Rearranges the asserted values to correspond */
/* to the order of the values described by the deftemplate. */
/*************************************************************************/
static struct expr *ReorderAssertSlotValues(
void *theEnv,
struct templateSlot *slotPtr,
struct expr *firstSlot,
int *error)
{
struct expr *firstArg = NULL;
struct expr *lastArg = NULL, *newArg;
/*=============================================*/
/* Loop through each of the slots in the order */
/* they're found in the deftemplate. */
/*=============================================*/
for (;
slotPtr != NULL;
slotPtr = slotPtr->next)
{
/*==============================================*/
/* Get either the value specified in the assert */
/* command or the default value for the slot. */
/*==============================================*/
newArg = GetSlotAssertValues(theEnv,slotPtr,firstSlot,error);
if (*error)
{
ReturnExpression(theEnv,firstArg);
return(NULL);
}
/*=====================================*/
/* Add the value to the list of values */
/* for the assert command. */
/*=====================================*/
if (newArg != NULL)
{
if (lastArg == NULL)
{ firstArg = newArg; }
else
{ lastArg->nextArg = newArg; }
lastArg = newArg;
}
}
/*==============================*/
/* Return the list of arguments */
/* for the assert command. */
/*==============================*/
return(firstArg);
}
/***************************************************************/
/* GetSlotAssertValues: Gets the assert value for a given slot */
/* of a deftemplate. If the value was supplied by the user, */
/* it will be used. If not the default value or default */
/* default value will be used. */
/***************************************************************/
static struct expr *GetSlotAssertValues(
void *theEnv,
struct templateSlot *slotPtr,
struct expr *firstSlot,
int *error)
{
struct expr *slotItem;
struct expr *newArg, *tempArg;
DATA_OBJECT theDefault;
/*==================================================*/
/* Determine if the slot is assigned in the assert. */
/*==================================================*/
slotItem = FindAssertSlotItem(slotPtr,firstSlot);
/*==========================================*/
/* If the slot is assigned, use that value. */
/*==========================================*/
if (slotItem != NULL)
{
newArg = slotItem->argList;
slotItem->argList = NULL;
}
/*=================================*/
/* Otherwise, use a default value. */
/*=================================*/
else
{
/*================================================*/
/* If the (default ?NONE) attribute was specified */
/* for the slot, then a value must be supplied. */
/*================================================*/
if (slotPtr->noDefault)
{
PrintErrorID(theEnv,"TMPLTRHS",1,TRUE);
EnvPrintRouter(theEnv,WERROR,"Slot ");
EnvPrintRouter(theEnv,WERROR,slotPtr->slotName->contents);
EnvPrintRouter(theEnv,WERROR," requires a value because of its (default ?NONE) attribute.\n");
*error = TRUE;
return(NULL);
}
/*===================================================*/
/* If the (default ?DERIVE) attribute was specified */
/* (the default), then derive the default value from */
/* the slot's constraints. */
/*===================================================*/
else if ((slotPtr->defaultPresent == FALSE) &&
(slotPtr->defaultDynamic == FALSE))
{
DeriveDefaultFromConstraints(theEnv,slotPtr->constraints,&theDefault,
(int) slotPtr->multislot,TRUE);
newArg = ConvertValueToExpression(theEnv,&theDefault);
}
/*=========================================*/
/* Otherwise, use the expression contained */
/* in the default attribute. */
/*=========================================*/
else
{ newArg = CopyExpression(theEnv,slotPtr->defaultList); }
}
/*=======================================================*/
/* Since a multifield slot default can contain a list of */
/* values, the values need to have a store-multifield */
/* function called wrapped around it to group all of the */
/* values into a single multifield value. */
/*=======================================================*/
if (slotPtr->multislot)
{
tempArg = GenConstant(theEnv,FACT_STORE_MULTIFIELD,AddBitMap(theEnv,(void *) "\0",1));
tempArg->argList = newArg;
newArg = tempArg;
}
/*==============================================*/
/* Return the value to be asserted in the slot. */
/*==============================================*/
return(newArg);
}
/*******************************************************************/
/* FindAssertSlotItem: Finds a particular slot in a list of slots. */
/*******************************************************************/
static struct expr *FindAssertSlotItem(
struct templateSlot *slotPtr,
struct expr *listOfSlots)
{
while (listOfSlots != NULL)
{
if (listOfSlots->value == (void *) slotPtr->slotName) return (listOfSlots);
listOfSlots = listOfSlots->nextArg;
}
return(NULL);
}
#endif /* DEFTEMPLATE_CONSTRUCT */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -