📄 genrcpsr.c
字号:
(or class addresses) NOTES : None *************************************************************/static EXPRESSION *ValidType( void *theEnv, SYMBOL_HN *tname) {#if OBJECT_SYSTEM DEFCLASS *cls; if (FindModuleSeparator(ValueToString(tname))) IllegalModuleSpecifierMessage(theEnv); else { cls = LookupDefclassInScope(theEnv,ValueToString(tname)); if (cls == NULL) { PrintErrorID(theEnv,"GENRCPSR",14,FALSE); EnvPrintRouter(theEnv,WERROR,"Unknown class in method.\n"); return(NULL); } return(GenConstant(theEnv,EXTERNAL_ADDRESS,(void *) cls)); }#else if (strcmp(ValueToString(tname),INTEGER_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) INTEGER))); if (strcmp(ValueToString(tname),FLOAT_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) FLOAT))); if (strcmp(ValueToString(tname),SYMBOL_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) SYMBOL))); if (strcmp(ValueToString(tname),STRING_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) STRING))); if (strcmp(ValueToString(tname),MULTIFIELD_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) MULTIFIELD))); if (strcmp(ValueToString(tname),EXTERNAL_ADDRESS_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) EXTERNAL_ADDRESS))); if (strcmp(ValueToString(tname),FACT_ADDRESS_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) FACT_ADDRESS))); if (strcmp(ValueToString(tname),NUMBER_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) NUMBER_TYPE_CODE))); if (strcmp(ValueToString(tname),LEXEME_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) LEXEME_TYPE_CODE))); if (strcmp(ValueToString(tname),ADDRESS_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) ADDRESS_TYPE_CODE))); if (strcmp(ValueToString(tname),PRIMITIVE_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) PRIMITIVE_TYPE_CODE))); if (strcmp(ValueToString(tname),OBJECT_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) OBJECT_TYPE_CODE))); if (strcmp(ValueToString(tname),INSTANCE_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) INSTANCE_TYPE_CODE))); if (strcmp(ValueToString(tname),INSTANCE_NAME_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) INSTANCE_NAME))); if (strcmp(ValueToString(tname),INSTANCE_ADDRESS_TYPE_NAME) == 0) return(GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) INSTANCE_ADDRESS))); PrintErrorID(theEnv,"GENRCPSR",14,FALSE); EnvPrintRouter(theEnv,WERROR,"Unknown type in method.\n");#endif return(NULL); }/************************************************************* NAME : RedundantClasses DESCRIPTION : Determines if one class (type) is subsumes (or is subsumed by) another. INPUTS : Two void pointers which are class pointers if COOL is installed or integer hash nodes for type codes otherwise. RETURNS : TRUE if there is subsumption, FALSE otherwise SIDE EFFECTS : An error message is printed, if appropriate. NOTES : None *************************************************************/static intBool RedundantClasses( void *theEnv, void *c1, void *c2) { char *tname;#if OBJECT_SYSTEM if (HasSuperclass((DEFCLASS *) c1,(DEFCLASS *) c2)) tname = EnvGetDefclassName(theEnv,c1); else if (HasSuperclass((DEFCLASS *) c2,(DEFCLASS *) c1)) tname = EnvGetDefclassName(theEnv,c2);#else if (SubsumeType(ValueToInteger(c1),ValueToInteger(c2))) tname = TypeName(theEnv,ValueToInteger(c1)); else if (SubsumeType(ValueToInteger(c2),ValueToInteger(c1))) tname = TypeName(theEnv,ValueToInteger(c2));#endif else return(FALSE); PrintErrorID(theEnv,"GENRCPSR",15,FALSE); EnvPrintRouter(theEnv,WERROR,tname); EnvPrintRouter(theEnv,WERROR," class is redundant.\n"); return(TRUE); }/********************************************************* NAME : AddGeneric DESCRIPTION : Inserts a new generic function header into the generic list INPUTS : 1) Symbolic name of the new generic 2) Caller's input buffer for flag if added generic is new or not RETURNS : The address of the new node, or address of old node if already present SIDE EFFECTS : Generic header inserted If the node is already present, it is moved to the end of the list, otherwise the new node is inserted at the end NOTES : None *********************************************************/static DEFGENERIC *AddGeneric( void *theEnv, SYMBOL_HN *name, int *newGeneric) { DEFGENERIC *gfunc; gfunc = (DEFGENERIC *) EnvFindDefgeneric(theEnv,ValueToString(name)); if (gfunc != NULL) { *newGeneric = FALSE; if (ConstructData(theEnv)->CheckSyntaxMode) { return(gfunc); } /* ================================ The old trace state is preserved ================================ */ RemoveConstructFromModule(theEnv,(struct constructHeader *) gfunc); } else { *newGeneric = TRUE; gfunc = NewGeneric(theEnv,name); IncrementSymbolCount(name); AddImplicitMethods(theEnv,gfunc); } AddConstructToModule((struct constructHeader *) gfunc); return(gfunc); }/********************************************************************** NAME : AddGenericMethod DESCRIPTION : Inserts a blank method (with the method-index set) into the specified position of the generic method array INPUTS : 1) The generic function 2) The index where to add the method in the array 3) The method user-index (0 if don't care) RETURNS : The address of the new method SIDE EFFECTS : Fields initialized (index set) and new method inserted Generic function new method-index set to specified by user-index if > current new method-index NOTES : None **********************************************************************/static DEFMETHOD *AddGenericMethod( void *theEnv, DEFGENERIC *gfunc, int mposn, short mi) { DEFMETHOD *narr; long b, e; narr = (DEFMETHOD *) gm2(theEnv,(sizeof(DEFMETHOD) * (gfunc->mcnt+1))); for (b = e = 0 ; b < gfunc->mcnt ; b++ , e++) { if (b == mposn) e++; GenCopyMemory(DEFMETHOD,1,&narr[e],&gfunc->methods[b]); } if (mi == 0) narr[mposn].index = gfunc->new_index++; else { narr[mposn].index = mi; if (mi >= gfunc->new_index) gfunc->new_index = mi+1; } narr[mposn].busy = 0;#if DEBUGGING_FUNCTIONS narr[mposn].trace = DefgenericData(theEnv)->WatchMethods;#endif narr[mposn].minRestrictions = 0; narr[mposn].maxRestrictions = 0; narr[mposn].restrictionCount = 0; narr[mposn].localVarCount = 0; narr[mposn].system = 0; narr[mposn].restrictions = NULL; narr[mposn].actions = NULL; narr[mposn].ppForm = NULL; narr[mposn].usrData = NULL; if (gfunc->mcnt != 0) rm(theEnv,(void *) gfunc->methods,(sizeof(DEFMETHOD) * gfunc->mcnt)); gfunc->mcnt++; gfunc->methods = narr; return(&narr[mposn]); }/**************************************************************** NAME : RestrictionsCompare DESCRIPTION : Compares the restriction-expression list with an existing methods restrictions to determine an ordering INPUTS : 1) The parameter/restriction expression list 2) The total number of restrictions 3) The number of minimum restrictions 4) The number of maximum restrictions (-1 if unlimited) 5) The method with which to compare restrictions RETURNS : A code representing how the method restrictions -1 : New restrictions have higher precedence 0 : New restrictions are identical 1 : New restrictions have lower precedence SIDE EFFECTS : None NOTES : The new restrictions are stored in the argList pointers of the parameter expressions ****************************************************************/static int RestrictionsCompare( EXPRESSION *params, int rcnt, int min, int max, DEFMETHOD *meth) { register int i; register RESTRICTION *r1,*r2; int diff = FALSE,rtn; for (i = 0 ; (i < rcnt) && (i < meth->restrictionCount) ; i++) { /* ============================================================= A wildcard parameter always has lower precedence than a regular parameter, regardless of the class restriction list ============================================================= */ if ((i == rcnt-1) && (max == -1) && (meth->maxRestrictions != -1)) return(LOWER_PRECEDENCE); if ((i == meth->restrictionCount-1) && (max != -1) && (meth->maxRestrictions == -1)) return(HIGHER_PRECEDENCE); /* ============================================================= The parameter with the most specific type list has precedence ============================================================= */ r1 = (RESTRICTION *) params->argList; r2 = &meth->restrictions[i]; rtn = TypeListCompare(r1,r2); if (rtn != IDENTICAL) return(rtn); /* ===================================================== The parameter with a query restriction has precedence ===================================================== */ if ((r1->query == NULL) && (r2->query != NULL)) return(LOWER_PRECEDENCE); if ((r1->query != NULL) && (r2->query == NULL)) return(HIGHER_PRECEDENCE); /* ========================================================== Remember if the method restrictions differ at all - query expressions must be identical as well for the restrictions to be the same ========================================================== */ if (IdenticalExpression(r1->query,r2->query) == FALSE) diff = TRUE; params = params->nextArg; } /* ============================================================= If the methods have the same number of parameters here, they are either the same restrictions, or they differ only in the query restrictions ============================================================= */ if (rcnt == meth->restrictionCount) return(diff ? LOWER_PRECEDENCE : IDENTICAL); /* ============================================= The method with the greater number of regular parameters has precedence If they require the smae # of reg params, then one without a wildcard has precedence ============================================= */ if (min > meth->minRestrictions) return(HIGHER_PRECEDENCE); if (meth->minRestrictions < min) return(LOWER_PRECEDENCE); return((max == - 1) ? LOWER_PRECEDENCE : HIGHER_PRECEDENCE); }/***************************************************** NAME : TypeListCompare DESCRIPTION : Determines the precedence between the class lists on two restrictions INPUTS : 1) Restriction address #1 2) Restriction address #2 RETURNS : -1 : r1 precedes r2 0 : Identical classes 1 : r2 precedes r1 SIDE EFFECTS : None NOTES : None *****************************************************/static int TypeListCompare( RESTRICTION *r1, RESTRICTION *r2) { long i; int diff = FALSE; if ((r1->tcnt == 0) && (r2->tcnt == 0)) return(IDENTICAL); if (r1->tcnt == 0) return(LOWER_PRECEDENCE); if (r2->tcnt == 0) return(HIGHER_PRECEDENCE); for (i = 0 ; (i < r1->tcnt) && (i < r2->tcnt) ; i++) { if (r1->types[i] != r2->types[i]) { diff = TRUE;#if OBJECT_SYSTEM if (HasSuperclass((DEFCLASS *) r1->types[i],(DEFCLASS *) r2->types[i])) return(HIGHER_PRECEDENCE); if (HasSuperclass((DEFCLASS *) r2->types[i],(DEFCLASS *) r1->types[i])) return(LOWER_PRECEDENCE);#else if (SubsumeType(ValueToInteger(r1->types[i]),ValueToInteger(r2->types[i]))) return(HIGHER_PRECEDENCE); if (SubsumeType(ValueToInteger(r2->types[i]),ValueToInteger(r1->types[i]))) return(LOWER_PRECEDENCE);#endif } } if (r1->tcnt < r2->tcnt) return(HIGHER_PRECEDENCE); if (r1->tcnt > r2->tcnt) return(LOWER_PRECEDENCE); if (diff) return(LOWER_PRECEDENCE); return(IDENTICAL); }/*************************************************** NAME : NewGeneric DESCRIPTION : Allocates and initializes a new generic function header INPUTS : The name of the new generic RETURNS : The address of the new generic SIDE EFFECTS : Generic function header created NOTES : None ***************************************************/static DEFGENERIC *NewGeneric( void *theEnv, SYMBOL_HN *gname) { DEFGENERIC *ngen; ngen = get_struct(theEnv,defgeneric); InitializeConstructHeader(theEnv,"defgeneric",(struct constructHeader *) ngen,gname); ngen->busy = 0; ngen->new_index = 1; ngen->methods = NULL; ngen->mcnt = 0;#if DEBUGGING_FUNCTIONS ngen->trace = DefgenericData(theEnv)->WatchGenerics;#endif return(ngen); }#endif /* DEFGENERIC_CONSTRUCT && (! BLOAD_ONLY) && (! RUN_TIME) *//*************************************************** NAME : DESCRIPTION : INPUTS : RETURNS : SIDE EFFECTS : NOTES : ***************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -