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
00034 #include "setup.h"
00035
00036 #if OBJECT_SYSTEM && (! BLOAD_ONLY) && (! RUN_TIME)
00037
00038 #include <string.h>
00039
00040 #if BLOAD || BLOAD_AND_BSAVE
00041 #include "bload.h"
00042 #endif
00043
00044 #include "classcom.h"
00045 #include "classfun.h"
00046 #include "memalloc.h"
00047 #include "constrct.h"
00048 #include "cstrcpsr.h"
00049 #include "cstrnchk.h"
00050 #include "envrnmnt.h"
00051 #include "exprnpsr.h"
00052 #include "insfun.h"
00053 #include "msgcom.h"
00054 #include "msgfun.h"
00055 #include "pprint.h"
00056 #include "prccode.h"
00057 #include "router.h"
00058 #include "scanner.h"
00059 #include "strngrtr.h"
00060
00061 #define _MSGPSR_SOURCE_
00062 #include "msgpsr.h"
00063
00064
00065
00066
00067
00068
00069 #define SELF_LEN 4
00070 #define SELF_SLOT_REF ':'
00071
00072
00073
00074
00075
00076
00077
00078 static intBool IsParameterSlotReference(void *,char *);
00079 static int SlotReferenceVar(void *,EXPRESSION *,void *);
00080 static int BindSlotReference(void *,EXPRESSION *,void *);
00081 static SLOT_DESC *CheckSlotReference(void *,DEFCLASS *,int,void *,intBool,EXPRESSION *);
00082 static void GenHandlerSlotReference(void *,EXPRESSION *,unsigned short,SLOT_DESC *);
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 globle int ParseDefmessageHandler(
00105 void *theEnv,
00106 char *readSource)
00107 {
00108 DEFCLASS *cls;
00109 SYMBOL_HN *cname,*mname,*wildcard;
00110 unsigned mtype = MPRIMARY;
00111 int min,max,error,lvars;
00112 EXPRESSION *hndParams,*actions;
00113 HANDLER *hnd;
00114
00115 SetPPBufferStatus(theEnv,ON);
00116 FlushPPBuffer(theEnv);
00117 SetIndentDepth(theEnv,3);
00118 SavePPBuffer(theEnv,"(defmessage-handler ");
00119
00120 #if BLOAD || BLOAD_AND_BSAVE
00121 if ((Bloaded(theEnv)) && (! ConstructData(theEnv)->CheckSyntaxMode))
00122 {
00123 CannotLoadWithBloadMessage(theEnv,"defmessage-handler");
00124 return(TRUE);
00125 }
00126 #endif
00127 cname = GetConstructNameAndComment(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken,"defmessage-handler",
00128 NULL,NULL,"~",TRUE,FALSE,TRUE);
00129 if (cname == NULL)
00130 return(TRUE);
00131 cls = LookupDefclassByMdlOrScope(theEnv,ValueToString(cname));
00132 if (cls == NULL)
00133 {
00134 PrintErrorID(theEnv,"MSGPSR",1,FALSE);
00135 EnvPrintRouter(theEnv,WERROR,"A class must be defined before its message-handlers.\n");
00136 return(TRUE);
00137 }
00138 if ((cls == DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_NAME]) ||
00139 (cls == DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_ADDRESS]) ||
00140 (cls == DefclassData(theEnv)->PrimitiveClassMap[INSTANCE_NAME]->directSuperclasses.classArray[0]))
00141 {
00142 PrintErrorID(theEnv,"MSGPSR",8,FALSE);
00143 EnvPrintRouter(theEnv,WERROR,"Message-handlers cannot be attached to the class ");
00144 EnvPrintRouter(theEnv,WERROR,EnvGetDefclassName(theEnv,(void *) cls));
00145 EnvPrintRouter(theEnv,WERROR,".\n");
00146 return(TRUE);
00147 }
00148 if (HandlersExecuting(cls))
00149 {
00150 PrintErrorID(theEnv,"MSGPSR",2,FALSE);
00151 EnvPrintRouter(theEnv,WERROR,"Cannot (re)define message-handlers during execution of \n");
00152 EnvPrintRouter(theEnv,WERROR," other message-handlers for the same class.\n");
00153 return(TRUE);
00154 }
00155 if (GetType(DefclassData(theEnv)->ObjectParseToken) != SYMBOL)
00156 {
00157 SyntaxErrorMessage(theEnv,"defmessage-handler");
00158 return(TRUE);
00159 }
00160 PPBackup(theEnv);
00161 PPBackup(theEnv);
00162 SavePPBuffer(theEnv," ");
00163 SavePPBuffer(theEnv,DefclassData(theEnv)->ObjectParseToken.printForm);
00164 SavePPBuffer(theEnv," ");
00165 mname = (SYMBOL_HN *) GetValue(DefclassData(theEnv)->ObjectParseToken);
00166 GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
00167 if (GetType(DefclassData(theEnv)->ObjectParseToken) != LPAREN)
00168 {
00169 SavePPBuffer(theEnv," ");
00170 if (GetType(DefclassData(theEnv)->ObjectParseToken) != STRING)
00171 {
00172 if (GetType(DefclassData(theEnv)->ObjectParseToken) != SYMBOL)
00173 {
00174 SyntaxErrorMessage(theEnv,"defmessage-handler");
00175 return(TRUE);
00176 }
00177 mtype = HandlerType(theEnv,"defmessage-handler",DOToString(DefclassData(theEnv)->ObjectParseToken));
00178 if (mtype == MERROR)
00179 return(TRUE);
00180
00181 GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
00182 if (GetType(DefclassData(theEnv)->ObjectParseToken) == STRING)
00183 {
00184 SavePPBuffer(theEnv," ");
00185 GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
00186 }
00187 }
00188 else
00189 {
00190 SavePPBuffer(theEnv," ");
00191 GetToken(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken);
00192 }
00193 }
00194 PPBackup(theEnv);
00195 PPBackup(theEnv);
00196 PPCRAndIndent(theEnv);
00197 SavePPBuffer(theEnv,DefclassData(theEnv)->ObjectParseToken.printForm);
00198
00199 hnd = FindHandlerByAddress(cls,mname,mtype);
00200 if (GetPrintWhileLoading(theEnv) && GetCompilationsWatch(theEnv))
00201 {
00202 EnvPrintRouter(theEnv,WDIALOG," Handler ");
00203 EnvPrintRouter(theEnv,WDIALOG,ValueToString(mname));
00204 EnvPrintRouter(theEnv,WDIALOG," ");
00205 EnvPrintRouter(theEnv,WDIALOG,MessageHandlerData(theEnv)->hndquals[mtype]);
00206 if (hnd == NULL)
00207 EnvPrintRouter(theEnv,WDIALOG," defined.\n");
00208 else
00209 EnvPrintRouter(theEnv,WDIALOG," redefined.\n");
00210 }
00211
00212 if ((hnd != NULL) ? hnd->system : FALSE)
00213 {
00214 PrintErrorID(theEnv,"MSGPSR",3,FALSE);
00215 EnvPrintRouter(theEnv,WERROR,"System message-handlers may not be modified.\n");
00216 return(TRUE);
00217 }
00218
00219 hndParams = GenConstant(theEnv,SYMBOL,(void *) MessageHandlerData(theEnv)->SELF_SYMBOL);
00220 hndParams = ParseProcParameters(theEnv,readSource,&DefclassData(theEnv)->ObjectParseToken,hndParams,
00221 &wildcard,&min,&max,&error,IsParameterSlotReference);
00222 if (error)
00223 return(TRUE);
00224 PPCRAndIndent(theEnv);
00225 ExpressionData(theEnv)->ReturnContext = TRUE;
00226 actions = ParseProcActions(theEnv,"message-handler",readSource,
00227 &DefclassData(theEnv)->ObjectParseToken,hndParams,wildcard,
00228 SlotReferenceVar,BindSlotReference,&lvars,
00229 (void *) cls);
00230 if (actions == NULL)
00231 {
00232 ReturnExpression(theEnv,hndParams);
00233 return(TRUE);
00234 }
00235 if (GetType(DefclassData(theEnv)->ObjectParseToken) != RPAREN)
00236 {
00237 SyntaxErrorMessage(theEnv,"defmessage-handler");
00238 ReturnExpression(theEnv,hndParams);
00239 ReturnPackedExpression(theEnv,actions);
00240 return(TRUE);
00241 }
00242 PPBackup(theEnv);
00243 PPBackup(theEnv);
00244 SavePPBuffer(theEnv,DefclassData(theEnv)->ObjectParseToken.printForm);
00245 SavePPBuffer(theEnv,"\n");
00246
00247
00248
00249
00250
00251
00252 if (ConstructData(theEnv)->CheckSyntaxMode)
00253 {
00254 ReturnExpression(theEnv,hndParams);
00255 ReturnPackedExpression(theEnv,actions);
00256 return(FALSE);
00257 }
00258
00259 if (hnd != NULL)
00260 {
00261 ExpressionDeinstall(theEnv,hnd->actions);
00262 ReturnPackedExpression(theEnv,hnd->actions);
00263 if (hnd->ppForm != NULL)
00264 rm(theEnv,(void *) hnd->ppForm,
00265 (sizeof(char) * (strlen(hnd->ppForm)+1)));
00266 }
00267 else
00268 {
00269 hnd = InsertHandlerHeader(theEnv,cls,mname,(int) mtype);
00270 IncrementSymbolCount(hnd->name);
00271 }
00272 ReturnExpression(theEnv,hndParams);
00273
00274 hnd->minParams = (short) min;
00275 hnd->maxParams = (short) max;
00276 hnd->localVarCount = (short) lvars;
00277 hnd->actions = actions;
00278 ExpressionInstall(theEnv,hnd->actions);
00279 #if DEBUGGING_FUNCTIONS
00280
00281
00282
00283
00284 if (EnvGetConserveMemory(theEnv) == FALSE)
00285 hnd->ppForm = CopyPPBuffer(theEnv);
00286 else
00287 #endif
00288 hnd->ppForm = NULL;
00289 return(FALSE);
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 globle void CreateGetAndPutHandlers(
00316 void *theEnv,
00317 SLOT_DESC *sd)
00318 {
00319 char *className,*slotName;
00320 size_t bufsz;
00321 char *buf,*handlerRouter = "*** Default Public Handlers ***";
00322 int oldPWL,oldCM;
00323 char *oldRouter;
00324 char *oldString;
00325 long oldIndex;
00326
00327 if ((sd->createReadAccessor == 0) && (sd->createWriteAccessor == 0))
00328 return;
00329 className = ValueToString(sd->cls->header.name);
00330 slotName = ValueToString(sd->slotName->name);
00331
00332 bufsz = (sizeof(char) * (strlen(className) + (strlen(slotName) * 2) + 80));
00333 buf = (char *) gm2(theEnv,bufsz);
00334
00335 oldPWL = GetPrintWhileLoading(theEnv);
00336 SetPrintWhileLoading(theEnv,FALSE);
00337 oldCM = EnvSetConserveMemory(theEnv,TRUE);
00338
00339 if (sd->createReadAccessor)
00340 {
00341 gensprintf(buf,"%s get-%s () ?self:%s)",className,slotName,slotName);
00342
00343 oldRouter = RouterData(theEnv)->FastCharGetRouter;
00344 oldString = RouterData(theEnv)->FastCharGetString;
00345 oldIndex = RouterData(theEnv)->FastCharGetIndex;
00346
00347 RouterData(theEnv)->FastCharGetRouter = handlerRouter;
00348 RouterData(theEnv)->FastCharGetIndex = 0;
00349 RouterData(theEnv)->FastCharGetString = buf;
00350
00351 ParseDefmessageHandler(theEnv,handlerRouter);
00352 DestroyPPBuffer(theEnv);
00353
00354
00355
00356
00357
00358
00359
00360
00361 RouterData(theEnv)->FastCharGetRouter = oldRouter;
00362 RouterData(theEnv)->FastCharGetIndex = oldIndex;
00363 RouterData(theEnv)->FastCharGetString = oldString;
00364 }
00365
00366 if (sd->createWriteAccessor)
00367 {
00368 gensprintf(buf,"%s put-%s ($?value) (bind ?self:%s ?value))",
00369 className,slotName,slotName);
00370
00371 oldRouter = RouterData(theEnv)->FastCharGetRouter;
00372 oldString = RouterData(theEnv)->FastCharGetString;
00373 oldIndex = RouterData(theEnv)->FastCharGetIndex;
00374
00375 RouterData(theEnv)->FastCharGetRouter = handlerRouter;
00376 RouterData(theEnv)->FastCharGetIndex = 0;
00377 RouterData(theEnv)->FastCharGetString = buf;
00378
00379 ParseDefmessageHandler(theEnv,handlerRouter);
00380 DestroyPPBuffer(theEnv);
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 RouterData(theEnv)->FastCharGetRouter = oldRouter;
00391 RouterData(theEnv)->FastCharGetIndex = oldIndex;
00392 RouterData(theEnv)->FastCharGetString = oldString;
00393 }
00394
00395 SetPrintWhileLoading(theEnv,oldPWL);
00396 EnvSetConserveMemory(theEnv,oldCM);
00397
00398 rm(theEnv,(void *) buf,bufsz);
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418 static intBool IsParameterSlotReference(
00419 void *theEnv,
00420 char *pname)
00421 {
00422 if ((strncmp(pname,SELF_STRING,SELF_LEN) == 0) ?
00423 (pname[SELF_LEN] == SELF_SLOT_REF) : FALSE)
00424 {
00425 PrintErrorID(theEnv,"MSGPSR",4,FALSE);
00426 EnvPrintRouter(theEnv,WERROR,"Illegal slot reference in parameter list.\n");
00427 return(TRUE);
00428 }
00429 return(FALSE);
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 static int SlotReferenceVar(
00453 void *theEnv,
00454 EXPRESSION *varexp,
00455 void *userBuffer)
00456 {
00457 struct token itkn;
00458 int oldpp;
00459 SLOT_DESC *sd;
00460
00461 if ((varexp->type != SF_VARIABLE) && (varexp->type != MF_VARIABLE))
00462 return(0);
00463 if ((strncmp(ValueToString(varexp->value),SELF_STRING,SELF_LEN) == 0) ?
00464 (ValueToString(varexp->value)[SELF_LEN] == SELF_SLOT_REF) : FALSE)
00465 {
00466 OpenStringSource(theEnv,"hnd-var",ValueToString(varexp->value) + SELF_LEN + 1,0);
00467 oldpp = GetPPBufferStatus(theEnv);
00468 SetPPBufferStatus(theEnv,OFF);
00469 GetToken(theEnv,"hnd-var",&itkn);
00470 SetPPBufferStatus(theEnv,oldpp);
00471 CloseStringSource(theEnv,"hnd-var");
00472 if (itkn.type != STOP)
00473 {
00474 sd = CheckSlotReference(theEnv,(DEFCLASS *) userBuffer,itkn.type,itkn.value,
00475 FALSE,NULL);
00476 if (sd == NULL)
00477 return(-1);
00478 GenHandlerSlotReference(theEnv,varexp,HANDLER_GET,sd);
00479 return(1);
00480 }
00481 }
00482 return(0);
00483 }
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 static int BindSlotReference(
00505 void *theEnv,
00506 EXPRESSION *bindExp,
00507 void *userBuffer)
00508 {
00509 char *bindName;
00510 struct token itkn;
00511 int oldpp;
00512 SLOT_DESC *sd;
00513 EXPRESSION *saveExp;
00514
00515 bindName = ValueToString(bindExp->argList->value);
00516 if (strcmp(bindName,SELF_STRING) == 0)
00517 {
00518 PrintErrorID(theEnv,"MSGPSR",5,FALSE);
00519 EnvPrintRouter(theEnv,WERROR,"Active instance parameter cannot be changed.\n");
00520 return(-1);
00521 }
00522 if ((strncmp(bindName,SELF_STRING,SELF_LEN) == 0) ?
00523 (bindName[SELF_LEN] == SELF_SLOT_REF) : FALSE)
00524 {
00525 OpenStringSource(theEnv,"hnd-var",bindName + SELF_LEN + 1,0);
00526 oldpp = GetPPBufferStatus(theEnv);
00527 SetPPBufferStatus(theEnv,OFF);
00528 GetToken(theEnv,"hnd-var",&itkn);
00529 SetPPBufferStatus(theEnv,oldpp);
00530 CloseStringSource(theEnv,"hnd-var");
00531 if (itkn.type != STOP)
00532 {
00533 saveExp = bindExp->argList->nextArg;
00534 sd = CheckSlotReference(theEnv,(DEFCLASS *) userBuffer,itkn.type,itkn.value,
00535 TRUE,saveExp);
00536 if (sd == NULL)
00537 return(-1);
00538 GenHandlerSlotReference(theEnv,bindExp,HANDLER_PUT,sd);
00539 bindExp->argList->nextArg = NULL;
00540 ReturnExpression(theEnv,bindExp->argList);
00541 bindExp->argList = saveExp;
00542 return(1);
00543 }
00544 }
00545 return(0);
00546 }
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575 static SLOT_DESC *CheckSlotReference(
00576 void *theEnv,
00577 DEFCLASS *theDefclass,
00578 int theType,
00579 void *theValue,
00580 intBool writeFlag,
00581 EXPRESSION *writeExpression)
00582 {
00583 int slotIndex;
00584 SLOT_DESC *sd;
00585 int vCode;
00586
00587 if (theType != SYMBOL)
00588 {
00589 PrintErrorID(theEnv,"MSGPSR",7,FALSE);
00590 EnvPrintRouter(theEnv,WERROR,"Illegal value for ?self reference.\n");
00591 return(NULL);
00592 }
00593 slotIndex = FindInstanceTemplateSlot(theEnv,theDefclass,(SYMBOL_HN *) theValue);
00594 if (slotIndex == -1)
00595 {
00596 PrintErrorID(theEnv,"MSGPSR",6,FALSE);
00597 EnvPrintRouter(theEnv,WERROR,"No such slot ");
00598 EnvPrintRouter(theEnv,WERROR,ValueToString(theValue));
00599 EnvPrintRouter(theEnv,WERROR," in class ");
00600 EnvPrintRouter(theEnv,WERROR,EnvGetDefclassName(theEnv,(void *) theDefclass));
00601 EnvPrintRouter(theEnv,WERROR," for ?self reference.\n");
00602 return(NULL);
00603 }
00604 sd = theDefclass->instanceTemplate[slotIndex];
00605 if ((sd->publicVisibility == 0) && (sd->cls != theDefclass))
00606 {
00607 SlotVisibilityViolationError(theEnv,sd,theDefclass);
00608 return(NULL);
00609 }
00610 if (! writeFlag)
00611 return(sd);
00612
00613
00614
00615
00616
00617
00618
00619 if (sd->noWrite && (sd->initializeOnly == 0))
00620 {
00621 SlotAccessViolationError(theEnv,ValueToString(theValue),
00622 FALSE,(void *) theDefclass);
00623 return(NULL);
00624 }
00625
00626 if (EnvGetStaticConstraintChecking(theEnv))
00627 {
00628 vCode = ConstraintCheckExpressionChain(theEnv,writeExpression,sd->constraint);
00629 if (vCode != NO_VIOLATION)
00630 {
00631 PrintErrorID(theEnv,"CSTRNCHK",1,FALSE);
00632 EnvPrintRouter(theEnv,WERROR,"Expression for ");
00633 PrintSlot(theEnv,WERROR,sd,NULL,"direct slot write");
00634 ConstraintViolationErrorMessage(theEnv,NULL,NULL,0,0,NULL,0,
00635 vCode,sd->constraint,FALSE);
00636 return(NULL);
00637 }
00638 }
00639 return(sd);
00640 }
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657 static void GenHandlerSlotReference(
00658 void *theEnv,
00659 EXPRESSION *theExp,
00660 unsigned short theType,
00661 SLOT_DESC *sd)
00662 {
00663 HANDLER_SLOT_REFERENCE handlerReference;
00664
00665 ClearBitString(&handlerReference,sizeof(HANDLER_SLOT_REFERENCE));
00666 handlerReference.classID = (unsigned short) sd->cls->id;
00667 handlerReference.slotID = (unsigned) sd->slotName->id;
00668 theExp->type = theType;
00669 theExp->value = EnvAddBitMap(theEnv,(void *) &handlerReference,
00670 (int) sizeof(HANDLER_SLOT_REFERENCE));
00671 }
00672
00673 #endif
00674
00675
00676
00677
00678
00679
00680
00681
00682