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 #define _EXPRESSN_SOURCE_
00031
00032 #include "setup.h"
00033
00034 #include <stdio.h>
00035 #define _STDIO_INCLUDED_
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <ctype.h>
00039
00040 #include "bload.h"
00041 #include "memalloc.h"
00042 #include "envrnmnt.h"
00043 #include "router.h"
00044 #include "extnfunc.h"
00045 #include "exprnops.h"
00046 #include "prntutil.h"
00047 #include "evaluatn.h"
00048
00049 #include "expressn.h"
00050
00051 #define PRIME_ONE 257
00052 #define PRIME_TWO 263
00053 #define PRIME_THREE 269
00054
00055
00056
00057
00058
00059 #if (! RUN_TIME)
00060 static long ListToPacked(struct expr *,
00061 struct expr *,long);
00062 static EXPRESSION_HN *FindHashedExpression(void *,EXPRESSION *,unsigned *,EXPRESSION_HN **);
00063 static unsigned HashExpression(EXPRESSION *);
00064 #endif
00065 static void DeallocateExpressionData(void *);
00066
00067
00068
00069
00070
00071
00072 globle void InitExpressionData(
00073 void *theEnv)
00074 {
00075 #if ! RUN_TIME
00076 register unsigned i;
00077 #endif
00078
00079 AllocateEnvironmentData(theEnv,EXPRESSION_DATA,sizeof(struct expressionData),DeallocateExpressionData);
00080
00081 #if ! RUN_TIME
00082 InitExpressionPointers(theEnv);
00083
00084 ExpressionData(theEnv)->ExpressionHashTable = (EXPRESSION_HN **)
00085 gm2(theEnv,(int) (sizeof(EXPRESSION_HN *) * EXPRESSION_HASH_SIZE));
00086 for (i = 0 ; i < EXPRESSION_HASH_SIZE ; i++)
00087 ExpressionData(theEnv)->ExpressionHashTable[i] = NULL;
00088 #endif
00089 }
00090
00091
00092
00093
00094
00095 static void DeallocateExpressionData(
00096 void *theEnv)
00097 {
00098 #if ! RUN_TIME
00099 int i;
00100 EXPRESSION_HN *tmpPtr, *nextPtr;
00101
00102 #if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE)
00103 if (! Bloaded(theEnv))
00104 #endif
00105 {
00106 for (i = 0; i < EXPRESSION_HASH_SIZE; i++)
00107 {
00108 tmpPtr = ExpressionData(theEnv)->ExpressionHashTable[i];
00109 while (tmpPtr != NULL)
00110 {
00111 nextPtr = tmpPtr->next;
00112 ReturnPackedExpression(theEnv,tmpPtr->exp);
00113 rtn_struct(theEnv,exprHashNode,tmpPtr);
00114 tmpPtr = nextPtr;
00115 }
00116 }
00117 }
00118
00119 rm(theEnv,ExpressionData(theEnv)->ExpressionHashTable,
00120 (int) (sizeof(EXPRESSION_HN *) * EXPRESSION_HASH_SIZE));
00121 #else
00122 #if MAC_MCW || WIN_MCW || MAC_XCD
00123 #pragma unused(theEnv)
00124 #endif
00125 #endif
00126
00127 #if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE)
00128 if ((ExpressionData(theEnv)->NumberOfExpressions != 0) && Bloaded(theEnv))
00129 {
00130 genfree(theEnv,(void *) ExpressionData(theEnv)->ExpressionArray,
00131 ExpressionData(theEnv)->NumberOfExpressions * sizeof(struct expr));
00132 }
00133 #endif
00134 }
00135
00136
00137
00138
00139
00140 globle void InitExpressionPointers(
00141 void *theEnv)
00142 {
00143 ExpressionData(theEnv)->PTR_AND = (void *) FindFunction(theEnv,"and");
00144 ExpressionData(theEnv)->PTR_OR = (void *) FindFunction(theEnv,"or");
00145 ExpressionData(theEnv)->PTR_EQ = (void *) FindFunction(theEnv,"eq");
00146 ExpressionData(theEnv)->PTR_NEQ = (void *) FindFunction(theEnv,"neq");
00147 ExpressionData(theEnv)->PTR_NOT = (void *) FindFunction(theEnv,"not");
00148
00149 if ((ExpressionData(theEnv)->PTR_AND == NULL) || (ExpressionData(theEnv)->PTR_OR == NULL) ||
00150 (ExpressionData(theEnv)->PTR_EQ == NULL) || (ExpressionData(theEnv)->PTR_NEQ == NULL) || (ExpressionData(theEnv)->PTR_NOT == NULL))
00151 {
00152 SystemError(theEnv,"EXPRESSN",1);
00153 EnvExitRouter(theEnv,EXIT_FAILURE);
00154 }
00155 }
00156
00157
00158
00159
00160
00161 globle void ExpressionInstall(
00162 void *theEnv,
00163 struct expr *expression)
00164 {
00165 if (expression == NULL) return;
00166
00167 while (expression != NULL)
00168 {
00169 AtomInstall(theEnv,expression->type,expression->value);
00170 ExpressionInstall(theEnv,expression->argList);
00171 expression = expression->nextArg;
00172 }
00173 }
00174
00175
00176
00177
00178
00179 globle void ExpressionDeinstall(
00180 void *theEnv,
00181 struct expr *expression)
00182 {
00183 if (expression == NULL) return;
00184
00185 while (expression != NULL)
00186 {
00187 AtomDeinstall(theEnv,expression->type,expression->value);
00188 ExpressionDeinstall(theEnv,expression->argList);
00189 expression = expression->nextArg;
00190 }
00191 }
00192
00193 #if (! RUN_TIME)
00194
00195
00196
00197
00198
00199
00200
00201
00202 globle struct expr *PackExpression(
00203 void *theEnv,
00204 struct expr *original)
00205 {
00206 struct expr *packPtr;
00207
00208 if (original == NULL) return (NULL);
00209 packPtr = (struct expr *)
00210 gm3(theEnv,(long) sizeof (struct expr) *
00211 (long) ExpressionSize(original));
00212 ListToPacked(original,packPtr,0L);
00213 return(packPtr);
00214 }
00215
00216
00217
00218
00219 static long ListToPacked(
00220 struct expr *original,
00221 struct expr *destination,
00222 long count)
00223 {
00224 long i;
00225
00226 if (original == NULL) { return(count); }
00227
00228 while (original != NULL)
00229 {
00230 i = count;
00231 count++;
00232
00233 destination[i].type = original->type;
00234 destination[i].value = original->value;
00235
00236 if (original->argList == NULL)
00237 { destination[i].argList = NULL; }
00238 else
00239 {
00240 destination[i].argList =
00241 (struct expr *) &destination[(long) count];
00242 count = ListToPacked(original->argList,destination,count);
00243 }
00244
00245 if (original->nextArg == NULL)
00246 { destination[i].nextArg = NULL; }
00247 else
00248 {
00249 destination[i].nextArg =
00250 (struct expr *) &destination[(long) count];
00251 }
00252
00253 original = original->nextArg;
00254 }
00255
00256 return(count);
00257 }
00258
00259
00260
00261
00262
00263 globle void ReturnPackedExpression(
00264 void *theEnv,
00265 struct expr *packPtr)
00266 {
00267 if (packPtr != NULL)
00268 {
00269 rm3(theEnv,(void *) packPtr,(long) sizeof (struct expr) *
00270 ExpressionSize(packPtr));
00271 }
00272 }
00273
00274 #endif
00275
00276
00277
00278
00279
00280 globle void ReturnExpression(
00281 void *theEnv,
00282 struct expr *waste)
00283 {
00284 register struct expr *tmp;
00285
00286 while (waste != NULL)
00287 {
00288 if (waste->argList != NULL) ReturnExpression(theEnv,waste->argList);
00289 tmp = waste;
00290 waste = waste->nextArg;
00291 rtn_struct(theEnv,expr,tmp);
00292 }
00293 }
00294
00295 #if (! RUN_TIME)
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311 static EXPRESSION_HN *FindHashedExpression(
00312 void *theEnv,
00313 EXPRESSION *theExp,
00314 unsigned *hashval,
00315 EXPRESSION_HN **prv)
00316 {
00317 EXPRESSION_HN *exphash;
00318
00319 if (theExp == NULL)
00320 return(NULL);
00321 *hashval = HashExpression(theExp);
00322 *prv = NULL;
00323 exphash = ExpressionData(theEnv)->ExpressionHashTable[*hashval];
00324 while (exphash != NULL)
00325 {
00326 if (IdenticalExpression(exphash->exp,theExp))
00327 return(exphash);
00328 *prv = exphash;
00329 exphash = exphash->next;
00330 }
00331 return(NULL);
00332 }
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 static unsigned HashExpression(
00344 EXPRESSION *theExp)
00345 {
00346 unsigned long tally = PRIME_THREE;
00347 union
00348 {
00349 void *vv;
00350 unsigned long uv;
00351 } fis;
00352
00353 if (theExp->argList != NULL)
00354 tally += HashExpression(theExp->argList) * PRIME_ONE;
00355 while (theExp != NULL)
00356 {
00357 tally += (unsigned long) (theExp->type * PRIME_TWO);
00358 fis.uv = 0;
00359 fis.vv = theExp->value;
00360 tally += fis.uv;
00361 theExp = theExp->nextArg;
00362 }
00363 return((unsigned) (tally % EXPRESSION_HASH_SIZE));
00364 }
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 globle void RemoveHashedExpression(
00381 void *theEnv,
00382 EXPRESSION *theExp)
00383 {
00384 EXPRESSION_HN *exphash,*prv;
00385 unsigned hashval;
00386
00387 exphash = FindHashedExpression(theEnv,theExp,&hashval,&prv);
00388 if (exphash == NULL)
00389 return;
00390 if (--exphash->count != 0)
00391 return;
00392 if (prv == NULL)
00393 ExpressionData(theEnv)->ExpressionHashTable[hashval] = exphash->next;
00394 else
00395 prv->next = exphash->next;
00396 ExpressionDeinstall(theEnv,exphash->exp);
00397 ReturnPackedExpression(theEnv,exphash->exp);
00398 rtn_struct(theEnv,exprHashNode,exphash);
00399 }
00400
00401 #endif
00402
00403 #if (! BLOAD_ONLY) && (! RUN_TIME)
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419 globle EXPRESSION *AddHashedExpression(
00420 void *theEnv,
00421 EXPRESSION *theExp)
00422 {
00423 EXPRESSION_HN *prv,*exphash;
00424 unsigned hashval;
00425
00426 if (theExp == NULL) return(NULL);
00427 exphash = FindHashedExpression(theEnv,theExp,&hashval,&prv);
00428 if (exphash != NULL)
00429 {
00430 exphash->count++;
00431 return(exphash->exp);
00432 }
00433 exphash = get_struct(theEnv,exprHashNode);
00434 exphash->hashval = hashval;
00435 exphash->count = 1;
00436 exphash->exp = PackExpression(theEnv,theExp);
00437 ExpressionInstall(theEnv,exphash->exp);
00438 exphash->next = ExpressionData(theEnv)->ExpressionHashTable[exphash->hashval];
00439 ExpressionData(theEnv)->ExpressionHashTable[exphash->hashval] = exphash;
00440 exphash->bsaveID = 0L;
00441 return(exphash->exp);
00442 }
00443
00444 #endif
00445
00446 #if (BLOAD_AND_BSAVE || BLOAD_ONLY || BLOAD || CONSTRUCT_COMPILER) && (! RUN_TIME)
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457 globle long HashedExpressionIndex(
00458 void *theEnv,
00459 EXPRESSION *theExp)
00460 {
00461 EXPRESSION_HN *exphash,*prv;
00462 unsigned hashval;
00463
00464 if (theExp == NULL)
00465 return(-1L);
00466 exphash = FindHashedExpression(theEnv,theExp,&hashval,&prv);
00467 return((exphash != NULL) ? exphash->bsaveID : -1L);
00468 }
00469
00470 #endif
00471