00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include "setup.h"
00030
00031 #if DEFGENERIC_CONSTRUCT
00032
00033 #if OBJECT_SYSTEM
00034 #include "classcom.h"
00035 #include "classfun.h"
00036 #include "insfun.h"
00037 #endif
00038
00039 #include "argacces.h"
00040 #include "constrct.h"
00041 #include "envrnmnt.h"
00042 #include "genrccom.h"
00043 #include "prcdrfun.h"
00044 #include "prccode.h"
00045 #include "proflfun.h"
00046 #include "router.h"
00047 #include "utility.h"
00048
00049 #define _GENRCEXE_SOURCE_
00050 #include "genrcexe.h"
00051
00052
00053
00054
00055
00056
00057
00058 #define BEGIN_TRACE ">>"
00059 #define END_TRACE "<<"
00060
00061
00062
00063
00064
00065
00066
00067 static DEFMETHOD *FindApplicableMethod(void *,DEFGENERIC *,DEFMETHOD *);
00068
00069 #if DEBUGGING_FUNCTIONS
00070 static void WatchGeneric(void *,char *);
00071 static void WatchMethod(void *,char *);
00072 #endif
00073
00074 #if OBJECT_SYSTEM
00075 static DEFCLASS *DetermineRestrictionClass(void *,DATA_OBJECT *);
00076 #endif
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 globle void GenericDispatch(
00114 void *theEnv,
00115 DEFGENERIC *gfunc,
00116 DEFMETHOD *prevmeth,
00117 DEFMETHOD *meth,
00118 EXPRESSION *params,
00119 DATA_OBJECT *result)
00120 {
00121 DEFGENERIC *previousGeneric;
00122 DEFMETHOD *previousMethod;
00123 int oldce;
00124 #if PROFILING_FUNCTIONS
00125 struct profileFrameInfo profileFrame;
00126 #endif
00127
00128 result->type = SYMBOL;
00129 result->value = EnvFalseSymbol(theEnv);
00130 EvaluationData(theEnv)->EvaluationError = FALSE;
00131 if (EvaluationData(theEnv)->HaltExecution)
00132 return;
00133 oldce = ExecutingConstruct(theEnv);
00134 SetExecutingConstruct(theEnv,TRUE);
00135 previousGeneric = DefgenericData(theEnv)->CurrentGeneric;
00136 previousMethod = DefgenericData(theEnv)->CurrentMethod;
00137 DefgenericData(theEnv)->CurrentGeneric = gfunc;
00138 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00139 gfunc->busy++;
00140 PushProcParameters(theEnv,params,CountArguments(params),
00141 EnvGetDefgenericName(theEnv,(void *) gfunc),
00142 "generic function",UnboundMethodErr);
00143 if (EvaluationData(theEnv)->EvaluationError)
00144 {
00145 gfunc->busy--;
00146 DefgenericData(theEnv)->CurrentGeneric = previousGeneric;
00147 DefgenericData(theEnv)->CurrentMethod = previousMethod;
00148 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00149 PeriodicCleanup(theEnv,FALSE,TRUE);
00150 SetExecutingConstruct(theEnv,oldce);
00151 return;
00152 }
00153 if (meth != NULL)
00154 {
00155 if (IsMethodApplicable(theEnv,meth))
00156 {
00157 meth->busy++;
00158 DefgenericData(theEnv)->CurrentMethod = meth;
00159 }
00160 else
00161 {
00162 PrintErrorID(theEnv,"GENRCEXE",4,FALSE);
00163 SetEvaluationError(theEnv,TRUE);
00164 DefgenericData(theEnv)->CurrentMethod = NULL;
00165 EnvPrintRouter(theEnv,WERROR,"Generic function ");
00166 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) gfunc));
00167 EnvPrintRouter(theEnv,WERROR," method #");
00168 PrintLongInteger(theEnv,WERROR,(long long) meth->index);
00169 EnvPrintRouter(theEnv,WERROR," is not applicable to the given arguments.\n");
00170 }
00171 }
00172 else
00173 DefgenericData(theEnv)->CurrentMethod = FindApplicableMethod(theEnv,gfunc,prevmeth);
00174 if (DefgenericData(theEnv)->CurrentMethod != NULL)
00175 {
00176 #if DEBUGGING_FUNCTIONS
00177 if (DefgenericData(theEnv)->CurrentGeneric->trace)
00178 WatchGeneric(theEnv,BEGIN_TRACE);
00179 if (DefgenericData(theEnv)->CurrentMethod->trace)
00180 WatchMethod(theEnv,BEGIN_TRACE);
00181 #endif
00182 if (DefgenericData(theEnv)->CurrentMethod->system)
00183 {
00184 EXPRESSION fcall;
00185
00186 fcall.type = FCALL;
00187 fcall.value = DefgenericData(theEnv)->CurrentMethod->actions->value;
00188 fcall.nextArg = NULL;
00189 fcall.argList = GetProcParamExpressions(theEnv);
00190 EvaluateExpression(theEnv,&fcall,result);
00191 }
00192 else
00193 {
00194 #if PROFILING_FUNCTIONS
00195 StartProfile(theEnv,&profileFrame,
00196 &DefgenericData(theEnv)->CurrentMethod->usrData,
00197 ProfileFunctionData(theEnv)->ProfileConstructs);
00198 #endif
00199
00200 EvaluateProcActions(theEnv,DefgenericData(theEnv)->CurrentGeneric->header.whichModule->theModule,
00201 DefgenericData(theEnv)->CurrentMethod->actions,DefgenericData(theEnv)->CurrentMethod->localVarCount,
00202 result,UnboundMethodErr);
00203
00204 #if PROFILING_FUNCTIONS
00205 EndProfile(theEnv,&profileFrame);
00206 #endif
00207 }
00208 DefgenericData(theEnv)->CurrentMethod->busy--;
00209 #if DEBUGGING_FUNCTIONS
00210 if (DefgenericData(theEnv)->CurrentMethod->trace)
00211 WatchMethod(theEnv,END_TRACE);
00212 if (DefgenericData(theEnv)->CurrentGeneric->trace)
00213 WatchGeneric(theEnv,END_TRACE);
00214 #endif
00215 }
00216 else if (! EvaluationData(theEnv)->EvaluationError)
00217 {
00218 PrintErrorID(theEnv,"GENRCEXE",1,FALSE);
00219 EnvPrintRouter(theEnv,WERROR,"No applicable methods for ");
00220 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) gfunc));
00221 EnvPrintRouter(theEnv,WERROR,".\n");
00222 SetEvaluationError(theEnv,TRUE);
00223 }
00224 gfunc->busy--;
00225 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
00226 PopProcParameters(theEnv);
00227 DefgenericData(theEnv)->CurrentGeneric = previousGeneric;
00228 DefgenericData(theEnv)->CurrentMethod = previousMethod;
00229 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00230 PropagateReturnValue(theEnv,result);
00231 PeriodicCleanup(theEnv,FALSE,TRUE);
00232 SetExecutingConstruct(theEnv,oldce);
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245 globle void UnboundMethodErr(
00246 void *theEnv)
00247 {
00248 EnvPrintRouter(theEnv,WERROR,"generic function ");
00249 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) DefgenericData(theEnv)->CurrentGeneric));
00250 EnvPrintRouter(theEnv,WERROR," method #");
00251 PrintLongInteger(theEnv,WERROR,(long long) DefgenericData(theEnv)->CurrentMethod->index);
00252 EnvPrintRouter(theEnv,WERROR,".\n");
00253 }
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 globle intBool IsMethodApplicable(
00267 void *theEnv,
00268 DEFMETHOD *meth)
00269 {
00270 DATA_OBJECT temp;
00271 short i,j,k;
00272 register RESTRICTION *rp;
00273 #if OBJECT_SYSTEM
00274 void *type;
00275 #else
00276 int type;
00277 #endif
00278
00279 if ((ProceduralPrimitiveData(theEnv)->ProcParamArraySize < meth->minRestrictions) ||
00280 ((ProceduralPrimitiveData(theEnv)->ProcParamArraySize > meth->minRestrictions) && (meth->maxRestrictions != -1)))
00281 return(FALSE);
00282 for (i = 0 , k = 0 ; i < ProceduralPrimitiveData(theEnv)->ProcParamArraySize ; i++)
00283 {
00284 rp = &meth->restrictions[k];
00285 if (rp->tcnt != 0)
00286 {
00287 #if OBJECT_SYSTEM
00288 type = (void *) DetermineRestrictionClass(theEnv,&ProceduralPrimitiveData(theEnv)->ProcParamArray[i]);
00289 if (type == NULL)
00290 return(FALSE);
00291 for (j = 0 ; j < rp->tcnt ; j++)
00292 {
00293 if (type == rp->types[j])
00294 break;
00295 if (HasSuperclass((DEFCLASS *) type,(DEFCLASS *) rp->types[j]))
00296 break;
00297 if (rp->types[j] == (void *) DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_ADDRESS])
00298 {
00299 if (ProceduralPrimitiveData(theEnv)->ProcParamArray[i].type == INSTANCE_ADDRESS)
00300 break;
00301 }
00302 else if (rp->types[j] == (void *) DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_NAME])
00303 {
00304 if (ProceduralPrimitiveData(theEnv)->ProcParamArray[i].type == INSTANCE_NAME)
00305 break;
00306 }
00307 else if (rp->types[j] ==
00308 (void *) DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_NAME]->directSuperclasses.classArray[0])
00309 {
00310 if ((ProceduralPrimitiveData(theEnv)->ProcParamArray[i].type == INSTANCE_NAME) ||
00311 (ProceduralPrimitiveData(theEnv)->ProcParamArray[i].type == INSTANCE_ADDRESS))
00312 break;
00313 }
00314 }
00315 #else
00316 type = ProceduralPrimitiveData(theEnv)->ProcParamArray[i].type;
00317 for (j = 0 ; j < rp->tcnt ; j++)
00318 {
00319 if (type == ValueToInteger(rp->types[j]))
00320 break;
00321 if (SubsumeType(type,ValueToInteger(rp->types[j])))
00322 break;
00323 }
00324 #endif
00325 if (j == rp->tcnt)
00326 return(FALSE);
00327 }
00328 if (rp->query != NULL)
00329 {
00330 DefgenericData(theEnv)->GenericCurrentArgument = &ProceduralPrimitiveData(theEnv)->ProcParamArray[i];
00331 EvaluateExpression(theEnv,rp->query,&temp);
00332 if ((temp.type != SYMBOL) ? FALSE :
00333 (temp.value == EnvFalseSymbol(theEnv)))
00334 return(FALSE);
00335 }
00336 if (((int) k) != meth->restrictionCount-1)
00337 k++;
00338 }
00339 return(TRUE);
00340 }
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 globle int NextMethodP(
00354 void *theEnv)
00355 {
00356 register DEFMETHOD *meth;
00357
00358 if (DefgenericData(theEnv)->CurrentMethod == NULL)
00359 return(FALSE);
00360 meth = FindApplicableMethod(theEnv,DefgenericData(theEnv)->CurrentGeneric,DefgenericData(theEnv)->CurrentMethod);
00361 if (meth != NULL)
00362 {
00363 meth->busy--;
00364 return(TRUE);
00365 }
00366 return(FALSE);
00367 }
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 globle void CallNextMethod(
00381 void *theEnv,
00382 DATA_OBJECT *result)
00383 {
00384 DEFMETHOD *oldMethod;
00385 #if PROFILING_FUNCTIONS
00386 struct profileFrameInfo profileFrame;
00387 #endif
00388
00389 result->type = SYMBOL;
00390 result->value = EnvFalseSymbol(theEnv);
00391 if (EvaluationData(theEnv)->HaltExecution)
00392 return;
00393 oldMethod = DefgenericData(theEnv)->CurrentMethod;
00394 if (DefgenericData(theEnv)->CurrentMethod != NULL)
00395 DefgenericData(theEnv)->CurrentMethod = FindApplicableMethod(theEnv,DefgenericData(theEnv)->CurrentGeneric,DefgenericData(theEnv)->CurrentMethod);
00396 if (DefgenericData(theEnv)->CurrentMethod == NULL)
00397 {
00398 DefgenericData(theEnv)->CurrentMethod = oldMethod;
00399 PrintErrorID(theEnv,"GENRCEXE",2,FALSE);
00400 EnvPrintRouter(theEnv,WERROR,"Shadowed methods not applicable in current context.\n");
00401 SetEvaluationError(theEnv,TRUE);
00402 return;
00403 }
00404
00405 #if DEBUGGING_FUNCTIONS
00406 if (DefgenericData(theEnv)->CurrentMethod->trace)
00407 WatchMethod(theEnv,BEGIN_TRACE);
00408 #endif
00409 if (DefgenericData(theEnv)->CurrentMethod->system)
00410 {
00411 EXPRESSION fcall;
00412
00413 fcall.type = FCALL;
00414 fcall.value = DefgenericData(theEnv)->CurrentMethod->actions->value;
00415 fcall.nextArg = NULL;
00416 fcall.argList = GetProcParamExpressions(theEnv);
00417 EvaluateExpression(theEnv,&fcall,result);
00418 }
00419 else
00420 {
00421 #if PROFILING_FUNCTIONS
00422 StartProfile(theEnv,&profileFrame,
00423 &DefgenericData(theEnv)->CurrentGeneric->header.usrData,
00424 ProfileFunctionData(theEnv)->ProfileConstructs);
00425 #endif
00426
00427 EvaluateProcActions(theEnv,DefgenericData(theEnv)->CurrentGeneric->header.whichModule->theModule,
00428 DefgenericData(theEnv)->CurrentMethod->actions,DefgenericData(theEnv)->CurrentMethod->localVarCount,
00429 result,UnboundMethodErr);
00430
00431 #if PROFILING_FUNCTIONS
00432 EndProfile(theEnv,&profileFrame);
00433 #endif
00434 }
00435
00436 DefgenericData(theEnv)->CurrentMethod->busy--;
00437 #if DEBUGGING_FUNCTIONS
00438 if (DefgenericData(theEnv)->CurrentMethod->trace)
00439 WatchMethod(theEnv,END_TRACE);
00440 #endif
00441 DefgenericData(theEnv)->CurrentMethod = oldMethod;
00442 ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
00443 }
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 globle void CallSpecificMethod(
00458 void *theEnv,
00459 DATA_OBJECT *result)
00460 {
00461 DATA_OBJECT temp;
00462 DEFGENERIC *gfunc;
00463 int mi;
00464
00465 result->type = SYMBOL;
00466 result->value = EnvFalseSymbol(theEnv);
00467 if (EnvArgTypeCheck(theEnv,"call-specific-method",1,SYMBOL,&temp) == FALSE)
00468 return;
00469 gfunc = CheckGenericExists(theEnv,"call-specific-method",DOToString(temp));
00470 if (gfunc == NULL)
00471 return;
00472 if (EnvArgTypeCheck(theEnv,"call-specific-method",2,INTEGER,&temp) == FALSE)
00473 return;
00474 mi = CheckMethodExists(theEnv,"call-specific-method",gfunc,(long) DOToLong(temp));
00475 if (mi == -1)
00476 return;
00477 gfunc->methods[mi].busy++;
00478 GenericDispatch(theEnv,gfunc,NULL,&gfunc->methods[mi],
00479 GetFirstArgument()->nextArg->nextArg,result);
00480 gfunc->methods[mi].busy--;
00481 }
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 globle void OverrideNextMethod(
00493 void *theEnv,
00494 DATA_OBJECT *result)
00495 {
00496 result->type = SYMBOL;
00497 result->value = EnvFalseSymbol(theEnv);
00498 if (EvaluationData(theEnv)->HaltExecution)
00499 return;
00500 if (DefgenericData(theEnv)->CurrentMethod == NULL)
00501 {
00502 PrintErrorID(theEnv,"GENRCEXE",2,FALSE);
00503 EnvPrintRouter(theEnv,WERROR,"Shadowed methods not applicable in current context.\n");
00504 SetEvaluationError(theEnv,TRUE);
00505 return;
00506 }
00507 GenericDispatch(theEnv,DefgenericData(theEnv)->CurrentGeneric,DefgenericData(theEnv)->CurrentMethod,NULL,
00508 GetFirstArgument(),result);
00509 }
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 globle void GetGenericCurrentArgument(
00522 void *theEnv,
00523 DATA_OBJECT *result)
00524 {
00525 result->type = DefgenericData(theEnv)->GenericCurrentArgument->type;
00526 result->value = DefgenericData(theEnv)->GenericCurrentArgument->value;
00527 result->begin = DefgenericData(theEnv)->GenericCurrentArgument->begin;
00528 result->end = DefgenericData(theEnv)->GenericCurrentArgument->end;
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550 static DEFMETHOD *FindApplicableMethod(
00551 void *theEnv,
00552 DEFGENERIC *gfunc,
00553 DEFMETHOD *meth)
00554 {
00555 if (meth != NULL)
00556 meth++;
00557 else
00558 meth = gfunc->methods;
00559 for ( ; meth < &gfunc->methods[gfunc->mcnt] ; meth++)
00560 {
00561 meth->busy++;
00562 if (IsMethodApplicable(theEnv,meth))
00563 return(meth);
00564 meth->busy--;
00565 }
00566 return(NULL);
00567 }
00568
00569 #if DEBUGGING_FUNCTIONS
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 static void WatchGeneric(
00582 void *theEnv,
00583 char *tstring)
00584 {
00585 EnvPrintRouter(theEnv,WTRACE,"GNC ");
00586 EnvPrintRouter(theEnv,WTRACE,tstring);
00587 EnvPrintRouter(theEnv,WTRACE," ");
00588 if (DefgenericData(theEnv)->CurrentGeneric->header.whichModule->theModule != ((struct defmodule *) EnvGetCurrentModule(theEnv)))
00589 {
00590 EnvPrintRouter(theEnv,WTRACE,EnvGetDefmoduleName(theEnv,(void *)
00591 DefgenericData(theEnv)->CurrentGeneric->header.whichModule->theModule));
00592 EnvPrintRouter(theEnv,WTRACE,"::");
00593 }
00594 EnvPrintRouter(theEnv,WTRACE,ValueToString((void *) DefgenericData(theEnv)->CurrentGeneric->header.name));
00595 EnvPrintRouter(theEnv,WTRACE," ");
00596 EnvPrintRouter(theEnv,WTRACE," ED:");
00597 PrintLongInteger(theEnv,WTRACE,(long long) EvaluationData(theEnv)->CurrentEvaluationDepth);
00598 PrintProcParamArray(theEnv,WTRACE);
00599 }
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 static void WatchMethod(
00614 void *theEnv,
00615 char *tstring)
00616 {
00617 EnvPrintRouter(theEnv,WTRACE,"MTH ");
00618 EnvPrintRouter(theEnv,WTRACE,tstring);
00619 EnvPrintRouter(theEnv,WTRACE," ");
00620 if (DefgenericData(theEnv)->CurrentGeneric->header.whichModule->theModule != ((struct defmodule *) EnvGetCurrentModule(theEnv)))
00621 {
00622 EnvPrintRouter(theEnv,WTRACE,EnvGetDefmoduleName(theEnv,(void *)
00623 DefgenericData(theEnv)->CurrentGeneric->header.whichModule->theModule));
00624 EnvPrintRouter(theEnv,WTRACE,"::");
00625 }
00626 EnvPrintRouter(theEnv,WTRACE,ValueToString((void *) DefgenericData(theEnv)->CurrentGeneric->header.name));
00627 EnvPrintRouter(theEnv,WTRACE,":#");
00628 if (DefgenericData(theEnv)->CurrentMethod->system)
00629 EnvPrintRouter(theEnv,WTRACE,"SYS");
00630 PrintLongInteger(theEnv,WTRACE,(long long) DefgenericData(theEnv)->CurrentMethod->index);
00631 EnvPrintRouter(theEnv,WTRACE," ");
00632 EnvPrintRouter(theEnv,WTRACE," ED:");
00633 PrintLongInteger(theEnv,WTRACE,(long long) EvaluationData(theEnv)->CurrentEvaluationDepth);
00634 PrintProcParamArray(theEnv,WTRACE);
00635 }
00636
00637 #endif
00638
00639 #if OBJECT_SYSTEM
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650 static DEFCLASS *DetermineRestrictionClass(
00651 void *theEnv,
00652 DATA_OBJECT *dobj)
00653 {
00654 INSTANCE_TYPE *ins;
00655 DEFCLASS *cls;
00656
00657 if (dobj->type == INSTANCE_NAME)
00658 {
00659 ins = FindInstanceBySymbol(theEnv,(SYMBOL_HN *) dobj->value);
00660 cls = (ins != NULL) ? ins->cls : NULL;
00661 }
00662 else if (dobj->type == INSTANCE_ADDRESS)
00663 {
00664 ins = (INSTANCE_TYPE *) dobj->value;
00665 cls = (ins->garbage == 0) ? ins->cls : NULL;
00666 }
00667 else
00668 return(DefclassData(theEnv)->PrimitiveClassMap[dobj->type]);
00669 if (cls == NULL)
00670 {
00671 SetEvaluationError(theEnv,TRUE);
00672 PrintErrorID(theEnv,"GENRCEXE",3,FALSE);
00673 EnvPrintRouter(theEnv,WERROR,"Unable to determine class of ");
00674 PrintDataObject(theEnv,WERROR,dobj);
00675 EnvPrintRouter(theEnv,WERROR," in generic function ");
00676 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) DefgenericData(theEnv)->CurrentGeneric));
00677 EnvPrintRouter(theEnv,WERROR,".\n");
00678 }
00679 return(cls);
00680 }
00681
00682 #endif
00683
00684 #endif
00685