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

📄 msgpass.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
   /*******************************************************/   /*      "C" Language Integrated Production System      */   /*                                                     */   /*               CLIPS Version 6.24  05/17/06          */   /*                                                     */   /*              OBJECT MESSAGE DISPATCH CODE           */   /*******************************************************//*************************************************************//* Purpose:                                                  *//*                                                           *//* Principal Programmer(s):                                  *//*      Brian L. Donnell                                     *//*                                                           *//* Contributing Programmer(s):                               *//*                                                           *//* Revision History:                                         *//*      6.23: Correction for FalseSymbol/TrueSymbol. DR0859  *//*                                                           *//*      6.24: Removed IMPERATIVE_MESSAGE_HANDLERS and        *//*            AUXILIARY_MESSAGE_HANDLERS compilation flags.  *//*                                                           *//*            Renamed BOOLEAN macro type to intBool.         *//*                                                           *//*************************************************************//* =========================================   *****************************************               EXTERNAL DEFINITIONS   =========================================   ***************************************** */#include "setup.h"#if OBJECT_SYSTEM#ifndef _STDIO_INCLUDED_#include <stdio.h>#define _STDIO_INCLUDED_#endif#include <stdlib.h>#include "argacces.h"#include "classcom.h"#include "classfun.h"#include "memalloc.h"#include "constrct.h"#include "envrnmnt.h"#include "exprnpsr.h"#include "insfun.h"#include "msgcom.h"#include "msgfun.h"#include "multifld.h"#include "prcdrfun.h"#include "prccode.h"#include "proflfun.h"#include "router.h"#include "strngfun.h"#include "utility.h"#include "commline.h"#define _MSGPASS_SOURCE_#include "msgpass.h"#include "inscom.h"/* =========================================   *****************************************      INTERNALLY VISIBLE FUNCTION HEADERS   =========================================   ***************************************** */static void PerformMessage(void *,DATA_OBJECT *,EXPRESSION *,SYMBOL_HN *);static HANDLER_LINK *FindApplicableHandlers(void *,DEFCLASS *,SYMBOL_HN *);static void CallHandlers(void *,DATA_OBJECT *);static void EarlySlotBindError(void *,INSTANCE_TYPE *,DEFCLASS *,unsigned);/* =========================================   *****************************************          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(  void *theEnv,  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(theEnv,resultbuf,&args,msg);  }/***************************************************  NAME         : EnvSend  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 EnvSend(  void *theEnv,  DATA_OBJECT *idata,  char *msg,  char *args,  DATA_OBJECT *result)  {   int error;   EXPRESSION *iexp;   SYMBOL_HN *msym;   if ((EvaluationData(theEnv)->CurrentEvaluationDepth == 0) && (! CommandLineData(theEnv)->EvaluatingTopLevelCommand) &&       (EvaluationData(theEnv)->CurrentExpression == NULL))     { PeriodicCleanup(theEnv,TRUE,FALSE); }   SetEvaluationError(theEnv,FALSE);   result->type = SYMBOL;   result->value = EnvFalseSymbol(theEnv);   msym = FindSymbolHN(theEnv,msg);   if (msym == NULL)     {      PrintNoHandlerError(theEnv,msg);      SetEvaluationError(theEnv,TRUE);      return;     }   iexp = GenConstant(theEnv,idata->type,idata->value);   iexp->nextArg = ParseConstantArguments(theEnv,args,&error);   if (error == TRUE)     {      ReturnExpression(theEnv,iexp);      SetEvaluationError(theEnv,TRUE);      return;     }   PerformMessage(theEnv,result,iexp,msym);   ReturnExpression(theEnv,iexp);  }/*****************************************************  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(  void *theEnv,  HANDLER_LINK *mhead)  {   HANDLER_LINK *tmp;   while (mhead != NULL)     {      tmp = mhead;      mhead = mhead->nxt;      tmp->hnd->busy--;      DecrementDefclassBusyCount(theEnv,(void *) tmp->hnd->cls);      rtn_struct(theEnv,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        : H/L Syntax : (send <instance> <hnd> <args>*) ***********************************************************************/globle void SendCommand(  void *theEnv,  DATA_OBJECT *result)  {   EXPRESSION args;   SYMBOL_HN *msg;   DATA_OBJECT temp;   result->type = SYMBOL;   result->value = EnvFalseSymbol(theEnv);   if (EnvArgTypeCheck(theEnv,"send",2,SYMBOL,&temp) == 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(theEnv,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(  void *theEnv,  int n)  {   return(&ProceduralPrimitiveData(theEnv)->ProcParamArray[n]);  }/*****************************************************  NAME         : NextHandlerAvailable  DESCRIPTION  : Determines if there the currently                   executing handler can call a                   shadowed handler                 Used before calling call-next-handler  INPUTS       : None  RETURNS      : TRUE if shadow ready, FALSE otherwise  SIDE EFFECTS : None  NOTES        : H/L Syntax: (next-handlerp) *****************************************************/globle int NextHandlerAvailable(  void *theEnv)  {   if (MessageHandlerData(theEnv)->CurrentCore == NULL)     return(FALSE);   if (MessageHandlerData(theEnv)->CurrentCore->hnd->type == MAROUND)     return((MessageHandlerData(theEnv)->NextInCore != NULL) ? TRUE : FALSE);   if ((MessageHandlerData(theEnv)->CurrentCore->hnd->type == MPRIMARY) && (MessageHandlerData(theEnv)->NextInCore != NULL))     return((MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY) ? TRUE : FALSE);   return(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        : H/L Syntax: (call-next-handler) OR                    (override-next-handler <arg> ...) ********************************************************/globle void CallNextHandler(  void *theEnv,  DATA_OBJECT *result)  {   EXPRESSION args;   int overridep;   HANDLER_LINK *oldNext,*oldCurrent;#if PROFILING_FUNCTIONS   struct profileFrameInfo profileFrame;#endif   SetpType(result,SYMBOL);   SetpValue(result,EnvFalseSymbol(theEnv));   EvaluationData(theEnv)->EvaluationError = FALSE;   if (EvaluationData(theEnv)->HaltExecution)     return;   if (NextHandlerAvailable(theEnv) == FALSE)     {      PrintErrorID(theEnv,"MSGPASS",1,FALSE);      EnvPrintRouter(theEnv,WERROR,"Shadowed message-handlers not applicable in current context.\n");      SetEvaluationError(theEnv,TRUE);      return;     }   if (EvaluationData(theEnv)->CurrentExpression->value == (void *) FindFunction(theEnv,"override-next-handler"))     {      overridep = 1;      args.type = ProceduralPrimitiveData(theEnv)->ProcParamArray[0].type;      if (args.type != MULTIFIELD)        args.value = (void *) ProceduralPrimitiveData(theEnv)->ProcParamArray[0].value;      else        args.value = (void *) &ProceduralPrimitiveData(theEnv)->ProcParamArray[0];      args.nextArg = GetFirstArgument();      args.argList = NULL;      PushProcParameters(theEnv,&args,CountArguments(&args),                          ValueToString(MessageHandlerData(theEnv)->CurrentMessageName),"message",                          UnboundHandlerErr);      if (EvaluationData(theEnv)->EvaluationError)        {         ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;         return;        }     }   else     overridep = 0;   oldNext = MessageHandlerData(theEnv)->NextInCore;   oldCurrent = MessageHandlerData(theEnv)->CurrentCore;   if (MessageHandlerData(theEnv)->CurrentCore->hnd->type == MAROUND)     {      if (MessageHandlerData(theEnv)->NextInCore->hnd->type == MAROUND)        {         MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;         MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;#if DEBUGGING_FUNCTIONS         if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)

⌨️ 快捷键说明

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