1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 08/16/14 */
5 /* */
6 /* */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Generic Function Construct Compiler Code */
11 /* */
12 /* Principal Programmer(s): */
13 /* Brian L. Dantes */
14 /* */
15 /* Contributing Programmer(s): */
16 /* */
17 /* Revision History: */
18 /* */
19 /* 6.24: Added pragmas to remove unused parameter */
20 /* warnings. */
21 /* */
22 /* 6.30: Added support for path name argument to */
23 /* constructs-to-c. */
24 /* */
25 /* Changed integer type/precision. */
26 /* */
27 /* Removed conditional code for unsupported */
28 /* compilers/operating systems (IBM_MCW and */
29 /* MAC_MCW). */
30 /* */
31 /* Added const qualifiers to remove C++ */
32 /* deprecation warnings. */
33 /* */
34 /*************************************************************/
35
36 /* =========================================
37 *****************************************
38 EXTERNAL DEFINITIONS
39 =========================================
40 ***************************************** */
41 #include "setup.h"
42
43 #if DEFGENERIC_CONSTRUCT && CONSTRUCT_COMPILER && (! RUN_TIME)
44
45 #if DEFRULE_CONSTRUCT
46 #include "network.h"
47 #endif
48
49 #include "genrccom.h"
50 #include "conscomp.h"
51 #include "envrnmnt.h"
52
53 #if OBJECT_SYSTEM
54 #include "objcmp.h"
55 #endif
56
57 #define _GENRCCMP_SOURCE_
58 #include "genrccmp.h"
59
60 /* =========================================
61 *****************************************
62 CONSTANTS
63 =========================================
64 ***************************************** */
65 #define MODULEI 0
66 #define GENERICI 1
67 #define METHODI 2
68 #define RESTRICTIONI 3
69 #define TYPEI 4
70
71 #define SAVE_ITEMS 5
72
73 /* =========================================
74 *****************************************
75 MACROS AND TYPES
76 =========================================
77 ***************************************** */
78 #define MethodPrefix() ArbitraryPrefix(DefgenericData(theEnv)->DefgenericCodeItem,2)
79 #define RestrictionPrefix() ArbitraryPrefix(DefgenericData(theEnv)->DefgenericCodeItem,3)
80 #define TypePrefix() ArbitraryPrefix(DefgenericData(theEnv)->DefgenericCodeItem,4)
81
82 /* =========================================
83 *****************************************
84 INTERNALLY VISIBLE FUNCTION HEADERS
85 =========================================
86 ***************************************** */
87
88 static void ReadyDefgenericsForCode(void *);
89 static int DefgenericsToCode(void *,const char *,const char *,char *,int,FILE *,int,int);
90 static void CloseDefgenericFiles(void *,FILE *[SAVE_ITEMS],int [SAVE_ITEMS],
91 struct CodeGeneratorFile [SAVE_ITEMS],int);
92 static void DefgenericModuleToCode(void *,FILE *,struct defmodule *,int,int);
93 static void SingleDefgenericToCode(void *,FILE *,int,int,DEFGENERIC *,int,int,int);
94 static void MethodToCode(void *,FILE *,int,DEFMETHOD *,int,int);
95 static void RestrictionToCode(void *,FILE *,int,RESTRICTION *,int,int);
96 static void TypeToCode(void *,FILE *,int,void *,int);
97
98 /* =========================================
99 *****************************************
100 EXTERNALLY VISIBLE FUNCTIONS
101 =========================================
102 ***************************************** */
103
104 /***************************************************
105 NAME : SetupGenericsCompiler
106 DESCRIPTION : Initializes the construct compiler
107 item for generic functions
108 INPUTS : None
109 RETURNS : Nothing useful
110 SIDE EFFECTS : Code generator item initialized
111 NOTES : None
112 ***************************************************/
SetupGenericsCompiler(void * theEnv)113 globle void SetupGenericsCompiler(
114 void *theEnv)
115 {
116 DefgenericData(theEnv)->DefgenericCodeItem = AddCodeGeneratorItem(theEnv,"generics",0,ReadyDefgenericsForCode,
117 NULL,DefgenericsToCode,5);
118 }
119
120 /***************************************************
121 NAME : PrintGenericFunctionReference
122 DESCRIPTION : Prints a reference to the run-time
123 generic array for the construct
124 compiler
125 INPUTS : 1) The file output destination
126 2) A pointer to the generic
127 3) The id of the run-time image
128 4) The maximum number of indices
129 in any array
130 RETURNS : Nothing useful
131 SIDE EFFECTS : Reference printed
132 NOTES : None
133 ***************************************************/
PrintGenericFunctionReference(void * theEnv,FILE * fp,DEFGENERIC * gfunc,int imageID,int maxIndices)134 globle void PrintGenericFunctionReference(
135 void *theEnv,
136 FILE *fp,
137 DEFGENERIC *gfunc,
138 int imageID,
139 int maxIndices)
140 {
141 if (gfunc == NULL)
142 fprintf(fp,"NULL");
143 else
144 fprintf(fp,"&%s%d_%d[%d]",ConstructPrefix(DefgenericData(theEnv)->DefgenericCodeItem),imageID,
145 (int) ((gfunc->header.bsaveID / maxIndices) + 1),
146 (int) (gfunc->header.bsaveID % maxIndices));
147 }
148
149 /****************************************************
150 NAME : DefgenericCModuleReference
151 DESCRIPTION : Prints out a reference to a
152 defgeneric module
153 INPUTS : 1) The output file
154 2) The id of the module item
155 3) The id of the image
156 4) The maximum number of elements
157 allowed in an array
158 RETURNS : Nothing useful
159 SIDE EFFECTS : Defgeneric module reference printed
160 NOTES : None
161 ****************************************************/
DefgenericCModuleReference(void * theEnv,FILE * theFile,int count,int imageID,int maxIndices)162 globle void DefgenericCModuleReference(
163 void *theEnv,
164 FILE *theFile,
165 int count,
166 int imageID,
167 int maxIndices)
168 {
169 fprintf(theFile,"MIHS &%s%d_%d[%d]",
170 ModulePrefix(DefgenericData(theEnv)->DefgenericCodeItem),
171 imageID,
172 (count / maxIndices) + 1,
173 (count % maxIndices));
174 }
175
176 /* =========================================
177 *****************************************
178 INTERNALLY VISIBLE FUNCTIONS
179 =========================================
180 ***************************************** */
181
182 /***************************************************
183 NAME : ReadyDefgenericsForCode
184 DESCRIPTION : Sets index of generic-functions
185 for use in compiled expressions
186 INPUTS : None
187 RETURNS : Nothing useful
188 SIDE EFFECTS : BsaveIndices set
189 NOTES : None
190 ***************************************************/
ReadyDefgenericsForCode(void * theEnv)191 static void ReadyDefgenericsForCode(
192 void *theEnv)
193 {
194 MarkConstructBsaveIDs(theEnv,DefgenericData(theEnv)->DefgenericModuleIndex);
195 }
196
197 /*******************************************************
198 NAME : DefgenericsToCode
199 DESCRIPTION : Writes out static array code for
200 generic functions, methods, etc.
201 INPUTS : 1) The base name of the construct set
202 2) The base id for this construct
203 3) The file pointer for the header file
204 4) The base id for the construct set
205 5) The max number of indices allowed
206 in an array
207 RETURNS : -1 if no generic functions, 0 on errors,
208 1 if generic functions written
209 SIDE EFFECTS : Code written to files
210 NOTES : None
211 *******************************************************/
DefgenericsToCode(void * theEnv,const char * fileName,const char * pathName,char * fileNameBuffer,int fileID,FILE * headerFP,int imageID,int maxIndices)212 static int DefgenericsToCode(
213 void *theEnv,
214 const char *fileName,
215 const char *pathName,
216 char *fileNameBuffer,
217 int fileID,
218 FILE *headerFP,
219 int imageID,
220 int maxIndices)
221 {
222 int fileCount = 1;
223 struct defmodule *theModule;
224 DEFGENERIC *theDefgeneric;
225 DEFMETHOD *theMethod;
226 RESTRICTION *theRestriction;
227 short i,j,k;
228 int moduleCount = 0;
229 int itemArrayCounts[SAVE_ITEMS];
230 int itemArrayVersions[SAVE_ITEMS];
231 FILE *itemFiles[SAVE_ITEMS];
232 int itemReopenFlags[SAVE_ITEMS];
233 struct CodeGeneratorFile itemCodeFiles[SAVE_ITEMS];
234
235 for (i = 0 ; i < SAVE_ITEMS ; i++)
236 {
237 itemArrayCounts[i] = 0;
238 itemArrayVersions[i] = 1;
239 itemFiles[i] = NULL;
240 itemReopenFlags[i] = FALSE;
241 itemCodeFiles[i].filePrefix = NULL;
242 itemCodeFiles[i].pathName = pathName;
243 itemCodeFiles[i].fileNameBuffer = fileNameBuffer;
244 }
245
246 /* ===========================================
247 Include the appropriate generic header file
248 =========================================== */
249 fprintf(headerFP,"#include \"genrcfun.h\"\n");
250
251 /* =============================================================
252 Loop through all the modules and all the defgenerics writing
253 their C code representation to the file as they are traversed
254 ============================================================= */
255 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
256
257 while (theModule != NULL)
258 {
259 EnvSetCurrentModule(theEnv,(void *) theModule);
260
261 itemFiles[MODULEI] =
262 OpenFileIfNeeded(theEnv,itemFiles[MODULEI],fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
263 itemArrayVersions[MODULEI],headerFP,
264 "DEFGENERIC_MODULE",ModulePrefix(DefgenericData(theEnv)->DefgenericCodeItem),
265 itemReopenFlags[MODULEI],&itemCodeFiles[MODULEI]);
266 if (itemFiles[MODULEI] == NULL)
267 goto GenericCodeError;
268
269 DefgenericModuleToCode(theEnv,itemFiles[MODULEI],theModule,imageID,maxIndices);
270 itemFiles[MODULEI] =
271 CloseFileIfNeeded(theEnv,itemFiles[MODULEI],&itemArrayCounts[MODULEI],
272 &itemArrayVersions[MODULEI],maxIndices,
273 &itemReopenFlags[MODULEI],&itemCodeFiles[MODULEI]);
274
275 theDefgeneric = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,NULL);
276
277 while (theDefgeneric != NULL)
278 {
279 itemFiles[GENERICI] =
280 OpenFileIfNeeded(theEnv,itemFiles[GENERICI],fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
281 itemArrayVersions[GENERICI],headerFP,
282 "DEFGENERIC",ConstructPrefix(DefgenericData(theEnv)->DefgenericCodeItem),
283 itemReopenFlags[GENERICI],&itemCodeFiles[GENERICI]);
284 if (itemFiles[GENERICI] == NULL)
285 goto GenericCodeError;
286
287 SingleDefgenericToCode(theEnv,itemFiles[GENERICI],imageID,maxIndices,theDefgeneric,
288 moduleCount,itemArrayVersions[METHODI],
289 itemArrayCounts[METHODI]);
290 itemArrayCounts[GENERICI]++;
291 itemFiles[GENERICI] =
292 CloseFileIfNeeded(theEnv,itemFiles[GENERICI],&itemArrayCounts[GENERICI],
293 &itemArrayVersions[GENERICI],maxIndices,
294 &itemReopenFlags[GENERICI],&itemCodeFiles[GENERICI]);
295 if (theDefgeneric->mcnt > 0)
296 {
297
298 /* ===========================================
299 Make sure that all methods for a particular
300 generic function go into the same array
301 =========================================== */
302 itemFiles[METHODI] =
303 OpenFileIfNeeded(theEnv,itemFiles[METHODI],fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
304 itemArrayVersions[METHODI],headerFP,
305 "DEFMETHOD",MethodPrefix(),
306 itemReopenFlags[METHODI],&itemCodeFiles[METHODI]);
307 if (itemFiles[METHODI] == NULL)
308 goto GenericCodeError;
309
310 for (i = 0 ; i < theDefgeneric->mcnt ; i++)
311 {
312 theMethod = &theDefgeneric->methods[i];
313 if (i > 0)
314 fprintf(itemFiles[METHODI],",\n");
315 MethodToCode(theEnv,itemFiles[METHODI],imageID,theMethod,
316 itemArrayVersions[RESTRICTIONI],itemArrayCounts[RESTRICTIONI]);
317 if (theMethod->restrictionCount > 0)
318 {
319 /* ========================================
320 Make sure that all restrictions for a
321 particular method go into the same array
322 ======================================== */
323 itemFiles[RESTRICTIONI] =
324 OpenFileIfNeeded(theEnv,itemFiles[RESTRICTIONI],fileName,pathName,fileNameBuffer,fileID,
325 imageID,&fileCount,
326 itemArrayVersions[RESTRICTIONI],headerFP,
327 "RESTRICTION",RestrictionPrefix(),
328 itemReopenFlags[RESTRICTIONI],&itemCodeFiles[RESTRICTIONI]);
329 if (itemFiles[RESTRICTIONI] == NULL)
330 goto GenericCodeError;
331 for (j = 0 ; j < theMethod->restrictionCount ; j++)
332 {
333 theRestriction = &theMethod->restrictions[j];
334 if (j > 0)
335 fprintf(itemFiles[RESTRICTIONI],",\n");
336 RestrictionToCode(theEnv,itemFiles[RESTRICTIONI],imageID,theRestriction,
337 itemArrayVersions[TYPEI],itemArrayCounts[TYPEI]);
338
339 if (theRestriction->tcnt > 0)
340 {
341 /* =========================================
342 Make sure that all types for a particular
343 restriction go into the same array
344 ========================================= */
345 itemFiles[TYPEI] =
346 OpenFileIfNeeded(theEnv,itemFiles[TYPEI],fileName,pathName,fileNameBuffer,fileID,
347 imageID,&fileCount,
348 itemArrayVersions[TYPEI],headerFP,
349 "void *",TypePrefix(),
350 itemReopenFlags[TYPEI],&itemCodeFiles[TYPEI]);
351 if (itemFiles[TYPEI] == NULL)
352 goto GenericCodeError;
353 for (k = 0 ; k < theRestriction->tcnt ; k++)
354 {
355 if (k > 0)
356 fprintf(itemFiles[TYPEI],",\n");
357 TypeToCode(theEnv,itemFiles[TYPEI],imageID,
358 theRestriction->types[k],maxIndices);
359 }
360 itemArrayCounts[TYPEI] += (int) theRestriction->tcnt;
361 itemFiles[TYPEI] =
362 CloseFileIfNeeded(theEnv,itemFiles[TYPEI],&itemArrayCounts[TYPEI],
363 &itemArrayVersions[TYPEI],maxIndices,
364 &itemReopenFlags[TYPEI],&itemCodeFiles[TYPEI]);
365 }
366 }
367 itemArrayCounts[RESTRICTIONI] += theMethod->restrictionCount;
368 itemFiles[RESTRICTIONI] =
369 CloseFileIfNeeded(theEnv,itemFiles[RESTRICTIONI],&itemArrayCounts[RESTRICTIONI],
370 &itemArrayVersions[RESTRICTIONI],maxIndices,
371 &itemReopenFlags[RESTRICTIONI],&itemCodeFiles[RESTRICTIONI]);
372 }
373 }
374 itemArrayCounts[METHODI] += (int) theDefgeneric->mcnt;
375 itemFiles[METHODI] =
376 CloseFileIfNeeded(theEnv,itemFiles[METHODI],&itemArrayCounts[METHODI],
377 &itemArrayVersions[METHODI],maxIndices,
378 &itemReopenFlags[METHODI],&itemCodeFiles[METHODI]);
379 }
380 theDefgeneric = (DEFGENERIC *) EnvGetNextDefgeneric(theEnv,theDefgeneric);
381 }
382
383 theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule);
384 moduleCount++;
385 itemArrayCounts[MODULEI]++;
386 }
387 CloseDefgenericFiles(theEnv,itemFiles,itemReopenFlags,itemCodeFiles,maxIndices);
388 return(1);
389
390 GenericCodeError:
391 CloseDefgenericFiles(theEnv,itemFiles,itemReopenFlags,itemCodeFiles,maxIndices);
392 return(0);
393 }
394
395 /******************************************************
396 NAME : CloseDefgenericFiles
397 DESCRIPTION : Closes construct compiler files
398 for defgeneric structures
399 INPUTS : 1) An array containing all the
400 pertinent file pointers
401 2) An array containing all the
402 pertinent file reopen flags
403 3) An array containing all the
404 pertinent file name/id/version info
405 4) The maximum number of indices
406 allowed in an array
407 RETURNS : Nothing useful
408 SIDE EFFECTS : Files closed
409 NOTES : None
410 *****************************************************/
CloseDefgenericFiles(void * theEnv,FILE * itemFiles[SAVE_ITEMS],int itemReopenFlags[SAVE_ITEMS],struct CodeGeneratorFile itemCodeFiles[SAVE_ITEMS],int maxIndices)411 static void CloseDefgenericFiles(
412 void *theEnv,
413 FILE *itemFiles[SAVE_ITEMS],
414 int itemReopenFlags[SAVE_ITEMS],
415 struct CodeGeneratorFile itemCodeFiles[SAVE_ITEMS],
416 int maxIndices)
417 {
418 int count = maxIndices;
419 int arrayVersion = 0;
420 register int i;
421
422 for (i = 0 ; i < SAVE_ITEMS ; i++)
423 {
424 count = maxIndices;
425 itemFiles[i] = CloseFileIfNeeded(theEnv,itemFiles[i],&count,&arrayVersion,
426 maxIndices,&itemReopenFlags[i],
427 &itemCodeFiles[i]);
428 }
429 }
430
431 /***************************************************
432 NAME : DefgenericModuleToCode
433 DESCRIPTION : Writes out the C values for a
434 defgeneric module item
435 INPUTS : 1) The output file
436 2) The module for the defgenerics
437 3) The compile image id
438 4) The maximum number of elements
439 in an array
440 RETURNS : Nothing useful
441 SIDE EFFECTS : Defgeneric module item written
442 NOTES : None
443 ***************************************************/
DefgenericModuleToCode(void * theEnv,FILE * theFile,struct defmodule * theModule,int imageID,int maxIndices)444 static void DefgenericModuleToCode(
445 void *theEnv,
446 FILE *theFile,
447 struct defmodule *theModule,
448 int imageID,
449 int maxIndices)
450 {
451 fprintf(theFile,"{");
452 ConstructModuleToCode(theEnv,theFile,theModule,imageID,maxIndices,
453 DefgenericData(theEnv)->DefgenericModuleIndex,ConstructPrefix(DefgenericData(theEnv)->DefgenericCodeItem));
454 fprintf(theFile,"}");
455 }
456
457 /****************************************************************
458 NAME : SingleDefgenericToCode
459 DESCRIPTION : Writes out a single defgeneric's
460 data to the file
461 INPUTS : 1) The output file
462 2) The compile image id
463 3) The maximum number of
464 elements in an array
465 4) The defgeneric
466 5) The module index
467 6) The partition holding the
468 generic methods
469 7) The relative index of the
470 generics methods in the partition
471 RETURNS : Nothing useful
472 SIDE EFFECTS : Defgeneric data written
473 NOTES : None
474 ***************************************************************/
SingleDefgenericToCode(void * theEnv,FILE * theFile,int imageID,int maxIndices,DEFGENERIC * theDefgeneric,int moduleCount,int methodArrayVersion,int methodArrayCount)475 static void SingleDefgenericToCode(
476 void *theEnv,
477 FILE *theFile,
478 int imageID,
479 int maxIndices,
480 DEFGENERIC *theDefgeneric,
481 int moduleCount,
482 int methodArrayVersion,
483 int methodArrayCount)
484 {
485 /* ==================
486 Defgeneric Header
487 ================== */
488 fprintf(theFile,"{");
489 ConstructHeaderToCode(theEnv,theFile,&theDefgeneric->header,imageID,maxIndices,moduleCount,
490 ModulePrefix(DefgenericData(theEnv)->DefgenericCodeItem),
491 ConstructPrefix(DefgenericData(theEnv)->DefgenericCodeItem));
492
493 /* =========================
494 Defgeneric specific data
495 ========================= */
496 fprintf(theFile,",0,0,");
497 if (theDefgeneric->methods == NULL)
498 fprintf(theFile,"NULL");
499 else
500 {
501 fprintf(theFile,"&%s%d_%d[%d]",MethodPrefix(),imageID,
502 methodArrayVersion,methodArrayCount);
503 }
504 fprintf(theFile,",%hd,0}",theDefgeneric->mcnt);
505 }
506
507 /****************************************************************
508 NAME : MethodToCode
509 DESCRIPTION : Writes out a single method's
510 data to the file
511 INPUTS : 1) The output file
512 2) The compile image id
513 3) The method
514 4) The partition holding the
515 method restrictions
516 5) The relative index of the
517 method restrictions in the partition
518 RETURNS : Nothing useful
519 SIDE EFFECTS : Method data written
520 NOTES : None
521 ***************************************************************/
MethodToCode(void * theEnv,FILE * theFile,int imageID,DEFMETHOD * theMethod,int restrictionArrayVersion,int restrictionArrayCount)522 static void MethodToCode(
523 void *theEnv,
524 FILE *theFile,
525 int imageID,
526 DEFMETHOD *theMethod,
527 int restrictionArrayVersion,
528 int restrictionArrayCount)
529 {
530 fprintf(theFile,"{%hd,0,%hd,%hd,%hd,%hd,%u,0,",
531 theMethod->index,theMethod->restrictionCount,
532 theMethod->minRestrictions,theMethod->maxRestrictions,
533 theMethod->localVarCount,theMethod->system);
534 if (theMethod->restrictions == NULL)
535 fprintf(theFile,"NULL,");
536 else
537 fprintf(theFile,"&%s%d_%d[%d],",RestrictionPrefix(),imageID,
538 restrictionArrayVersion,restrictionArrayCount);
539 ExpressionToCode(theEnv,theFile,theMethod->actions);
540 fprintf(theFile,",NULL}");
541 }
542
543 /****************************************************************
544 NAME : RestrictionToCode
545 DESCRIPTION : Writes out a single restriction's
546 data to the file
547 INPUTS : 1) The output file
548 2) The compile image id
549 3) The restriction
550 4) The partition holding the
551 restriction types
552 5) The relative index of the
553 restriction types in the partition
554 RETURNS : Nothing useful
555 SIDE EFFECTS : Restriction data written
556 NOTES : None
557 ***************************************************************/
RestrictionToCode(void * theEnv,FILE * theFile,int imageID,RESTRICTION * theRestriction,int typeArrayVersion,int typeArrayCount)558 static void RestrictionToCode(
559 void *theEnv,
560 FILE *theFile,
561 int imageID,
562 RESTRICTION *theRestriction,
563 int typeArrayVersion,
564 int typeArrayCount)
565 {
566 fprintf(theFile,"{");
567 if (theRestriction->types == NULL)
568 fprintf(theFile,"NULL,");
569 else
570 fprintf(theFile,"&%s%d_%d[%d],",TypePrefix(),imageID,
571 typeArrayVersion,typeArrayCount);
572 ExpressionToCode(theEnv,theFile,theRestriction->query);
573 fprintf(theFile,",%hd}",theRestriction->tcnt);
574 }
575
576 /****************************************************************
577 NAME : TypeToCode
578 DESCRIPTION : Writes out a single type's
579 data to the file
580 INPUTS : 1) The output file
581 2) The compile image id
582 3) The type
583 RETURNS : Nothing useful
584 SIDE EFFECTS : Type data written
585 NOTES : None
586 ***************************************************************/
TypeToCode(void * theEnv,FILE * theFile,int imageID,void * theType,int maxIndices)587 static void TypeToCode(
588 void *theEnv,
589 FILE *theFile,
590 int imageID,
591 void *theType,
592 int maxIndices)
593 {
594 #if OBJECT_SYSTEM
595 fprintf(theFile,"VS ");
596 PrintClassReference(theEnv,theFile,(DEFCLASS *) theType,imageID,maxIndices);
597 #else
598
599 #if MAC_XCD
600 #pragma unused(imageID)
601 #pragma unused(maxIndices)
602 #endif
603
604 PrintIntegerReference(theEnv,theFile,(INTEGER_HN *) theType);
605 #endif
606 }
607
608
609 #endif
610