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
00030
00031
00032
00033 #include "setup.h"
00034
00035 #if DEFGENERIC_CONSTRUCT
00036
00037 #if BLOAD || BLOAD_AND_BSAVE
00038 #include "bload.h"
00039 #endif
00040
00041 #if OBJECT_SYSTEM
00042 #include "classcom.h"
00043 #include "classfun.h"
00044 #endif
00045
00046 #include "argacces.h"
00047 #include "constrct.h"
00048 #include "cstrcpsr.h"
00049 #include "envrnmnt.h"
00050 #include "genrccom.h"
00051 #include "genrcexe.h"
00052 #include "memalloc.h"
00053 #include "prccode.h"
00054 #include "router.h"
00055 #include "sysdep.h"
00056
00057 #define _GENRCFUN_SOURCE_
00058 #include "genrcfun.h"
00059
00060
00061
00062
00063
00064
00065
00066 #if DEBUGGING_FUNCTIONS
00067 static void DisplayGenericCore(void *,DEFGENERIC *);
00068 #endif
00069
00070
00071
00072
00073
00074
00075
00076 #if ! RUN_TIME
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 globle intBool ClearDefgenericsReady(
00093 void *theEnv)
00094 {
00095 return((DefgenericData(theEnv)->CurrentGeneric != NULL) ? FALSE : TRUE);
00096 }
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 globle void *AllocateDefgenericModule(
00108 void *theEnv)
00109 {
00110 return((void *) get_struct(theEnv,defgenericModule));
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 globle void FreeDefgenericModule(
00123 void *theEnv,
00124 void *theItem)
00125 {
00126 #if (! BLOAD_ONLY)
00127 FreeConstructHeaderModule(theEnv,(struct defmoduleItemHeader *) theItem,DefgenericData(theEnv)->DefgenericConstruct);
00128 #endif
00129 rtn_struct(theEnv,defgenericModule,theItem);
00130 }
00131
00132 #endif
00133
00134 #if (! BLOAD_ONLY) && (! RUN_TIME)
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 globle int ClearDefmethods(
00155 void *theEnv)
00156 {
00157 register DEFGENERIC *gfunc;
00158 int success = TRUE;
00159
00160 #if BLOAD || BLOAD_AND_BSAVE
00161 if (Bloaded(theEnv) == TRUE) return(FALSE);
00162 #endif
00163
00164 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,NULL);
00165 while (gfunc != NULL)
00166 {
00167 if (RemoveAllExplicitMethods(theEnv,gfunc) == FALSE)
00168 success = FALSE;
00169 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc);
00170 }
00171 return(success);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 globle int RemoveAllExplicitMethods(
00185 void *theEnv,
00186 DEFGENERIC *gfunc)
00187 {
00188 long i,j;
00189 unsigned systemMethodCount = 0;
00190 DEFMETHOD *narr;
00191
00192 if (MethodsExecuting(gfunc) == FALSE)
00193 {
00194 for (i = 0 ; i < gfunc->mcnt ; i++)
00195 {
00196 if (gfunc->methods[i].system)
00197 systemMethodCount++;
00198 else
00199 DeleteMethodInfo(theEnv,gfunc,&gfunc->methods[i]);
00200 }
00201 if (systemMethodCount != 0)
00202 {
00203 narr = (DEFMETHOD *) gm2(theEnv,(systemMethodCount * sizeof(DEFMETHOD)));
00204 i = 0;
00205 j = 0;
00206 while (i < gfunc->mcnt)
00207 {
00208 if (gfunc->methods[i].system)
00209 GenCopyMemory(DEFMETHOD,1,&narr[j++],&gfunc->methods[i]);
00210 i++;
00211 }
00212 rm(theEnv,(void *) gfunc->methods,(sizeof(DEFMETHOD) * gfunc->mcnt));
00213 gfunc->mcnt = (short) systemMethodCount;
00214 gfunc->methods = narr;
00215 }
00216 else
00217 {
00218 if (gfunc->mcnt != 0)
00219 rm(theEnv,(void *) gfunc->methods,(sizeof(DEFMETHOD) * gfunc->mcnt));
00220 gfunc->mcnt = 0;
00221 gfunc->methods = NULL;
00222 }
00223 return(TRUE);
00224 }
00225 return(FALSE);
00226 }
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 globle void RemoveDefgeneric(
00240 void *theEnv,
00241 void *vgfunc)
00242 {
00243 DEFGENERIC *gfunc = (DEFGENERIC *) vgfunc;
00244 long i;
00245
00246 for (i = 0 ; i < gfunc->mcnt ; i++)
00247 DeleteMethodInfo(theEnv,gfunc,&gfunc->methods[i]);
00248
00249 if (gfunc->mcnt != 0)
00250 rm(theEnv,(void *) gfunc->methods,(sizeof(DEFMETHOD) * gfunc->mcnt));
00251 DecrementSymbolCount(theEnv,GetDefgenericNamePointer((void *) gfunc));
00252 SetDefgenericPPForm((void *) gfunc,NULL);
00253 ClearUserDataList(theEnv,gfunc->header.usrData);
00254 rtn_struct(theEnv,defgeneric,gfunc);
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 globle int ClearDefgenerics(
00267 void *theEnv)
00268 {
00269 register DEFGENERIC *gfunc,*gtmp;
00270 int success = TRUE;
00271
00272 #if BLOAD || BLOAD_AND_BSAVE
00273 if (Bloaded(theEnv) == TRUE) return(FALSE);
00274 #endif
00275
00276 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,NULL);
00277 while (gfunc != NULL)
00278 {
00279 gtmp = gfunc;
00280 gfunc = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,(void *) gfunc);
00281 if (RemoveAllExplicitMethods(theEnv,gtmp) == FALSE)
00282 {
00283 CantDeleteItemErrorMessage(theEnv,"generic function",EnvGetDefgenericName(theEnv,gtmp));
00284 success = FALSE;
00285 }
00286 else
00287 {
00288 RemoveConstructFromModule(theEnv,(struct constructHeader *) gtmp);
00289 RemoveDefgeneric(theEnv,(void *) gtmp);
00290 }
00291 }
00292 return(success);
00293 }
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 globle void MethodAlterError(
00307 void *theEnv,
00308 DEFGENERIC *gfunc)
00309 {
00310 PrintErrorID(theEnv,"GENRCFUN",1,FALSE);
00311 EnvPrintRouter(theEnv,WERROR,"Defgeneric ");
00312 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) gfunc));
00313 EnvPrintRouter(theEnv,WERROR," cannot be modified while one of its methods is executing.\n");
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327 globle void DeleteMethodInfo(
00328 void *theEnv,
00329 DEFGENERIC *gfunc,
00330 DEFMETHOD *meth)
00331 {
00332 short j,k;
00333 RESTRICTION *rptr;
00334
00335 SaveBusyCount(gfunc);
00336 ExpressionDeinstall(theEnv,meth->actions);
00337 ReturnPackedExpression(theEnv,meth->actions);
00338 ClearUserDataList(theEnv,meth->usrData);
00339 if (meth->ppForm != NULL)
00340 rm(theEnv,(void *) meth->ppForm,(sizeof(char) * (strlen(meth->ppForm)+1)));
00341 for (j = 0 ; j < meth->restrictionCount ; j++)
00342 {
00343 rptr = &meth->restrictions[j];
00344
00345 for (k = 0 ; k < rptr->tcnt ; k++)
00346 #if OBJECT_SYSTEM
00347 DecrementDefclassBusyCount(theEnv,rptr->types[k]);
00348 #else
00349 DecrementIntegerCount(theEnv,(INTEGER_HN *) rptr->types[k]);
00350 #endif
00351
00352 if (rptr->types != NULL)
00353 rm(theEnv,(void *) rptr->types,(sizeof(void *) * rptr->tcnt));
00354 ExpressionDeinstall(theEnv,rptr->query);
00355 ReturnPackedExpression(theEnv,rptr->query);
00356 }
00357 if (meth->restrictions != NULL)
00358 rm(theEnv,(void *) meth->restrictions,
00359 (sizeof(RESTRICTION) * meth->restrictionCount));
00360 RestoreBusyCount(gfunc);
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 #if WIN_BTC
00375 #pragma argsused
00376 #endif
00377 globle void DestroyMethodInfo(
00378 void *theEnv,
00379 DEFGENERIC *gfunc,
00380 DEFMETHOD *meth)
00381 {
00382 register int j;
00383 register RESTRICTION *rptr;
00384 #if MAC_MCW || WIN_MCW || MAC_XCD
00385 #pragma unused(gfunc)
00386 #endif
00387
00388 ReturnPackedExpression(theEnv,meth->actions);
00389
00390 ClearUserDataList(theEnv,meth->usrData);
00391 if (meth->ppForm != NULL)
00392 rm(theEnv,(void *) meth->ppForm,(sizeof(char) * (strlen(meth->ppForm)+1)));
00393 for (j = 0 ; j < meth->restrictionCount ; j++)
00394 {
00395 rptr = &meth->restrictions[j];
00396
00397 if (rptr->types != NULL)
00398 rm(theEnv,(void *) rptr->types,(sizeof(void *) * rptr->tcnt));
00399 ReturnPackedExpression(theEnv,rptr->query);
00400 }
00401
00402 if (meth->restrictions != NULL)
00403 rm(theEnv,(void *) meth->restrictions,
00404 (sizeof(RESTRICTION) * meth->restrictionCount));
00405 }
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 globle int MethodsExecuting(
00419 DEFGENERIC *gfunc)
00420 {
00421 long i;
00422
00423 for (i = 0 ; i < gfunc->mcnt ; i++)
00424 if (gfunc->methods[i].busy > 0)
00425 return(TRUE);
00426 return(FALSE);
00427 }
00428
00429 #endif
00430
00431 #if ! OBJECT_SYSTEM
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 globle intBool SubsumeType(
00445 int t1,
00446 int t2)
00447 {
00448 if ((t2 == OBJECT_TYPE_CODE) || (t2 == PRIMITIVE_TYPE_CODE))
00449 return(TRUE);
00450 if ((t2 == NUMBER_TYPE_CODE) && ((t1 == INTEGER) || (t1 == FLOAT)))
00451 return(TRUE);
00452 if ((t2 == LEXEME_TYPE_CODE) && ((t1 == STRING) || (t1 == SYMBOL)))
00453 return(TRUE);
00454 if ((t2 == ADDRESS_TYPE_CODE) && ((t1 == EXTERNAL_ADDRESS) ||
00455 (t1 == FACT_ADDRESS) || (t1 == INSTANCE_ADDRESS)))
00456 return(TRUE);
00457 if ((t2 == LEXEME_TYPE_CODE) &&
00458 ((t1 == INSTANCE_NAME) || (t1 == INSTANCE_ADDRESS)))
00459 return(TRUE);
00460 return(FALSE);
00461 }
00462
00463 #endif
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477 globle long FindMethodByIndex(
00478 DEFGENERIC *gfunc,
00479 long theIndex)
00480 {
00481 long i;
00482
00483 for (i = 0 ; i < gfunc->mcnt ; i++)
00484 if (gfunc->methods[i].index == theIndex)
00485 return(i);
00486 return(-1);
00487 }
00488
00489 #if DEBUGGING_FUNCTIONS
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 globle void PreviewGeneric(
00505 void *theEnv)
00506 {
00507 DEFGENERIC *gfunc;
00508 DEFGENERIC *previousGeneric;
00509 int oldce;
00510 DATA_OBJECT temp;
00511
00512 EvaluationData(theEnv)->EvaluationError = FALSE;
00513 if (EnvArgTypeCheck(theEnv,"preview-generic",1,SYMBOL,&temp) == FALSE)
00514 return;
00515 gfunc = LookupDefgenericByMdlOrScope(theEnv,DOToString(temp));
00516 if (gfunc == NULL)
00517 {
00518 PrintErrorID(theEnv,"GENRCFUN",3,FALSE);
00519 EnvPrintRouter(theEnv,WERROR,"Unable to find generic function ");
00520 EnvPrintRouter(theEnv,WERROR,DOToString(temp));
00521 EnvPrintRouter(theEnv,WERROR," in function preview-generic.\n");
00522 return;
00523 }
00524 oldce = ExecutingConstruct(theEnv);
00525 SetExecutingConstruct(theEnv,TRUE);
00526 previousGeneric = DefgenericData(theEnv)->CurrentGeneric;
00527 DefgenericData(theEnv)->CurrentGeneric = gfunc;
00528 EvaluationData(theEnv)->CurrentEvaluationDepth++;
00529 PushProcParameters(theEnv,GetFirstArgument()->nextArg,
00530 CountArguments(GetFirstArgument()->nextArg),
00531 EnvGetDefgenericName(theEnv,(void *) gfunc),"generic function",
00532 UnboundMethodErr);
00533 if (EvaluationData(theEnv)->EvaluationError)
00534 {
00535 PopProcParameters(theEnv);
00536 DefgenericData(theEnv)->CurrentGeneric = previousGeneric;
00537 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00538 SetExecutingConstruct(theEnv,oldce);
00539 return;
00540 }
00541 gfunc->busy++;
00542 DisplayGenericCore(theEnv,gfunc);
00543 gfunc->busy--;
00544 PopProcParameters(theEnv);
00545 DefgenericData(theEnv)->CurrentGeneric = previousGeneric;
00546 EvaluationData(theEnv)->CurrentEvaluationDepth--;
00547 SetExecutingConstruct(theEnv,oldce);
00548 }
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560 #if WIN_BTC
00561 #pragma argsused
00562 #endif
00563 globle void PrintMethod(
00564 void *theEnv,
00565 char *buf,
00566 int buflen,
00567 DEFMETHOD *meth)
00568 {
00569 #if MAC_MCW || WIN_MCW || MAC_XCD
00570 #pragma unused(theEnv)
00571 #endif
00572 long j,k;
00573 register RESTRICTION *rptr;
00574 char numbuf[15];
00575
00576 buf[0] = '\0';
00577 if (meth->system)
00578 genstrncpy(buf,"SYS",(STD_SIZE) buflen);
00579 gensprintf(numbuf,"%-2d ",meth->index);
00580 genstrncat(buf,numbuf,(STD_SIZE) buflen-3);
00581 for (j = 0 ; j < meth->restrictionCount ; j++)
00582 {
00583 rptr = &meth->restrictions[j];
00584 if ((((int) j) == meth->restrictionCount-1) && (meth->maxRestrictions == -1))
00585 {
00586 if ((rptr->tcnt == 0) && (rptr->query == NULL))
00587 {
00588 genstrncat(buf,"$?",buflen-strlen(buf));
00589 break;
00590 }
00591 genstrncat(buf,"($? ",buflen-strlen(buf));
00592 }
00593 else
00594 genstrncat(buf,"(",buflen-strlen(buf));
00595 for (k = 0 ; k < rptr->tcnt ; k++)
00596 {
00597 #if OBJECT_SYSTEM
00598 genstrncat(buf,EnvGetDefclassName(theEnv,rptr->types[k]),buflen-strlen(buf));
00599 #else
00600 genstrncat(buf,TypeName(theEnv,ValueToInteger(rptr->types[k])),buflen-strlen(buf));
00601 #endif
00602 if (((int) k) < (((int) rptr->tcnt) - 1))
00603 genstrncat(buf," ",buflen-strlen(buf));
00604 }
00605 if (rptr->query != NULL)
00606 {
00607 if (rptr->tcnt != 0)
00608 genstrncat(buf," ",buflen-strlen(buf));
00609 genstrncat(buf,"<qry>",buflen-strlen(buf));
00610 }
00611 genstrncat(buf,")",buflen-strlen(buf));
00612 if (((int) j) != (((int) meth->restrictionCount)-1))
00613 genstrncat(buf," ",buflen-strlen(buf));
00614 }
00615 }
00616
00617 #endif
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631 globle DEFGENERIC *CheckGenericExists(
00632 void *theEnv,
00633 char *fname,
00634 char *gname)
00635 {
00636 DEFGENERIC *gfunc;
00637
00638 gfunc = LookupDefgenericByMdlOrScope(theEnv,gname);
00639 if (gfunc == NULL)
00640 {
00641 PrintErrorID(theEnv,"GENRCFUN",3,FALSE);
00642 EnvPrintRouter(theEnv,WERROR,"Unable to find generic function ");
00643 EnvPrintRouter(theEnv,WERROR,gname);
00644 EnvPrintRouter(theEnv,WERROR," in function ");
00645 EnvPrintRouter(theEnv,WERROR,fname);
00646 EnvPrintRouter(theEnv,WERROR,".\n");
00647 SetEvaluationError(theEnv,TRUE);
00648 }
00649 return(gfunc);
00650 }
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664 globle long CheckMethodExists(
00665 void *theEnv,
00666 char *fname,
00667 DEFGENERIC *gfunc,
00668 long mi)
00669 {
00670 long fi;
00671
00672 fi = FindMethodByIndex(gfunc,mi);
00673 if (fi == -1)
00674 {
00675 PrintErrorID(theEnv,"GENRCFUN",2,FALSE);
00676 EnvPrintRouter(theEnv,WERROR,"Unable to find method ");
00677 EnvPrintRouter(theEnv,WERROR,EnvGetDefgenericName(theEnv,(void *) gfunc));
00678 EnvPrintRouter(theEnv,WERROR," #");
00679 PrintLongInteger(theEnv,WERROR,mi);
00680 EnvPrintRouter(theEnv,WERROR," in function ");
00681 EnvPrintRouter(theEnv,WERROR,fname);
00682 EnvPrintRouter(theEnv,WERROR,".\n");
00683 SetEvaluationError(theEnv,TRUE);
00684 }
00685 return(fi);
00686 }
00687
00688 #if ! OBJECT_SYSTEM
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 globle char *TypeName(
00704 void *theEnv,
00705 int tcode)
00706 {
00707 switch (tcode)
00708 {
00709 case INTEGER : return(INTEGER_TYPE_NAME);
00710 case FLOAT : return(FLOAT_TYPE_NAME);
00711 case SYMBOL : return(SYMBOL_TYPE_NAME);
00712 case STRING : return(STRING_TYPE_NAME);
00713 case MULTIFIELD : return(MULTIFIELD_TYPE_NAME);
00714 case EXTERNAL_ADDRESS : return(EXTERNAL_ADDRESS_TYPE_NAME);
00715 case FACT_ADDRESS : return(FACT_ADDRESS_TYPE_NAME);
00716 case INSTANCE_ADDRESS : return(INSTANCE_ADDRESS_TYPE_NAME);
00717 case INSTANCE_NAME : return(INSTANCE_NAME_TYPE_NAME);
00718 case OBJECT_TYPE_CODE : return(OBJECT_TYPE_NAME);
00719 case PRIMITIVE_TYPE_CODE : return(PRIMITIVE_TYPE_NAME);
00720 case NUMBER_TYPE_CODE : return(NUMBER_TYPE_NAME);
00721 case LEXEME_TYPE_CODE : return(LEXEME_TYPE_NAME);
00722 case ADDRESS_TYPE_CODE : return(ADDRESS_TYPE_NAME);
00723 case INSTANCE_TYPE_CODE : return(INSTANCE_TYPE_NAME);
00724 default : PrintErrorID(theEnv,"INSCOM",1,FALSE);
00725 EnvPrintRouter(theEnv,WERROR,"Undefined type in function type.\n");
00726 SetEvaluationError(theEnv,TRUE);
00727 return("<UNKNOWN-TYPE>");
00728 }
00729 }
00730
00731 #endif
00732
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 globle void PrintGenericName(
00745 void *theEnv,
00746 char *logName,
00747 DEFGENERIC *gfunc)
00748 {
00749 if (gfunc->header.whichModule->theModule != ((struct defmodule *) EnvGetCurrentModule(theEnv)))
00750 {
00751 EnvPrintRouter(theEnv,logName,EnvGetDefmoduleName(theEnv,(void *)
00752 gfunc->header.whichModule->theModule));
00753 EnvPrintRouter(theEnv,logName,"::");
00754 }
00755 EnvPrintRouter(theEnv,logName,ValueToString((void *) gfunc->header.name));
00756 }
00757
00758
00759
00760
00761
00762
00763
00764 #if DEBUGGING_FUNCTIONS
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776 static void DisplayGenericCore(
00777 void *theEnv,
00778 DEFGENERIC *gfunc)
00779 {
00780 long i;
00781 char buf[256];
00782 int rtn = FALSE;
00783
00784 for (i = 0 ; i < gfunc->mcnt ; i++)
00785 {
00786 gfunc->methods[i].busy++;
00787 if (IsMethodApplicable(theEnv,&gfunc->methods[i]))
00788 {
00789 rtn = TRUE;
00790 EnvPrintRouter(theEnv,WDISPLAY,EnvGetDefgenericName(theEnv,(void *) gfunc));
00791 EnvPrintRouter(theEnv,WDISPLAY," #");
00792 PrintMethod(theEnv,buf,255,&gfunc->methods[i]);
00793 EnvPrintRouter(theEnv,WDISPLAY,buf);
00794 EnvPrintRouter(theEnv,WDISPLAY,"\n");
00795 }
00796 gfunc->methods[i].busy--;
00797 }
00798 if (rtn == FALSE)
00799 {
00800 EnvPrintRouter(theEnv,WDISPLAY,"No applicable methods for ");
00801 EnvPrintRouter(theEnv,WDISPLAY,EnvGetDefgenericName(theEnv,(void *) gfunc));
00802 EnvPrintRouter(theEnv,WDISPLAY,".\n");
00803 }
00804 }
00805
00806 #endif
00807
00808 #endif
00809