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