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

📄 msgpass.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 3 页
字号:
      return;     }   ins = GetActiveInstance();   sp = FindInstanceSlot(ins,(SYMBOL_HN *) temp.value);   if (sp == NULL)     {      SlotExistError(ValueToString(temp.value),"dynamic-put");      return;     }   if ((sp->desc->noWrite == 0) ? CLIPS_FALSE :       ((sp->desc->initializeOnly == 0) || (WithinInit == CLIPS_FALSE)))     {      SlotAccessViolationError(ValueToString(sp->desc->slotName->name),                               CLIPS_TRUE,(VOID *) ins);      SetEvaluationError(CLIPS_TRUE);      return;     }   if ((sp->desc->publicVisibility == 0) &&       (CurrentCore->hnd->cls != sp->desc->cls))     {      SlotVisibilityViolationError(sp->desc,CurrentCore->hnd->cls);      SetEvaluationError(CLIPS_TRUE);      return;     }   if (GetFirstArgument()->nextArg)     {      if (EvaluateAndStoreInDataObject((int) sp->desc->multiple,                        GetFirstArgument()->nextArg,&temp) == CLIPS_FALSE)        return;     }   else     {      SetpDOBegin(&temp,1);      SetpDOEnd(&temp,0);      SetpType(&temp,MULTIFIELD);      SetpValue(&temp,NoParamValue);     }   PutSlotValue(ins,sp,&temp,theResult,NULL);  }/* =========================================   *****************************************          INTERNALLY VISIBLE FUNCTIONS   =========================================   ***************************************** */   /*****************************************************  NAME         : PerformMessage  DESCRIPTION  : Calls core framework for a message  INPUTS       : 1) Caller's result buffer                 2) Message argument expressions                    (including implicit object)                 3) Message name  RETURNS      : Nothing useful  SIDE EFFECTS : Any side-effects of message execution                    and caller's result buffer set  NOTES        : None *****************************************************/static VOID PerformMessage(result,args,mname)  DATA_OBJECT *result;  EXPRESSION *args;  SYMBOL_HN *mname;  {   int oldce;   HANDLER_LINK *oldCore;   DEFCLASS *cls = NULL;   INSTANCE_TYPE *ins = NULL;   SYMBOL_HN *oldName;      result->type = SYMBOL;   result->value = CLIPSFalseSymbol;   EvaluationError = CLIPS_FALSE;   if (HaltExecution)     return;   oldce = ExecutingConstruct();   SetExecutingConstruct(CLIPS_TRUE);   oldName = CurrentMessageName;   CurrentMessageName = mname;   CurrentEvaluationDepth++;   PushProcParameters(args,CountArguments(args),                        ValueToString(CurrentMessageName),"message",                        UnboundHandlerErr);   if (EvaluationError)     {      CurrentEvaluationDepth--;      CurrentMessageName = oldName;      PeriodicCleanup(CLIPS_FALSE,CLIPS_TRUE);      SetExecutingConstruct(oldce);      return;     }   if (ProcParamArray->type == INSTANCE_ADDRESS)     {      ins = (INSTANCE_TYPE *) ProcParamArray->value;      if (ins->garbage == 1)        {         StaleInstanceAddress("send");         SetEvaluationError(CLIPS_TRUE);        }      else if (DefclassInScope(ins->cls,GetCurrentModule()) == CLIPS_FALSE)        NoInstanceError(ValueToString(ins->name),"send");      else        {         cls = ins->cls;         ins->busy++;        }     }   else if (ProcParamArray->type == INSTANCE_NAME)     {      ins = FindInstanceBySymbol((SYMBOL_HN *) ProcParamArray->value);      if (ins == NULL)        {         PrintErrorID("MSGPASS",2,CLIPS_FALSE);         PrintCLIPS(WERROR,"No such instance ");         PrintCLIPS(WERROR,ValueToString((SYMBOL_HN *) ProcParamArray->value));         PrintCLIPS(WERROR," in function send.\n");         SetEvaluationError(CLIPS_TRUE);        }      else        {         ProcParamArray->value = (VOID *) ins;         ProcParamArray->type = INSTANCE_ADDRESS;         cls = ins->cls;         ins->busy++;        }     }   else if ((cls = PrimitiveClassMap[ProcParamArray->type]) == NULL)     {      CLIPSSystemError("MSGPASS",1);      ExitCLIPS(2);     }   if (EvaluationError)     {      PopProcParameters();      CurrentEvaluationDepth--;      CurrentMessageName = oldName;      PeriodicCleanup(CLIPS_FALSE,CLIPS_TRUE);      SetExecutingConstruct(oldce);      return;     }   oldCore = TopOfCore;   TopOfCore = FindApplicableHandlers(cls,mname);   if (TopOfCore != NULL)     {      HANDLER_LINK *oldCurrent,*oldNext;      oldCurrent = CurrentCore;      oldNext = NextInCore;      #if IMPERATIVE_MESSAGE_HANDLERS      if (TopOfCore->hnd->type == MAROUND)        {         CurrentCore = TopOfCore;         NextInCore = TopOfCore->nxt;#if DEBUGGING_FUNCTIONS         if (WatchMessages)           WatchMessage(WTRACE,BEGIN_TRACE);         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);         if (WatchMessages)           WatchMessage(WTRACE,END_TRACE);#endif        }      else      #endif  /* IMPERATIVE_MESSAGE_HANDLERS */        {         CurrentCore = NULL;         NextInCore = TopOfCore;#if DEBUGGING_FUNCTIONS         if (WatchMessages)           WatchMessage(WTRACE,BEGIN_TRACE);#endif         CallHandlers(result);#if DEBUGGING_FUNCTIONS         if (WatchMessages)           WatchMessage(WTRACE,END_TRACE);#endif        }      DestroyHandlerLinks(TopOfCore);      CurrentCore = oldCurrent;      NextInCore = oldNext;     }   TopOfCore = oldCore;   ReturnFlag = CLIPS_FALSE;   if (ins != NULL)     ins->busy--;        /* ==================================      Restore the original calling frame      ================================== */   PopProcParameters();   CurrentEvaluationDepth--;   CurrentMessageName = oldName;   PropagateReturnValue(result);   PeriodicCleanup(CLIPS_FALSE,CLIPS_TRUE);   SetExecutingConstruct(oldce);   if (EvaluationError)     {      result->type = SYMBOL;      result->value = CLIPSFalseSymbol;     }  }/*****************************************************************************  NAME         : FindApplicableHandlers  DESCRIPTION  : Given a message name, this routine forms the "core frame"                   for the message : a list of all applicable class handlers.                   An applicable class handler is one whose name matches                     the message and whose class matches the instance.                                        The list is in the following order :                                      All around handlers (from most specific to most general)                   All before handlers (from most specific to most general)                   All primary handlers (from most specific to most general)                   All after handlers (from most general to most specific)                     INPUTS       : 1) The class of the instance (or primitive) for the message                 2) The message name  RETURNS      : NULL if no applicable handlers or errors,                   the list of handlers otherwise  SIDE EFFECTS : Links are allocated for the list  NOTES        : The instance is the first thing on the ProcParamArray                 The number of arguments is in ProcParamArraySize *****************************************************************************/static HANDLER_LINK *FindApplicableHandlers(cls,mname)  DEFCLASS *cls;  SYMBOL_HN *mname;  {   register int i;   HANDLER_LINK *tops[4],*bots[4];      for (i = MAROUND ; i <= MAFTER ; i++)     tops[i] = bots[i] = NULL;        for (i = 0 ; i < cls->allSuperclasses.classCount ; i++)     FindApplicableOfName(cls->allSuperclasses.classArray[i],tops,bots,mname);   return(JoinHandlerLinks(tops,bots,mname));  }  /***************************************************************  NAME         : CallHandlers  DESCRIPTION  : Moves though the current message frame                   for a send-message as follows :                 Call all before handlers and ignore their                   return values.                 Call the first primary handler and                   ignore the rest.  The return value                   of the handler frame is this message's value.                 Call all after handlers and ignore their                   return values.  INPUTS       : Caller's buffer for the return value of                   the message  RETURNS      : Nothing useful  SIDE EFFECTS : The handlers are evaluated.  NOTES        : IMPORTANT : The global NextInCore should be                 pointing to the first handler to be executed. ***************************************************************/static VOID CallHandlers(result)  DATA_OBJECT *result;  {   HANDLER_LINK *oldCurrent,*oldNext;#if AUXILIARY_MESSAGE_HANDLERS   DATA_OBJECT temp;#endif      if (HaltExecution)     return;     #if AUXILIARY_MESSAGE_HANDLERS   oldCurrent = CurrentCore;   oldNext = NextInCore;   while (NextInCore->hnd->type == MBEFORE)     {      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,                            &temp,UnboundHandlerErr);#if DEBUGGING_FUNCTIONS      if (CurrentCore->hnd->trace)        WatchHandler(WTRACE,CurrentCore,END_TRACE);#endif      ReturnFlag = CLIPS_FALSE;      if ((NextInCore == NULL) || HaltExecution)        {         NextInCore = oldNext;         CurrentCore = oldCurrent;         return;        }     }   if (NextInCore->hnd->type == MPRIMARY)     {#endif /* AUXILIARY_MESSAGE_HANDLERS */      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      ReturnFlag = CLIPS_FALSE;#if AUXILIARY_MESSAGE_HANDLERS      if ((NextInCore == NULL) || HaltExecution)        {         NextInCore = oldNext;         CurrentCore = oldCurrent;         return;        }      while (NextInCore->hnd->type == MPRIMARY)        {         NextInCore = NextInCore->nxt;         if (NextInCore == NULL)           {            NextInCore = oldNext;            CurrentCore = oldCurrent;            return;           }        }     }   while (NextInCore->hnd->type == MAFTER)     {      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,                            &temp,UnboundHandlerErr);#if DEBUGGING_FUNCTIONS      if (CurrentCore->hnd->trace)        WatchHandler(WTRACE,CurrentCore,END_TRACE);#endif      ReturnFlag = CLIPS_FALSE;      if ((NextInCore == NULL) || HaltExecution)        {         NextInCore = oldNext;         CurrentCore = oldCurrent;         return;        }     }#endif /*  AUXILIARY_MESSAGE_HANDLERS */   NextInCore = oldNext;   CurrentCore = oldCurrent;  }      /********************************************************  NAME         : EarlySlotBindError  DESCRIPTION  : Prints out an error message when                 a message-handler from a superclass                 which contains a static-bind                 slot access is not valid for the                 currently active instance (i.e.                 the instance is not using the                 superclass's slot)  INPUTS       : 1) The currently active instance                 2) The defclass holding the invalid slot                 3) The canonical id of the slot  RETURNS      : Nothing useful  SIDE EFFECTS : Error message printed  NOTES        : None ********************************************************/static VOID EarlySlotBindError(theInstance,theDefclass,slotID)  INSTANCE_TYPE *theInstance;  DEFCLASS *theDefclass;  unsigned slotID;  {   SLOT_DESC *sd;      sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[slotID] - 1];   PrintErrorID("MSGPASS",3,CLIPS_FALSE);   PrintCLIPS(WERROR,"Static reference to slot ");   PrintCLIPS(WERROR,ValueToString(sd->slotName->name));   PrintCLIPS(WERROR," of class ");   PrintClassName(WERROR,theDefclass,CLIPS_FALSE);   PrintCLIPS(WERROR," does not apply to ");   PrintInstanceNameAndClass(WERROR,theInstance,CLIPS_TRUE);  }  #endif/***************************************************  NAME         :   DESCRIPTION  :   INPUTS       :   RETURNS      :   SIDE EFFECTS :   NOTES        :  ***************************************************/

⌨️ 快捷键说明

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