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

📄 prccode.c

📁 clips源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
  int (*altvarfunc)(void *,EXPRESSION *,void *),  int (*altbindfunc)(void *,EXPRESSION *,void *),  int *lvarcnt,  void *userBuffer)  {   EXPRESSION *actions,*pactions;   /* ====================================================================      Clear parsed bind list - so that only local vars from this body will      be on it.  The position of vars on thsi list are used to generate      indices into the LocalVarArray at runtime.  The parsing of the      "bind" function adds vars to this list.      ==================================================================== */   ClearParsedBindNames(theEnv);   actions = GroupActions(theEnv,readSource,tkn,TRUE,NULL,FALSE);   if (actions == NULL)     return(NULL);   /* ====================================================================      Replace any bind functions with special functions before replacing      any variable references.  This allows those bind names to be removed      before they can be seen by variable replacement and thus generate      incorrect indices.      ==================================================================== */   if (altbindfunc != NULL)     {      if (ReplaceProcBinds(theEnv,actions,altbindfunc,userBuffer))        {         ClearParsedBindNames(theEnv);         ReturnExpression(theEnv,actions);         return(NULL);        }     }   /* ======================================================================      The number of names left on the bind list is the number of local      vars for this procedure body.  Replace all variable reference with      runtime access functions for ProcParamArray, LocalVarArray or      other special items, such as direct slot references, global variables,      or fact field references.      ====================================================================== */   *lvarcnt = CountParsedBindNames(theEnv);   if (ReplaceProcVars(theEnv,bodytype,actions,params,wildcard,altvarfunc,userBuffer))     {      ClearParsedBindNames(theEnv);      ReturnExpression(theEnv,actions);      return(NULL);     }   /* =======================================================================      Normally, actions are grouped in a progn.  If there is only one action,      the progn is unnecessary and can be removed.  Also, the actions are      packed into a contiguous array to save on memory overhead.  The      intermediate parsed bind names are freed to avoid tying up memory.      ======================================================================= */   actions = CompactActions(theEnv,actions);   pactions = PackExpression(theEnv,actions);   ReturnExpression(theEnv,actions);   ClearParsedBindNames(theEnv);   return(pactions);  }/*************************************************************************  NAME         : ReplaceProcVars  DESCRIPTION  : Examines an expression for variables                   and replaces any that correspond to                   procedure parameters or globals                   with function calls that get these                   variables' values at run-time.                   For example, procedure arguments                   are stored an array at run-time, so at                   parse-time, parameter-references are replaced                   with function calls referencing this array at                   the appropriate position.  INPUTS       : 1) The type of procedure being parsed                 2) The expression-actions to be examined                 3) The parameter list                 4) The wildcard parameter symbol (NULL if none)                 5) A pointer to a function to parse variables not                    recognized by the standard parser                    The function should accept the variable                    expression and a generic pointer for special                    data (can be NULL) as arguments.  If the variable                    is recognized, the function should modify the                    expression to access this variable.  Return 1                    if recognized, 0 if not, -1 on errors                    This argument can be NULL.                 6) Data buffer to be passed to alternate parsing                    function  RETURNS      : FALSE if OK, TRUE on errors  SIDE EFFECTS : Variable references replaced with function calls  NOTES        : This function works from the ParsedBindNames list in                    SPCLFORM.C to access local binds.  Make sure that                    the list accurately reflects the binds by calling                    ClearParsedBindNames(theEnv) before the parse of the body                    in which variables are being replaced. *************************************************************************/globle int ReplaceProcVars(  void *theEnv,  char *bodytype,  EXPRESSION *actions,  EXPRESSION *parameterList,  SYMBOL_HN *wildcard,  int (*altvarfunc)(void *,EXPRESSION *,void *),  void *specdata)  {   int position,altcode;   intBool boundPosn;   EXPRESSION *arg_lvl,*altvarexp;   SYMBOL_HN *bindName;   PACKED_PROC_VAR pvar;   while (actions != NULL)     {      if (actions->type == SF_VARIABLE)        {         /*===============================================*/         /* See if the variable is in the parameter list. */         /*===============================================*/         bindName = (SYMBOL_HN *) actions->value;         position = FindProcParameter(bindName,parameterList,wildcard);         /*=============================================================*/         /* Check to see if the variable is bound within the procedure. */         /*=============================================================*/         boundPosn = SearchParsedBindNames(theEnv,bindName);         /*=============================================*/         /* If variable is not defined in the parameter */         /* list or as part of a bind action then...    */         /*=============================================*/         if ((position == 0) && (boundPosn == 0))           {            /*================================================================*/            /* Check to see if the variable has a special access function,    */            /* such as direct slot reference or a rule RHS pattern reference. */            /*================================================================*/            if ((altvarfunc != NULL) ? ((*altvarfunc)(theEnv,actions,specdata) != 1) : TRUE)              {               PrintErrorID(theEnv,"PRCCODE",3,TRUE);               EnvPrintRouter(theEnv,WERROR,"Undefined variable ");               EnvPrintRouter(theEnv,WERROR,ValueToString(bindName));               EnvPrintRouter(theEnv,WERROR," referenced in ");               EnvPrintRouter(theEnv,WERROR,bodytype);               EnvPrintRouter(theEnv,WERROR,".\n");               return(TRUE);              }           }         /*===================================================*/         /* Else if variable is defined in the parameter list */         /* and not rebound within the procedure then...      */         /*===================================================*/         else if ((position > 0) && (boundPosn == 0))           {            actions->type = (unsigned short) ((bindName != wildcard) ? PROC_PARAM : PROC_WILD_PARAM);            actions->value = AddBitMap(theEnv,(void *) &position,(int) sizeof(int));           }         /*=========================================================*/         /* Else the variable is rebound within the procedure so... */         /*=========================================================*/         else           {            if (altvarfunc != NULL)              {               altvarexp = GenConstant(theEnv,actions->type,actions->value);               altcode = (*altvarfunc)(theEnv,altvarexp,specdata);               if (altcode == 0)                 {                  rtn_struct(theEnv,expr,altvarexp);                  altvarexp = NULL;                 }               else if (altcode == -1)                 {                  rtn_struct(theEnv,expr,altvarexp);                  return(TRUE);                 }              }            else              altvarexp = NULL;            actions->type = PROC_GET_BIND;            ClearBitString((void *) &pvar,(int) sizeof(PACKED_PROC_VAR));            pvar.first = boundPosn;            pvar.second = position;            pvar.secondFlag = (bindName != wildcard) ? 0 : 1;            actions->value = AddBitMap(theEnv,(void *) &pvar,(int) sizeof(PACKED_PROC_VAR));            actions->argList = GenConstant(theEnv,SYMBOL,(void *) bindName);            actions->argList->nextArg = altvarexp;           }        }#if DEFGLOBAL_CONSTRUCT      else if (actions->type == GBL_VARIABLE)        {         if (ReplaceGlobalVariable(theEnv,actions) == FALSE)           return(-1);        }#endif      if ((altvarfunc != NULL) ? ((*altvarfunc)(theEnv,actions,specdata) == -1) : FALSE)        return(TRUE);      if (actions->argList != NULL)        {         if (ReplaceProcVars(theEnv,bodytype,actions->argList,parameterList,                                        wildcard,altvarfunc,specdata))           return(TRUE);         /* ====================================================================            Check to see if this is a call to the bind function.  If so (and the            second argument is a symbol) then it is a locally bound variable            (as opposed to a global).            Replace the call to "bind" with a call to PROC_BIND - the            special internal function for procedure local variables.            ==================================================================== */         if ((actions->value == (void *) FindFunction(theEnv,"bind")) &&             (actions->argList->type == SYMBOL))           {            actions->type = PROC_BIND;            boundPosn = SearchParsedBindNames(theEnv,(SYMBOL_HN *) actions->argList->value);            actions->value = AddBitMap(theEnv,(void *) &boundPosn,(int) sizeof(intBool));            arg_lvl = actions->argList->nextArg;            rtn_struct(theEnv,expr,actions->argList);            actions->argList = arg_lvl;           }        }      actions = actions->nextArg;     }   return(FALSE);  }#if DEFGENERIC_CONSTRUCT/*****************************************************  NAME         : GenProcWildcardReference  DESCRIPTION  : Returns an expression to access the                    wildcard parameter for a method  INPUTS       : The starting index of the wildcard  RETURNS      : An expression containing the wildcard                 reference  SIDE EFFECTS : Expression allocated  NOTES        : None *****************************************************/globle EXPRESSION *GenProcWildcardReference(  void *theEnv,  int theIndex)  {   return(GenConstant(theEnv,PROC_WILD_PARAM,AddBitMap(theEnv,(void *) &theIndex,(int) sizeof(int))));  }#endif#endif/*******************************************************************  NAME         : PushProcParameters  DESCRIPTION  : Given a list of parameter expressions,                   this function evaluates each expression                   and stores the results in a contiguous                   array of DATA_OBJECTS.  Used in creating a new                   ProcParamArray for the execution of a                   procedure                 The current arrays are saved on a stack.  INPUTS       : 1) The paramter expression list                 2) The number of parameters in the list                 3) The name of the procedure for which                    these parameters are being evaluated                 4) The type of procedure                 5) A pointer to a function to print out a trace                    message about the currently executing                    procedure when unbound variables are detected                    at runtime (The function should take no                    arguments and have no return value.  The                    function should print its synopsis to WERROR                    and include the final carriage-return.)  RETURNS      : Nothing useful  SIDE EFFECTS : Any side-effects of the evaluation of the                   parameter expressions                 DATA_OBJECT array allocated (deallocated on errors)                 ProcParamArray set  NOTES        : EvaluationError set on errors *******************************************************************/globle void PushProcParameters(  void *theEnv,  EXPRESSION *parameterList,  int numberOfParameters,  char *pname,  char *bodytype,  void (*UnboundErrFunc)(void *))  {   register PROC_PARAM_STACK *ptmp;   ptmp = get_struct(theEnv,ProcParamStack);   ptmp->ParamArray = ProceduralPrimitiveData(theEnv)->ProcParamArray;   ptmp->ParamArraySize = ProceduralPrimitiveData(theEnv)->ProcParamArraySize;   ptmp->UnboundErrFunc = ProceduralPrimitiveData(theEnv)->ProcUnboundErrFunc;   ptmp->nxt = ProceduralPrimitiveData(theEnv)->pstack;   ProceduralPrimitiveData(theEnv)->pstack = ptmp;   EvaluateProcParameters(theEnv,parameterList,numberOfParameters,pname,bodytype);   if (EvaluationData(theEnv)->EvaluationError)     {      ptmp = ProceduralPrimitiveData(theEnv)->pstack;      ProceduralPrimitiveData(theEnv)->pstack = ProceduralPrimitiveData(theEnv)->pstack->nxt;      rtn_struct(theEnv,ProcParamStack,ptmp);      return;     }   /* ================================================================      Record ProcParamExpressions and WildcardValue for previous frame      AFTER evaluating arguments for the new frame, because they could      have gone from NULL to non-NULL (if they were already non-NULL,      they would remain unchanged.)      ================================================================ */#if DEFGENERIC_CONSTRUCT   ptmp->ParamExpressions = ProceduralPrimitiveData(theEnv)->ProcParamExpressions;   ProceduralPrimitiveData(theEnv)->ProcParamExpressions = NULL;#endif   ptmp->WildcardValue = ProceduralPrimitiveData(theEnv)->WildcardValue;   ProceduralPrimitiveData(theEnv)->WildcardValue = NULL;   ProceduralPrimitiveData(theEnv)->ProcUnboundErrFunc = UnboundErrFunc;  }/******************************************************************  NAME         : PopProcParameters  DESCRIPTION  : Restores old procedure arrays  INPUTS       : None  RETURNS      : Nothing useful  SIDE EFFECTS : Stack popped and globals restored  NOTES        : Assumes pstack != NULL ******************************************************************/globle void PopProcParameters(  void *theEnv)  {   register PROC_PARAM_STACK *ptmp;   if (ProceduralPrimitiveData(theEnv)->ProcParamArray != NULL)     rm(theEnv,(void *) ProceduralPrimitiveData(theEnv)->ProcParamArray,(sizeof(DATA_OBJECT) * ProceduralPrimitiveData(theEnv)->ProcParamArraySize));#if DEFGENERIC_CONSTRUCT   if (ProceduralPrimitiveData(theEnv)->ProcParamExpressions != NULL)     rm(theEnv,(void *) ProceduralPrimitiveData(theEnv)->ProcParamExpressions,(sizeof(EXPRESSION) * ProceduralPrimitiveData(theEnv)->ProcParamArraySize));#endif   ptmp = ProceduralPrimitiveData(theEnv)->pstack;   ProceduralPrimitiveData(theEnv)->pstack = ProceduralPrimitiveData(theEnv)->pstack->nxt;   ProceduralPrimitiveData(theEnv)->ProcParamArray = ptmp->ParamArray;   ProceduralPrimitiveData(theEnv)->ProcParamArraySize = ptmp->ParamArraySize;#if DEFGENERIC_CONSTRUCT   ProceduralPrimitiveData(theEnv)->ProcParamExpressions = ptmp->ParamExpressions;#endif   if (ProceduralPrimitiveData(theEnv)->WildcardValue != NULL)     {      MultifieldDeinstall(theEnv,(MULTIFIELD_PTR) ProceduralPrimitiveData(theEnv)->WildcardValue->value);      if (ProceduralPrimitiveData(theEnv)->WildcardValue->value != ProceduralPrimitiveData(theEnv)->NoParamValue)        AddToMultifieldList(theEnv,(MULTIFIELD_PTR) ProceduralPrimitiveData(theEnv)->WildcardValue->value);

⌨️ 快捷键说明

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