1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 08/16/14 */
5 /* */
6 /* EXPRESSION BSAVE/BLOAD MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Implements the binary save/load feature for the */
11 /* expression data structure. */
12 /* */
13 /* Principal Programmer(s): */
14 /* Gary D. Riley */
15 /* */
16 /* Contributing Programmer(s): */
17 /* Brian L. Dantes */
18 /* */
19 /* Revision History: */
20 /* */
21 /* 6.30: Changed integer type/precision. */
22 /* */
23 /*************************************************************/
24
25 #define _EXPRNBIN_SOURCE_
26
27 #include "setup.h"
28
29 #if (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE)
30
31 #include <stdio.h>
32 #define _STDIO_INCLUDED_
33
34 #include "memalloc.h"
35 #include "dffctdef.h"
36 #include "moduldef.h"
37 #include "constrct.h"
38 #include "extnfunc.h"
39 #include "bload.h"
40 #include "bsave.h"
41 #include "envrnmnt.h"
42
43 #if DEFRULE_CONSTRUCT
44 #include "network.h"
45 #endif
46
47 #if DEFGENERIC_CONSTRUCT
48 #include "genrcbin.h"
49 #endif
50
51 #if DEFFUNCTION_CONSTRUCT
52 #include "dffnxbin.h"
53 #endif
54
55 #if DEFTEMPLATE_CONSTRUCT
56 #include "tmpltbin.h"
57 #endif
58
59 #if DEFGLOBAL_CONSTRUCT
60 #include "globlbin.h"
61 #endif
62
63 #if OBJECT_SYSTEM
64 #include "objbin.h"
65 #include "insfun.h"
66 #include "inscom.h"
67 #endif
68
69 #include "exprnbin.h"
70
71 /***************************************/
72 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
73 /***************************************/
74
75 static void UpdateExpression(void *,void *,long);
76
77 /***********************************************************/
78 /* AllocateExpressions: Determines the amount of space */
79 /* required for loading the binary image of expressions */
80 /* and allocates that amount of space. */
81 /***********************************************************/
AllocateExpressions(void * theEnv)82 globle void AllocateExpressions(
83 void *theEnv)
84 {
85 size_t space;
86
87 GenReadBinary(theEnv,(void *) &ExpressionData(theEnv)->NumberOfExpressions,sizeof(long));
88 if (ExpressionData(theEnv)->NumberOfExpressions == 0L)
89 ExpressionData(theEnv)->ExpressionArray = NULL;
90 else
91 {
92 space = ExpressionData(theEnv)->NumberOfExpressions * sizeof(struct expr);
93 ExpressionData(theEnv)->ExpressionArray = (struct expr *) genalloc(theEnv,space);
94 }
95 }
96
97 /**********************************************/
98 /* RefreshExpressions: Refreshes the pointers */
99 /* used by the expression binary image. */
100 /**********************************************/
RefreshExpressions(void * theEnv)101 globle void RefreshExpressions(
102 void *theEnv)
103 {
104 if (ExpressionData(theEnv)->ExpressionArray == NULL) return;
105
106 BloadandRefresh(theEnv,ExpressionData(theEnv)->NumberOfExpressions,
107 (unsigned) sizeof(BSAVE_EXPRESSION),UpdateExpression);
108 }
109
110 /*********************************************************
111 NAME : UpdateExpression
112 DESCRIPTION : Given a bloaded expression buffer,
113 this routine refreshes the pointers
114 in the expression array
115 INPUTS : 1) a bloaded expression buffer
116 2) the index of the expression to refresh
117 RETURNS : Nothing useful
118 SIDE EFFECTS : Expression updated
119 NOTES : None
120 *********************************************************/
UpdateExpression(void * theEnv,void * buf,long obji)121 static void UpdateExpression(
122 void *theEnv,
123 void *buf,
124 long obji)
125 {
126 BSAVE_EXPRESSION *bexp;
127 long theIndex;
128
129 bexp = (BSAVE_EXPRESSION *) buf;
130 ExpressionData(theEnv)->ExpressionArray[obji].type = bexp->type;
131 switch(bexp->type)
132 {
133 case FCALL:
134 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) BloadData(theEnv)->FunctionArray[bexp->value];
135 break;
136
137 case GCALL:
138 #if DEFGENERIC_CONSTRUCT
139 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) GenericPointer(bexp->value);
140 #else
141 ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
142 #endif
143 break;
144
145 case PCALL:
146 #if DEFFUNCTION_CONSTRUCT
147 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) DeffunctionPointer(bexp->value);
148 #else
149 ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
150 #endif
151 break;
152
153 case DEFTEMPLATE_PTR:
154 #if DEFTEMPLATE_CONSTRUCT
155 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) DeftemplatePointer(bexp->value);
156 #else
157 ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
158 #endif
159 break;
160
161 case DEFCLASS_PTR:
162 #if OBJECT_SYSTEM
163 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) DefclassPointer(bexp->value);
164 #else
165 ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
166 #endif
167 break;
168
169 case DEFGLOBAL_PTR:
170
171 #if DEFGLOBAL_CONSTRUCT
172 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) DefglobalPointer(bexp->value);
173 #else
174 ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
175 #endif
176 break;
177
178
179 case INTEGER:
180 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) SymbolData(theEnv)->IntegerArray[bexp->value];
181 IncrementIntegerCount((INTEGER_HN *) ExpressionData(theEnv)->ExpressionArray[obji].value);
182 break;
183
184 case FLOAT:
185 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) SymbolData(theEnv)->FloatArray[bexp->value];
186 IncrementFloatCount((FLOAT_HN *) ExpressionData(theEnv)->ExpressionArray[obji].value);
187 break;
188
189 case INSTANCE_NAME:
190 #if ! OBJECT_SYSTEM
191 ExpressionData(theEnv)->ExpressionArray[obji].type = SYMBOL;
192 #endif
193 case GBL_VARIABLE:
194 case SYMBOL:
195 case STRING:
196 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) SymbolData(theEnv)->SymbolArray[bexp->value];
197 IncrementSymbolCount((SYMBOL_HN *) ExpressionData(theEnv)->ExpressionArray[obji].value);
198 break;
199
200 #if DEFTEMPLATE_CONSTRUCT
201 case FACT_ADDRESS:
202 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) &FactData(theEnv)->DummyFact;
203 EnvIncrementFactCount(theEnv,ExpressionData(theEnv)->ExpressionArray[obji].value);
204 break;
205 #endif
206
207 #if OBJECT_SYSTEM
208 case INSTANCE_ADDRESS:
209 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) &InstanceData(theEnv)->DummyInstance;
210 EnvIncrementInstanceCount(theEnv,ExpressionData(theEnv)->ExpressionArray[obji].value);
211 break;
212 #endif
213
214 case EXTERNAL_ADDRESS:
215 ExpressionData(theEnv)->ExpressionArray[obji].value = NULL;
216 break;
217
218 case RVOID:
219 break;
220
221 default:
222 if (EvaluationData(theEnv)->PrimitivesArray[bexp->type] == NULL) break;
223 if (EvaluationData(theEnv)->PrimitivesArray[bexp->type]->bitMap)
224 {
225 ExpressionData(theEnv)->ExpressionArray[obji].value = (void *) SymbolData(theEnv)->BitMapArray[bexp->value];
226 IncrementBitMapCount((BITMAP_HN *) ExpressionData(theEnv)->ExpressionArray[obji].value);
227 }
228 break;
229 }
230
231 theIndex = (long int) bexp->nextArg;
232 if (theIndex == -1L)
233 { ExpressionData(theEnv)->ExpressionArray[obji].nextArg = NULL; }
234 else
235 { ExpressionData(theEnv)->ExpressionArray[obji].nextArg = (struct expr *) &ExpressionData(theEnv)->ExpressionArray[theIndex]; }
236
237 theIndex = (long int) bexp->argList;
238 if (theIndex == -1L)
239 { ExpressionData(theEnv)->ExpressionArray[obji].argList = NULL; }
240 else
241 { ExpressionData(theEnv)->ExpressionArray[obji].argList = (struct expr *) &ExpressionData(theEnv)->ExpressionArray[theIndex]; }
242 }
243
244 /*********************************************/
245 /* ClearBloadedExpressions: Clears the space */
246 /* utilized by an expression binary image. */
247 /*********************************************/
ClearBloadedExpressions(void * theEnv)248 globle void ClearBloadedExpressions(
249 void *theEnv)
250 {
251 unsigned long int i;
252 size_t space;
253
254 /*===============================================*/
255 /* Update the busy counts of atomic data values. */
256 /*===============================================*/
257
258 for (i = 0; i < (unsigned long) ExpressionData(theEnv)->NumberOfExpressions; i++)
259 {
260 switch (ExpressionData(theEnv)->ExpressionArray[i].type)
261 {
262 case SYMBOL :
263 case STRING :
264 case INSTANCE_NAME :
265 case GBL_VARIABLE :
266 DecrementSymbolCount(theEnv,(SYMBOL_HN *) ExpressionData(theEnv)->ExpressionArray[i].value);
267 break;
268 case FLOAT :
269 DecrementFloatCount(theEnv,(FLOAT_HN *) ExpressionData(theEnv)->ExpressionArray[i].value);
270 break;
271 case INTEGER :
272 DecrementIntegerCount(theEnv,(INTEGER_HN *) ExpressionData(theEnv)->ExpressionArray[i].value);
273 break;
274
275 #if DEFTEMPLATE_CONSTRUCT
276 case FACT_ADDRESS :
277 EnvDecrementFactCount(theEnv,ExpressionData(theEnv)->ExpressionArray[i].value);
278 break;
279 #endif
280
281 #if OBJECT_SYSTEM
282 case INSTANCE_ADDRESS :
283 EnvDecrementInstanceCount(theEnv,ExpressionData(theEnv)->ExpressionArray[i].value);
284 break;
285 #endif
286
287 case RVOID:
288 break;
289
290 default:
291 if (EvaluationData(theEnv)->PrimitivesArray[ExpressionData(theEnv)->ExpressionArray[i].type] == NULL) break;
292 if (EvaluationData(theEnv)->PrimitivesArray[ExpressionData(theEnv)->ExpressionArray[i].type]->bitMap)
293 { DecrementBitMapCount(theEnv,(BITMAP_HN *) ExpressionData(theEnv)->ExpressionArray[i].value); }
294 break;
295 }
296 }
297
298 /*===================================*/
299 /* Free the binary expression array. */
300 /*===================================*/
301
302 space = ExpressionData(theEnv)->NumberOfExpressions * sizeof(struct expr);
303 if (space != 0) genfree(theEnv,(void *) ExpressionData(theEnv)->ExpressionArray,space);
304 ExpressionData(theEnv)->ExpressionArray = 0;
305 }
306
307
308 #if BLOAD_AND_BSAVE
309
310 /***************************************************
311 NAME : FindHashedExpressions
312 DESCRIPTION : Sets the bsave expression array
313 indices for hashed expression nodes
314 and marks the items needed by
315 these expressions
316 INPUTS : None
317 RETURNS : Nothing useful
318 SIDE EFFECTS : Atoms marked and ids set
319 NOTES : None
320 ***************************************************/
FindHashedExpressions(void * theEnv)321 globle void FindHashedExpressions(
322 void *theEnv)
323 {
324 register unsigned i;
325 EXPRESSION_HN *exphash;
326
327 for (i = 0 ; i < EXPRESSION_HASH_SIZE ; i++)
328 for (exphash = ExpressionData(theEnv)->ExpressionHashTable[i] ; exphash != NULL ; exphash = exphash->next)
329 {
330 MarkNeededItems(theEnv,exphash->exp);
331 exphash->bsaveID = ExpressionData(theEnv)->ExpressionCount;
332 ExpressionData(theEnv)->ExpressionCount += ExpressionSize(exphash->exp);
333 }
334 }
335
336 /***************************************************
337 NAME : BsaveHashedExpressions
338 DESCRIPTION : Writes out hashed expressions
339 INPUTS : Bsave file stream pointer
340 RETURNS : Nothing useful
341 SIDE EFFECTS : Expressions written
342 NOTES : None
343 ***************************************************/
BsaveHashedExpressions(void * theEnv,FILE * fp)344 globle void BsaveHashedExpressions(
345 void *theEnv,
346 FILE *fp)
347 {
348 register unsigned i;
349 EXPRESSION_HN *exphash;
350
351 for (i = 0 ; i < EXPRESSION_HASH_SIZE ; i++)
352 for (exphash = ExpressionData(theEnv)->ExpressionHashTable[i] ; exphash != NULL ; exphash = exphash->next)
353 BsaveExpression(theEnv,exphash->exp,fp);
354 }
355
356 /***************************************************************/
357 /* BsaveConstructExpressions: Writes all expression needed by */
358 /* constructs for this binary image to the binary save file. */
359 /***************************************************************/
BsaveConstructExpressions(void * theEnv,FILE * fp)360 globle void BsaveConstructExpressions(
361 void *theEnv,
362 FILE *fp)
363 {
364 struct BinaryItem *biPtr;
365
366 for (biPtr = BsaveData(theEnv)->ListOfBinaryItems;
367 biPtr != NULL;
368 biPtr = biPtr->next)
369 {
370 if (biPtr->expressionFunction != NULL)
371 { (*biPtr->expressionFunction)(theEnv,fp); }
372 }
373 }
374
375 /***************************************/
376 /* BsaveExpression: Recursively saves */
377 /* an expression to the binary file. */
378 /***************************************/
BsaveExpression(void * theEnv,struct expr * testPtr,FILE * fp)379 globle void BsaveExpression(
380 void *theEnv,
381 struct expr *testPtr,
382 FILE *fp)
383 {
384 BSAVE_EXPRESSION newTest;
385 long int newIndex;
386
387 while (testPtr != NULL)
388 {
389 ExpressionData(theEnv)->ExpressionCount++;
390
391 /*================*/
392 /* Copy the type. */
393 /*================*/
394
395 newTest.type = testPtr->type;
396
397 /*=======================================*/
398 /* Convert the argList slot to an index. */
399 /*=======================================*/
400
401 if (testPtr->argList == NULL)
402 { newTest.argList = -1L; }
403 else
404 { newTest.argList = ExpressionData(theEnv)->ExpressionCount; }
405
406 /*========================================*/
407 /* Convert the nextArg slot to an index. */
408 /*========================================*/
409
410 if (testPtr->nextArg == NULL)
411 { newTest.nextArg = -1L; }
412 else
413 {
414 newIndex = ExpressionData(theEnv)->ExpressionCount + ExpressionSize(testPtr->argList);
415 newTest.nextArg = newIndex;
416 }
417
418 /*=========================*/
419 /* Convert the value slot. */
420 /*=========================*/
421
422 switch(testPtr->type)
423 {
424 case FLOAT:
425 newTest.value = (long) ((FLOAT_HN *) testPtr->value)->bucket;
426 break;
427
428 case INTEGER:
429 newTest.value = (long) ((INTEGER_HN *) testPtr->value)->bucket;
430 break;
431
432 case FCALL:
433 newTest.value = (long) ((struct FunctionDefinition *)
434 testPtr->value)->bsaveIndex;
435 break;
436
437 case GCALL:
438 #if DEFGENERIC_CONSTRUCT
439 if (testPtr->value != NULL)
440 newTest.value = ((struct constructHeader *) testPtr->value)->bsaveID;
441 else
442 #endif
443 newTest.value = -1L;
444 break;
445
446 case PCALL:
447 #if DEFFUNCTION_CONSTRUCT
448 if (testPtr->value != NULL)
449 newTest.value = ((struct constructHeader *) testPtr->value)->bsaveID;
450 else
451 #endif
452 newTest.value = -1L;
453 break;
454
455 case DEFTEMPLATE_PTR:
456 #if DEFTEMPLATE_CONSTRUCT
457 if (testPtr->value != NULL)
458 newTest.value = ((struct constructHeader *) testPtr->value)->bsaveID;
459 else
460 #endif
461 newTest.value = -1L;
462 break;
463
464 case DEFCLASS_PTR:
465 #if OBJECT_SYSTEM
466 if (testPtr->value != NULL)
467 newTest.value = ((struct constructHeader *) testPtr->value)->bsaveID;
468 else
469 #endif
470 newTest.value = -1L;
471 break;
472
473 case DEFGLOBAL_PTR:
474 #if DEFGLOBAL_CONSTRUCT
475 if (testPtr->value != NULL)
476 newTest.value = ((struct defglobal *) testPtr->value)->header.bsaveID;
477 else
478 #endif
479 newTest.value = -1L;
480 break;
481
482 #if OBJECT_SYSTEM
483 case INSTANCE_NAME:
484 #endif
485 case SYMBOL:
486 case GBL_VARIABLE:
487 case STRING:
488 newTest.value = (long) ((SYMBOL_HN *) testPtr->value)->bucket;
489 break;
490
491 case FACT_ADDRESS:
492 case INSTANCE_ADDRESS:
493 case EXTERNAL_ADDRESS:
494 newTest.value = -1L;
495 break;
496
497 case RVOID:
498 break;
499
500 default:
501 if (EvaluationData(theEnv)->PrimitivesArray[testPtr->type] == NULL) break;
502 if (EvaluationData(theEnv)->PrimitivesArray[testPtr->type]->bitMap)
503 { newTest.value = (long) ((BITMAP_HN *) testPtr->value)->bucket; }
504 break;
505 }
506
507 /*===========================*/
508 /* Write out the expression. */
509 /*===========================*/
510
511 GenWrite(&newTest,(unsigned long) sizeof(BSAVE_EXPRESSION),fp);
512
513 /*==========================*/
514 /* Write out argument list. */
515 /*==========================*/
516
517 if (testPtr->argList != NULL)
518 {
519 BsaveExpression(theEnv,testPtr->argList,fp);
520 }
521
522 testPtr = testPtr->nextArg;
523 }
524 }
525
526 #endif /* BLOAD_AND_BSAVE */
527
528 #endif /* (BLOAD || BLOAD_ONLY || BLOAD_AND_BSAVE) */
529
530