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

📄 msgpsr.c

📁 NASA 开发使用的一个专家系统
💻 C
📖 第 1 页 / 共 2 页
字号:
  {   char *className,*slotName;   int bufsz;   char *buf,*handlerRouter = "*** Default Public Handlers ***";   int oldPWL,oldCM;      if ((sd->createReadAccessor == 0) && (sd->createWriteAccessor == 0))     return;   className = ValueToString(sd->cls->header.name);   slotName = ValueToString(sd->slotName->name);      bufsz = (int) (sizeof(char) * (strlen(className) + (strlen(slotName) * 2) + 80));   buf = (char *) gm2(bufsz);      oldPWL = GetPrintWhileLoading();   SetPrintWhileLoading(CLIPS_FALSE);   oldCM = SetConserveMemory(CLIPS_TRUE);      if (sd->createReadAccessor)     {      sprintf(buf,"%s get-%s () ?self:%s)",className,slotName,slotName);      if (OpenStringSource(handlerRouter,buf,0))        {         ParseDefmessageHandler(handlerRouter);         DestroyPPBuffer();         CloseStringSource(handlerRouter);        }     }        if (sd->createWriteAccessor)     {      sprintf(buf,"%s put-%s ($?value) (bind ?self:%s ?value))",                  className,slotName,slotName);      if (OpenStringSource(handlerRouter,buf,0))        {         ParseDefmessageHandler(handlerRouter);         DestroyPPBuffer();         CloseStringSource(handlerRouter);        }     }        SetPrintWhileLoading(oldPWL);   SetConserveMemory(oldCM);      rm((VOID *) buf,bufsz);  }  /* =========================================   *****************************************          INTERNALLY VISIBLE FUNCTIONS   =========================================   ***************************************** *//*****************************************************************  NAME         : IsParameterSlotReference  DESCRIPTION  : Determines if a message-handler parameter is of                 the form ?self:<name>, which is not allowed since                 this is slot reference syntax  INPUTS       : The paramter name  RETURNS      : CLIPS_TRUE if the parameter is a slot reference,                 CLIPS_FALSE otherwise  SIDE EFFECTS : None  NOTES        : None *****************************************************************/static BOOLEAN IsParameterSlotReference(pname)  char *pname;  {   if ((strncmp(pname,SELF_STRING,SELF_LEN) == 0) ?                  (pname[SELF_LEN] == SELF_SLOT_REF) : CLIPS_FALSE)     {      PrintErrorID("MSGPSR",4,CLIPS_FALSE);      PrintCLIPS(WERROR,"Illegal slot reference in parameter list.\n");      return(CLIPS_TRUE);     }   return(CLIPS_FALSE);  }  /****************************************************************************  NAME         : SlotReferenceVar  DESCRIPTION  : Replaces direct slot references in handler body                   with special function calls to reference active instance                   at run-time                 The slot in in the class bound at parse-time is always                   referenced (early binding).                 Slot references of the form ?self:<name> directly reference                   ProcParamArray[0] (the message object - ?self) to                   find the specified slot at run-time  INPUTS       : 1) Variable expression                 2) The class of the handler being parsed  RETURNS      : 0 if not recognized, 1 if so, -1 on errors  SIDE EFFECTS : Handler body SF_VARIABLE and MF_VARIABLE replaced with                    direct slot access function  NOTES        : Objects are allowed to directly access their own slots                 without sending a message to themselves.  Since the object                 is "within the boundary of its internals", this does not                 violate the encapsulation principle of OOP. ****************************************************************************/static int SlotReferenceVar(varexp,userBuffer)  EXPRESSION *varexp;  VOID *userBuffer;  {   struct token itkn;   int oldpp;   SLOT_DESC *sd;     if ((varexp->type != SF_VARIABLE) && (varexp->type != MF_VARIABLE))     return(0);   if ((strncmp(ValueToString(varexp->value),SELF_STRING,SELF_LEN) == 0) ?               (ValueToString(varexp->value)[SELF_LEN] == SELF_SLOT_REF) : CLIPS_FALSE)     {      OpenStringSource("hnd-var",ValueToString(varexp->value) + SELF_LEN + 1,0);      oldpp = GetPPBufferStatus();      SetPPBufferStatus(OFF);      GetToken("hnd-var",&itkn);      SetPPBufferStatus(oldpp);      CloseStringSource("hnd-var");      if (itkn.type != STOP)        {         sd = CheckSlotReference((DEFCLASS *) userBuffer,itkn.type,itkn.value,                                 CLIPS_FALSE,NULL);         if (sd == NULL)           return(-1);         GenHandlerSlotReference(varexp,HANDLER_GET,sd);         return(1);        }     }   return(0);  }  /****************************************************************************  NAME         : BindSlotReference  DESCRIPTION  : Replaces direct slot binds in handler body with special                 function calls to reference active instance at run-time                 The slot in in the class bound at parse-time is always                 referenced (early binding).                 Slot references of the form ?self:<name> directly reference                   ProcParamArray[0] (the message object - ?self) to                   find the specified slot at run-time  INPUTS       : 1) Variable expression                 2) The class for the message-handler being parsed  RETURNS      : 0 if not recognized, 1 if so, -1 on errors  SIDE EFFECTS : Handler body "bind" call replaced with  direct slot access                   function  NOTES        : Objects are allowed to directly access their own slots                 without sending a message to themselves.  Since the object                 is "within the boundary of its internals", this does not                 violate the encapsulation principle of OOP. ****************************************************************************/static int BindSlotReference(bindExp,userBuffer)  EXPRESSION *bindExp;  VOID *userBuffer;  {   char *bindName;   struct token itkn;   int oldpp;   SLOT_DESC *sd;   EXPRESSION *saveExp;      bindName = ValueToString(bindExp->argList->value);   if (strcmp(bindName,SELF_STRING) == 0)     {      PrintErrorID("MSGPSR",5,CLIPS_FALSE);      PrintCLIPS(WERROR,"Active instance parameter cannot be changed.\n");      return(-1);     }   if ((strncmp(bindName,SELF_STRING,SELF_LEN) == 0) ?               (bindName[SELF_LEN] == SELF_SLOT_REF) : CLIPS_FALSE)     {      OpenStringSource("hnd-var",bindName + SELF_LEN + 1,0);      oldpp = GetPPBufferStatus();      SetPPBufferStatus(OFF);      GetToken("hnd-var",&itkn);      SetPPBufferStatus(oldpp);      CloseStringSource("hnd-var");      if (itkn.type != STOP)        {         saveExp = bindExp->argList->nextArg;         sd = CheckSlotReference((DEFCLASS *) userBuffer,itkn.type,itkn.value,                                 CLIPS_TRUE,saveExp);         if (sd == NULL)           return(-1);         GenHandlerSlotReference(bindExp,HANDLER_PUT,sd);         bindExp->argList->nextArg = NULL;         ReturnExpression(bindExp->argList);         bindExp->argList = saveExp;         return(1);        }     }   return(0);  }/*********************************************************  NAME         : CheckSlotReference  DESCRIPTION  : Examines a ?self:<slot-name> reference                 If the reference is a single-field or                 global variable, checking and evaluation                 is delayed until run-time.  If the                 reference is a symbol, this routine                 verifies that the slot is a legal                 slot for the reference (i.e., it exists                 in the class to which the message-handler                 is being attached, it is visible and it                 is writable for write reference)  INPUTS       : 1) A buffer holding the class                    of the handler being parsed                 2) The type of the slot reference                 3) The value of the slot reference                 4) A flag indicating if this is a read                    or write access                 5) Value expression for write  RETURNS      : Class slot on success, NULL on errors  SIDE EFFECTS : Messages printed on errors.  NOTES        : For static references, this function                 insures that the slot is either                 publicly visible or that the handler                 is being attached to the same class in                 which the private slot is defined. *********************************************************/static SLOT_DESC *CheckSlotReference(theDefclass,theType,theValue,                                     writeFlag,writeExpression)  DEFCLASS *theDefclass;  int theType;  VOID *theValue;  BOOLEAN writeFlag;  EXPRESSION *writeExpression;  {   int slotIndex;   SLOT_DESC *sd;   int vCode;      if (theType != SYMBOL)     {      PrintErrorID("MSGPSR",7,CLIPS_FALSE);      PrintCLIPS(WERROR,"Illegal value for ?self reference.\n");      return(NULL);     }   slotIndex = FindInstanceTemplateSlot(theDefclass,(SYMBOL_HN *) theValue);   if (slotIndex == -1)     {      PrintErrorID("MSGPSR",6,CLIPS_FALSE);      PrintCLIPS(WERROR,"No such slot ");      PrintCLIPS(WERROR,ValueToString(theValue));      PrintCLIPS(WERROR," in class ");      PrintCLIPS(WERROR,GetDefclassName((VOID *) theDefclass));      PrintCLIPS(WERROR," for ?self reference.\n");      return(NULL);     }   sd = theDefclass->instanceTemplate[slotIndex];   if ((sd->publicVisibility == 0) && (sd->cls != theDefclass))     {      SlotVisibilityViolationError(sd,theDefclass);      return(NULL);     }   if (! writeFlag)     return(sd);        /* =================================================      If a slot is initialize-only, the WithinInit flag      still needs to be checked at run-time, for the      handler could be called out of the context of      an init.      ================================================= */   if (sd->noWrite && (sd->initializeOnly == 0))     {      SlotAccessViolationError(ValueToString(theValue),                               CLIPS_FALSE,(VOID *) theDefclass);      return(NULL);     }   if (GetStaticConstraintChecking())     {      vCode = ConstraintCheckExpressionChain(writeExpression,sd->constraint);      if (vCode != NO_VIOLATION)        {         PrintErrorID("CSTRNCHK",1,CLIPS_FALSE);         PrintCLIPS(WERROR,"Expression for ");         PrintSlot(WERROR,sd,NULL,"direct slot write");         ConstraintViolationErrorMessage(NULL,NULL,0,0,NULL,0,                                         vCode,sd->constraint,CLIPS_FALSE);         return(NULL);        }     }   return(sd);  }    /***************************************************  NAME         : GenHandlerSlotReference  DESCRIPTION  : Creates a bitmap of the class id                 and slot index for the get or put                 operation. The bitmap and operation                 type are stored in the given                 expression.  INPUTS       : 1) The expression                 2) The operation type                 3) The class slot  RETURNS      : Nothing useful  SIDE EFFECTS : Bitmap created and expression                 initialized  NOTES        : None ***************************************************/static VOID GenHandlerSlotReference(exp,theType,sd)  EXPRESSION *exp;  int theType;  SLOT_DESC *sd;  {   HANDLER_SLOT_REFERENCE handlerReference;      ClearBitString(&handlerReference,sizeof(HANDLER_SLOT_REFERENCE));   handlerReference.classID = (unsigned short) sd->cls->id;   handlerReference.slotID = (unsigned) sd->slotName->id;   exp->type = (short) theType;   exp->value =  AddBitMap((VOID *) &handlerReference,                           (int) sizeof(HANDLER_SLOT_REFERENCE));  }  #endif/***************************************************  NAME         :   DESCRIPTION  :   INPUTS       :   RETURNS      :   SIDE EFFECTS :   NOTES        :  ***************************************************/

⌨️ 快捷键说明

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