📄 default.c
字号:
/*******************************************************/
/* "C" Language Integrated Production System */
/* */
/* CLIPS Version 6.24 06/05/06 */
/* */
/* DEFAULT ATTRIBUTE MODULE */
/*******************************************************/
/*************************************************************/
/* Purpose: Provides functions for parsing the default */
/* attribute and determining default values based on */
/* slot constraints. */
/* */
/* Principal Programmer(s): */
/* Gary D. Riley */
/* */
/* Contributing Programmer(s): */
/* Brian Donnell */
/* */
/* Revision History: */
/* */
/* 6.24: Support for deftemplate-slot-default-value */
/* function. */
/* */
/*************************************************************/
#define _DEFAULT_SOURCE_
#include "setup.h"
#include <stdio.h>
#define _STDIO_INCLUDED_
#include <stdlib.h>
#include <string.h>
#include "constant.h"
#include "constrnt.h"
#include "cstrnchk.h"
#include "multifld.h"
#include "inscom.h"
#include "exprnpsr.h"
#include "scanner.h"
#include "router.h"
#include "factmngr.h"
#include "cstrnutl.h"
#include "envrnmnt.h"
#include "default.h"
/***************************************/
/* LOCAL INTERNAL FUNCTION DEFINITIONS */
/***************************************/
static void *FindDefaultValue(void *,int,CONSTRAINT_RECORD *,void *);
/********************************************************/
/* DeriveDefaultFromConstraints: Returns an appropriate */
/* default value for the supplied constraints. */
/********************************************************/
globle void DeriveDefaultFromConstraints(
void *theEnv,
CONSTRAINT_RECORD *constraints,
DATA_OBJECT *theDefault,
int multifield,
int garbageMultifield)
{
unsigned short theType;
unsigned long minFields;
void *theValue;
/*=============================================================*/
/* If no constraints are specified, then use the symbol nil as */
/* a default for single field slots and a multifield of length */
/* 0 as a default for multifield slots. */
/*=============================================================*/
if (constraints == NULL)
{
if (multifield)
{
SetpType(theDefault,MULTIFIELD);
SetpDOBegin(theDefault,1);
SetpDOEnd(theDefault,0);
if (garbageMultifield) SetpValue(theDefault,(void *) EnvCreateMultifield(theEnv,0L));
else SetpValue(theDefault,(void *) CreateMultifield2(theEnv,0L));
}
else
{
theDefault->type = SYMBOL;
theDefault->value = EnvAddSymbol(theEnv,"nil");
}
return;
}
/*=========================================*/
/* Determine the default's type and value. */
/*=========================================*/
if (constraints->anyAllowed || constraints->symbolsAllowed)
{
theType = SYMBOL;
theValue = FindDefaultValue(theEnv,SYMBOL,constraints,EnvAddSymbol(theEnv,"nil"));
}
else if (constraints->stringsAllowed)
{
theType = STRING;
theValue = FindDefaultValue(theEnv,STRING,constraints,EnvAddSymbol(theEnv,""));
}
else if (constraints->integersAllowed)
{
theType = INTEGER;
theValue = FindDefaultValue(theEnv,INTEGER,constraints,EnvAddLong(theEnv,0L));
}
else if (constraints->floatsAllowed)
{
theType = FLOAT;
theValue = FindDefaultValue(theEnv,FLOAT,constraints,EnvAddDouble(theEnv,0.0));
}
#if OBJECT_SYSTEM
else if (constraints->instanceNamesAllowed)
{
theType = INSTANCE_NAME;
theValue = FindDefaultValue(theEnv,INSTANCE_NAME,constraints,EnvAddSymbol(theEnv,"nil"));
}
else if (constraints->instanceAddressesAllowed)
{
theType = INSTANCE_ADDRESS;
theValue = (void *) &InstanceData(theEnv)->DummyInstance;
}
#endif
#if DEFTEMPLATE_CONSTRUCT
else if (constraints->factAddressesAllowed)
{
theType = FACT_ADDRESS;
theValue = (void *) &FactData(theEnv)->DummyFact;
}
#endif
else if (constraints->externalAddressesAllowed)
{
theType = EXTERNAL_ADDRESS;
theValue = NULL;
}
else
{
theType = SYMBOL;
theValue = EnvAddSymbol(theEnv,"nil");
}
/*=========================================================*/
/* If the default is for a multifield slot, then create a */
/* multifield default value that satisfies the cardinality */
/* constraints for the slot. The default value for a */
/* multifield slot is a multifield of length 0. */
/*=========================================================*/
if (multifield)
{
if (constraints->minFields == NULL) minFields = 0;
else if (constraints->minFields->value == SymbolData(theEnv)->NegativeInfinity) minFields = 0;
else minFields = (unsigned long) ValueToLong(constraints->minFields->value);
SetpType(theDefault,MULTIFIELD);
SetpDOBegin(theDefault,1);
SetpDOEnd(theDefault,(long) minFields);
if (garbageMultifield) SetpValue(theDefault,(void *) EnvCreateMultifield(theEnv,minFields));
else SetpValue(theDefault,(void *) CreateMultifield2(theEnv,minFields));
for (; minFields > 0; minFields--)
{
SetMFType(GetpValue(theDefault),minFields,theType);
SetMFValue(GetpValue(theDefault),minFields,theValue);
}
}
else
{
theDefault->type = theType;
theDefault->value = theValue;
}
}
/***********************************************************************/
/* FindDefaultValue: Searches the list of restriction values for a */
/* constraint to find a default value of the specified type. For */
/* example, if the attribute (allowed-symbols on off) was specified, */
/* then the symbol "on" would be used as a default value rather than */
/* the symbol "nil". For integers and floats, the range attribute is */
/* also used to select a suitable default value. If a minimum value */
/* was specified, then this value is used first followed by the */
/* maximum value. */
/************************************************************************/
static void *FindDefaultValue(
void *theEnv,
int theType,
CONSTRAINT_RECORD *theConstraints,
void *standardDefault)
{
struct expr *theList;
/*=====================================================*/
/* Look on the the allowed values list to see if there */
/* is a value of the requested type. Return the first */
/* value found of the requested type. */
/*=====================================================*/
theList = theConstraints->restrictionList;
while (theList != NULL)
{
if (theList->type == theType) return(theList->value);
theList = theList->nextArg;
}
/*=============================================================*/
/* If no specific values were available for the default value, */
/* and the type requested is a float or integer, then use the */
/* range attribute to select a default value. */
/*=============================================================*/
if (theType == INTEGER)
{
if (theConstraints->minValue->type == INTEGER)
{ return(theConstraints->minValue->value); }
else if (theConstraints->minValue->type == FLOAT)
{ return(EnvAddLong(theEnv,(long) ValueToDouble(theConstraints->minValue->value))); }
else if (theConstraints->maxValue->type == INTEGER)
{ return(theConstraints->maxValue->value); }
else if (theConstraints->maxValue->type == FLOAT)
{ return(EnvAddLong(theEnv,(long) ValueToDouble(theConstraints->maxValue->value))); }
}
else if (theType == FLOAT)
{
if (theConstraints->minValue->type == FLOAT)
{ return(theConstraints->minValue->value); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -