1    /*******************************************************/
2    /*      "C" Language Integrated Production System      */
3    /*                                                     */
4    /*             CLIPS Version 6.30  08/16/14            */
5    /*                                                     */
6    /*          DEFTEMPLATE CONSTRUCTS-TO-C MODULE         */
7    /*******************************************************/
8 
9 /*************************************************************/
10 /* Purpose: Implements the constructs-to-c feature for the   */
11 /*    deftemplate construct.                                 */
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.23: Added support for templates maintaining their  */
22 /*            own list of facts.                             */
23 /*                                                           */
24 /*      6.30: Added support for path name argument to        */
25 /*            constructs-to-c.                               */
26 /*                                                           */
27 /*            Removed conditional code for unsupported       */
28 /*            compilers/operating systems (IBM_MCW,          */
29 /*            MAC_MCW, and IBM_TBC).                         */
30 /*                                                           */
31 /*            Support for deftemplate slot facets.           */
32 /*                                                           */
33 /*            Added code for deftemplate run time            */
34 /*            initialization of hashed comparisons to        */
35 /*            constants.                                     */
36 /*                                                           */
37 /*            Added const qualifiers to remove C++           */
38 /*            deprecation warnings.                          */
39 /*                                                           */
40 /*************************************************************/
41 
42 #define _TMPLTCMP_SOURCE_
43 
44 #include "setup.h"
45 
46 #if DEFTEMPLATE_CONSTRUCT && CONSTRUCT_COMPILER && (! RUN_TIME)
47 
48 #define SlotPrefix() ArbitraryPrefix(DeftemplateData(theEnv)->DeftemplateCodeItem,2)
49 
50 #include <stdio.h>
51 #define _STDIO_INCLUDED_
52 
53 #include "conscomp.h"
54 #include "factcmp.h"
55 #include "cstrncmp.h"
56 #include "tmpltdef.h"
57 #include "envrnmnt.h"
58 
59 #include "tmpltcmp.h"
60 
61 /***************************************/
62 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
63 /***************************************/
64 
65    static int                     ConstructToCode(void *,const char *,const char *,char *,int,FILE *,int,int);
66    static void                    SlotToCode(void *,FILE *,struct templateSlot *,int,int,int);
67    static void                    DeftemplateModuleToCode(void *,FILE *,struct defmodule *,int,int,int);
68    static void                    DeftemplateToCode(void *,FILE *,struct deftemplate *,
69                                                  int,int,int,int);
70    static void                    CloseDeftemplateFiles(void *,FILE *,FILE *,FILE *,int);
71    static void                    InitDeftemplateCode(void *,FILE *,int,int);
72 
73 /*********************************************************/
74 /* DeftemplateCompilerSetup: Initializes the deftemplate */
75 /*   construct for use with the constructs-to-c command. */
76 /*********************************************************/
DeftemplateCompilerSetup(void * theEnv)77 globle void DeftemplateCompilerSetup(
78   void *theEnv)
79   {
80    DeftemplateData(theEnv)->DeftemplateCodeItem = AddCodeGeneratorItem(theEnv,"deftemplate",0,NULL,InitDeftemplateCode,ConstructToCode,3);
81   }
82 
83 /*************************************************************/
84 /* ConstructToCode: Produces deftemplate code for a run-time */
85 /*   module created using the constructs-to-c function.      */
86 /*************************************************************/
ConstructToCode(void * theEnv,const char * fileName,const char * pathName,char * fileNameBuffer,int fileID,FILE * headerFP,int imageID,int maxIndices)87 static int ConstructToCode(
88   void *theEnv,
89   const char *fileName,
90   const char *pathName,
91   char *fileNameBuffer,
92   int fileID,
93   FILE *headerFP,
94   int imageID,
95   int maxIndices)
96   {
97    int fileCount = 1;
98    struct defmodule *theModule;
99    struct deftemplate *theTemplate;
100    struct templateSlot *slotPtr;
101    int slotCount = 0, slotArrayCount = 0, slotArrayVersion = 1;
102    int moduleCount = 0, moduleArrayCount = 0, moduleArrayVersion = 1;
103    int templateArrayCount = 0, templateArrayVersion = 1;
104    FILE *slotFile = NULL, *moduleFile = NULL, *templateFile = NULL;
105 
106    /*==================================================*/
107    /* Include the appropriate deftemplate header file. */
108    /*==================================================*/
109 
110    fprintf(headerFP,"#include \"tmpltdef.h\"\n");
111 
112    /*=============================================================*/
113    /* Loop through all the modules, all the deftemplates, and all */
114    /* the deftemplate slots writing their C code representation   */
115    /* to the file as they are traversed.                          */
116    /*=============================================================*/
117 
118    theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL);
119 
120    while (theModule != NULL)
121      {
122       EnvSetCurrentModule(theEnv,(void *) theModule);
123 
124       moduleFile = OpenFileIfNeeded(theEnv,moduleFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
125                                     moduleArrayVersion,headerFP,
126                                     "struct deftemplateModule",ModulePrefix(DeftemplateData(theEnv)->DeftemplateCodeItem),
127                                     FALSE,NULL);
128 
129       if (moduleFile == NULL)
130         {
131          CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices);
132          return(0);
133         }
134 
135       DeftemplateModuleToCode(theEnv,moduleFile,theModule,imageID,maxIndices,moduleCount);
136       moduleFile = CloseFileIfNeeded(theEnv,moduleFile,&moduleArrayCount,&moduleArrayVersion,
137                                      maxIndices,NULL,NULL);
138 
139       /*=======================================================*/
140       /* Loop through each of the deftemplates in this module. */
141       /*=======================================================*/
142 
143       theTemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,NULL);
144 
145       while (theTemplate != NULL)
146         {
147          templateFile = OpenFileIfNeeded(theEnv,templateFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
148                                          templateArrayVersion,headerFP,
149                                          "struct deftemplate",ConstructPrefix(DeftemplateData(theEnv)->DeftemplateCodeItem),
150                                          FALSE,NULL);
151          if (templateFile == NULL)
152            {
153             CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices);
154             return(0);
155            }
156 
157          DeftemplateToCode(theEnv,templateFile,theTemplate,imageID,maxIndices,
158                         moduleCount,slotCount);
159          templateArrayCount++;
160          templateFile = CloseFileIfNeeded(theEnv,templateFile,&templateArrayCount,&templateArrayVersion,
161                                           maxIndices,NULL,NULL);
162 
163          /*======================================================*/
164          /* Loop through each of the slots for this deftemplate. */
165          /*======================================================*/
166 
167          slotPtr = theTemplate->slotList;
168          while (slotPtr != NULL)
169            {
170             slotFile = OpenFileIfNeeded(theEnv,slotFile,fileName,pathName,fileNameBuffer,fileID,imageID,&fileCount,
171                                         slotArrayVersion,headerFP,
172                                        "struct templateSlot",SlotPrefix(),FALSE,NULL);
173             if (slotFile == NULL)
174               {
175                CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices);
176                return(0);
177               }
178 
179             SlotToCode(theEnv,slotFile,slotPtr,imageID,maxIndices,slotCount);
180             slotCount++;
181             slotArrayCount++;
182             slotFile = CloseFileIfNeeded(theEnv,slotFile,&slotArrayCount,&slotArrayVersion,
183                                          maxIndices,NULL,NULL);
184             slotPtr = slotPtr->next;
185            }
186 
187          theTemplate = (struct deftemplate *) EnvGetNextDeftemplate(theEnv,theTemplate);
188         }
189 
190       theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,theModule);
191       moduleCount++;
192       moduleArrayCount++;
193 
194      }
195 
196    CloseDeftemplateFiles(theEnv,moduleFile,templateFile,slotFile,maxIndices);
197 
198    return(1);
199   }
200 
201 /************************************************************/
202 /* CloseDeftemplateFiles: Closes all of the C files created */
203 /*   for deftemplates. Called when an error occurs or when  */
204 /*   the deftemplates have all been written to the files.   */
205 /************************************************************/
CloseDeftemplateFiles(void * theEnv,FILE * moduleFile,FILE * templateFile,FILE * slotFile,int maxIndices)206 static void CloseDeftemplateFiles(
207   void *theEnv,
208   FILE *moduleFile,
209   FILE *templateFile,
210   FILE *slotFile,
211   int maxIndices)
212   {
213    int count = maxIndices;
214    int arrayVersion = 0;
215 
216    if (slotFile != NULL)
217      {
218       count = maxIndices;
219       CloseFileIfNeeded(theEnv,slotFile,&count,&arrayVersion,maxIndices,NULL,NULL);
220      }
221 
222    if (templateFile != NULL)
223      {
224       count = maxIndices;
225       CloseFileIfNeeded(theEnv,templateFile,&count,&arrayVersion,maxIndices,NULL,NULL);
226      }
227 
228    if (moduleFile != NULL)
229      {
230       count = maxIndices;
231       CloseFileIfNeeded(theEnv,moduleFile,&count,&arrayVersion,maxIndices,NULL,NULL);
232      }
233   }
234 
235 /*************************************************************/
236 /* DeftemplateModuleToCode: Writes the C code representation */
237 /*   of a single deftemplate module to the specified file.   */
238 /*************************************************************/
DeftemplateModuleToCode(void * theEnv,FILE * theFile,struct defmodule * theModule,int imageID,int maxIndices,int moduleCount)239 static void DeftemplateModuleToCode(
240   void *theEnv,
241   FILE *theFile,
242   struct defmodule *theModule,
243   int imageID,
244   int maxIndices,
245   int moduleCount)
246   {
247 #if MAC_XCD
248 #pragma unused(moduleCount)
249 #endif
250 
251    fprintf(theFile,"{");
252 
253    ConstructModuleToCode(theEnv,theFile,theModule,imageID,maxIndices,
254                          DeftemplateData(theEnv)->DeftemplateModuleIndex,ConstructPrefix(DeftemplateData(theEnv)->DeftemplateCodeItem));
255 
256    fprintf(theFile,"}");
257   }
258 
259 /************************************************************/
260 /* DeftemplateToCode: Writes the C code representation of a */
261 /*   single deftemplate construct to the specified file.    */
262 /************************************************************/
DeftemplateToCode(void * theEnv,FILE * theFile,struct deftemplate * theTemplate,int imageID,int maxIndices,int moduleCount,int slotCount)263 static void DeftemplateToCode(
264   void *theEnv,
265   FILE *theFile,
266   struct deftemplate *theTemplate,
267   int imageID,
268   int maxIndices,
269   int moduleCount,
270   int slotCount)
271   {
272    /*====================*/
273    /* Deftemplate Header */
274    /*====================*/
275 
276    fprintf(theFile,"{");
277 
278    ConstructHeaderToCode(theEnv,theFile,&theTemplate->header,imageID,maxIndices,
279                                   moduleCount,ModulePrefix(DeftemplateData(theEnv)->DeftemplateCodeItem),
280                                   ConstructPrefix(DeftemplateData(theEnv)->DeftemplateCodeItem));
281    fprintf(theFile,",");
282 
283    /*===========*/
284    /* Slot List */
285    /*===========*/
286 
287    if (theTemplate->slotList == NULL)
288      { fprintf(theFile,"NULL,"); }
289    else
290      {
291       fprintf(theFile,"&%s%d_%d[%d],",SlotPrefix(),
292                  imageID,
293                  (slotCount / maxIndices) + 1,
294                  slotCount % maxIndices);
295      }
296 
297    /*==========================================*/
298    /* Implied Flag, Watch Flag, In Scope Flag, */
299    /* Number of Slots, and Busy Count.         */
300    /*==========================================*/
301 
302    fprintf(theFile,"%d,0,0,%d,%ld,",theTemplate->implied,theTemplate->numberOfSlots,theTemplate->busyCount);
303 
304    /*=================*/
305    /* Pattern Network */
306    /*=================*/
307 
308    if (theTemplate->patternNetwork == NULL)
309      { fprintf(theFile,"NULL"); }
310    else
311      { FactPatternNodeReference(theEnv,theTemplate->patternNetwork,theFile,imageID,maxIndices); }
312 
313    /*============================================*/
314    /* Print the factList and lastFact references */
315    /* and close the structure.                   */
316    /*============================================*/
317 
318    fprintf(theFile,",NULL,NULL}");
319   }
320 
321 /*****************************************************/
322 /* SlotToCode: Writes the C code representation of a */
323 /*   single deftemplate slot to the specified file.  */
324 /*****************************************************/
SlotToCode(void * theEnv,FILE * theFile,struct templateSlot * theSlot,int imageID,int maxIndices,int slotCount)325 static void SlotToCode(
326   void *theEnv,
327   FILE *theFile,
328   struct templateSlot *theSlot,
329   int imageID,
330   int maxIndices,
331   int slotCount)
332   {
333    /*===========*/
334    /* Slot Name */
335    /*===========*/
336 
337    fprintf(theFile,"{");
338    PrintSymbolReference(theEnv,theFile,theSlot->slotName);
339 
340    /*=============================*/
341    /* Multislot and Default Flags */
342    /*=============================*/
343 
344    fprintf(theFile,",%d,%d,%d,%d,",theSlot->multislot,theSlot->noDefault,
345                                    theSlot->defaultPresent,theSlot->defaultDynamic);
346 
347    /*=============*/
348    /* Constraints */
349    /*=============*/
350 
351    PrintConstraintReference(theEnv,theFile,theSlot->constraints,imageID,maxIndices);
352 
353    /*===============*/
354    /* Default Value */
355    /*===============*/
356 
357    fprintf(theFile,",");
358    PrintHashedExpressionReference(theEnv,theFile,theSlot->defaultList,imageID,maxIndices);
359 
360    /*============*/
361    /* Facet List */
362    /*============*/
363 
364    fprintf(theFile,",");
365    PrintHashedExpressionReference(theEnv,theFile,theSlot->facetList,imageID,maxIndices);
366    fprintf(theFile,",");
367 
368    /*===========*/
369    /* Next Slot */
370    /*===========*/
371 
372    if (theSlot->next == NULL)
373      { fprintf(theFile,"NULL}"); }
374    else
375      {
376       fprintf(theFile,"&%s%d_%d[%d]}",SlotPrefix(),imageID,
377                                ((slotCount+1) / maxIndices) + 1,
378                                 (slotCount+1) % maxIndices);
379      }
380   }
381 
382 /*****************************************************************/
383 /* DeftemplateCModuleReference: Writes the C code representation */
384 /*   of a reference to a deftemplate module data structure.      */
385 /*****************************************************************/
DeftemplateCModuleReference(void * theEnv,FILE * theFile,int count,int imageID,int maxIndices)386 globle void DeftemplateCModuleReference(
387   void *theEnv,
388   FILE *theFile,
389   int count,
390   int imageID,
391   int maxIndices)
392   {
393    fprintf(theFile,"MIHS &%s%d_%d[%d]",ModulePrefix(DeftemplateData(theEnv)->DeftemplateCodeItem),
394                       imageID,
395                       (count / maxIndices) + 1,
396                       (count % maxIndices));
397   }
398 
399 /********************************************************************/
400 /* DeftemplateCConstructReference: Writes the C code representation */
401 /*   of a reference to a deftemplate data structure.                */
402 /********************************************************************/
DeftemplateCConstructReference(void * theEnv,FILE * theFile,void * vTheTemplate,int imageID,int maxIndices)403 globle void DeftemplateCConstructReference(
404   void *theEnv,
405   FILE *theFile,
406   void *vTheTemplate,
407   int imageID,
408   int maxIndices)
409   {
410    struct deftemplate *theTemplate = (struct deftemplate *) vTheTemplate;
411 
412    if (theTemplate == NULL)
413      { fprintf(theFile,"NULL"); }
414    else
415      {
416       fprintf(theFile,"&%s%d_%ld[%ld]",ConstructPrefix(DeftemplateData(theEnv)->DeftemplateCodeItem),
417                       imageID,
418                       (theTemplate->header.bsaveID / maxIndices) + 1,
419                       theTemplate->header.bsaveID % maxIndices);
420      }
421 
422   }
423 
424 /*******************************************/
425 /* InitDeftemplateCode: Writes out runtime */
426 /*   initialization code for deftemplates. */
427 /*******************************************/
InitDeftemplateCode(void * theEnv,FILE * initFP,int imageID,int maxIndices)428 static void InitDeftemplateCode(
429   void *theEnv,
430   FILE *initFP,
431   int imageID,
432   int maxIndices)
433   {
434 #if MAC_XCD
435 #pragma unused(theEnv)
436 #pragma unused(imageID)
437 #pragma unused(maxIndices)
438 #endif
439 
440    fprintf(initFP,"   DeftemplateRunTimeInitialize(theEnv);\n");
441   }
442 
443 #endif /* DEFTEMPLATE_CONSTRUCT && CONSTRUCT_COMPILER && (! RUN_TIME) */
444 
445