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