/********************************************************************* NAME : SlotExistPCommand DESCRIPTION : Determines if a slot is present in a class INPUTS : None RETURNS : True if the slot exists, false otherwise SIDE EFFECTS : None NOTES : H/L Syntax : (slot-existp <class> <slot> [inherit]) *********************************************************************/ void SlotExistPCommand( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { Defclass *cls; SlotDescriptor *sd; bool inheritFlag = false; UDFValue theArg; sd = CheckSlotExists(context,"slot-existp",&cls,false,true); if (sd == NULL) { returnValue->lexemeValue = FalseSymbol(theEnv); return; } if (UDFHasNextArgument(context)) { if (! UDFNextArgument(context,SYMBOL_BIT,&theArg)) { return; } if (strcmp(theArg.lexemeValue->contents,"inherit") != 0) { UDFInvalidArgumentMessage(context,"keyword \"inherit\""); SetEvaluationError(theEnv,true); returnValue->lexemeValue = FalseSymbol(theEnv); return; } inheritFlag = true; } returnValue->lexemeValue = CreateBoolean(theEnv,((sd->cls == cls) ? true : inheritFlag)); }
void DivisionFunction( UDFContext *context, CLIPSValue *returnValue) { CLIPSFloat ftotal = 1.0; CLIPSFloat theNumber; CLIPSValue theArg; Environment *theEnv = UDFContextEnvironment(context); /*===================================================*/ /* Get the first argument. This number which will be */ /* the starting product from which all subsequent */ /* arguments will divide. If the auto float dividend */ /* feature is enable, then this number is converted */ /* to a float if it is an integer. */ /*===================================================*/ if (! UDFFirstArgument(context,NUMBER_TYPES,&theArg)) { return; } ftotal = mCVToFloat(&theArg); /*====================================================*/ /* Loop through each of the arguments dividing it */ /* into a running product. If a floating point number */ /* is encountered, then do all subsequent operations */ /* using floating point values. Each argument is */ /* checked to prevent a divide by zero error. */ /*====================================================*/ while (UDFHasNextArgument(context)) { if (! UDFNextArgument(context,NUMBER_TYPES,&theArg)) { return; } theNumber = mCVToFloat(&theArg); if (theNumber == 0.0) { DivideByZeroErrorMessage(theEnv,"/"); EnvSetEvaluationError(theEnv,true); mCVSetFloat(returnValue,1.0); return; } ftotal /= theNumber; } /*======================================================*/ /* If a floating point number was in the argument list, */ /* then return a float, otherwise return an integer. */ /*======================================================*/ mCVSetFloat(returnValue,ftotal); }
void DivFunction( UDFContext *context, CLIPSValue *returnValue) { CLIPSInteger total = 1LL; DATA_OBJECT theArg; CLIPSInteger theNumber; void *theEnv = UDFContextEnvironment(context); /*===================================================*/ /* Get the first argument. This number which will be */ /* the starting product from which all subsequent */ /* arguments will divide. */ /*===================================================*/ if (! UDFFirstArgument(context,NUMBER_TYPES,&theArg)) { return; } total = mCVToInteger(&theArg); /*=====================================================*/ /* Loop through each of the arguments dividing it into */ /* a running product. Floats are converted to integers */ /* and each argument is checked to prevent a divide by */ /* zero error. */ /*=====================================================*/ while (UDFHasNextArgument(context)) { if (! UDFNextArgument(context,NUMBER_TYPES,&theArg)) { return; } theNumber = mCVToInteger(&theArg); if (theNumber == 0LL) { DivideByZeroErrorMessage(theEnv,"div"); EnvSetEvaluationError(theEnv,true); mCVSetInteger(returnValue,1L); return; } total /= theNumber; } /*======================================================*/ /* The result of the div function is always an integer. */ /*======================================================*/ mCVSetInteger(returnValue,total); }
void AdditionFunction( UDFContext *context, CLIPSValue *returnValue) { CLIPSFloat ftotal = 0.0; CLIPSInteger ltotal = 0LL; bool useFloatTotal = false; CLIPSValue theArg; /*=================================================*/ /* Loop through each of the arguments adding it to */ /* a running total. If a floating point number is */ /* encountered, then do all subsequent operations */ /* using floating point values. */ /*=================================================*/ while (UDFHasNextArgument(context)) { if (! UDFNextArgument(context,NUMBER_TYPES,&theArg)) { return; } if (useFloatTotal) { ftotal += mCVToFloat(&theArg); } else { if (mCVIsType(&theArg,INTEGER_TYPE)) { ltotal += mCVToInteger(&theArg); } else { ftotal = ((CLIPSFloat) ltotal) + mCVToFloat(&theArg); useFloatTotal = true; } } } /*======================================================*/ /* If a floating point number was in the argument list, */ /* then return a float, otherwise return an integer. */ /*======================================================*/ if (useFloatTotal) { mCVSetFloat(returnValue,ftotal); } else { mCVSetInteger(returnValue,ltotal); } }
/************************************************************************************ NAME : MessageHandlerExistPCommand DESCRIPTION : Determines if a message-handler is present in a class INPUTS : None RETURNS : True if the message header is present, false otherwise SIDE EFFECTS : None NOTES : H/L Syntax : (message-handler-existp <class> <hnd> [<type>]) ************************************************************************************/ void MessageHandlerExistPCommand( Environment *theEnv, UDFContext *context, UDFValue *returnValue) { Defclass *cls; CLIPSLexeme *mname; UDFValue theArg; unsigned mtype = MPRIMARY; if (! UDFFirstArgument(context,SYMBOL_BIT,&theArg)) { return; } cls = LookupDefclassByMdlOrScope(theEnv,theArg.lexemeValue->contents); if (cls == NULL) { ClassExistError(theEnv,"message-handler-existp",theArg.lexemeValue->contents); returnValue->lexemeValue = FalseSymbol(theEnv); return; } if (! UDFNextArgument(context,SYMBOL_BIT,&theArg)) { return; } mname = theArg.lexemeValue; if (UDFHasNextArgument(context)) { if (! UDFNextArgument(context,SYMBOL_BIT,&theArg)) { return; } mtype = HandlerType(theEnv,"message-handler-existp",true,theArg.lexemeValue->contents); if (mtype == MERROR) { SetEvaluationError(theEnv,true); returnValue->lexemeValue = FalseSymbol(theEnv); return; } } if (FindHandlerByAddress(cls,mname,mtype) != NULL) { returnValue->lexemeValue = TrueSymbol(theEnv); } else { returnValue->lexemeValue = FalseSymbol(theEnv); } }
void MaxFunction( UDFContext *context, CLIPSValue *returnValue) { CLIPSValue nextPossible; /*============================================*/ /* Check that the first argument is a number. */ /*============================================*/ if (! UDFFirstArgument(context,NUMBER_TYPES,returnValue)) { return; } /*===========================================================*/ /* Loop through the remaining arguments, first checking each */ /* argument to see that it is a number, and then determining */ /* if the argument is greater than the previous arguments */ /* and is thus the maximum value. */ /*===========================================================*/ while (UDFHasNextArgument(context)) { if (! UDFNextArgument(context,NUMBER_TYPES,&nextPossible)) { return; } /*=============================================*/ /* If either argument is a float, convert both */ /* to floats. Otherwise compare two integers. */ /*=============================================*/ if (mCVIsType(returnValue,FLOAT_TYPE) || mCVIsType(&nextPossible,FLOAT_TYPE)) { if (mCVToFloat(returnValue) < mCVToFloat(&nextPossible)) { CVSetCLIPSValue(returnValue,&nextPossible); } } else { if (mCVToInteger(returnValue) < mCVToInteger(&nextPossible)) { CVSetCLIPSValue(returnValue,&nextPossible); } } } }
void SubtractionFunction( UDFContext *context, CLIPSValue *returnValue) { CLIPSFloat ftotal = 0.0; CLIPSInteger ltotal = 0LL; bool useFloatTotal = false; CLIPSValue theArg; /*=================================================*/ /* Get the first argument. This number which will */ /* be the starting total from which all subsequent */ /* arguments will subtracted. */ /*=================================================*/ if (! UDFFirstArgument(context,NUMBER_TYPES,&theArg)) { return; } if (mCVIsType(&theArg,INTEGER_TYPE)) { ltotal = mCVToInteger(&theArg); } else { ftotal = mCVToFloat(&theArg); useFloatTotal = true; } /*===================================================*/ /* Loop through each of the arguments subtracting it */ /* from a running total. If a floating point number */ /* is encountered, then do all subsequent operations */ /* using floating point values. */ /*===================================================*/ while (UDFHasNextArgument(context)) { if (! UDFNextArgument(context,NUMBER_TYPES,&theArg)) { return; } if (useFloatTotal) { ftotal -= mCVToFloat(&theArg); } else { if (mCVIsType(&theArg,INTEGER_TYPE)) { ltotal -= mCVToInteger(&theArg); } else { ftotal = ((CLIPSFloat) ltotal) - mCVToFloat(&theArg); useFloatTotal = true; } } } /*======================================================*/ /* If a floating point number was in the argument list, */ /* then return a float, otherwise return an integer. */ /*======================================================*/ if (useFloatTotal) { mCVSetFloat(returnValue,ftotal); } else { mCVSetInteger(returnValue,ltotal); } }