📄 prcdrfun.c
字号:
/*******************************************************/ /* "C" Language Integrated Production System */ /* */ /* CLIPS Version 6.05 04/09/97 */ /* */ /* PROCEDURAL FUNCTIONS MODULE */ /*******************************************************//*************************************************************//* Purpose: Contains the code for several procedural *//* functions including if, while, loop-for-count, bind, *//* progn, return, break, and switch *//* *//* Principal Programmer(s): *//* Gary D. Riley *//* Brian L. Donnell *//* *//* Contributing Programmer(s): *//* *//* Revision History: *//* *//*************************************************************/#define _PRCDRFUN_SOURCE_#include <stdio.h>#define _CLIPS_STDIO_#include "setup.h"#include "clipsmem.h"#include "router.h"#include "argacces.h"#include "constrnt.h"#include "cstrnchk.h"#include "cstrnops.h"#include "multifld.h"#include "exprnpsr.h"#include "scanner.h"#include "utility.h"#include "prcdrpsr.h"#include "prcdrfun.h"#if DEFGLOBAL_CONSTRUCT #include "globldef.h" #endiftypedef struct loopCounterStack { long loopCounter; struct loopCounterStack *nxt; } LOOP_COUNTER_STACK; /****************************************//* GLOBAL INTERNAL VARIABLE DEFINITIONS *//****************************************/ globle int ReturnFlag = CLIPS_FALSE; globle int BreakFlag = CLIPS_FALSE;/***************************************//* LOCAL INTERNAL VARIABLE DEFINITIONS *//***************************************/ static LOOP_COUNTER_STACK *LoopCounterStack = NULL; static struct dataObject *BindList = NULL;#if ! RUN_TIME/**********************************************//* ProceduralFunctionDefinitions: Initializes *//* the procedural functions. *//**********************************************/globle VOID ProceduralFunctionDefinitions() { DefineFunction2("if", 'u', PTIF IfFunction, "IfFunction", NULL); DefineFunction2("while", 'u', PTIF WhileFunction, "WhileFunction", NULL); DefineFunction2("loop-for-count",'u', PTIF LoopForCountFunction, "LoopForCountFunction", NULL); DefineFunction2("(get-loop-count)",'l', PTIF GetLoopCount, "GetLoopCount", NULL); DefineFunction2("bind", 'u', PTIF BindFunction, "BindFunction", NULL); DefineFunction2("progn", 'u', PTIF PrognFunction, "PrognFunction", NULL); DefineFunction2("return", 'u', PTIF ReturnFunction, "ReturnFunction",NULL); DefineFunction2("break", 'v', PTIF BreakFunction, "BreakFunction",NULL); DefineFunction2("switch", 'u', PTIF SwitchFunction, "SwitchFunction",NULL); ProceduralFunctionParsers(); FuncSeqOvlFlags("progn",CLIPS_FALSE,CLIPS_FALSE); FuncSeqOvlFlags("if",CLIPS_FALSE,CLIPS_FALSE); FuncSeqOvlFlags("while",CLIPS_FALSE,CLIPS_FALSE); FuncSeqOvlFlags("loop-for-count",CLIPS_FALSE,CLIPS_FALSE); FuncSeqOvlFlags("return",CLIPS_FALSE,CLIPS_FALSE); FuncSeqOvlFlags("switch",CLIPS_FALSE,CLIPS_FALSE); }#endif/***************************************//* WhileFunction: CLIPS access routine *//* for the while function. *//***************************************/globle VOID WhileFunction(returnValue) DATA_OBJECT_PTR returnValue; { DATA_OBJECT theResult; /*====================================================*/ /* Evaluate the body of the while loop as long as the */ /* while condition evaluates to a non-FALSE value. */ /*====================================================*/ CurrentEvaluationDepth++; RtnUnknown(1,&theResult); while (((theResult.value != CLIPSFalseSymbol) || (theResult.type != SYMBOL)) && (HaltExecution != CLIPS_TRUE)) { if ((BreakFlag == CLIPS_TRUE) || (ReturnFlag == CLIPS_TRUE)) break; RtnUnknown(2,&theResult); CurrentEvaluationDepth--; if (ReturnFlag == CLIPS_TRUE) { PropagateReturnValue(&theResult); } PeriodicCleanup(CLIPS_FALSE,CLIPS_TRUE); CurrentEvaluationDepth++; if ((BreakFlag == CLIPS_TRUE) || (ReturnFlag == CLIPS_TRUE)) break; RtnUnknown(1,&theResult); } CurrentEvaluationDepth--; /*=====================================================*/ /* Reset the break flag. The return flag is not reset */ /* because the while loop is probably contained within */ /* a deffunction or RHS of a rule which needs to be */ /* returned from as well. */ /*=====================================================*/ BreakFlag = CLIPS_FALSE; /*====================================================*/ /* If the return command was issued, then return that */ /* value, otherwise return the symbol FALSE. */ /*====================================================*/ if (ReturnFlag == CLIPS_TRUE) { returnValue->type = theResult.type; returnValue->value = theResult.value; returnValue->begin = theResult.begin; returnValue->end = theResult.end; } else { returnValue->type = SYMBOL; returnValue->value = CLIPSFalseSymbol; } } /**********************************************//* LoopForCountFunction: CLIPS access routine *//* for the loop-for-count function. *//**********************************************/globle VOID LoopForCountFunction(loopResult) DATA_OBJECT_PTR loopResult; { DATA_OBJECT arg_ptr; long iterationEnd; LOOP_COUNTER_STACK *tmpCounter; tmpCounter = get_struct(loopCounterStack); tmpCounter->loopCounter = 0L; tmpCounter->nxt = LoopCounterStack; LoopCounterStack = tmpCounter; if (ArgTypeCheck("loop-for-count",1,INTEGER,&arg_ptr) == CLIPS_FALSE) { loopResult->type = SYMBOL; loopResult->value = CLIPSFalseSymbol; LoopCounterStack = tmpCounter->nxt; rtn_struct(loopCounterStack,tmpCounter); return; } tmpCounter->loopCounter = DOToLong(arg_ptr); if (ArgTypeCheck("loop-for-count",2,INTEGER,&arg_ptr) == CLIPS_FALSE) { loopResult->type = SYMBOL; loopResult->value = CLIPSFalseSymbol; LoopCounterStack = tmpCounter->nxt; rtn_struct(loopCounterStack,tmpCounter); return; } iterationEnd = DOToLong(arg_ptr); while ((tmpCounter->loopCounter <= iterationEnd) && (HaltExecution != CLIPS_TRUE)) { if ((BreakFlag == CLIPS_TRUE) || (ReturnFlag == CLIPS_TRUE)) break; CurrentEvaluationDepth++; RtnUnknown(3,&arg_ptr); CurrentEvaluationDepth--; if (ReturnFlag == CLIPS_TRUE) { PropagateReturnValue(&arg_ptr); } PeriodicCleanup(CLIPS_FALSE,CLIPS_TRUE); if ((BreakFlag == CLIPS_TRUE) || (ReturnFlag == CLIPS_TRUE)) break; tmpCounter->loopCounter++; } BreakFlag = CLIPS_FALSE; if (ReturnFlag == CLIPS_TRUE) { loopResult->type = arg_ptr.type; loopResult->value = arg_ptr.value; loopResult->begin = arg_ptr.begin; loopResult->end = arg_ptr.end; } else { loopResult->type = SYMBOL; loopResult->value = CLIPSFalseSymbol; } LoopCounterStack = tmpCounter->nxt; rtn_struct(loopCounterStack,tmpCounter); }/************************************************//* GetLoopCount *//************************************************/globle long GetLoopCount() { int depth; LOOP_COUNTER_STACK *tmpCounter; depth = ValueToInteger(GetFirstArgument()->value); tmpCounter = LoopCounterStack; while (depth > 0) { tmpCounter = tmpCounter->nxt; depth--; } return(tmpCounter->loopCounter); }/************************************//* IfFunction: CLIPS access routine *//* for the if function. *//************************************/globle VOID IfFunction(returnValue) DATA_OBJECT_PTR returnValue; { int numArgs; /*============================================*/ /* Check for the correct number of arguments. */ /*============================================*/ if ((numArgs = ArgRangeCheck("if",2,3)) == -1) { returnValue->type = SYMBOL; returnValue->value = CLIPSFalseSymbol; return; } /*=========================*/ /* Evaluate the condition. */ /*=========================*/ RtnUnknown(1,returnValue); if ((BreakFlag == CLIPS_TRUE) || (ReturnFlag == CLIPS_TRUE)) { return; } /*=========================================*/ /* If the condition evaluated to FALSE and */ /* an "else" portion exists, evaluate it */ /* and return the value. */ /*=========================================*/ if ((returnValue->value == CLIPSFalseSymbol) && (returnValue->type == SYMBOL) && (numArgs == 3)) { RtnUnknown(3,returnValue); return; } /*===================================================*/ /* Otherwise if the symbol evaluated to a non-FALSE */ /* value, evaluate the "then" portion and return it. */ /*===================================================*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -