⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 msgpass.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*               CLIPS Version 6.05  04/09/97          */   /*                                                     */   /*              OBJECT MESSAGE DISPATCH CODE           */   /*******************************************************//*************************************************************//* Purpose:                                                  *//*                                                           *//* Principal Programmer(s):                                  *//*      Brian L. Donnell                                     *//*                                                           *//* Contributing Programmer(s):                               *//*                                                           *//* Revision History:                                         *//*                                                           *//*************************************************************/   /* =========================================   *****************************************               EXTERNAL DEFINITIONS   =========================================   ***************************************** */#include "setup.h"#if OBJECT_SYSTEM#ifndef _CLIPS_STDIO_#include <stdio.h>#define _CLIPS_STDIO_#endif#include "argacces.h"#include "classcom.h"#include "classfun.h"#include "clipsmem.h"#include "constrct.h"#include "exprnpsr.h"#include "insfun.h"#include "msgfun.h"#include "multifld.h"#include "prcdrfun.h"#include "prccode.h"#include "router.h"#include "utility.h"#include "commline.h"#define _MSGPASS_SOURCE_#include "msgpass.h"/* =========================================   *****************************************                   CONSTANTS   =========================================   ***************************************** *//* =========================================   *****************************************      INTERNALLY VISIBLE FUNCTION HEADERS   =========================================   ***************************************** */#if ANSI_COMPILERstatic VOID PerformMessage(DATA_OBJECT *,EXPRESSION *,SYMBOL_HN *);static HANDLER_LINK *FindApplicableHandlers(DEFCLASS *,SYMBOL_HN *);static VOID CallHandlers(DATA_OBJECT *);static VOID EarlySlotBindError(INSTANCE_TYPE *,DEFCLASS *,unsigned);#elsestatic VOID PerformMessage();static HANDLER_LINK *FindApplicableHandlers();static VOID CallHandlers();static VOID EarlySlotBindError();#endif      /* =========================================   *****************************************      EXTERNALLY VISIBLE GLOBAL VARIABLES   =========================================   ***************************************** */globle SYMBOL_HN *CurrentMessageName = NULL;globle HANDLER_LINK *CurrentCore = NULL;/* =========================================   *****************************************      INTERNALLY VISIBLE GLOBAL VARIABLES   =========================================   ***************************************** */static HANDLER_LINK *TopOfCore = NULL, *NextInCore = NULL;/* =========================================   *****************************************          EXTERNALLY VISIBLE FUNCTIONS   =========================================   ***************************************** */   /*****************************************************  NAME         : DirectMessage  DESCRIPTION  : Plugs in given instance and                   performs specified message  INPUTS       : 1) Message symbolic name                 2) The instance address                 3) Address of DATA_OBJECT buffer                    (NULL if don't care)                 4) Message argument expressions  RETURNS      : Nothing useful  SIDE EFFECTS : Side effects of message execution  NOTES        : None *****************************************************/globle VOID DirectMessage(msg,ins,resultbuf,remargs)  SYMBOL_HN *msg;  INSTANCE_TYPE *ins;  DATA_OBJECT *resultbuf;  EXPRESSION *remargs;  {   EXPRESSION args;   DATA_OBJECT temp;         if (resultbuf == NULL)     resultbuf = &temp;   args.nextArg = remargs;   args.argList = NULL;   args.type = INSTANCE_ADDRESS;   args.value = (VOID *) ins;   PerformMessage(resultbuf,&args,msg);  }    /***************************************************  NAME         : Send  DESCRIPTION  : C Interface for sending messages to                  instances  INPUTS       : 1) The data object of the instance                 2) The message name-string                 3) The message arguments string                    (Constants only)                 4) Caller's buffer for result  RETURNS      : Nothing useful  SIDE EFFECTS : Executes message and stores result                   caller's buffer  NOTES        : None ***************************************************/globle VOID Send(idata,msg,args,result)  DATA_OBJECT *idata,*result;  char *msg,*args;  {   int error;   EXPRESSION *iexp;   SYMBOL_HN *msym;   SetEvaluationError(CLIPS_FALSE);   result->type = SYMBOL;   result->value = CLIPSFalseSymbol;   msym = FindSymbol(msg);   if (msym == NULL)     {      PrintNoHandlerError(msg);      SetEvaluationError(CLIPS_TRUE);      return;     }   iexp = GenConstant(idata->type,idata->value);   iexp->nextArg = ParseConstantArguments(args,&error);   if (error == CLIPS_TRUE)     {      ReturnExpression(iexp);      SetEvaluationError(CLIPS_TRUE);      return;     }   PerformMessage(result,iexp,msym);   ReturnExpression(iexp);      if ((CurrentEvaluationDepth == 0) && (! EvaluatingTopLevelCommand) &&       (CurrentExpression == NULL))     { PeriodicCleanup(CLIPS_TRUE,CLIPS_FALSE); }  }/*****************************************************  NAME         : DestroyHandlerLinks  DESCRIPTION  : Iteratively deallocates handler-links  INPUTS       : The handler-link list  RETURNS      : Nothing useful  SIDE EFFECTS : Deallocation of links  NOTES        : None *****************************************************/globle VOID DestroyHandlerLinks(mhead)  HANDLER_LINK *mhead;  {   HANDLER_LINK *tmp;      while (mhead != NULL)     {      tmp = mhead;      mhead = mhead->nxt;      tmp->hnd->busy--;      DecrementDefclassBusyCount((VOID *) tmp->hnd->cls);      rtn_struct(messageHandlerLink,tmp);     }  }  /***********************************************************************  NAME         : SendCommand  DESCRIPTION  : Determines the applicable handler(s) and sets up the                   core calling frame.  Then calls the core frame.  INPUTS       : Caller's space for storing the result of the handler(s)  RETURNS      : Nothing useful  SIDE EFFECTS : Any side-effects caused by the execution of handlers in                   the core framework  NOTES        : CLIPS Syntax : (send <instance> <hnd> <args>*) ***********************************************************************/globle VOID SendCommand(result)  DATA_OBJECT *result;  {   EXPRESSION args;   SYMBOL_HN *msg;   DATA_OBJECT temp;      result->type = SYMBOL;   result->value = CLIPSFalseSymbol;   if (ArgTypeCheck("send",2,SYMBOL,&temp) == CLIPS_FALSE)     return;   msg = (SYMBOL_HN *) temp.value;      /* =============================================       Get the instance or primitive for the message      ============================================= */   args.type = GetFirstArgument()->type;   args.value = GetFirstArgument()->value;   args.argList = GetFirstArgument()->argList;   args.nextArg = GetFirstArgument()->nextArg->nextArg;      PerformMessage(result,&args,msg);  }/***************************************************  NAME         : GetNthMessageArgument  DESCRIPTION  : Returns the address of the nth                 (starting at 1) which is an                 argument of the current message                 dispatch  INPUTS       : None  RETURNS      : The message argument  SIDE EFFECTS : None  NOTES        : The active instance is always                 stored as the first argument (0) in                 the call frame of the message ***************************************************/globle DATA_OBJECT *GetNthMessageArgument(n)  int n;  {   return(&ProcParamArray[n]);  }        #if IMPERATIVE_MESSAGE_HANDLERS/*****************************************************  NAME         : NextHandlerAvailable  DESCRIPTION  : Determines if there the currently                   executing handler can call a                   shadowed handler                 Used before calling call-next-handler  INPUTS       : None  RETURNS      : CLIPS_TRUE if shadow ready, CLIPS_FALSE otherwise  SIDE EFFECTS : None  NOTES        : CLIPS Syntax: (next-handlerp) *****************************************************/globle int NextHandlerAvailable()  {   if (CurrentCore == NULL)     return(CLIPS_FALSE);   if (CurrentCore->hnd->type == MAROUND)     return((NextInCore != NULL) ? CLIPS_TRUE : CLIPS_FALSE);   if ((CurrentCore->hnd->type == MPRIMARY) && (NextInCore != NULL))     return((NextInCore->hnd->type == MPRIMARY) ? CLIPS_TRUE : CLIPS_FALSE);   return(CLIPS_FALSE);  }  /********************************************************  NAME         : CallNextHandler  DESCRIPTION  : This function allows around-handlers                   to execute the rest of the core frame.                 It also allows primary handlers                   to execute shadowed primaries.                                    The original handler arguments are                   left intact.  INPUTS       : The caller's result-value buffer  RETURNS      : Nothing useful  SIDE EFFECTS : The core frame is called and any                   appropriate changes are made when                   used in an around handler                   See CallHandlers()                 But when call-next-handler is called                   from a primary, the same shadowed                   primary is called over and over                   again for repeated calls to                   call-next-handler.  NOTES        : CLIPS Syntax: (call-next-handler) OR                    (override-next-handler <arg> ...) ********************************************************/globle VOID CallNextHandler(result)  DATA_OBJECT *result;  {   EXPRESSION args;   int overridep;   HANDLER_LINK *oldNext,*oldCurrent;      SetpType(result,SYMBOL);   SetpValue(result,CLIPSFalseSymbol);   EvaluationError = CLIPS_FALSE;   if (HaltExecution)     return;   if (NextHandlerAvailable() == CLIPS_FALSE)     {      PrintErrorID("MSGPASS",1,CLIPS_FALSE);      PrintCLIPS(WERROR,"Shadowed message-handlers not applicable in current context.\n");      SetEvaluationError(CLIPS_TRUE);      return;     }   if (CurrentExpression->value == (VOID *) FindFunction("override-next-handler"))     {      overridep = 1;      args.type = (short) ProcParamArray[0].type;      if (args.type != MULTIFIELD)        args.value = (VOID *) ProcParamArray[0].value;      else        args.value = (VOID *) &ProcParamArray[0];      args.nextArg = GetFirstArgument();      args.argList = NULL;      PushProcParameters(&args,CountArguments(&args),                          ValueToString(CurrentMessageName),"message",                          UnboundHandlerErr);      if (EvaluationError)        {         ReturnFlag = CLIPS_FALSE;         return;        }     }   else     overridep = 0;   oldNext = NextInCore;   oldCurrent = CurrentCore;   if (CurrentCore->hnd->type == MAROUND)     {      if (NextInCore->hnd->type == MAROUND)        {         CurrentCore = NextInCore;         NextInCore = NextInCore->nxt;#if DEBUGGING_FUNCTIONS         if (CurrentCore->hnd->trace)           WatchHandler(WTRACE,CurrentCore,BEGIN_TRACE);#endif         if (CheckHandlerArgCount())           EvaluateProcActions(CurrentCore->hnd->cls->header.whichModule->theModule,                               CurrentCore->hnd->actions,                               CurrentCore->hnd->localVarCount,                               result,UnboundHandlerErr);#if DEBUGGING_FUNCTIONS         if (CurrentCore->hnd->trace)           WatchHandler(WTRACE,CurrentCore,END_TRACE);#endif        }      else        CallHandlers(result);     }   else     {      CurrentCore = NextInCore;      NextInCore = NextInCore->nxt;#if DEBUGGING_FUNCTIONS      if (CurrentCore->hnd->trace)        WatchHandler(WTRACE,CurrentCore,BEGIN_TRACE);#endif      if (CheckHandlerArgCount())        EvaluateProcActions(CurrentCore->hnd->cls->header.whichModule->theModule,                            CurrentCore->hnd->actions,                            CurrentCore->hnd->localVarCount,                            result,UnboundHandlerErr);#if DEBUGGING_FUNCTIONS      if (CurrentCore->hnd->trace)        WatchHandler(WTRACE,CurrentCore,END_TRACE);#endif     }   NextInCore = oldNext;   CurrentCore = oldCurrent;   if (overridep)     PopProcParameters();   ReturnFlag = CLIPS_FALSE;  }#endif /* IMPERATIVE_MESSAGE_HANDLERS *//*************************************************************************  NAME         : FindApplicableOfName  DESCRIPTION  : Groups all handlers of all types of the specified                   class of the specified name into the applicable handler                   list  INPUTS       : 1) The class address                 2-3) The tops and bottoms of the four handler type lists:                      around, before, primary and after                 4) The message name symbol  RETURNS      : Nothing useful  SIDE EFFECTS : Modifies the handler lists to include applicable handlers  NOTES        : None *************************************************************************/globle VOID FindApplicableOfName(cls,tops,bots,mname)  DEFCLASS *cls;  HANDLER_LINK *tops[4],*bots[4];  SYMBOL_HN *mname;  {   register int i,e;   HANDLER *hnd;   unsigned *arr;   HANDLER_LINK *tmp;      i = FindHandlerNameGroup(cls,mname);   if (i == -1)     return;   e = cls->handlerCount-1;   hnd = cls->handlers;   arr = cls->handlerOrderMap;   for ( ; i <= e ; i++)     {      if (hnd[arr[i]].name != mname)        break;#if ! IMPERATIVE_MESSAGE_HANDLERS      if ((hnd[arr[i]].type == MPRIMARY) && (tops[MPRIMARY] != NULL))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -