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 #define _ANALYSIS_SOURCE_
00027
00028 #include "setup.h"
00029
00030 #if (! RUN_TIME) && (! BLOAD_ONLY) && DEFRULE_CONSTRUCT
00031
00032 #include <stdio.h>
00033 #define _STDIO_INCLUDED_
00034
00035 #include "constant.h"
00036 #include "symbol.h"
00037 #include "memalloc.h"
00038 #include "exprnpsr.h"
00039 #include "reorder.h"
00040 #include "generate.h"
00041 #include "pattern.h"
00042 #include "router.h"
00043 #include "ruledef.h"
00044 #include "cstrnchk.h"
00045 #include "cstrnutl.h"
00046 #include "cstrnops.h"
00047 #include "rulecstr.h"
00048 #include "modulutl.h"
00049 #include "analysis.h"
00050
00051 #if DEFGLOBAL_CONSTRUCT
00052 #include "globldef.h"
00053 #endif
00054
00055
00056
00057
00058
00059 static int GetVariables(void *,struct lhsParseNode *);
00060 static intBool UnboundVariablesInPattern(void *,struct lhsParseNode *,int);
00061 static int PropagateVariableToNodes(void *,
00062 struct lhsParseNode *,
00063 int,
00064 struct symbolHashNode *,
00065 struct lhsParseNode *,
00066 int,int,int);
00067 static struct lhsParseNode *CheckExpression(void *,
00068 struct lhsParseNode *,
00069 struct lhsParseNode *,
00070 int,
00071 struct symbolHashNode *,
00072 int);
00073 static void VariableReferenceErrorMessage(void *,
00074 struct symbolHashNode *,
00075 struct lhsParseNode *,
00076 int,
00077 struct symbolHashNode *,
00078 int);
00079 static int ProcessField(void *theEnv,
00080 struct lhsParseNode *,
00081 struct lhsParseNode *,
00082 struct lhsParseNode *);
00083 static int ProcessVariable(void *,
00084 struct lhsParseNode *,
00085 struct lhsParseNode *,
00086 struct lhsParseNode *);
00087 static void VariableMixingErrorMessage(void *,struct symbolHashNode *);
00088 static int PropagateVariableDriver(void *,
00089 struct lhsParseNode *,
00090 struct lhsParseNode *,
00091 struct lhsParseNode *,
00092 int,struct symbolHashNode *,
00093 struct lhsParseNode *,
00094 int);
00095 static void CombineNandExpressions(void *,struct lhsParseNode *);
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 globle int VariableAnalysis(
00106 void *theEnv,
00107 struct lhsParseNode *patternPtr)
00108 {
00109 struct lhsParseNode *rv, *theList, *tempList;
00110 int errorFlag = FALSE;
00111 struct lhsParseNode *topNode;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 topNode = patternPtr;
00123 while (patternPtr != NULL)
00124 {
00125
00126
00127
00128
00129
00130
00131 if (patternPtr->type == PATTERN_CE)
00132 {
00133
00134
00135
00136
00137
00138 if ((patternPtr->value != NULL) &&
00139 (patternPtr->referringNode != NULL))
00140 {
00141 errorFlag = TRUE;
00142 if (patternPtr->referringNode->index == -1)
00143 {
00144 PrintErrorID(theEnv,"ANALYSIS",1,TRUE);
00145 EnvPrintRouter(theEnv,WERROR,"Duplicate pattern-address ?");
00146 EnvPrintRouter(theEnv,WERROR,ValueToString(patternPtr->value));
00147 EnvPrintRouter(theEnv,WERROR," found in CE #");
00148 PrintLongInteger(theEnv,WERROR,(long) patternPtr->whichCE);
00149 EnvPrintRouter(theEnv,WERROR,".\n");
00150 }
00151 else
00152 {
00153 PrintErrorID(theEnv,"ANALYSIS",2,TRUE);
00154 EnvPrintRouter(theEnv,WERROR,"Pattern-address ?");
00155 EnvPrintRouter(theEnv,WERROR,ValueToString(patternPtr->value));
00156 EnvPrintRouter(theEnv,WERROR," used in CE #");
00157 PrintLongInteger(theEnv,WERROR,(long) patternPtr->whichCE);
00158 EnvPrintRouter(theEnv,WERROR," was previously bound within a pattern CE.\n");
00159 }
00160 }
00161
00162
00163
00164
00165
00166
00167
00168 if (GetVariables(theEnv,patternPtr)) return(TRUE);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178 else if (patternPtr->type == TEST_CE)
00179 {
00180
00181
00182
00183
00184 rv = CheckExpression(theEnv,patternPtr->expression,NULL,(int) patternPtr->whichCE,NULL,0);
00185
00186
00187
00188
00189
00190
00191
00192
00193 theList = GetExpressionVarConstraints(theEnv,patternPtr->expression);
00194 for (tempList = theList; tempList != NULL; tempList = tempList->right)
00195 {
00196 if (PropagateVariableDriver(theEnv,patternPtr,patternPtr,NULL,SF_VARIABLE,
00197 (SYMBOL_HN *) tempList->value,tempList,FALSE))
00198 {
00199 ReturnLHSParseNodes(theEnv,theList);
00200 return(TRUE);
00201 }
00202 }
00203 ReturnLHSParseNodes(theEnv,theList);
00204
00205
00206
00207
00208
00209
00210
00211 if (rv != NULL)
00212 { errorFlag = TRUE; }
00213 else
00214 {
00215 if (IsNandTest(patternPtr->expression))
00216 { patternPtr->externalNetworkTest = GetvarReplace(theEnv,patternPtr->expression,TRUE); }
00217 else
00218 { patternPtr->networkTest = GetvarReplace(theEnv,patternPtr->expression,FALSE); }
00219 }
00220 }
00221
00222
00223
00224
00225
00226 patternPtr = patternPtr->bottom;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235 CombineNandExpressions(theEnv,topNode);
00236
00237
00238
00239
00240
00241 return(errorFlag);
00242 }
00243
00244
00245
00246
00247
00248
00249
00250 static int GetVariables(
00251 void *theEnv,
00252 struct lhsParseNode *thePattern)
00253 {
00254 struct lhsParseNode *patternHead = thePattern;
00255 struct lhsParseNode *multifieldHeader = NULL;
00256
00257
00258
00259
00260
00261
00262 while (thePattern != NULL)
00263 {
00264
00265
00266
00267
00268
00269 if (thePattern->multifieldSlot)
00270 {
00271 multifieldHeader = thePattern;
00272 thePattern = thePattern->bottom;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282 if (thePattern != NULL)
00283 {
00284 if ((thePattern->type == SF_VARIABLE) ||
00285 (thePattern->type == MF_VARIABLE) ||
00286 ((thePattern->type == PATTERN_CE) && (thePattern->value != NULL)))
00287 {
00288 if (ProcessVariable(theEnv,thePattern,multifieldHeader,patternHead))
00289 { return(TRUE); }
00290 }
00291 else
00292 {
00293 if (ProcessField(theEnv,thePattern,multifieldHeader,patternHead))
00294 { return(TRUE); }
00295 }
00296 }
00297
00298
00299
00300
00301
00302
00303 if (thePattern == NULL)
00304 { thePattern = multifieldHeader; }
00305 else if ((thePattern->right == NULL) && (multifieldHeader != NULL))
00306 {
00307 thePattern = multifieldHeader;
00308 multifieldHeader = NULL;
00309 }
00310
00311 thePattern = thePattern->right;
00312 }
00313
00314
00315
00316
00317
00318
00319 return(FALSE);
00320 }
00321
00322
00323
00324
00325
00326 static int ProcessVariable(
00327 void *theEnv,
00328 struct lhsParseNode *thePattern,
00329 struct lhsParseNode *multifieldHeader,
00330 struct lhsParseNode *patternHead)
00331 {
00332 int theType;
00333 struct symbolHashNode *theVariable;
00334 struct constraintRecord *theConstraints;
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 if (thePattern->type == PATTERN_CE)
00345 {
00346 theType = SF_VARIABLE;
00347 theVariable = (struct symbolHashNode *) thePattern->value;
00348 if (thePattern->derivedConstraints) RemoveConstraint(theEnv,thePattern->constraints);
00349 theConstraints = GetConstraintRecord(theEnv);
00350 thePattern->constraints = theConstraints;
00351 thePattern->constraints->anyAllowed = FALSE;
00352 thePattern->constraints->instanceAddressesAllowed = TRUE;
00353 thePattern->constraints->factAddressesAllowed = TRUE;
00354 thePattern->derivedConstraints = TRUE;
00355 }
00356
00357
00358
00359
00360
00361 else
00362 {
00363 theType = thePattern->type;
00364 theVariable = (struct symbolHashNode *) thePattern->value;
00365 }
00366
00367
00368
00369
00370
00371
00372 if (thePattern->type != PATTERN_CE)
00373 {
00374 PropagateVariableToNodes(theEnv,thePattern->bottom,theType,theVariable,
00375 thePattern,patternHead->beginNandDepth,
00376 TRUE,FALSE);
00377
00378 if (ProcessField(theEnv,thePattern,multifieldHeader,patternHead))
00379 { return(TRUE); }
00380 }
00381
00382
00383
00384
00385
00386 return(PropagateVariableDriver(theEnv,patternHead,thePattern,multifieldHeader,theType,
00387 theVariable,thePattern,TRUE));
00388 }
00389
00390
00391
00392
00393
00394 static int PropagateVariableDriver(
00395 void *theEnv,
00396 struct lhsParseNode *patternHead,
00397 struct lhsParseNode *theNode,
00398 struct lhsParseNode *multifieldHeader,
00399 int theType,
00400 struct symbolHashNode *variableName,
00401 struct lhsParseNode *theReference,
00402 int assignReference)
00403 {
00404
00405
00406
00407
00408
00409 if (multifieldHeader != NULL)
00410 {
00411 if (PropagateVariableToNodes(theEnv,multifieldHeader->right,theType,variableName,
00412 theReference,patternHead->beginNandDepth,assignReference,FALSE))
00413 {
00414 VariableMixingErrorMessage(theEnv,variableName);
00415 return(TRUE);
00416 }
00417 }
00418
00419
00420
00421
00422
00423
00424 if (PropagateVariableToNodes(theEnv,theNode->right,theType,variableName,theReference,
00425 patternHead->beginNandDepth,assignReference,FALSE))
00426 {
00427 VariableMixingErrorMessage(theEnv,variableName);
00428 return(TRUE);
00429 }
00430
00431
00432
00433
00434
00435
00436
00437 if (((patternHead->type == PATTERN_CE) || (patternHead->type == TEST_CE)) &&
00438 (patternHead->negated == FALSE) &&
00439 (patternHead->exists == FALSE) &&
00440 (patternHead->beginNandDepth <= patternHead->endNandDepth))
00441 {
00442 int ignoreVariableMixing;
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452 if (patternHead->type == TEST_CE) ignoreVariableMixing = TRUE;
00453 else ignoreVariableMixing = FALSE;
00454
00455
00456
00457
00458
00459 if (PropagateVariableToNodes(theEnv,patternHead->bottom,theType,variableName,theReference,
00460 patternHead->beginNandDepth,assignReference,
00461 ignoreVariableMixing))
00462 {
00463 VariableMixingErrorMessage(theEnv,variableName);
00464 return(TRUE);
00465 }
00466 }
00467
00468
00469
00470
00471
00472
00473 return(FALSE);
00474 }
00475
00476
00477
00478
00479
00480 static int ProcessField(
00481 void *theEnv,
00482 struct lhsParseNode *thePattern,
00483 struct lhsParseNode *multifieldHeader,
00484 struct lhsParseNode *patternHead)
00485 {
00486 struct lhsParseNode *theList, *tempList;
00487
00488
00489
00490
00491
00492
00493
00494 if (thePattern->type == PATTERN_CE) return(FALSE);
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 theList = DeriveVariableConstraints(theEnv,thePattern);
00505 for (tempList = theList; tempList != NULL; tempList = tempList->right)
00506 {
00507 if (PropagateVariableDriver(theEnv,patternHead,thePattern,multifieldHeader,tempList->type,
00508 (SYMBOL_HN *) tempList->value,tempList,FALSE))
00509 {
00510 ReturnLHSParseNodes(theEnv,theList);
00511 return(TRUE);
00512 }
00513 }
00514 ReturnLHSParseNodes(theEnv,theList);
00515
00516
00517
00518
00519
00520
00521 if (UnboundVariablesInPattern(theEnv,thePattern,(int) patternHead->whichCE))
00522 { return(TRUE); }
00523
00524
00525
00526
00527
00528
00529
00530 if (ProcessConnectedConstraints(theEnv,thePattern,multifieldHeader,patternHead))
00531 { return(TRUE); }
00532
00533
00534
00535
00536
00537
00538 FieldConversion(theEnv,thePattern,patternHead);
00539
00540
00541
00542
00543
00544 return(FALSE);
00545 }
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 static int PropagateVariableToNodes(
00556 void *theEnv,
00557 struct lhsParseNode *theNode,
00558 int theType,
00559 struct symbolHashNode *variableName,
00560 struct lhsParseNode *theReference,
00561 int startDepth,
00562 int assignReference,
00563 int ignoreVariableTypes)
00564 {
00565 struct constraintRecord *tempConstraints;
00566
00567
00568
00569
00570
00571 while (theNode != NULL)
00572 {
00573
00574
00575
00576
00577
00578
00579 if (theNode->expression != NULL)
00580 {
00581 PropagateVariableToNodes(theEnv,theNode->expression,theType,variableName,
00582 theReference,startDepth,assignReference,TRUE);
00583 }
00584
00585
00586
00587
00588
00589
00590
00591 else if (((theNode->type == SF_VARIABLE) || (theNode->type == MF_VARIABLE)) &&
00592 (theNode->value == (void *) variableName))
00593 {
00594
00595
00596
00597
00598 if (ignoreVariableTypes == FALSE)
00599 {
00600 if (((theType == SF_VARIABLE) && (theNode->type == MF_VARIABLE)) ||
00601 ((theType == MF_VARIABLE) && (theNode->type == SF_VARIABLE)))
00602 { return(TRUE); }
00603 }
00604
00605
00606
00607
00608
00609
00610 if ((theReference->constraints != NULL) && (! theNode->negated))
00611 {
00612 tempConstraints = theNode->constraints;
00613 theNode->constraints = IntersectConstraints(theEnv,theReference->constraints,
00614 tempConstraints);
00615 if (theNode->derivedConstraints)
00616 { RemoveConstraint(theEnv,tempConstraints); }
00617
00618 theNode->derivedConstraints = TRUE;
00619 }
00620
00621
00622
00623
00624
00625
00626
00627 if (assignReference)
00628 {
00629 if (theNode->referringNode == NULL)
00630 { theNode->referringNode = theReference; }
00631 else if (theReference->pattern == theNode->pattern)
00632 { theNode->referringNode = theReference; }
00633 else if (theReference->patternType == theNode->patternType)
00634 { theNode->referringNode = theReference; }
00635 }
00636 }
00637
00638
00639
00640
00641
00642
00643
00644
00645 else if ((theNode->type == PATTERN_CE) &&
00646 (theNode->value == (void *) variableName) &&
00647 (assignReference == TRUE))
00648 {
00649 if (theType == MF_VARIABLE) return(TRUE);
00650
00651 theNode->referringNode = theReference;
00652 }
00653
00654
00655
00656
00657
00658
00659 if (theNode->right != NULL)
00660 {
00661 if (PropagateVariableToNodes(theEnv,theNode->right,theType,variableName,
00662 theReference,startDepth,assignReference,ignoreVariableTypes))
00663 { return(TRUE); }
00664 }
00665
00666
00667
00668
00669
00670
00671
00672 if ((theNode->type == PATTERN_CE) || (theNode->type == TEST_CE))
00673 {
00674 if (theNode->endNandDepth < startDepth) theNode = NULL;
00675 else theNode = theNode->bottom;
00676 }
00677 else
00678 { theNode = theNode->bottom; }
00679 }
00680
00681
00682
00683
00684
00685 return(FALSE);
00686 }
00687
00688
00689
00690
00691
00692
00693
00694 static intBool UnboundVariablesInPattern(
00695 void *theEnv,
00696 struct lhsParseNode *theSlot,
00697 int pattern)
00698 {
00699 struct lhsParseNode *andField;
00700 struct lhsParseNode *rv;
00701 int result;
00702 struct lhsParseNode *orField;
00703 struct symbolHashNode *slotName;
00704 CONSTRAINT_RECORD *theConstraints;
00705 int theField;
00706
00707
00708
00709
00710
00711
00712 if (theSlot->multifieldSlot)
00713 {
00714 theSlot = theSlot->bottom;
00715 while (theSlot != NULL)
00716 {
00717 if (UnboundVariablesInPattern(theEnv,theSlot,pattern))
00718 { return(TRUE); }
00719 theSlot = theSlot->right;
00720 }
00721
00722 return(FALSE);
00723 }
00724
00725
00726
00727
00728
00729 slotName = theSlot->slot;
00730 theField = theSlot->index;
00731 theConstraints = theSlot->constraints;
00732
00733
00734
00735
00736
00737 for (orField = theSlot->bottom;
00738 orField != NULL;
00739 orField = orField->bottom)
00740 {
00741
00742
00743
00744
00745
00746 for (andField = orField;
00747 andField != NULL;
00748 andField = andField->right)
00749 {
00750
00751
00752
00753
00754
00755
00756
00757 if (((andField->type == SF_VARIABLE) || (andField->type == MF_VARIABLE)) &&
00758 (andField->referringNode == NULL))
00759 {
00760 VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) andField->value,NULL,pattern,
00761 slotName,theField);
00762 return(TRUE);
00763 }
00764
00765
00766
00767
00768
00769
00770
00771 else if ((andField->type == PREDICATE_CONSTRAINT) ||
00772 (andField->type == RETURN_VALUE_CONSTRAINT))
00773 {
00774 rv = CheckExpression(theEnv,andField->expression,NULL,pattern,slotName,theField);
00775 if (rv != NULL) return(TRUE);
00776 }
00777
00778
00779
00780
00781
00782
00783
00784
00785 else if (((andField->type == INTEGER) || (andField->type == FLOAT) ||
00786 (andField->type == SYMBOL) || (andField->type == STRING) ||
00787 (andField->type == INSTANCE_NAME)) &&
00788 EnvGetStaticConstraintChecking(theEnv))
00789 {
00790 result = ConstraintCheckValue(theEnv,andField->type,andField->value,theConstraints);
00791 if (result != NO_VIOLATION)
00792 {
00793 ConstraintViolationErrorMessage(theEnv,"A literal restriction value",
00794 NULL,FALSE,pattern,
00795 slotName,theField,result,
00796 theConstraints,TRUE);
00797 return(TRUE);
00798 }
00799 }
00800 }
00801 }
00802
00803
00804
00805
00806
00807
00808 return(FALSE);
00809 }
00810
00811
00812
00813
00814
00815
00816 static struct lhsParseNode *CheckExpression(
00817 void *theEnv,
00818 struct lhsParseNode *exprPtr,
00819 struct lhsParseNode *lastOne,
00820 int whichCE,
00821 struct symbolHashNode *slotName,
00822 int theField)
00823 {
00824 struct lhsParseNode *rv;
00825 int i = 1;
00826
00827 while (exprPtr != NULL)
00828 {
00829
00830
00831
00832
00833
00834
00835 if (exprPtr->type == SF_VARIABLE)
00836 {
00837 if (exprPtr->referringNode == NULL)
00838 {
00839 VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,
00840 whichCE,slotName,theField);
00841 return(exprPtr);
00842 }
00843 else if ((UnmatchableConstraint(exprPtr->constraints)) &&
00844 EnvGetStaticConstraintChecking(theEnv))
00845 {
00846 ConstraintReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,i,
00847 whichCE,slotName,theField);
00848 return(exprPtr);
00849 }
00850 }
00851
00852
00853
00854
00855
00856
00857 else if ((exprPtr->type == MF_VARIABLE) && (exprPtr->referringNode == NULL))
00858 {
00859 VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,
00860 whichCE,slotName,theField);
00861 return(exprPtr);
00862 }
00863
00864
00865
00866
00867
00868
00869
00870 #if DEFGLOBAL_CONSTRUCT
00871 else if (exprPtr->type == GBL_VARIABLE)
00872 {
00873 int count;
00874
00875 if (FindImportedConstruct(theEnv,"defglobal",NULL,ValueToString(exprPtr->value),
00876 &count,TRUE,NULL) == NULL)
00877 {
00878 VariableReferenceErrorMessage(theEnv,(SYMBOL_HN *) exprPtr->value,lastOne,
00879 whichCE,slotName,theField);
00880 return(exprPtr);
00881 }
00882 }
00883 #endif
00884
00885
00886
00887
00888
00889
00890 else if (((exprPtr->type == FCALL)
00891 #if DEFGENERIC_CONSTRUCT
00892 || (exprPtr->type == GCALL)
00893 #endif
00894 #if DEFFUNCTION_CONSTRUCT
00895 || (exprPtr->type == PCALL)
00896 #endif
00897 ) && (exprPtr->bottom != NULL))
00898 {
00899 if ((rv = CheckExpression(theEnv,exprPtr->bottom,exprPtr,whichCE,slotName,theField)) != NULL)
00900 { return(rv); }
00901 }
00902
00903
00904
00905
00906
00907 i++;
00908 exprPtr = exprPtr->right;
00909 }
00910
00911
00912
00913
00914
00915 return(NULL);
00916 }
00917
00918
00919
00920
00921
00922 static void VariableReferenceErrorMessage(
00923 void *theEnv,
00924 struct symbolHashNode *theVariable,
00925 struct lhsParseNode *theExpression,
00926 int whichCE,
00927 struct symbolHashNode *slotName,
00928 int theField)
00929 {
00930 struct expr *temprv;
00931
00932
00933
00934
00935
00936 PrintErrorID(theEnv,"ANALYSIS",4,TRUE);
00937
00938
00939
00940
00941
00942 EnvPrintRouter(theEnv,WERROR,"Variable ?");
00943 EnvPrintRouter(theEnv,WERROR,ValueToString(theVariable));
00944 EnvPrintRouter(theEnv,WERROR," ");
00945
00946
00947
00948
00949
00950
00951 if (theExpression != NULL)
00952 {
00953 temprv = LHSParseNodesToExpression(theEnv,theExpression);
00954 ReturnExpression(theEnv,temprv->nextArg);
00955 temprv->nextArg = NULL;
00956 EnvPrintRouter(theEnv,WERROR,"found in the expression ");
00957 PrintExpression(theEnv,WERROR,temprv);
00958 EnvPrintRouter(theEnv,WERROR,"\n");
00959 ReturnExpression(theEnv,temprv);
00960 }
00961
00962
00963
00964
00965
00966 EnvPrintRouter(theEnv,WERROR,"was referenced in CE #");
00967 PrintLongInteger(theEnv,WERROR,(long int) whichCE);
00968
00969
00970
00971
00972
00973
00974 if (slotName == NULL)
00975 {
00976 if (theField > 0)
00977 {
00978 EnvPrintRouter(theEnv,WERROR," field #");
00979 PrintLongInteger(theEnv,WERROR,(long int) theField);
00980 }
00981 }
00982 else
00983 {
00984 EnvPrintRouter(theEnv,WERROR," slot ");
00985 EnvPrintRouter(theEnv,WERROR,ValueToString(slotName));
00986 }
00987
00988 EnvPrintRouter(theEnv,WERROR," before being defined.\n");
00989 }
00990
00991
00992
00993
00994
00995
00996 static void VariableMixingErrorMessage(
00997 void *theEnv,
00998 struct symbolHashNode *theVariable)
00999 {
01000 PrintErrorID(theEnv,"ANALYSIS",3,TRUE);
01001 EnvPrintRouter(theEnv,WERROR,"Variable ?");
01002 EnvPrintRouter(theEnv,WERROR,ValueToString(theVariable));
01003 EnvPrintRouter(theEnv,WERROR," is used as both a single and multifield variable in the LHS\n");
01004 }
01005
01006
01007
01008
01009 static void CombineNandExpressions(
01010 void *theEnv,
01011 struct lhsParseNode *theLHS)
01012 {
01013 int scanDepth;
01014 struct lhsParseNode *thePattern, *lastPattern;
01015 struct expr *theNandExpression, *theRightExpression, *theLeftExpression;
01016
01017 if (theLHS == NULL) return;
01018
01019 lastPattern = theLHS;
01020
01021 for (theLHS = theLHS->bottom;
01022 theLHS != NULL;
01023 theLHS = theLHS->bottom)
01024 {
01025 if ((theLHS->beginNandDepth == 1) ||
01026 (theLHS->beginNandDepth == lastPattern->endNandDepth))
01027 { continue; }
01028
01029 scanDepth = theLHS->beginNandDepth;
01030
01031 thePattern = theLHS;
01032 theNandExpression = NULL;
01033 theRightExpression = NULL;
01034 theLeftExpression = NULL;
01035
01036 while (thePattern != NULL)
01037 {
01038 if (thePattern->beginNandDepth == scanDepth)
01039 {
01040 theNandExpression = CombineExpressions(theEnv,thePattern->externalNetworkTest,theNandExpression);
01041 theLeftExpression = AppendExpressions(thePattern->externalLeftHash,theLeftExpression);
01042 theRightExpression = AppendExpressions(thePattern->externalRightHash,theRightExpression);
01043 thePattern->externalNetworkTest = NULL;
01044 thePattern->externalLeftHash = NULL;
01045 thePattern->externalRightHash = NULL;
01046 }
01047
01048 if (thePattern->endNandDepth < scanDepth)
01049 {
01050 theLHS->externalNetworkTest = theNandExpression;
01051 theLHS->externalLeftHash = theLeftExpression;
01052 theLHS->externalRightHash = theRightExpression;
01053 break;
01054 }
01055
01056 thePattern = thePattern->bottom;
01057 }
01058 }
01059 }
01060
01061 #endif
01062
01063