#include "setup.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "memalloc.h"
#include "constant.h"
#include "envrnmnt.h"
#if DEFGLOBAL_CONSTRUCT
#include "globlpsr.h"
#endif
#include "exprnpsr.h"
#include "multifld.h"
#if OBJECT_SYSTEM
#include "object.h"
#endif
#include "pprint.h"
#include "prcdrpsr.h"
#include "prntutil.h"
#include "router.h"
#include "utility.h"
#include "prccode.h"
typedef struct
{
unsigned firstFlag : 1;
unsigned first : 15;
unsigned secondFlag : 1;
unsigned second : 15;
} PACKED_PROC_VAR;
static void EvaluateProcParameters(Environment *,Expression *,unsigned int,const char *,const char *);
static bool RtnProcParam(Environment *,void *,UDFValue *);
static bool GetProcBind(Environment *,void *,UDFValue *);
static bool PutProcBind(Environment *,void *,UDFValue *);
static bool RtnProcWild(Environment *,void *,UDFValue *);
static void DeallocateProceduralPrimitiveData(Environment *);
static void ReleaseProcParameters(Environment *);
#if (! BLOAD_ONLY) && (! RUN_TIME)
static unsigned int FindProcParameter(CLIPSLexeme *,Expression *,CLIPSLexeme *);
static bool ReplaceProcBinds(Environment *,Expression *,
int (*)(Environment *,Expression *,void *),void *);
static Expression *CompactActions(Environment *,Expression *);
#endif
#if (! DEFFUNCTION_CONSTRUCT) || (! DEFGENERIC_CONSTRUCT)
static bool EvaluateBadCall(Environment *,void *,UDFValue *);
#endif
void InstallProcedurePrimitives(
Environment *theEnv)
{
EntityRecord procParameterInfo = { "PROC_PARAM", PROC_PARAM,0,1,0,NULL,NULL,NULL,
(EntityEvaluationFunction *) RtnProcParam,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL },
procWildInfo = { "PROC_WILD_PARAM", PROC_WILD_PARAM,0,1,0,NULL,NULL,NULL,
(EntityEvaluationFunction *) RtnProcWild,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL },
procGetInfo = { "PROC_GET_BIND", PROC_GET_BIND,0,1,0,NULL,NULL,NULL,
(EntityEvaluationFunction *) GetProcBind,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL },
procBindInfo = { "PROC_BIND", PROC_BIND,0,1,0,NULL,NULL,NULL,
(EntityEvaluationFunction *) PutProcBind,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
#if ! DEFFUNCTION_CONSTRUCT
EntityRecord deffunctionEntityRecord =
{ "PCALL", PCALL,0,0,1,
NULL,NULL,NULL,
EvaluateBadCall,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
#endif
#if ! DEFGENERIC_CONSTRUCT
EntityRecord genericEntityRecord =
{ "GCALL", GCALL,0,0,1,
NULL,NULL,NULL,
EvaluateBadCall,
NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
#endif
AllocateEnvironmentData(theEnv,PROCEDURAL_PRIMITIVE_DATA,sizeof(struct proceduralPrimitiveData),DeallocateProceduralPrimitiveData);
memcpy(&ProceduralPrimitiveData(theEnv)->ProcParameterInfo,&procParameterInfo,sizeof(struct entityRecord));
memcpy(&ProceduralPrimitiveData(theEnv)->ProcWildInfo,&procWildInfo,sizeof(struct entityRecord));
memcpy(&ProceduralPrimitiveData(theEnv)->ProcGetInfo,&procGetInfo,sizeof(struct entityRecord));
memcpy(&ProceduralPrimitiveData(theEnv)->ProcBindInfo,&procBindInfo,sizeof(struct entityRecord));
InstallPrimitive(theEnv,&ProceduralPrimitiveData(theEnv)->ProcParameterInfo,PROC_PARAM);
InstallPrimitive(theEnv,&ProceduralPrimitiveData(theEnv)->ProcWildInfo,PROC_WILD_PARAM);
InstallPrimitive(theEnv,&ProceduralPrimitiveData(theEnv)->ProcGetInfo,PROC_GET_BIND);
InstallPrimitive(theEnv,&ProceduralPrimitiveData(theEnv)->ProcBindInfo,PROC_BIND);
ProceduralPrimitiveData(theEnv)->Oldindex = UINT_MAX;
#if ! DEFFUNCTION_CONSTRUCT
memcpy(&ProceduralPrimitiveData(theEnv)->DeffunctionEntityRecord,&deffunctionEntityRecord,sizeof(struct entityRecord));
InstallPrimitive(theEnv,&ProceduralPrimitiveData(theEnv)->DeffunctionEntityRecord,PCALL);
#endif
#if ! DEFGENERIC_CONSTRUCT
memcpy(&ProceduralPrimitiveData(theEnv)->GenericEntityRecord,&genericEntityRecord,sizeof(struct entityRecord));
InstallPrimitive(theEnv,&ProceduralPrimitiveData(theEnv)->GenericEntityRecord,GCALL);
#endif
ProceduralPrimitiveData(theEnv)->NoParamValue = CreateUnmanagedMultifield(theEnv,0L);
RetainMultifield(theEnv,ProceduralPrimitiveData(theEnv)->NoParamValue);
}
static void DeallocateProceduralPrimitiveData(
Environment *theEnv)
{
ReturnMultifield(theEnv,ProceduralPrimitiveData(theEnv)->NoParamValue);
ReleaseProcParameters(theEnv);
}
#if (! BLOAD_ONLY) && (! RUN_TIME)
#if DEFFUNCTION_CONSTRUCT || OBJECT_SYSTEM
Expression *ParseProcParameters(
Environment *theEnv,
const char *readSource,
struct token *tkn,
Expression *parameterList,
CLIPSLexeme **wildcard,
unsigned short *min,
unsigned short *max,
bool *error,
bool (*checkfunc)(Environment *,const char *))
{
Expression *nextOne,*lastOne,*check;
int paramprintp = 0;
*wildcard = NULL;
*min = 0;
*error = true;
lastOne = nextOne = parameterList;
while (nextOne != NULL)
{
(*min)++;
lastOne = nextOne;
nextOne = nextOne->nextArg;
}
if (tkn->tknType != LEFT_PARENTHESIS_TOKEN)
{
SyntaxErrorMessage(theEnv,"parameter list");
ReturnExpression(theEnv,parameterList);
return NULL;
}
GetToken(theEnv,readSource,tkn);
while ((tkn->tknType == SF_VARIABLE_TOKEN) || (tkn->tknType == MF_VARIABLE_TOKEN))
{
for (check = parameterList ; check != NULL ; check = check->nextArg)
if (check->value == tkn->value)
{
PrintErrorID(theEnv,"PRCCODE",7,false);
WriteString(theEnv,STDERR,"Duplicate parameter names not allowed.\n");
ReturnExpression(theEnv,parameterList);
return NULL;
}
if (*wildcard != NULL)
{
PrintErrorID(theEnv,"PRCCODE",8,false);
WriteString(theEnv,STDERR,"No parameters allowed after wildcard parameter.\n");
ReturnExpression(theEnv,parameterList);
return NULL;
}
if ((checkfunc != NULL) ? (*checkfunc)(theEnv,tkn->lexemeValue->contents) : false)
{
ReturnExpression(theEnv,parameterList);
return NULL;
}
nextOne = GenConstant(theEnv,TokenTypeToType(tkn->tknType),tkn->value);
if (tkn->tknType == MF_VARIABLE_TOKEN)
*wildcard = tkn->lexemeValue;
else
(*min)++;
if (lastOne == NULL)
{ parameterList = nextOne; }
else
{ lastOne->nextArg = nextOne; }
lastOne = nextOne;
SavePPBuffer(theEnv," ");
paramprintp = 1;
GetToken(theEnv,readSource,tkn);
}
if (tkn->tknType != RIGHT_PARENTHESIS_TOKEN)
{
SyntaxErrorMessage(theEnv,"parameter list");
ReturnExpression(theEnv,parameterList);
return NULL;
}
if (paramprintp)
{
PPBackup(theEnv);
PPBackup(theEnv);
SavePPBuffer(theEnv,")");
}
*error = false;
*max = (*wildcard != NULL) ? PARAMETERS_UNBOUNDED : *min;
return(parameterList);
}
#endif
Expression *ParseProcActions(
Environment *theEnv,
const char *bodytype,
const char *readSource,
struct token *tkn,
Expression *params,
CLIPSLexeme *wildcard,
int (*altvarfunc)(Environment *,Expression *,void *),
int (*altbindfunc)(Environment *,Expression *,void *),
unsigned short *lvarcnt,
void *userBuffer)
{
Expression *actions,*pactions;
ClearParsedBindNames(theEnv);
actions = GroupActions(theEnv,readSource,tkn,true,NULL,false);
if (actions == NULL)
return NULL;
if (altbindfunc != NULL)
{
if (ReplaceProcBinds(theEnv,actions,altbindfunc,userBuffer))
{
ClearParsedBindNames(theEnv);
ReturnExpression(theEnv,actions);
return NULL;
}
}
*lvarcnt = CountParsedBindNames(theEnv);
if (ReplaceProcVars(theEnv,bodytype,actions,params,wildcard,altvarfunc,userBuffer))
{
ClearParsedBindNames(theEnv);
ReturnExpression(theEnv,actions);
return NULL;
}
actions = CompactActions(theEnv,actions);
pactions = PackExpression(theEnv,actions);
ReturnExpression(theEnv,actions);
ClearParsedBindNames(theEnv);
return(pactions);
}
int ReplaceProcVars(
Environment *theEnv,
const char *bodytype,
Expression *actions,
Expression *parameterList,
CLIPSLexeme *wildcard,
int (*altvarfunc)(Environment *,Expression *,void *),
void *specdata)
{
int altcode;
unsigned position, boundPosn;
Expression *arg_lvl,*altvarexp;
CLIPSLexeme *bindName;
PACKED_PROC_VAR pvar;
int errorCode;
while (actions != NULL)
{
if (actions->type == SF_VARIABLE)
{
bindName = actions->lexemeValue;
position = FindProcParameter(bindName,parameterList,wildcard);
boundPosn = SearchParsedBindNames(theEnv,bindName);
if ((position == 0) && (boundPosn == 0))
{
if (altvarfunc == NULL)
{ errorCode = 0; }
else
{ errorCode = (*altvarfunc)(theEnv,actions,specdata); }
if (errorCode != 1)
{
if (errorCode == 0)
{
PrintErrorID(theEnv,"PRCCODE",3,true);
WriteString(theEnv,STDERR,"Undefined variable ?");
WriteString(theEnv,STDERR,bindName->contents);
WriteString(theEnv,STDERR," referenced in ");
WriteString(theEnv,STDERR,bodytype);
WriteString(theEnv,STDERR,".\n");
}
return 1;
}
}
else if ((position > 0) && (boundPosn == 0))
{
actions->type = ((bindName != wildcard) ? PROC_PARAM : PROC_WILD_PARAM);
actions->value = AddBitMap(theEnv,&position,sizeof(int));
}
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(&pvar,sizeof(PACKED_PROC_VAR));
pvar.first = boundPosn;
pvar.second = position;
pvar.secondFlag = (bindName != wildcard) ? 0 : 1;
actions->value = AddBitMap(theEnv,&pvar,sizeof(PACKED_PROC_VAR));
actions->argList = GenConstant(theEnv,SYMBOL_TYPE,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 1;
if (actions->argList != NULL)
{
if (ReplaceProcVars(theEnv,bodytype,actions->argList,parameterList,
wildcard,altvarfunc,specdata))
return 1;
if ((actions->value == (void *) FindFunction(theEnv,"bind")) &&
(actions->argList->type == SYMBOL_TYPE))
{
actions->type = PROC_BIND;
boundPosn = SearchParsedBindNames(theEnv,actions->argList->lexemeValue);
actions->value = AddBitMap(theEnv,&boundPosn,sizeof(int));
arg_lvl = actions->argList->nextArg;
rtn_struct(theEnv,expr,actions->argList);
actions->argList = arg_lvl;
}
}
actions = actions->nextArg;
}
return 0;
}
#if DEFGENERIC_CONSTRUCT
Expression *GenProcWildcardReference(
Environment *theEnv,
int theIndex)
{
return(GenConstant(theEnv,PROC_WILD_PARAM,AddBitMap(theEnv,&theIndex,sizeof(int))));
}
#endif
#endif
void PushProcParameters(
Environment *theEnv,
Expression *parameterList,
unsigned int numberOfParameters,
const char *pname,
const char *bodytype,
void (*UnboundErrFunc)(Environment *,const char *))
{
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;
}
#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;
}
void PopProcParameters(
Environment *theEnv)
{
PROC_PARAM_STACK *ptmp;
if (ProceduralPrimitiveData(theEnv)->ProcParamArray != NULL)
rm(theEnv,ProceduralPrimitiveData(theEnv)->ProcParamArray,(sizeof(UDFValue) * ProceduralPrimitiveData(theEnv)->ProcParamArraySize));
#if DEFGENERIC_CONSTRUCT
if (ProceduralPrimitiveData(theEnv)->ProcParamExpressions != NULL)
rm(theEnv,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)
{
ReleaseMultifield(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
if (ProceduralPrimitiveData(theEnv)->WildcardValue->value != ProceduralPrimitiveData(theEnv)->NoParamValue)
AddToMultifieldList(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
rtn_struct(theEnv,udfValue,ProceduralPrimitiveData(theEnv)->WildcardValue);
}
ProceduralPrimitiveData(theEnv)->WildcardValue = ptmp->WildcardValue;
ProceduralPrimitiveData(theEnv)->ProcUnboundErrFunc = ptmp->UnboundErrFunc;
rtn_struct(theEnv,ProcParamStack,ptmp);
}
static void ReleaseProcParameters(
Environment *theEnv)
{
PROC_PARAM_STACK *ptmp, *next;
if (ProceduralPrimitiveData(theEnv)->ProcParamArray != NULL)
rm(theEnv,ProceduralPrimitiveData(theEnv)->ProcParamArray,(sizeof(UDFValue) * ProceduralPrimitiveData(theEnv)->ProcParamArraySize));
if (ProceduralPrimitiveData(theEnv)->WildcardValue != NULL)
{
if (ProceduralPrimitiveData(theEnv)->WildcardValue->value != ProceduralPrimitiveData(theEnv)->NoParamValue)
{ ReturnMultifield(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue); }
rtn_struct(theEnv,udfValue,ProceduralPrimitiveData(theEnv)->WildcardValue);
}
#if DEFGENERIC_CONSTRUCT
if (ProceduralPrimitiveData(theEnv)->ProcParamExpressions != NULL)
rm(theEnv,ProceduralPrimitiveData(theEnv)->ProcParamExpressions,(sizeof(Expression) * ProceduralPrimitiveData(theEnv)->ProcParamArraySize));
#endif
ptmp = ProceduralPrimitiveData(theEnv)->pstack;
while (ptmp != NULL)
{
next = ptmp->nxt;
if (ptmp->ParamArray != NULL)
{ rm(theEnv,ptmp->ParamArray,(sizeof(UDFValue) * ptmp->ParamArraySize)); }
#if DEFGENERIC_CONSTRUCT
if (ptmp->ParamExpressions != NULL)
{ rm(theEnv,ptmp->ParamExpressions,(sizeof(Expression) * ptmp->ParamArraySize)); }
#endif
if (ptmp->WildcardValue != NULL)
{
if (ptmp->WildcardValue->value != ProceduralPrimitiveData(theEnv)->NoParamValue)
{ ReturnMultifield(theEnv,ptmp->WildcardValue->multifieldValue); }
rtn_struct(theEnv,udfValue,ptmp->WildcardValue);
}
rtn_struct(theEnv,ProcParamStack,ptmp);
ptmp = next;
}
}
#if DEFGENERIC_CONSTRUCT
Expression *GetProcParamExpressions(
Environment *theEnv)
{
unsigned int i;
if ((ProceduralPrimitiveData(theEnv)->ProcParamArray == NULL) || (ProceduralPrimitiveData(theEnv)->ProcParamExpressions != NULL))
return(ProceduralPrimitiveData(theEnv)->ProcParamExpressions);
ProceduralPrimitiveData(theEnv)->ProcParamExpressions = (Expression *)
gm2(theEnv,(sizeof(Expression) * ProceduralPrimitiveData(theEnv)->ProcParamArraySize));
for (i = 0 ; i < ProceduralPrimitiveData(theEnv)->ProcParamArraySize ; i++)
{
ProceduralPrimitiveData(theEnv)->ProcParamExpressions[i].type = ProceduralPrimitiveData(theEnv)->ProcParamArray[i].header->type; if (ProceduralPrimitiveData(theEnv)->ProcParamArray[i].header->type != MULTIFIELD_TYPE)
ProceduralPrimitiveData(theEnv)->ProcParamExpressions[i].value = ProceduralPrimitiveData(theEnv)->ProcParamArray[i].value;
else
ProceduralPrimitiveData(theEnv)->ProcParamExpressions[i].value = &ProceduralPrimitiveData(theEnv)->ProcParamArray[i];
ProceduralPrimitiveData(theEnv)->ProcParamExpressions[i].argList = NULL;
ProceduralPrimitiveData(theEnv)->ProcParamExpressions[i].nextArg =
((i + 1) != ProceduralPrimitiveData(theEnv)->ProcParamArraySize) ? &ProceduralPrimitiveData(theEnv)->ProcParamExpressions[i+1] : NULL;
}
return(ProceduralPrimitiveData(theEnv)->ProcParamExpressions);
}
#endif
void EvaluateProcActions(
Environment *theEnv,
Defmodule *theModule,
Expression *actions,
unsigned short lvarcnt,
UDFValue *returnValue,
void (*crtproc)(Environment *,const char *))
{
UDFValue *oldLocalVarArray;
unsigned short i;
Defmodule *oldModule;
Expression *oldActions;
struct trackedMemory *theTM;
oldLocalVarArray = ProceduralPrimitiveData(theEnv)->LocalVarArray;
ProceduralPrimitiveData(theEnv)->LocalVarArray = (lvarcnt == 0) ? NULL :
(UDFValue *) gm2(theEnv,(sizeof(UDFValue) * lvarcnt));
if (lvarcnt != 0)
{ theTM = AddTrackedMemory(theEnv,ProceduralPrimitiveData(theEnv)->LocalVarArray,sizeof(UDFValue) * lvarcnt); }
else
{ theTM = NULL; }
for (i = 0 ; i < lvarcnt ; i++)
ProceduralPrimitiveData(theEnv)->LocalVarArray[i].supplementalInfo = FalseSymbol(theEnv);
oldModule = GetCurrentModule(theEnv);
if (oldModule != theModule)
SetCurrentModule(theEnv,theModule);
oldActions = ProceduralPrimitiveData(theEnv)->CurrentProcActions;
ProceduralPrimitiveData(theEnv)->CurrentProcActions = actions;
if (EvaluateExpression(theEnv,actions,returnValue))
{
returnValue->value = FalseSymbol(theEnv);
}
ProceduralPrimitiveData(theEnv)->CurrentProcActions = oldActions;
if (oldModule != GetCurrentModule(theEnv))
SetCurrentModule(theEnv,oldModule);
if ((crtproc != NULL) ? EvaluationData(theEnv)->HaltExecution : false)
{
const char *logName;
if (GetEvaluationError(theEnv))
{
PrintErrorID(theEnv,"PRCCODE",4,false);
logName = STDERR;
}
else
{
PrintWarningID(theEnv,"PRCCODE",4,false);
logName = STDWRN;
}
WriteString(theEnv,logName,"Execution halted during the actions of ");
(*crtproc)(theEnv,logName);
}
if ((ProceduralPrimitiveData(theEnv)->WildcardValue != NULL) ? (returnValue->value == ProceduralPrimitiveData(theEnv)->WildcardValue->value) : false)
{
ReleaseMultifield(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
if (ProceduralPrimitiveData(theEnv)->WildcardValue->value != ProceduralPrimitiveData(theEnv)->NoParamValue)
AddToMultifieldList(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
rtn_struct(theEnv,udfValue,ProceduralPrimitiveData(theEnv)->WildcardValue);
ProceduralPrimitiveData(theEnv)->WildcardValue = NULL;
}
if (lvarcnt != 0)
{
RemoveTrackedMemory(theEnv,theTM);
for (i = 0 ; i < lvarcnt ; i++)
if (ProceduralPrimitiveData(theEnv)->LocalVarArray[i].supplementalInfo == TrueSymbol(theEnv))
ReleaseUDFV(theEnv,&ProceduralPrimitiveData(theEnv)->LocalVarArray[i]);
rm(theEnv,ProceduralPrimitiveData(theEnv)->LocalVarArray,(sizeof(UDFValue) * lvarcnt));
}
ProceduralPrimitiveData(theEnv)->LocalVarArray = oldLocalVarArray;
}
void PrintProcParamArray(
Environment *theEnv,
const char *logName)
{
unsigned int i;
WriteString(theEnv,logName," (");
for (i = 0 ; i < ProceduralPrimitiveData(theEnv)->ProcParamArraySize ; i++)
{
WriteUDFValue(theEnv,logName,&ProceduralPrimitiveData(theEnv)->ProcParamArray[i]);
if (i != ProceduralPrimitiveData(theEnv)->ProcParamArraySize-1)
WriteString(theEnv,logName," ");
}
WriteString(theEnv,logName,")\n");
}
void GrabProcWildargs(
Environment *theEnv,
UDFValue *returnValue,
unsigned int theIndex)
{
unsigned int i, j;
size_t k;
size_t size;
UDFValue *val;
returnValue->begin = 0;
if (ProceduralPrimitiveData(theEnv)->WildcardValue == NULL)
{
ProceduralPrimitiveData(theEnv)->WildcardValue = get_struct(theEnv,udfValue);
ProceduralPrimitiveData(theEnv)->WildcardValue->begin = 0;
}
else if (theIndex == ProceduralPrimitiveData(theEnv)->Oldindex)
{
returnValue->range = ProceduralPrimitiveData(theEnv)->WildcardValue->range;
returnValue->value = ProceduralPrimitiveData(theEnv)->WildcardValue->value;
return;
}
else
{
ReleaseMultifield(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
if (ProceduralPrimitiveData(theEnv)->WildcardValue->value != ProceduralPrimitiveData(theEnv)->NoParamValue)
AddToMultifieldList(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
}
ProceduralPrimitiveData(theEnv)->Oldindex = theIndex;
size = ProceduralPrimitiveData(theEnv)->ProcParamArraySize + 1 - theIndex;
if (size == 0)
{
returnValue->range = 0;
ProceduralPrimitiveData(theEnv)->WildcardValue->range = 0;
returnValue->value = ProceduralPrimitiveData(theEnv)->WildcardValue->value = ProceduralPrimitiveData(theEnv)->NoParamValue;
RetainMultifield(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
return;
}
for (i = theIndex-1 ; i < ProceduralPrimitiveData(theEnv)->ProcParamArraySize ; i++)
{
if (ProceduralPrimitiveData(theEnv)->ProcParamArray[i].header->type == MULTIFIELD_TYPE)
size += ProceduralPrimitiveData(theEnv)->ProcParamArray[i].range - 1;
}
returnValue->range = size;
ProceduralPrimitiveData(theEnv)->WildcardValue->range = size;
returnValue->value = ProceduralPrimitiveData(theEnv)->WildcardValue->value = CreateUnmanagedMultifield(theEnv,size);
for (i = theIndex-1 , j = 0 ; i < ProceduralPrimitiveData(theEnv)->ProcParamArraySize ; i++)
{
if (ProceduralPrimitiveData(theEnv)->ProcParamArray[i].header->type != MULTIFIELD_TYPE)
{
returnValue->multifieldValue->contents[j].value = ProceduralPrimitiveData(theEnv)->ProcParamArray[i].value;
j++;
}
else
{
val = &ProceduralPrimitiveData(theEnv)->ProcParamArray[i];
for (k = val->begin ; k < (val->begin + val->range) ; k++ , j++)
{
returnValue->multifieldValue->contents[j].value = val->multifieldValue->contents[k].value;
}
}
}
RetainMultifield(theEnv,ProceduralPrimitiveData(theEnv)->WildcardValue->multifieldValue);
}
static void EvaluateProcParameters(
Environment *theEnv,
Expression *parameterList,
unsigned int numberOfParameters,
const char *pname,
const char *bodytype)
{
UDFValue *rva,temp;
int i = 0;
if (numberOfParameters == 0)
{
ProceduralPrimitiveData(theEnv)->ProcParamArray = NULL;
ProceduralPrimitiveData(theEnv)->ProcParamArraySize = 0;
return;
}
rva = (UDFValue *) gm2(theEnv,(sizeof(UDFValue) * numberOfParameters));
while (parameterList != NULL)
{
if ((EvaluateExpression(theEnv,parameterList,&temp) == true) ? true :
(temp.header->type == VOID_TYPE))
{
if (temp.header->type == VOID_TYPE)
{
PrintErrorID(theEnv,"PRCCODE",2,false);
WriteString(theEnv,STDERR,"Functions without a return value are illegal as ");
WriteString(theEnv,STDERR,bodytype);
WriteString(theEnv,STDERR," arguments.\n");
SetEvaluationError(theEnv,true);
}
PrintErrorID(theEnv,"PRCCODE",6,false);
WriteString(theEnv,STDERR,"This error occurred while evaluating arguments ");
WriteString(theEnv,STDERR,"for the ");
WriteString(theEnv,STDERR,bodytype);
WriteString(theEnv,STDERR," '");
WriteString(theEnv,STDERR,pname);
WriteString(theEnv,STDERR,"'.\n");
rm(theEnv,rva,(sizeof(UDFValue) * numberOfParameters));
return;
}
rva[i].value = temp.value;
rva[i].begin = temp.begin;
rva[i].range = temp.range;
parameterList = parameterList->nextArg;
i++;
}
ProceduralPrimitiveData(theEnv)->ProcParamArraySize = numberOfParameters;
ProceduralPrimitiveData(theEnv)->ProcParamArray = rva;
}
static bool RtnProcParam(
Environment *theEnv,
void *value,
UDFValue *returnValue)
{
UDFValue *src;
src = &ProceduralPrimitiveData(theEnv)->ProcParamArray[*((int *) ((CLIPSBitMap *) value)->contents) - 1];
returnValue->value = src->value;
returnValue->begin = src->begin;
returnValue->range = src->range;
return true;
}
static bool GetProcBind(
Environment *theEnv,
void *value,
UDFValue *returnValue)
{
UDFValue *src;
PACKED_PROC_VAR *pvar;
pvar = (PACKED_PROC_VAR *) ((CLIPSBitMap *) value)->contents;
src = &ProceduralPrimitiveData(theEnv)->LocalVarArray[pvar->first - 1];
if (src->supplementalInfo == TrueSymbol(theEnv))
{
returnValue->value = src->value;
returnValue->begin = src->begin;
returnValue->range = src->range;
return true;
}
if (GetFirstArgument()->nextArg != NULL)
{
EvaluateExpression(theEnv,GetFirstArgument()->nextArg,returnValue);
return true;
}
if (pvar->second == 0)
{
PrintErrorID(theEnv,"PRCCODE",5,false);
SetEvaluationError(theEnv,true);
WriteString(theEnv,STDERR,"Variable ?");
WriteString(theEnv,STDERR,GetFirstArgument()->lexemeValue->contents);
if (ProceduralPrimitiveData(theEnv)->ProcUnboundErrFunc != NULL)
{
WriteString(theEnv,STDERR," unbound in ");
(*ProceduralPrimitiveData(theEnv)->ProcUnboundErrFunc)(theEnv,STDERR);
}
else
WriteString(theEnv,STDERR," unbound.\n");
returnValue->value = FalseSymbol(theEnv);
return true;
}
if (pvar->secondFlag == 0)
{
src = &ProceduralPrimitiveData(theEnv)->ProcParamArray[pvar->second - 1];
returnValue->value = src->value;
returnValue->begin = src->begin;
returnValue->range = src->range;
}
else
GrabProcWildargs(theEnv,returnValue,pvar->second);
return true;
}
static bool PutProcBind(
Environment *theEnv,
void *value,
UDFValue *returnValue)
{
UDFValue *dst;
dst = &ProceduralPrimitiveData(theEnv)->LocalVarArray[*((int *) ((CLIPSBitMap *) value)->contents) - 1];
if (GetFirstArgument() == NULL)
{
if (dst->supplementalInfo == TrueSymbol(theEnv))
ReleaseUDFV(theEnv,dst);
dst->supplementalInfo = FalseSymbol(theEnv);
returnValue->value = FalseSymbol(theEnv);
}
else
{
if (GetFirstArgument()->nextArg != NULL)
StoreInMultifield(theEnv,returnValue,GetFirstArgument(),true);
else
EvaluateExpression(theEnv,GetFirstArgument(),returnValue);
if (dst->supplementalInfo == TrueSymbol(theEnv))
ReleaseUDFV(theEnv,dst);
dst->supplementalInfo = TrueSymbol(theEnv);
dst->value = returnValue->value;
dst->begin = returnValue->begin;
dst->range = returnValue->range;
RetainUDFV(theEnv,dst);
}
return true;
}
static bool RtnProcWild(
Environment *theEnv,
void *value,
UDFValue *returnValue)
{
GrabProcWildargs(theEnv,returnValue,*(unsigned *) ((CLIPSBitMap *) value)->contents);
return true;
}
#if (! BLOAD_ONLY) && (! RUN_TIME)
static unsigned int FindProcParameter(
CLIPSLexeme *name,
Expression *parameterList,
CLIPSLexeme *wildcard)
{
unsigned int i = 1;
while (parameterList != NULL)
{
if (parameterList->value == (void *) name)
{ return i; }
i++;
parameterList = parameterList->nextArg;
}
if (name == wildcard)
{ return i; }
return 0;
}
static bool ReplaceProcBinds(
Environment *theEnv,
Expression *actions,
int (*altbindfunc)(Environment *,Expression *,void *),
void *userBuffer)
{
int bcode;
CLIPSLexeme *bname;
while (actions != NULL)
{
if (actions->argList != NULL)
{
if (ReplaceProcBinds(theEnv,actions->argList,altbindfunc,userBuffer))
return true;
if ((actions->value == (void *) FindFunction(theEnv,"bind")) &&
(actions->argList->type == SYMBOL_TYPE))
{
bname = actions->argList->lexemeValue;
bcode = (*altbindfunc)(theEnv,actions,userBuffer);
if (bcode == -1)
return true;
if (bcode == 1)
RemoveParsedBindName(theEnv,bname);
}
}
actions = actions->nextArg;
}
return false;
}
static Expression *CompactActions(
Environment *theEnv,
Expression *actions)
{
struct expr *tmp;
if (actions->argList == NULL)
{
actions->type = SYMBOL_TYPE;
actions->value = FalseSymbol(theEnv);
}
else if (actions->argList->nextArg == NULL)
{
tmp = actions;
actions = actions->argList;
rtn_struct(theEnv,expr,tmp);
}
return(actions);
}
#endif
#if (! DEFFUNCTION_CONSTRUCT) || (! DEFGENERIC_CONSTRUCT)
static bool EvaluateBadCall(
Environment *theEnv,
void *value,
UDFValue *returnValue)
{
#if MAC_XCD
#pragma unused(value)
#endif
PrintErrorID(theEnv,"PRCCODE",1,false);
WriteString(theEnv,STDERR,"Attempted to call a deffunction/generic function ");
WriteString(theEnv,STDERR,"which does not exist.\n");
SetEvaluationError(theEnv,true);
returnValue->value = FalseSymbol(theEnv);
return false;
}
#endif