00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #define _TMPLTPSR_SOURCE_
00024
00025 #include "setup.h"
00026
00027 #if DEFTEMPLATE_CONSTRUCT
00028
00029 #include <stdio.h>
00030 #define _STDIO_INCLUDED_
00031 #include <string.h>
00032
00033 #include "constant.h"
00034 #include "memalloc.h"
00035 #include "symbol.h"
00036 #include "scanner.h"
00037 #include "exprnpsr.h"
00038 #include "router.h"
00039 #include "constrct.h"
00040 #include "envrnmnt.h"
00041 #include "factmngr.h"
00042 #include "cstrnchk.h"
00043 #include "cstrnpsr.h"
00044 #include "cstrcpsr.h"
00045 #if BLOAD || BLOAD_AND_BSAVE
00046 #include "bload.h"
00047 #endif
00048 #include "default.h"
00049 #include "pattern.h"
00050 #include "watch.h"
00051 #include "cstrnutl.h"
00052
00053 #include "tmpltdef.h"
00054 #include "tmpltbsc.h"
00055
00056 #include "tmpltpsr.h"
00057
00058
00059
00060
00061
00062 #if (! RUN_TIME) && (! BLOAD_ONLY)
00063 static struct templateSlot *SlotDeclarations(void *,char *,struct token *);
00064 static struct templateSlot *ParseSlot(void *,char *,struct token *,struct templateSlot *);
00065 static struct templateSlot *DefinedSlots(void *,char *,SYMBOL_HN *,int,struct token *);
00066 static intBool ParseFacetAttribute(void *,char *,struct templateSlot *,intBool);
00067 #endif
00068
00069
00070
00071
00072 globle int ParseDeftemplate(
00073 void *theEnv,
00074 char *readSource)
00075 {
00076 #if (MAC_MCW || WIN_MCW) && (RUN_TIME || BLOAD_ONLY)
00077 #pragma unused(readSource)
00078 #endif
00079
00080 #if (! RUN_TIME) && (! BLOAD_ONLY)
00081 SYMBOL_HN *deftemplateName;
00082 struct deftemplate *newDeftemplate;
00083 struct templateSlot *slots;
00084 struct token inputToken;
00085
00086
00087
00088
00089
00090 DeftemplateData(theEnv)->DeftemplateError = FALSE;
00091 SetPPBufferStatus(theEnv,ON);
00092 FlushPPBuffer(theEnv);
00093 SavePPBuffer(theEnv,"(deftemplate ");
00094
00095
00096
00097
00098
00099 #if BLOAD || BLOAD_AND_BSAVE
00100 if ((Bloaded(theEnv) == TRUE) && (! ConstructData(theEnv)->CheckSyntaxMode))
00101 {
00102 CannotLoadWithBloadMessage(theEnv,"deftemplate");
00103 return(TRUE);
00104 }
00105 #endif
00106
00107
00108
00109
00110
00111 #if DEBUGGING_FUNCTIONS
00112 DeftemplateData(theEnv)->DeletedTemplateDebugFlags = 0;
00113 #endif
00114
00115 deftemplateName = GetConstructNameAndComment(theEnv,readSource,&inputToken,"deftemplate",
00116 EnvFindDeftemplate,EnvUndeftemplate,"%",
00117 TRUE,TRUE,TRUE);
00118 if (deftemplateName == NULL) return(TRUE);
00119
00120 if (ReservedPatternSymbol(theEnv,ValueToString(deftemplateName),"deftemplate"))
00121 {
00122 ReservedPatternSymbolErrorMsg(theEnv,ValueToString(deftemplateName),"a deftemplate name");
00123 return(TRUE);
00124 }
00125
00126
00127
00128
00129
00130 slots = SlotDeclarations(theEnv,readSource,&inputToken);
00131 if (DeftemplateData(theEnv)->DeftemplateError == TRUE) return(TRUE);
00132
00133
00134
00135
00136
00137
00138 if (ConstructData(theEnv)->CheckSyntaxMode)
00139 {
00140 ReturnSlots(theEnv,slots);
00141 return(FALSE);
00142 }
00143
00144
00145
00146
00147
00148 newDeftemplate = get_struct(theEnv,deftemplate);
00149 newDeftemplate->header.name = deftemplateName;
00150 newDeftemplate->header.next = NULL;
00151 newDeftemplate->header.usrData = NULL;
00152 newDeftemplate->slotList = slots;
00153 newDeftemplate->implied = FALSE;
00154 newDeftemplate->numberOfSlots = 0;
00155 newDeftemplate->busyCount = 0;
00156 newDeftemplate->watch = 0;
00157 newDeftemplate->inScope = TRUE;
00158 newDeftemplate->patternNetwork = NULL;
00159 newDeftemplate->factList = NULL;
00160 newDeftemplate->lastFact = NULL;
00161 newDeftemplate->header.whichModule = (struct defmoduleItemHeader *)
00162 GetModuleItem(theEnv,NULL,DeftemplateData(theEnv)->DeftemplateModuleIndex);
00163
00164
00165
00166
00167
00168 while (slots != NULL)
00169 {
00170 newDeftemplate->numberOfSlots++;
00171 slots = slots->next;
00172 }
00173
00174
00175
00176
00177
00178 if (EnvGetConserveMemory(theEnv) == TRUE)
00179 { newDeftemplate->header.ppForm = NULL; }
00180 else
00181 { newDeftemplate->header.ppForm = CopyPPBuffer(theEnv); }
00182
00183
00184
00185
00186
00187 #if DEBUGGING_FUNCTIONS
00188 if ((BitwiseTest(DeftemplateData(theEnv)->DeletedTemplateDebugFlags,0)) || EnvGetWatchItem(theEnv,"facts"))
00189 { EnvSetDeftemplateWatch(theEnv,ON,(void *) newDeftemplate); }
00190 #endif
00191
00192
00193
00194
00195
00196 AddConstructToModule(&newDeftemplate->header);
00197
00198 InstallDeftemplate(theEnv,newDeftemplate);
00199
00200 #else
00201 #if MAC_MCW || WIN_MCW || MAC_XCD
00202 #pragma unused(theEnv)
00203 #endif
00204 #endif
00205
00206 return(FALSE);
00207 }
00208
00209 #if (! RUN_TIME) && (! BLOAD_ONLY)
00210
00211
00212
00213
00214
00215
00216 globle void InstallDeftemplate(
00217 void *theEnv,
00218 struct deftemplate *theDeftemplate)
00219 {
00220 struct templateSlot *slotPtr;
00221 struct expr *tempExpr;
00222
00223 IncrementSymbolCount(theDeftemplate->header.name);
00224
00225 for (slotPtr = theDeftemplate->slotList;
00226 slotPtr != NULL;
00227 slotPtr = slotPtr->next)
00228 {
00229 IncrementSymbolCount(slotPtr->slotName);
00230 tempExpr = AddHashedExpression(theEnv,slotPtr->defaultList);
00231 ReturnExpression(theEnv,slotPtr->defaultList);
00232 slotPtr->defaultList = tempExpr;
00233 tempExpr = AddHashedExpression(theEnv,slotPtr->facetList);
00234 ReturnExpression(theEnv,slotPtr->facetList);
00235 slotPtr->facetList = tempExpr;
00236 slotPtr->constraints = AddConstraint(theEnv,slotPtr->constraints);
00237 }
00238 }
00239
00240
00241
00242
00243 static struct templateSlot *SlotDeclarations(
00244 void *theEnv,
00245 char *readSource,
00246 struct token *inputToken)
00247 {
00248 struct templateSlot *newSlot, *slotList = NULL, *lastSlot = NULL;
00249 struct templateSlot *multiSlot = NULL;
00250
00251 while (inputToken->type != RPAREN)
00252 {
00253
00254
00255
00256
00257 if (inputToken->type != LPAREN)
00258 {
00259 SyntaxErrorMessage(theEnv,"deftemplate");
00260 ReturnSlots(theEnv,slotList);
00261 ReturnSlots(theEnv,multiSlot);
00262 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00263 return(NULL);
00264 }
00265
00266 GetToken(theEnv,readSource,inputToken);
00267 if (inputToken->type != SYMBOL)
00268 {
00269 SyntaxErrorMessage(theEnv,"deftemplate");
00270 ReturnSlots(theEnv,slotList);
00271 ReturnSlots(theEnv,multiSlot);
00272 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00273 return(NULL);
00274 }
00275
00276
00277
00278
00279
00280 newSlot = ParseSlot(theEnv,readSource,inputToken,slotList);
00281 if (DeftemplateData(theEnv)->DeftemplateError == TRUE)
00282 {
00283 ReturnSlots(theEnv,newSlot);
00284 ReturnSlots(theEnv,slotList);
00285 ReturnSlots(theEnv,multiSlot);
00286 return(NULL);
00287 }
00288
00289
00290
00291
00292
00293 if (newSlot != NULL)
00294 {
00295 if (lastSlot == NULL)
00296 { slotList = newSlot; }
00297 else
00298 { lastSlot->next = newSlot; }
00299 lastSlot = newSlot;
00300 }
00301
00302
00303
00304
00305
00306 GetToken(theEnv,readSource,inputToken);
00307 if (inputToken->type != RPAREN)
00308 {
00309 PPBackup(theEnv);
00310 SavePPBuffer(theEnv,"\n ");
00311 SavePPBuffer(theEnv,inputToken->printForm);
00312 }
00313 }
00314
00315 SavePPBuffer(theEnv,"\n");
00316
00317
00318
00319
00320
00321 return(slotList);
00322 }
00323
00324
00325
00326
00327 static struct templateSlot *ParseSlot(
00328 void *theEnv,
00329 char *readSource,
00330 struct token *inputToken,
00331 struct templateSlot *slotList)
00332 {
00333 int parsingMultislot;
00334 SYMBOL_HN *slotName;
00335 struct templateSlot *newSlot;
00336 int rv;
00337
00338
00339
00340
00341
00342 if ((strcmp(ValueToString(inputToken->value),"field") != 0) &&
00343 (strcmp(ValueToString(inputToken->value),"multifield") != 0) &&
00344 (strcmp(ValueToString(inputToken->value),"slot") != 0) &&
00345 (strcmp(ValueToString(inputToken->value),"multislot") != 0))
00346 {
00347 SyntaxErrorMessage(theEnv,"deftemplate");
00348 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00349 return(NULL);
00350 }
00351
00352
00353
00354
00355
00356 if ((strcmp(ValueToString(inputToken->value),"multifield") == 0) ||
00357 (strcmp(ValueToString(inputToken->value),"multislot") == 0))
00358 { parsingMultislot = TRUE; }
00359 else
00360 { parsingMultislot = FALSE; }
00361
00362
00363
00364
00365
00366 SavePPBuffer(theEnv," ");
00367 GetToken(theEnv,readSource,inputToken);
00368 if (inputToken->type != SYMBOL)
00369 {
00370 SyntaxErrorMessage(theEnv,"deftemplate");
00371 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00372 return(NULL);
00373 }
00374
00375 slotName = (SYMBOL_HN *) inputToken->value;
00376
00377
00378
00379
00380
00381 while (slotList != NULL)
00382 {
00383 if (slotList->slotName == slotName)
00384 {
00385 AlreadyParsedErrorMessage(theEnv,"slot ",ValueToString(slotList->slotName));
00386 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00387 return(NULL);
00388 }
00389
00390 slotList = slotList->next;
00391 }
00392
00393
00394
00395
00396
00397 newSlot = DefinedSlots(theEnv,readSource,slotName,parsingMultislot,inputToken);
00398 if (newSlot == NULL)
00399 {
00400 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00401 return(NULL);
00402 }
00403
00404
00405
00406
00407
00408 if (CheckConstraintParseConflicts(theEnv,newSlot->constraints) == FALSE)
00409 {
00410 ReturnSlots(theEnv,newSlot);
00411 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00412 return(NULL);
00413 }
00414
00415 if ((newSlot->defaultPresent) || (newSlot->defaultDynamic))
00416 { rv = ConstraintCheckExpressionChain(theEnv,newSlot->defaultList,newSlot->constraints); }
00417 else
00418 { rv = NO_VIOLATION; }
00419
00420 if ((rv != NO_VIOLATION) && EnvGetStaticConstraintChecking(theEnv))
00421 {
00422 char *temp;
00423 if (newSlot->defaultDynamic) temp = "the default-dynamic attribute";
00424 else temp = "the default attribute";
00425 ConstraintViolationErrorMessage(theEnv,"An expression",temp,FALSE,0,
00426 newSlot->slotName,0,rv,newSlot->constraints,TRUE);
00427 ReturnSlots(theEnv,newSlot);
00428 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00429 return(NULL);
00430 }
00431
00432
00433
00434
00435
00436 return(newSlot);
00437 }
00438
00439
00440
00441
00442 static struct templateSlot *DefinedSlots(
00443 void *theEnv,
00444 char *readSource,
00445 SYMBOL_HN *slotName,
00446 int multifieldSlot,
00447 struct token *inputToken)
00448 {
00449 struct templateSlot *newSlot;
00450 struct expr *defaultList;
00451 int defaultFound = FALSE;
00452 int noneSpecified, deriveSpecified;
00453 CONSTRAINT_PARSE_RECORD parsedConstraints;
00454
00455
00456
00457
00458
00459 newSlot = get_struct(theEnv,templateSlot);
00460 newSlot->slotName = slotName;
00461 newSlot->defaultList = NULL;
00462 newSlot->facetList = NULL;
00463 newSlot->constraints = GetConstraintRecord(theEnv);
00464 if (multifieldSlot)
00465 { newSlot->constraints->multifieldsAllowed = TRUE; }
00466 newSlot->multislot = multifieldSlot;
00467 newSlot->noDefault = FALSE;
00468 newSlot->defaultPresent = FALSE;
00469 newSlot->defaultDynamic = FALSE;
00470 newSlot->next = NULL;
00471
00472
00473
00474
00475
00476 InitializeConstraintParseRecord(&parsedConstraints);
00477 GetToken(theEnv,readSource,inputToken);
00478
00479 while (inputToken->type != RPAREN)
00480 {
00481 PPBackup(theEnv);
00482 SavePPBuffer(theEnv," ");
00483 SavePPBuffer(theEnv,inputToken->printForm);
00484
00485
00486
00487
00488
00489 if (inputToken->type != LPAREN)
00490 {
00491 SyntaxErrorMessage(theEnv,"deftemplate");
00492 ReturnSlots(theEnv,newSlot);
00493 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00494 return(NULL);
00495 }
00496
00497
00498
00499
00500
00501 GetToken(theEnv,readSource,inputToken);
00502 if (inputToken->type != SYMBOL)
00503 {
00504 SyntaxErrorMessage(theEnv,"deftemplate");
00505 ReturnSlots(theEnv,newSlot);
00506 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00507 return(NULL);
00508 }
00509
00510
00511
00512
00513
00514 if (StandardConstraint(ValueToString(inputToken->value)))
00515 {
00516 if (ParseStandardConstraint(theEnv,readSource,(ValueToString(inputToken->value)),
00517 newSlot->constraints,&parsedConstraints,
00518 multifieldSlot) == FALSE)
00519 {
00520 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00521 ReturnSlots(theEnv,newSlot);
00522 return(NULL);
00523 }
00524 }
00525
00526
00527
00528
00529
00530
00531 else if ((strcmp(ValueToString(inputToken->value),"default") == 0) ||
00532 (strcmp(ValueToString(inputToken->value),"default-dynamic") == 0))
00533 {
00534
00535
00536
00537
00538 if (defaultFound)
00539 {
00540 AlreadyParsedErrorMessage(theEnv,"default attribute",NULL);
00541 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00542 ReturnSlots(theEnv,newSlot);
00543 return(NULL);
00544 }
00545
00546 newSlot->noDefault = FALSE;
00547
00548
00549
00550
00551
00552 if (strcmp(ValueToString(inputToken->value),"default") == 0)
00553 {
00554 newSlot->defaultPresent = TRUE;
00555 newSlot->defaultDynamic = FALSE;
00556 }
00557 else
00558 {
00559 newSlot->defaultPresent = FALSE;
00560 newSlot->defaultDynamic = TRUE;
00561 }
00562
00563
00564
00565
00566
00567 defaultList = ParseDefault(theEnv,readSource,multifieldSlot,(int) newSlot->defaultDynamic,
00568 TRUE,&noneSpecified,&deriveSpecified,&DeftemplateData(theEnv)->DeftemplateError);
00569 if (DeftemplateData(theEnv)->DeftemplateError == TRUE)
00570 {
00571 ReturnSlots(theEnv,newSlot);
00572 return(NULL);
00573 }
00574
00575
00576
00577
00578
00579 defaultFound = TRUE;
00580 if (deriveSpecified) newSlot->defaultPresent = FALSE;
00581 else if (noneSpecified)
00582 {
00583 newSlot->noDefault = TRUE;
00584 newSlot->defaultPresent = FALSE;
00585 }
00586 newSlot->defaultList = defaultList;
00587 }
00588
00589
00590
00591
00592
00593 else if (strcmp(ValueToString(inputToken->value),"facet") == 0)
00594 {
00595 if (! ParseFacetAttribute(theEnv,readSource,newSlot,FALSE))
00596 {
00597 ReturnSlots(theEnv,newSlot);
00598 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00599 return(NULL);
00600 }
00601 }
00602
00603 else if (strcmp(ValueToString(inputToken->value),"multifacet") == 0)
00604 {
00605 if (! ParseFacetAttribute(theEnv,readSource,newSlot,TRUE))
00606 {
00607 ReturnSlots(theEnv,newSlot);
00608 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00609 return(NULL);
00610 }
00611 }
00612
00613
00614
00615
00616
00617 else
00618 {
00619 SyntaxErrorMessage(theEnv,"slot attributes");
00620 ReturnSlots(theEnv,newSlot);
00621 DeftemplateData(theEnv)->DeftemplateError = TRUE;
00622 return(NULL);
00623 }
00624
00625
00626
00627
00628
00629 GetToken(theEnv,readSource,inputToken);
00630 }
00631
00632
00633
00634
00635
00636 return(newSlot);
00637 }
00638
00639
00640
00641
00642 static intBool ParseFacetAttribute(
00643 void *theEnv,
00644 char *readSource,
00645 struct templateSlot *theSlot,
00646 intBool multifacet)
00647 {
00648 struct token inputToken;
00649 SYMBOL_HN *facetName;
00650 struct expr *facetPair, *tempFacet, *facetValue = NULL, *lastValue = NULL;
00651
00652
00653
00654
00655
00656 SavePPBuffer(theEnv," ");
00657 GetToken(theEnv,readSource,&inputToken);
00658
00659
00660
00661
00662
00663 if (inputToken.type != SYMBOL)
00664 {
00665 if (multifacet) SyntaxErrorMessage(theEnv,"multifacet attribute");
00666 else SyntaxErrorMessage(theEnv,"facet attribute");
00667 return(FALSE);
00668 }
00669
00670 facetName = (SYMBOL_HN *) inputToken.value;
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 for (tempFacet = theSlot->facetList;
00682 tempFacet != NULL;
00683 tempFacet = tempFacet->nextArg)
00684 {
00685 if (tempFacet->value == facetName)
00686 {
00687 if (multifacet) AlreadyParsedErrorMessage(theEnv,"multifacet ",ValueToString(facetName));
00688 else AlreadyParsedErrorMessage(theEnv,"facet ",ValueToString(facetName));
00689 return(FALSE);
00690 }
00691 }
00692
00693
00694
00695
00696
00697 SavePPBuffer(theEnv," ");
00698 GetToken(theEnv,readSource,&inputToken);
00699
00700 while (inputToken.type != RPAREN)
00701 {
00702
00703
00704
00705
00706 if (! ConstantType(inputToken.type))
00707 {
00708 if (multifacet) SyntaxErrorMessage(theEnv,"multifacet attribute");
00709 else SyntaxErrorMessage(theEnv,"facet attribute");
00710 ReturnExpression(theEnv,facetValue);
00711 return(FALSE);
00712 }
00713
00714
00715
00716
00717
00718 if (lastValue == NULL)
00719 {
00720 facetValue = GenConstant(theEnv,inputToken.type,inputToken.value);
00721 lastValue = facetValue;
00722 }
00723 else
00724 {
00725 lastValue->nextArg = GenConstant(theEnv,inputToken.type,inputToken.value);
00726 lastValue = lastValue->nextArg;
00727 }
00728
00729
00730
00731
00732
00733 SavePPBuffer(theEnv," ");
00734 GetToken(theEnv,readSource,&inputToken);
00735
00736
00737
00738
00739
00740 if ((! multifacet) && (inputToken.type != RPAREN))
00741 {
00742 SyntaxErrorMessage(theEnv,"facet attribute");
00743 ReturnExpression(theEnv,facetValue);
00744 return(FALSE);
00745 }
00746 }
00747
00748
00749
00750
00751
00752 PPBackup(theEnv);
00753 PPBackup(theEnv);
00754 SavePPBuffer(theEnv,")");
00755
00756
00757
00758
00759
00760 if ((! multifacet) && (facetValue == NULL))
00761 {
00762 SyntaxErrorMessage(theEnv,"facet attribute");
00763 return(FALSE);
00764 }
00765
00766
00767
00768
00769
00770 facetPair = GenConstant(theEnv,SYMBOL,facetName);
00771
00772 if (multifacet)
00773 {
00774 facetPair->argList = GenConstant(theEnv,FCALL,(void *) FindFunction(theEnv,"create$"));
00775 facetPair->argList->argList = facetValue;
00776 }
00777 else
00778 { facetPair->argList = facetValue; }
00779
00780 facetPair->nextArg = theSlot->facetList;
00781 theSlot->facetList = facetPair;
00782
00783
00784
00785
00786
00787 return(TRUE);
00788 }
00789
00790 #endif
00791
00792 #endif
00793
00794