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 #define _TMPLTRHS_SOURCE_
00029
00030 #include "setup.h"
00031
00032 #if DEFTEMPLATE_CONSTRUCT
00033
00034 #include <stdio.h>
00035 #define _STDIO_INCLUDED_
00036
00037 #include "memalloc.h"
00038 #include "prntutil.h"
00039 #include "router.h"
00040 #include "tmpltfun.h"
00041 #include "tmpltdef.h"
00042 #include "factrhs.h"
00043 #include "extnfunc.h"
00044 #include "modulutl.h"
00045 #include "default.h"
00046 #include "tmpltutl.h"
00047 #include "tmpltlhs.h"
00048
00049 #include "tmpltrhs.h"
00050
00051
00052
00053
00054
00055 static struct expr *ParseAssertSlotValues(void *,char *,struct token *,struct templateSlot *,int *,int);
00056 static struct expr *ReorderAssertSlotValues(void *,struct templateSlot *,struct expr *,int *);
00057 static struct expr *GetSlotAssertValues(void *,struct templateSlot *,struct expr *,int *);
00058 static struct expr *FindAssertSlotItem(struct templateSlot *,struct expr *);
00059 static struct templateSlot *ParseSlotLabel(void *,char *,struct token *,struct deftemplate *,int *,int);
00060
00061
00062
00063
00064
00065 globle struct expr *ParseAssertTemplate(
00066 void *theEnv,
00067 char *readSource,
00068 struct token *theToken,
00069 int *error,
00070 int endType,
00071 int constantsOnly,
00072 struct deftemplate *theDeftemplate)
00073 {
00074 struct expr *firstSlot, *lastSlot, *nextSlot;
00075 struct expr *firstArg, *tempSlot;
00076 struct templateSlot *slotPtr;
00077
00078 firstSlot = NULL;
00079 lastSlot = NULL;
00080
00081
00082
00083
00084
00085 while ((slotPtr = ParseSlotLabel(theEnv,readSource,theToken,theDeftemplate,error,endType)) != NULL)
00086 {
00087
00088
00089
00090
00091 for (tempSlot = firstSlot;
00092 tempSlot != NULL;
00093 tempSlot = tempSlot->nextArg)
00094 {
00095 if (tempSlot->value == (void *) slotPtr->slotName)
00096 {
00097 AlreadyParsedErrorMessage(theEnv,"slot ",ValueToString(slotPtr->slotName));
00098 *error = TRUE;
00099 ReturnExpression(theEnv,firstSlot);
00100 return(NULL);
00101 }
00102 }
00103
00104
00105
00106
00107
00108 nextSlot = ParseAssertSlotValues(theEnv,readSource,theToken,
00109 slotPtr,error,constantsOnly);
00110
00111 if (*error)
00112 {
00113 ReturnExpression(theEnv,firstSlot);
00114 return(NULL);
00115 }
00116
00117
00118
00119
00120
00121
00122 if (CheckRHSSlotTypes(theEnv,nextSlot->argList,slotPtr,"assert") == 0)
00123 {
00124 *error = TRUE;
00125 ReturnExpression(theEnv,firstSlot);
00126 ReturnExpression(theEnv,nextSlot);
00127 return(NULL);
00128 }
00129
00130
00131
00132
00133
00134 if (lastSlot == NULL)
00135 { firstSlot = nextSlot; }
00136 else
00137 { lastSlot->nextArg = nextSlot; }
00138
00139 lastSlot = nextSlot;
00140 }
00141
00142
00143
00144
00145
00146 if (*error)
00147 {
00148 ReturnExpression(theEnv,firstSlot);
00149 return(NULL);
00150 }
00151
00152
00153
00154
00155
00156 firstArg = ReorderAssertSlotValues(theEnv,theDeftemplate->slotList,firstSlot,error);
00157 ReturnExpression(theEnv,firstSlot);
00158
00159
00160
00161
00162
00163 return(firstArg);
00164 }
00165
00166
00167
00168
00169
00170 static struct templateSlot *ParseSlotLabel(
00171 void *theEnv,
00172 char *inputSource,
00173 struct token *tempToken,
00174 struct deftemplate *theDeftemplate,
00175 int *error,
00176 int endType)
00177 {
00178 struct templateSlot *slotPtr;
00179 short position;
00180
00181
00182
00183
00184
00185 *error = FALSE;
00186
00187
00188
00189
00190
00191
00192 GetToken(theEnv,inputSource,tempToken);
00193 if (tempToken->type == endType)
00194 { return(NULL); }
00195
00196
00197
00198
00199
00200
00201 PPBackup(theEnv);
00202 SavePPBuffer(theEnv," ");
00203 SavePPBuffer(theEnv,tempToken->printForm);
00204
00205
00206
00207
00208
00209 if (tempToken->type != LPAREN)
00210 {
00211 SyntaxErrorMessage(theEnv,"deftemplate pattern");
00212 *error = TRUE;
00213 return(NULL);
00214 }
00215
00216
00217
00218
00219
00220 GetToken(theEnv,inputSource,tempToken);
00221 if (tempToken->type != SYMBOL)
00222 {
00223 SyntaxErrorMessage(theEnv,"deftemplate pattern");
00224 *error = TRUE;
00225 return(NULL);
00226 }
00227
00228
00229
00230
00231
00232 if ((slotPtr = FindSlot(theDeftemplate,(SYMBOL_HN *) tempToken->value,&position)) == NULL)
00233 {
00234 InvalidDeftemplateSlotMessage(theEnv,ValueToString(tempToken->value),
00235 ValueToString(theDeftemplate->header.name),TRUE);
00236 *error = TRUE;
00237 return(NULL);
00238 }
00239
00240
00241
00242
00243
00244 return(slotPtr);
00245 }
00246
00247
00248
00249
00250 static struct expr *ParseAssertSlotValues(
00251 void *theEnv,
00252 char *inputSource,
00253 struct token *tempToken,
00254 struct templateSlot *slotPtr,
00255 int *error,
00256 int constantsOnly)
00257 {
00258 struct expr *nextSlot;
00259 struct expr *newField, *valueList, *lastValue;
00260 int printError;
00261
00262
00263
00264
00265
00266 if (slotPtr->multislot == FALSE)
00267 {
00268
00269
00270
00271
00272 SavePPBuffer(theEnv," ");
00273
00274 newField = GetAssertArgument(theEnv,inputSource,tempToken,
00275 error,RPAREN,constantsOnly,&printError);
00276 if (*error)
00277 {
00278 if (printError) SyntaxErrorMessage(theEnv,"deftemplate pattern");
00279 return(NULL);
00280 }
00281
00282
00283
00284
00285
00286
00287 if (newField == NULL)
00288 {
00289 *error = TRUE;
00290 SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents);
00291 return(NULL);
00292 }
00293
00294
00295
00296
00297
00298
00299 if ((newField->type == FCALL) ? (ExpressionFunctionType(newField) == 'm') :
00300 (newField->type == MF_VARIABLE))
00301 {
00302 *error = TRUE;
00303 SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents);
00304 ReturnExpression(theEnv,newField);
00305 return(NULL);
00306 }
00307
00308
00309
00310
00311
00312 GetToken(theEnv,inputSource,tempToken);
00313 }
00314
00315
00316
00317
00318
00319
00320 else
00321 {
00322 SavePPBuffer(theEnv," ");
00323 valueList = GetAssertArgument(theEnv,inputSource,tempToken,
00324 error,RPAREN,constantsOnly,&printError);
00325 if (*error)
00326 {
00327 if (printError) SyntaxErrorMessage(theEnv,"deftemplate pattern");
00328 return(NULL);
00329 }
00330
00331 if (valueList == NULL)
00332 {
00333 PPBackup(theEnv);
00334 PPBackup(theEnv);
00335 SavePPBuffer(theEnv,")");
00336 }
00337
00338 lastValue = valueList;
00339
00340 while (lastValue != NULL)
00341 {
00342 if (tempToken->type == RPAREN)
00343 { SavePPBuffer(theEnv," "); }
00344 else
00345 {
00346
00347 SavePPBuffer(theEnv," ");
00348
00349 }
00350
00351 newField = GetAssertArgument(theEnv,inputSource,tempToken,error,RPAREN,constantsOnly,&printError);
00352 if (*error)
00353 {
00354 if (printError) SyntaxErrorMessage(theEnv,"deftemplate pattern");
00355 ReturnExpression(theEnv,valueList);
00356 return(NULL);
00357 }
00358
00359 if (newField == NULL)
00360 {
00361 PPBackup(theEnv);
00362 PPBackup(theEnv);
00363 SavePPBuffer(theEnv,")");
00364 }
00365
00366 lastValue->nextArg = newField;
00367 lastValue = newField;
00368 }
00369
00370 newField = valueList;
00371 }
00372
00373
00374
00375
00376
00377 if (tempToken->type != RPAREN)
00378 {
00379 SingleFieldSlotCardinalityError(theEnv,slotPtr->slotName->contents);
00380 *error = TRUE;
00381 ReturnExpression(theEnv,newField);
00382 return(NULL);
00383 }
00384
00385
00386
00387
00388
00389 nextSlot = GenConstant(theEnv,SYMBOL,slotPtr->slotName);
00390 nextSlot->argList = newField;
00391
00392 return(nextSlot);
00393 }
00394
00395
00396
00397
00398
00399 static struct expr *ReorderAssertSlotValues(
00400 void *theEnv,
00401 struct templateSlot *slotPtr,
00402 struct expr *firstSlot,
00403 int *error)
00404 {
00405 struct expr *firstArg = NULL;
00406 struct expr *lastArg = NULL, *newArg;
00407
00408
00409
00410
00411
00412
00413 for (;
00414 slotPtr != NULL;
00415 slotPtr = slotPtr->next)
00416 {
00417
00418
00419
00420
00421
00422 newArg = GetSlotAssertValues(theEnv,slotPtr,firstSlot,error);
00423
00424 if (*error)
00425 {
00426 ReturnExpression(theEnv,firstArg);
00427 return(NULL);
00428 }
00429
00430
00431
00432
00433
00434
00435 if (newArg != NULL)
00436 {
00437 if (lastArg == NULL)
00438 { firstArg = newArg; }
00439 else
00440 { lastArg->nextArg = newArg; }
00441
00442 lastArg = newArg;
00443 }
00444 }
00445
00446
00447
00448
00449
00450
00451 return(firstArg);
00452 }
00453
00454
00455
00456
00457
00458
00459
00460 static struct expr *GetSlotAssertValues(
00461 void *theEnv,
00462 struct templateSlot *slotPtr,
00463 struct expr *firstSlot,
00464 int *error)
00465 {
00466 struct expr *slotItem;
00467 struct expr *newArg, *tempArg;
00468 DATA_OBJECT theDefault;
00469 char *nullBitMap = "\0";
00470
00471
00472
00473
00474
00475 slotItem = FindAssertSlotItem(slotPtr,firstSlot);
00476
00477
00478
00479
00480
00481 if (slotItem != NULL)
00482 {
00483 newArg = slotItem->argList;
00484 slotItem->argList = NULL;
00485 }
00486
00487
00488
00489
00490
00491 else
00492 {
00493
00494
00495
00496
00497
00498 if (slotPtr->noDefault)
00499 {
00500 PrintErrorID(theEnv,"TMPLTRHS",1,TRUE);
00501 EnvPrintRouter(theEnv,WERROR,"Slot ");
00502 EnvPrintRouter(theEnv,WERROR,slotPtr->slotName->contents);
00503 EnvPrintRouter(theEnv,WERROR," requires a value because of its (default ?NONE) attribute.\n");
00504 *error = TRUE;
00505 return(NULL);
00506 }
00507
00508
00509
00510
00511
00512
00513
00514 else if ((slotPtr->defaultPresent == FALSE) &&
00515 (slotPtr->defaultDynamic == FALSE))
00516 {
00517 DeriveDefaultFromConstraints(theEnv,slotPtr->constraints,&theDefault,
00518 (int) slotPtr->multislot,TRUE);
00519 newArg = ConvertValueToExpression(theEnv,&theDefault);
00520 }
00521
00522
00523
00524
00525
00526
00527 else
00528 { newArg = CopyExpression(theEnv,slotPtr->defaultList); }
00529 }
00530
00531
00532
00533
00534
00535
00536
00537
00538 if (slotPtr->multislot)
00539 {
00540 tempArg = GenConstant(theEnv,FACT_STORE_MULTIFIELD,EnvAddBitMap(theEnv,(void *) nullBitMap,1));
00541 tempArg->argList = newArg;
00542 newArg = tempArg;
00543 }
00544
00545
00546
00547
00548
00549 return(newArg);
00550 }
00551
00552
00553
00554
00555 static struct expr *FindAssertSlotItem(
00556 struct templateSlot *slotPtr,
00557 struct expr *listOfSlots)
00558 {
00559 while (listOfSlots != NULL)
00560 {
00561 if (listOfSlots->value == (void *) slotPtr->slotName) return (listOfSlots);
00562 listOfSlots = listOfSlots->nextArg;
00563 }
00564
00565 return(NULL);
00566 }
00567
00568 #endif
00569