tizen 2.4 release
[external/clips.git] / src / tmpltcmp.c
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 /*********************************************************/
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 /*************************************************************/
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 /************************************************************/
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 /*************************************************************/
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 /************************************************************/
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 /*****************************************************/
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 /*****************************************************************/
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 /********************************************************************/
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 /*******************************************/
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