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 #include "setup.h"
00033
00034 #if INSTANCE_SET_QUERIES && (! RUN_TIME)
00035
00036 #include <string.h>
00037
00038 #include "classcom.h"
00039 #include "envrnmnt.h"
00040 #include "exprnpsr.h"
00041 #include "extnfunc.h"
00042 #include "insquery.h"
00043 #include "prcdrpsr.h"
00044 #include "prntutil.h"
00045 #include "router.h"
00046 #include "scanner.h"
00047 #include "strngrtr.h"
00048
00049 #define _INSQYPSR_SOURCE_
00050 #include "insqypsr.h"
00051
00052
00053
00054
00055
00056
00057 #define INSTANCE_SLOT_REF ':'
00058
00059
00060
00061
00062
00063
00064
00065 static EXPRESSION *ParseQueryRestrictions(void *,EXPRESSION *,char *,struct token *);
00066 static intBool ReplaceClassNameWithReference(void *,EXPRESSION *);
00067 static int ParseQueryTestExpression(void *,EXPRESSION *,char *);
00068 static int ParseQueryActionExpression(void *,EXPRESSION *,char *,EXPRESSION *,struct token *);
00069 static void ReplaceInstanceVariables(void *,EXPRESSION *,EXPRESSION *,int,int);
00070 static void ReplaceSlotReference(void *,EXPRESSION *,EXPRESSION *,
00071 struct FunctionDefinition *,int);
00072 static int IsQueryFunction(EXPRESSION *);
00073
00074
00075
00076
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 globle EXPRESSION *ParseQueryNoAction(
00110 void *theEnv,
00111 EXPRESSION *top,
00112 char *readSource)
00113 {
00114 EXPRESSION *insQuerySetVars;
00115 struct token queryInputToken;
00116
00117 insQuerySetVars = ParseQueryRestrictions(theEnv,top,readSource,&queryInputToken);
00118 if (insQuerySetVars == NULL)
00119 return(NULL);
00120 IncrementIndentDepth(theEnv,3);
00121 PPCRAndIndent(theEnv);
00122 if (ParseQueryTestExpression(theEnv,top,readSource) == FALSE)
00123 {
00124 DecrementIndentDepth(theEnv,3);
00125 ReturnExpression(theEnv,insQuerySetVars);
00126 return(NULL);
00127 }
00128 DecrementIndentDepth(theEnv,3);
00129 GetToken(theEnv,readSource,&queryInputToken);
00130 if (GetType(queryInputToken) != RPAREN)
00131 {
00132 SyntaxErrorMessage(theEnv,"instance-set query function");
00133 ReturnExpression(theEnv,top);
00134 ReturnExpression(theEnv,insQuerySetVars);
00135 return(NULL);
00136 }
00137 ReplaceInstanceVariables(theEnv,insQuerySetVars,top->argList,TRUE,0);
00138 ReturnExpression(theEnv,insQuerySetVars);
00139 return(top);
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 globle EXPRESSION *ParseQueryAction(
00172 void *theEnv,
00173 EXPRESSION *top,
00174 char *readSource)
00175 {
00176 EXPRESSION *insQuerySetVars;
00177 struct token queryInputToken;
00178
00179 insQuerySetVars = ParseQueryRestrictions(theEnv,top,readSource,&queryInputToken);
00180 if (insQuerySetVars == NULL)
00181 return(NULL);
00182 IncrementIndentDepth(theEnv,3);
00183 PPCRAndIndent(theEnv);
00184 if (ParseQueryTestExpression(theEnv,top,readSource) == FALSE)
00185 {
00186 DecrementIndentDepth(theEnv,3);
00187 ReturnExpression(theEnv,insQuerySetVars);
00188 return(NULL);
00189 }
00190 PPCRAndIndent(theEnv);
00191 if (ParseQueryActionExpression(theEnv,top,readSource,insQuerySetVars,&queryInputToken) == FALSE)
00192 {
00193 DecrementIndentDepth(theEnv,3);
00194 ReturnExpression(theEnv,insQuerySetVars);
00195 return(NULL);
00196 }
00197 DecrementIndentDepth(theEnv,3);
00198
00199 if (GetType(queryInputToken) != RPAREN)
00200 {
00201 SyntaxErrorMessage(theEnv,"instance-set query function");
00202 ReturnExpression(theEnv,top);
00203 ReturnExpression(theEnv,insQuerySetVars);
00204 return(NULL);
00205 }
00206 ReplaceInstanceVariables(theEnv,insQuerySetVars,top->argList,TRUE,0);
00207 ReplaceInstanceVariables(theEnv,insQuerySetVars,top->argList->nextArg,FALSE,0);
00208 ReturnExpression(theEnv,insQuerySetVars);
00209 return(top);
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232 static EXPRESSION *ParseQueryRestrictions(
00233 void *theEnv,
00234 EXPRESSION *top,
00235 char *readSource,
00236 struct token *queryInputToken)
00237 {
00238 EXPRESSION *insQuerySetVars = NULL,*lastInsQuerySetVars = NULL,
00239 *classExp = NULL,*lastClassExp,
00240 *tmp,*lastOne = NULL;
00241 int error = FALSE;
00242
00243 SavePPBuffer(theEnv," ");
00244 GetToken(theEnv,readSource,queryInputToken);
00245 if (queryInputToken->type != LPAREN)
00246 goto ParseQueryRestrictionsError1;
00247 GetToken(theEnv,readSource,queryInputToken);
00248 if (queryInputToken->type != LPAREN)
00249 goto ParseQueryRestrictionsError1;
00250 while (queryInputToken->type == LPAREN)
00251 {
00252 GetToken(theEnv,readSource,queryInputToken);
00253 if (queryInputToken->type != SF_VARIABLE)
00254 goto ParseQueryRestrictionsError1;
00255 tmp = insQuerySetVars;
00256 while (tmp != NULL)
00257 {
00258 if (tmp->value == queryInputToken->value)
00259 {
00260 PrintErrorID(theEnv,"INSQYPSR",1,FALSE);
00261 EnvPrintRouter(theEnv,WERROR,"Duplicate instance member variable name in function ");
00262 EnvPrintRouter(theEnv,WERROR,ValueToString(ExpressionFunctionCallName(top)));
00263 EnvPrintRouter(theEnv,WERROR,".\n");
00264 goto ParseQueryRestrictionsError2;
00265 }
00266 tmp = tmp->nextArg;
00267 }
00268 tmp = GenConstant(theEnv,SF_VARIABLE,queryInputToken->value);
00269 if (insQuerySetVars == NULL)
00270 insQuerySetVars = tmp;
00271 else
00272 lastInsQuerySetVars->nextArg = tmp;
00273 lastInsQuerySetVars = tmp;
00274 SavePPBuffer(theEnv," ");
00275 classExp = ArgumentParse(theEnv,readSource,&error);
00276 if (error)
00277 goto ParseQueryRestrictionsError2;
00278 if (classExp == NULL)
00279 goto ParseQueryRestrictionsError1;
00280 if (ReplaceClassNameWithReference(theEnv,classExp) == FALSE)
00281 goto ParseQueryRestrictionsError2;
00282 lastClassExp = classExp;
00283 SavePPBuffer(theEnv," ");
00284 while ((tmp = ArgumentParse(theEnv,readSource,&error)) != NULL)
00285 {
00286 if (ReplaceClassNameWithReference(theEnv,tmp) == FALSE)
00287 goto ParseQueryRestrictionsError2;
00288 lastClassExp->nextArg = tmp;
00289 lastClassExp = tmp;
00290 SavePPBuffer(theEnv," ");
00291 }
00292 if (error)
00293 goto ParseQueryRestrictionsError2;
00294 PPBackup(theEnv);
00295 PPBackup(theEnv);
00296 SavePPBuffer(theEnv,")");
00297 tmp = GenConstant(theEnv,SYMBOL,(void *) InstanceQueryData(theEnv)->QUERY_DELIMETER_SYMBOL);
00298 lastClassExp->nextArg = tmp;
00299 lastClassExp = tmp;
00300 if (top->argList == NULL)
00301 top->argList = classExp;
00302 else
00303 lastOne->nextArg = classExp;
00304 lastOne = lastClassExp;
00305 classExp = NULL;
00306 SavePPBuffer(theEnv," ");
00307 GetToken(theEnv,readSource,queryInputToken);
00308 }
00309 if (queryInputToken->type != RPAREN)
00310 goto ParseQueryRestrictionsError1;
00311 PPBackup(theEnv);
00312 PPBackup(theEnv);
00313 SavePPBuffer(theEnv,")");
00314 return(insQuerySetVars);
00315
00316 ParseQueryRestrictionsError1:
00317 SyntaxErrorMessage(theEnv,"instance-set query function");
00318
00319 ParseQueryRestrictionsError2:
00320 ReturnExpression(theEnv,classExp);
00321 ReturnExpression(theEnv,top);
00322 ReturnExpression(theEnv,insQuerySetVars);
00323 return(NULL);
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 static intBool ReplaceClassNameWithReference(
00341 void *theEnv,
00342 EXPRESSION *theExp)
00343 {
00344 char *theClassName;
00345 void *theDefclass;
00346
00347 if (theExp->type == SYMBOL)
00348 {
00349 theClassName = ValueToString(theExp->value);
00350 theDefclass = (void *) LookupDefclassByMdlOrScope(theEnv,theClassName);
00351 if (theDefclass == NULL)
00352 {
00353 CantFindItemErrorMessage(theEnv,"class",theClassName);
00354 return(FALSE);
00355 }
00356 theExp->type = DEFCLASS_PTR;
00357 theExp->value = theDefclass;
00358 }
00359 return(TRUE);
00360 }
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 static int ParseQueryTestExpression(
00375 void *theEnv,
00376 EXPRESSION *top,
00377 char *readSource)
00378 {
00379 EXPRESSION *qtest;
00380 int error;
00381 struct BindInfo *oldBindList;
00382
00383 error = FALSE;
00384 oldBindList = GetParsedBindNames(theEnv);
00385 SetParsedBindNames(theEnv,NULL);
00386 qtest = ArgumentParse(theEnv,readSource,&error);
00387 if (error == TRUE)
00388 {
00389 SetParsedBindNames(theEnv,oldBindList);
00390 ReturnExpression(theEnv,top);
00391 return(FALSE);
00392 }
00393 if (qtest == NULL)
00394 {
00395 SetParsedBindNames(theEnv,oldBindList);
00396 SyntaxErrorMessage(theEnv,"instance-set query function");
00397 ReturnExpression(theEnv,top);
00398 return(FALSE);
00399 }
00400 qtest->nextArg = top->argList;
00401 top->argList = qtest;
00402 if (ParsedBindNamesEmpty(theEnv) == FALSE)
00403 {
00404 ClearParsedBindNames(theEnv);
00405 SetParsedBindNames(theEnv,oldBindList);
00406 PrintErrorID(theEnv,"INSQYPSR",2,FALSE);
00407 EnvPrintRouter(theEnv,WERROR,"Binds are not allowed in instance-set query in function ");
00408 EnvPrintRouter(theEnv,WERROR,ValueToString(ExpressionFunctionCallName(top)));
00409 EnvPrintRouter(theEnv,WERROR,".\n");
00410 ReturnExpression(theEnv,top);
00411 return(FALSE);
00412 }
00413 SetParsedBindNames(theEnv,oldBindList);
00414 return(TRUE);
00415 }
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431 static int ParseQueryActionExpression(
00432 void *theEnv,
00433 EXPRESSION *top,
00434 char *readSource,
00435 EXPRESSION *insQuerySetVars,
00436 struct token *queryInputToken)
00437 {
00438 EXPRESSION *qaction,*tmpInsSetVars;
00439 int error;
00440 struct BindInfo *oldBindList,*newBindList,*prev;
00441
00442 error = FALSE;
00443 oldBindList = GetParsedBindNames(theEnv);
00444 SetParsedBindNames(theEnv,NULL);
00445 ExpressionData(theEnv)->BreakContext = TRUE;
00446 ExpressionData(theEnv)->ReturnContext = ExpressionData(theEnv)->svContexts->rtn;
00447
00448 qaction = GroupActions(theEnv,readSource,queryInputToken,TRUE,NULL,FALSE);
00449 PPBackup(theEnv);
00450 PPBackup(theEnv);
00451 SavePPBuffer(theEnv,queryInputToken->printForm);
00452
00453 ExpressionData(theEnv)->BreakContext = FALSE;
00454 if (error == TRUE)
00455 {
00456 SetParsedBindNames(theEnv,oldBindList);
00457 ReturnExpression(theEnv,top);
00458 return(FALSE);
00459 }
00460 if (qaction == NULL)
00461 {
00462 SetParsedBindNames(theEnv,oldBindList);
00463 SyntaxErrorMessage(theEnv,"instance-set query function");
00464 ReturnExpression(theEnv,top);
00465 return(FALSE);
00466 }
00467 qaction->nextArg = top->argList->nextArg;
00468 top->argList->nextArg = qaction;
00469 newBindList = GetParsedBindNames(theEnv);
00470 prev = NULL;
00471 while (newBindList != NULL)
00472 {
00473 tmpInsSetVars = insQuerySetVars;
00474 while (tmpInsSetVars != NULL)
00475 {
00476 if (tmpInsSetVars->value == (void *) newBindList->name)
00477 {
00478 ClearParsedBindNames(theEnv);
00479 SetParsedBindNames(theEnv,oldBindList);
00480 PrintErrorID(theEnv,"INSQYPSR",3,FALSE);
00481 EnvPrintRouter(theEnv,WERROR,"Cannot rebind instance-set member variable ");
00482 EnvPrintRouter(theEnv,WERROR,ValueToString(tmpInsSetVars->value));
00483 EnvPrintRouter(theEnv,WERROR," in function ");
00484 EnvPrintRouter(theEnv,WERROR,ValueToString(ExpressionFunctionCallName(top)));
00485 EnvPrintRouter(theEnv,WERROR,".\n");
00486 ReturnExpression(theEnv,top);
00487 return(FALSE);
00488 }
00489 tmpInsSetVars = tmpInsSetVars->nextArg;
00490 }
00491 prev = newBindList;
00492 newBindList = newBindList->next;
00493 }
00494 if (prev == NULL)
00495 SetParsedBindNames(theEnv,oldBindList);
00496 else
00497 prev->next = oldBindList;
00498 return(TRUE);
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 static void ReplaceInstanceVariables(
00521 void *theEnv,
00522 EXPRESSION *vlist,
00523 EXPRESSION *bexp,
00524 int sdirect,
00525 int ndepth)
00526 {
00527 EXPRESSION *eptr;
00528 struct FunctionDefinition *rindx_func,*rslot_func;
00529 int posn;
00530
00531 rindx_func = FindFunction(theEnv,"(query-instance)");
00532 rslot_func = FindFunction(theEnv,"(query-instance-slot)");
00533 while (bexp != NULL)
00534 {
00535 if (bexp->type == SF_VARIABLE)
00536 {
00537 eptr = vlist;
00538 posn = 0;
00539 while ((eptr != NULL) ? (eptr->value != bexp->value) : FALSE)
00540 {
00541 eptr = eptr->nextArg;
00542 posn++;
00543 }
00544 if (eptr != NULL)
00545 {
00546 bexp->type = FCALL;
00547 bexp->value = (void *) rindx_func;
00548 eptr = GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) ndepth));
00549 eptr->nextArg = GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) posn));
00550 bexp->argList = eptr;
00551 }
00552 else if (sdirect == TRUE)
00553 ReplaceSlotReference(theEnv,vlist,bexp,rslot_func,ndepth);
00554 }
00555 if (bexp->argList != NULL)
00556 {
00557 if (IsQueryFunction(bexp))
00558 ReplaceInstanceVariables(theEnv,vlist,bexp->argList,sdirect,ndepth+1);
00559 else
00560 ReplaceInstanceVariables(theEnv,vlist,bexp->argList,sdirect,ndepth);
00561 }
00562 bexp = bexp->nextArg;
00563 }
00564 }
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581 static void ReplaceSlotReference(
00582 void *theEnv,
00583 EXPRESSION *vlist,
00584 EXPRESSION *theExp,
00585 struct FunctionDefinition *func,
00586 int ndepth)
00587 {
00588 size_t len;
00589 int posn,oldpp;
00590 size_t i;
00591 register char *str;
00592 EXPRESSION *eptr;
00593 struct token itkn;
00594
00595 str = ValueToString(theExp->value);
00596 len = strlen(str);
00597 if (len < 3)
00598 return;
00599 for (i = len-2 ; i >= 1 ; i--)
00600 {
00601 if ((str[i] == INSTANCE_SLOT_REF) ? (i >= 1) : FALSE)
00602 {
00603 eptr = vlist;
00604 posn = 0;
00605 while (eptr && ((i != strlen(ValueToString(eptr->value))) ||
00606 strncmp(ValueToString(eptr->value),str,
00607 (STD_SIZE) i)))
00608 {
00609 eptr = eptr->nextArg;
00610 posn++;
00611 }
00612 if (eptr != NULL)
00613 {
00614 OpenStringSource(theEnv,"query-var",str+i+1,0);
00615 oldpp = GetPPBufferStatus(theEnv);
00616 SetPPBufferStatus(theEnv,OFF);
00617 GetToken(theEnv,"query-var",&itkn);
00618 SetPPBufferStatus(theEnv,oldpp);
00619 CloseStringSource(theEnv,"query-var");
00620 theExp->type = FCALL;
00621 theExp->value = (void *) func;
00622 theExp->argList = GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) ndepth));
00623 theExp->argList->nextArg =
00624 GenConstant(theEnv,INTEGER,(void *) EnvAddLong(theEnv,(long long) posn));
00625 theExp->argList->nextArg->nextArg = GenConstant(theEnv,itkn.type,itkn.value);
00626 break;
00627 }
00628 }
00629 }
00630 }
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640 static int IsQueryFunction(
00641 EXPRESSION *theExp)
00642 {
00643 int (*fptr)(void);
00644
00645 if (theExp->type != FCALL)
00646 return(FALSE);
00647 fptr = (int (*)(void)) ExpressionFunctionPointer(theExp);
00648 if (fptr == (int (*)(void)) AnyInstances)
00649 return(TRUE);
00650 if (fptr == (int (*)(void)) QueryFindInstance)
00651 return(TRUE);
00652 if (fptr == (int (*)(void)) QueryFindAllInstances)
00653 return(TRUE);
00654 if (fptr == (int (*)(void)) QueryDoForInstance)
00655 return(TRUE);
00656 if (fptr == (int (*)(void)) QueryDoForAllInstances)
00657 return(TRUE);
00658 if (fptr == (int (*)(void)) DelayedQueryDoForAllInstances)
00659 return(TRUE);
00660 return(FALSE);
00661 }
00662
00663 #endif
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674