Bug Summary

File:src/gencpp.c
Warning:line 4071, column 67
Access to field 'parents' results in a dereference of a null pointer (loaded from field 'methods')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name gencpp.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/home/kfp/aldor/aldor/aldor/src -fcoverage-compilation-dir=/home/kfp/aldor/aldor/aldor/src -resource-dir /usr/local/lib/clang/18 -D PACKAGE_NAME="aldor" -D PACKAGE_TARNAME="aldor" -D PACKAGE_VERSION="1.4.0" -D PACKAGE_STRING="aldor 1.4.0" -D PACKAGE_BUGREPORT="aldor@xinutec.org" -D PACKAGE_URL="" -D PACKAGE="aldor" -D VERSION="1.4.0" -D YYTEXT_POINTER=1 -D HAVE_STDIO_H=1 -D HAVE_STDLIB_H=1 -D HAVE_STRING_H=1 -D HAVE_INTTYPES_H=1 -D HAVE_STDINT_H=1 -D HAVE_STRINGS_H=1 -D HAVE_SYS_STAT_H=1 -D HAVE_SYS_TYPES_H=1 -D HAVE_UNISTD_H=1 -D STDC_HEADERS=1 -D HAVE_LIBREADLINE=1 -D HAVE_READLINE_READLINE_H=1 -D HAVE_READLINE_HISTORY=1 -D HAVE_READLINE_HISTORY_H=1 -D USE_GLOOP_SHELL=1 -D GENERATOR_COROUTINES=0 -D HAVE_DLFCN_H=1 -D LT_OBJDIR=".libs/" -I . -D VCSVERSION="2c53e759f1e00e345f8b172e7139debda72fda13" -internal-isystem /usr/local/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-empty-body -Wno-enum-compare -Wno-missing-field-initializers -Wno-unused -Wno-unused-parameter -Wno-error=format -Wno-error=type-limits -Wno-error=strict-aliasing -Wno-sign-compare -Wno-error=shift-negative-value -Wno-error=clobbered -std=c99 -ferror-limit 19 -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2026-01-15-223856-845667-1 -x c gencpp.c
1#include "axltop.h"
2#include "genc.h"
3#include "gencpp.h"
4#include "stab.h"
5#include "store.h"
6/*
7 * 2006/Dec/20
8 *
9 * Including cconfig.h to gain access to CC_SF_is_double
10 */
11#include "cconfig.h"
12/*
13 * Define a local macro for the C data type being used to represent
14 * a single float. We cannot just go and include the normal definition
15 * because that becomes a tangle of conflicting definitions from all the
16 * other files that are included as a result.
17 */
18#ifdef CC_SF_is_double
19# define SF_STRING"float" "double"
20#else
21# define SF_STRING"float" "float"
22#endif
23
24localstatic String itoa_(int);
25
26/* ----------- GLOBAL OBJECTS ----------- */
27
28String CurrentClassAldor = NULL((void*)0);
29String CurrentClassCpp = NULL((void*)0);
30const int theTRUE = 1;
31const int theFALSE = 0;
32
33String commonOperators[] = { "+", "-", "/" };
34int CO_size = sizeof(commonOperators)/sizeof(String);
35
36/* Some types can not be used in an export statement */
37String typesToSkip[] = { "HInt", "Bool", "Char", "SFlo", "XByte" };
38int tTS_size = sizeof(typesToSkip)/sizeof(String);
39
40String infixOps[] = { "+", "-", "/", "*", "mod", "rem", "quo", "by", "^",
41 "/\\", "\\/", "=", "~", "~=", "<", "<=", ">", ">=" };
42int IO_size = sizeof(infixOps)/sizeof(String);
43
44String cppKeywords[] = { "case", "switch", "class" };
45int CK_size = sizeof(cppKeywords)/sizeof(String);
46
47int globalFuncCounter = 0;
48const int TabZero = 0;
49
50String *basicAldorTypes;
51int bAT_size;
52String *basicCppTypes;
53int basicHasBeenUsrDefined = 0; /* basic type correspondence not defined yet */
54int discriminationReturnType = 0; /* no discrimination on return type */
55
56#define CPPOPT_BASICFILE"basicfile=" "basicfile=" /* file containing basic type correspondence */
57#define CPPOPT_DISCRETYP"discrim-return" "discrim-return" /* discrimination on return type for overloading */
58#define CPPOPT_NODISCRETYP"no-discrim-return" "no-discrim-return" /* no discrimination (default) */
59
60/* ----------- BASIC TYPES default ------------- */
61
62static String defaultBasicAldorTypes[] = {
63 "SingleInteger", "String", "Character", "SingleFloat", "DoubleFloat",
64 "Pointer", "()", "Word", "Ptr", "Bool", "Byte", "SInt", "Char",
65 "Arr", "Rec", "BInt", "DFlo" };
66static int def_bAT_size = sizeof(defaultBasicAldorTypes)/sizeof(String);
67
68static String defaultBasicCppTypes[] = {
69 "int", "char *", "char", SF_STRING"float", "double*",
70 "void *", "void", "FiWord", "FiPtr", "FiBool", "FiByte", "FiSInt", "FiChar",
71 "FiArr", "FiRec", "FiBInt", "FiDFlo" };
72
73/* ----------- DIRECTLY USED FROM genCpp -------------- */
74
75/* THE MAIN FUNCTION */
76
77void genCpp(AbSyn ab, String dir, String file) {
78 /* From a sequence, two jobs are done:
79 1- Determination of the "type" of the node
80 2- Code generation
81 */
82
83 FILE *as_file, *cc_file;
84
85 if (!ab) {
1
Assuming 'ab' is non-null
2
Taking false branch
86 fprintf(stderrstderr, "C++ generation can not proceed.\nAbstract Syntax tree not available.\n");
87 return;
88 }
89
90 if (!basicHasBeenUsrDefined) InitBasicTypesArray(NULL((void*)0));
3
Assuming 'basicHasBeenUsrDefined' is not equal to 0
4
Taking false branch
91 CreateOutputFiles(dir,file,&cc_file,&as_file);
92
93 if (SequenceCheck(ab)) return;
5
Taking false branch
94
95 /* PreDeclarationOfClasses(ab,cc_file); This should not be needed anymore */
96 ExportGen(ab,cc_file,as_file);
6
Calling 'ExportGen'
97 CodeGen(ab,cc_file,as_file);
98
99 fclose(as_file);
100 fclose(cc_file);
101}
102
103int cppOption(String opt) {
104 String s;
105
106 if ((s = strIsPrefix(CPPOPT_BASICFILE"basicfile=", opt))) {
107 if (InitBasicTypesArray(s) == -1) return -1;
108 basicHasBeenUsrDefined = theTRUE;
109 return 0;
110 }
111
112 if (strEqual(CPPOPT_DISCRETYP"discrim-return",opt)) {
113 discriminationReturnType = theTRUE;
114 return 0;
115 }
116
117 if (strEqual(CPPOPT_NODISCRETYP"no-discrim-return",opt)) {
118 discriminationReturnType = theFALSE;
119 return 0;
120 }
121
122 return -1;
123}
124
125void updateBasicTypes(String s, int typeNumber) {
126 String current;
127 int lg, i, previndex;
128
129 lg = strlen(s);
130
131 /* spaces in the front */
132 i = 0;
133 while ((s[i] == ' ') && (i < lg)) i++;
134
135 /* type */
136 previndex = i;
137 while ((s[i] != ' ') && (i < lg)) i++;
138 basicAldorTypes[typeNumber] = strAlloc(i-previndex+1);
139 i = previndex;
140 current = basicAldorTypes[typeNumber];
141 while ((s[i] != ' ') && (i < lg)) {
142 if (s[i] != '\n') {
143 *current = s[i];
144 current++;
145 }
146 i++;
147 }
148 *current = '\0';
149
150 /* spaces in the middle */
151 while ((s[i] == ' ') && (i < lg)) i++;
152
153 /* type */
154 previndex = i;
155 while ((s[i] != ' ') && (i < lg)) i++;
156 basicCppTypes[typeNumber] = strAlloc(i-previndex+1);
157 i = previndex;
158 current = basicCppTypes[typeNumber];
159 while ((s[i] != ' ') && (i < lg)) {
160 if (s[i] != '\n') {
161 *current = s[i];
162 current++;
163 }
164 i++;
165 }
166 *current = '\0';
167}
168
169int InitBasicTypesArray(String file) {
170 /* If parameter is NULL, then no '-P' option has been used */
171 /* returned value: 0 -> ok, -1 -> problem */
172
173 FILE *basic = NULL((void*)0);
174 int numberOfTypes, i;
175 String s = strAlloc(1000);
176
177 /* Open the file */
178
179 if (file) {
180 basic = fopen(file,"r");
181 if (!basic) return -1;
182 }
183 else { /* no '-P' option, we have to do it ourselves */
184 /* Try 'basic.typ' in the current directory */
185 basic = fopen("./basic.typ","r");
186 if (!basic) { /* no user defined basic types */
187 /* Try in the standard directory */
188 if (compRootDir) {
189 String s = strPrintf("%s/include/basic.typ",compRootDir);
190 basic = fopen(s,"r");
191 }
192 if (!basic) { /* argh ! no standard defined basic types */
193 /* we use the default hard-coded one */
194 fprintf(stderrstderr,"Unable to find basic.typ\n");
195 fprintf(stderrstderr,"Using default basic types correspondence\n");
196 basicAldorTypes = defaultBasicAldorTypes;
197 bAT_size = def_bAT_size;
198 basicCppTypes = defaultBasicCppTypes;
199 return 0; /* no more work to do */
200 }
201 }
202 }
203
204 /* Create the list */
205
206 /* 1st: how many lines in the file ? */
207 numberOfTypes = 0;
208 while (!feof(basic)) {
209 IgnoreResult(fgets(s,1000,basic))if (fgets(s,1000,basic));;
210 numberOfTypes++;
211 }
212 numberOfTypes--; /* there is always one extra loop, don't know why */
213
214 /* 2nd: allocation of memory */
215 basicAldorTypes = (String *) malloc(numberOfTypes*sizeof(String));
216 basicCppTypes = (String *) malloc(numberOfTypes*sizeof(String));
217 bAT_size = numberOfTypes;
218
219 /* 3rd: filling the arrays */
220 rewind(basic);
221 for (i = 0; i < numberOfTypes; i++) {
222 IgnoreResult(fgets(s,1000,basic))if (fgets(s,1000,basic));;
223 updateBasicTypes(s, i);
224 }
225
226#if !defined(NDEBUG)
227 fprintf(stderrstderr, " Basic types correspondence:\n");
228 for (i = 0; i < numberOfTypes; i++)
229 fprintf(stderrstderr," [%s] and [%s]\n",basicAldorTypes[i],basicCppTypes[i]);
230#endif
231
232 strFree(s);
233 fclose(basic);
234 return 0;
235}
236
237
238void CreateOutputFiles(String dir, String file, FILE **cc, FILE **as) {
239 /*
240 Nothing special here, we create the C++ and the Aldor files
241 to output the generated code ...
242 */
243
244 String s;
245
246 s = strPrintf("%s/%s_cc.h",dir,file);
247 *cc = fopen(s,"w+");
248 strFree(s);
249 s = strPrintf("%s/%s_as.as",dir,file);
250 *as = fopen(s,"w+");
251 strFree(s);
252
253 /* Output the headers (#include) */
254 fprintf(*as,"#include \"%s.as\"\n",file);
255}
256
257int SequenceCheck(AbSyn ab) {
258 /* A simple check to be sure we deal with a sequence */
259 if (abTag(ab)((ab)->abHdr.tag) != AB_Sequence) {
260 fprintf(stderrstderr,"Should be sequence ! (node code = %d)\n",abTag(ab)((ab)->abHdr.tag));
261 return 1;
262 }
263 return 0;
264}
265
266
267int DeterminationTypeOf(AbSyn ab) {
268 /*
269 Depending on the structure of the subtree, it is possible to
270 determine a correspondence with C++ types (classes, abstract
271 classes, templates, variable, function)
272 */
273 int typof;
274
275 switch (abTag(ab)((ab)->abHdr.tag)) {
276 case AB_Define:
277 typof = GettypDefine(ab);
278 break;
279 case AB_Assign:
280 typof = AC_VAR;
281 break;
282 case AB_Local:
283 typof = AC_VAR;
284 break;
285 case AB_Default:
286 typof = AC_VAR;
287 break;
288 default:
289 typof = AC_NONE;
290 break;
291 }
292
293 return typof;
294}
295
296/* --------------------------------------------------------- */
297/* HERE COMES THE THREE MAIN FUNCTIONS */
298/* */
299/* 1. PreDeclarationOfClasses => class A; */
300/* 2. ExportGen => extern "C" and import from Foreign C */
301/* 3. CodeGen => classes generation and stubs */
302/* --------------------------------------------------------- */
303
304void PreDeclarationOfClasses(AbSyn ab, FILE *cc) {
305 AbSyn tmp;
306 int typof,i;
307
308 /* C++ and Aldor code generation for predeclaration of classes in C++ */
309 for (i=0; i < abArgc(ab)((ab)->abHdr.argc); i++) {
310 tmp = abSeqArg(ab,i)((ab)->abSequence.argv[(i)]);
311
312 typof = DeterminationTypeOf(tmp);
313
314 /* Code generation */
315 switch (typof) {
316 case AC_NONE:
317 break;
318 case AC_CLASS:
319 fprintf(cc,"class %s;\n",abIdStr(abDeclareId(abDefineLhs(tmp)))((((((tmp)->abDefine.lhs))->abDeclare.id))->abId.sym
->str)
);
320 if (abTag(abDeclareType(abDefineLhs(tmp)))((((((tmp)->abDefine.lhs))->abDeclare.type))->abHdr.
tag)
== AB_With)
321 fprintf(cc,"class ALDORCategory%s;\n",abIdStr(abDeclareId(abDefineLhs(tmp)))((((((tmp)->abDefine.lhs))->abDeclare.id))->abId.sym
->str)
);
322 break;
323 case AC_ABS_CLASS:
324 fprintf(cc,"class %s;\n",abIdStr(abDeclareId(abDefineLhs(tmp)))((((((tmp)->abDefine.lhs))->abDeclare.id))->abId.sym
->str)
);
325 break;
326 default:
327 break;
328 }
329 }
330}
331
332void DebugGen(int typof) {
333#if !defined(NDEBUG)
334 switch (typof) {
335 case AC_NONE:
336 break;
337 case AC_FUNCTION:
338 fprintf(stderrstderr,"Function generation\n");
339 break;
340 case AC_CLASS:
341 fprintf(stderrstderr,"Class generation\n");
342 break;
343 case AC_TEMPL_CLASS:
344 fprintf(stderrstderr,"Template class generation\n");
345 break;
346 case AC_ABS_CLASS:
347 fprintf(stderrstderr,"Abstract class generation\n");
348 /* Should not be necessary ... well maybe for the default section ...*/
349 break;
350 case AC_ABS_TMPL_CLASS:
351 fprintf(stderrstderr,"Abstract template class generation\n");
352 /* Should not be necessary ... well maybe for the default section ...*/
353 break;
354 case AC_VAR:
355 fprintf(stderrstderr,"Variable generation\n");
356 break;
357 default:
358 break;
359 }
360#endif
361}
362
363void ExportGen(AbSyn ab, FILE *cc, FILE *as) {
364 AbSyn tmp;
365 int typof,i;
366
367#if !defined(NDEBUG)
368 fprintf(stderrstderr,"\n\n IMPORT/EXPORT GENERATION \n\n");
369#endif
370
371 fprintf(as,"export {\n");
372 fprintf(cc,"#include <foam_c.h>\n");
373 fprintf(cc,"extern \"C\" {\n");
374
375 globalFuncCounter = 0;
376
377 /* C++ and Aldor code generation for C interface */
378 for (i=0; i < abArgc(ab)((ab)->abHdr.argc); i++) {
7
Assuming 'i' is < field 'argc'
8
Loop condition is true. Entering loop body
11
Assuming 'i' is < field 'argc'
12
Loop condition is true. Entering loop body
15
Assuming 'i' is < field 'argc'
16
Loop condition is true. Entering loop body
379 tmp = abSeqArg(ab,i)((ab)->abSequence.argv[(i)]);
380
381 typof = DeterminationTypeOf(tmp);
382
383 /* Debug */
384 DebugGen(typof);
385
386 /* Code generation */
387 switch (typof) {
9
Control jumps to 'case AC_NONE:' at line 388
13
Control jumps to 'case AC_VAR:' at line 405
17
Control jumps to 'case AC_TEMPL_CLASS:' at line 396
388 case AC_NONE:
389 break;
10
Execution continues on line 378
390 case AC_FUNCTION:
391 GenExportFunction(tmp,as,cc);
392 break;
393 case AC_CLASS:
394 GenExportClass(tmp,!BL_IsTmpltheTRUE,as,cc);
395 break;
396 case AC_TEMPL_CLASS:
397 GenExportClass(tmp,BL_IsTmpltheTRUE,as,cc);
18
Calling 'GenExportClass'
398 break;
399 case AC_ABS_CLASS:
400 /* Should not be necessary ... well maybe for the default section ...*/
401 break;
402 case AC_ABS_TMPL_CLASS:
403 /* Should not be necessary ... well maybe for the default section ...*/
404 break;
405 case AC_VAR:
406 break;
14
Execution continues on line 378
407 default:
408 break;
409 }
410 }
411
412 fprintf(as,"} to Foreign C;\n");
413 fprintf(cc,"}\n");
414}
415
416void CodeGen(AbSyn ab, FILE *cc, FILE *as) {
417 AbSyn tmp;
418 int typof,i;
419
420#if !defined(NDEBUG)
421 fprintf(stderrstderr,"\n\n CODE GENERATION \n\n");
422#endif
423
424 globalFuncCounter = 0;
425
426 for (i=0; i < abArgc(ab)((ab)->abHdr.argc); i++) {
427 tmp = abSeqArg(ab,i)((ab)->abSequence.argv[(i)]);
428
429 typof = DeterminationTypeOf(tmp);
430
431 /* Debug */
432 DebugGen(typof);
433
434 /* Code generation */
435 switch (typof) {
436 case AC_NONE:
437 break;
438 case AC_FUNCTION:
439 GenFunction(tmp,as,cc);
440 break;
441 case AC_CLASS:
442 GenClassesForDomains(tmp,theFALSE,as,cc);
443 break;
444 case AC_TEMPL_CLASS:
445 GenClassesForDomains(tmp,theTRUE,as,cc);
446 break;
447 case AC_ABS_CLASS:
448 GenClassForCategories(tmp,theFALSE,as,cc);
449 break;
450 case AC_ABS_TMPL_CLASS:
451 GenClassForCategories(tmp,theTRUE,as,cc);
452 break;
453 case AC_VAR:
454 break;
455 default:
456 break;
457 }
458 }
459}
460
461/* ------------------------------------------------------------------- BUILDING CLASSES ---------- */
462
463/* ---------- ERROR ---------- */
464
465Class *errorBuildClass(Class *cl) {
466 FreeClass(cl);
467 return NULL((void*)0);
468}
469
470/* ---------- END ERROR ---------- */
471
472/* ---------- ID HANDLING ---------- */
473
474void BuildParentIdAbs(Ident *id, AbSyn ab) {
475 /* abTag(ab) should be AB_Apply */
476 String tmp;
477
478 if (abHasTag(ab,AB_Apply)((ab)->abHdr.tag == (AB_Apply))) id->basic = abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str);
479 else id->basic = abIdStr(ab)((ab)->abId.sym->str); /* ab is an abId */
480 tmp = BldId(ab);
481 if (!tmp) {
482 id->typeAldor = strPrintf("%s",abIdStr(ab)((ab)->abId.sym->str));
483 id->typeCpp = strPrintf("%s<PercentType>",abIdStr(ab)((ab)->abId.sym->str));
484 id->export = id->basic;
485 }
486 else {
487 id->typeAldor = strPrintf("%s(%s)",abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),tmp);
488 id->typeCpp = strPrintf("%s<PercentType,%s>",abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),tmp);
489 id->export = id->basic;
490 strFree(tmp);
491 }
492}
493
494void BuildExtraClassId(Class *mother, Class *cl, int isTmpl) {
495 if (!isTmpl) {
496 cl->id.export = cl->id.basic;
497 cl->id.typeAldor = strPrintf("%s",cl->id.basic);
498 cl->id.typeCpp = strPrintf("%s<%s>",cl->id.basic,mother->id.typeCpp);
499 }
500 else {
501 if ((!tfIsMulti(cl->params)(((cl->params)->tag) == TF_Multiple)) && (!tfIsDeclare(cl->params)(((cl->params)->tag) == TF_Declare))) {
502 cl->id.export = cl->id.basic;
503 cl->id.typeAldor = strPrintf("%s",cl->id.basic);
504 cl->id.typeCpp = strPrintf("%s<%s>",cl->id.basic,mother->id.typeCpp);
505 }
506 else if (tfIsDeclare(cl->params)(((cl->params)->tag) == TF_Declare)) {
507 String str = symString(tfDeclareId(cl->params))((tfDeclareId(cl->params))->str);
508
509 cl->id.export = strPrintf("%s%s", cl->id.basic, str);
510 cl->id.typeCpp = strPrintf("%s<%s,%s>", cl->id.basic, mother->id.typeCpp, str);
511 cl->id.typeAldor = strPrintf("%s(%s)", cl->id.basic, str);
512 }
513 else {
514 String str;
515 String str_tmp = InitStr()strAlloc(500);
516 size_t i,j;
517 j = tfMultiArgc(cl->params);
518
519 /* Create strings for the identifiers used for import/export, in C++, in Aldor */
520
521 /* export */
522 str_tmp = STRCAT(str_tmp,cl->id.basic);
523 for (i = 0; i < j; i++) {
524 str = symString(tfDeclareId(tfMultiArgN(cl->params,i)))((tfDeclareId(tfFollowArg(cl->params, i)))->str);
525 str_tmp = STRCAT(str_tmp,str);
526 }
527 cl->id.export = strCopy(str_tmp);
528
529 /* typeCpp */
530 str_tmp[0] = 0;
531 str_tmp = STRCAT(str_tmp,cl->id.basic);
532 str_tmp = STRCAT(str_tmp,"<");
533 str_tmp = STRCAT(str_tmp,mother->id.typeCpp);
534 if (j) str_tmp = STRCAT(str_tmp,",");
535 for (i = 0; i < j; i++) {
536 str = symString(tfDeclareId(tfMultiArgN(cl->params,i)))((tfDeclareId(tfFollowArg(cl->params, i)))->str);
537 str_tmp = STRCAT(str_tmp,str);
538 if (i < j-1) str_tmp = STRCAT(str_tmp,",");
539 }
540 str_tmp = STRCAT(str_tmp,">");
541 cl->id.typeCpp = strCopy(str_tmp);
542
543 /* typeAldor */
544 str_tmp[0] = 0;
545 str_tmp = STRCAT(str_tmp,cl->id.basic);
546 str_tmp = STRCAT(str_tmp,"(");
547 if (j) str_tmp = STRCAT(str_tmp,",");
548 for (i = 0; i < j; i++) {
549 str = symString(tfDeclareId(tfMultiArgN(cl->params,i)))((tfDeclareId(tfFollowArg(cl->params, i)))->str);
550 str_tmp = STRCAT(str_tmp,str);
551 if (i < j-1) str_tmp = STRCAT(str_tmp,",");
552 }
553 str_tmp = STRCAT(str_tmp,")");
554 cl->id.typeAldor = strCopy(str_tmp);
555
556 strFree(str_tmp);
557 }
558 }
559}
560
561void BuildClassId(Class *cl, int isTmpl) {
562 if (!isTmpl
37.1
'isTmpl' is 1
)
38
Taking false branch
563 cl->id.export = cl->id.typeAldor = cl->id.typeCpp = cl->id.basic;
564 else {
565 size_t i,j;
566 String str;
567
568 /* Compute the lengths of the strings export and type ... */
569 if ((!tfIsMulti(cl->params)(((cl->params)->tag) == TF_Multiple)) && (!tfIsDeclare(cl->params)(((cl->params)->tag) == TF_Declare)))
39
Assuming field 'tag' is not equal to TF_Multiple
40
Assuming field 'tag' is not equal to TF_Declare
41
Taking true branch
570 cl->id.export = cl->id.typeAldor = cl->id.typeCpp = cl->id.basic;
571 else if (tfIsDeclare(cl->params)(((cl->params)->tag) == TF_Declare)) {
572 str = symString(tfDeclareId(cl->params))((tfDeclareId(cl->params))->str);
573 cl->id.export = strPrintf("%s%s", cl->id.basic, str);
574 cl->id.typeCpp = strPrintf("%s<%s>", cl->id.basic, str);
575 cl->id.typeAldor = strPrintf("%s(%s)", cl->id.basic, str);
576 } else {
577 String str_tmp = InitStr()strAlloc(500);
578 j = tfMultiArgc(cl->params);
579
580 /* Create strings */
581
582 /* export */
583 str_tmp = STRCAT(str_tmp,cl->id.basic);
584 for (i = 0; i < j; i++) {
585 str = symString(tfDeclareId(tfMultiArgN(cl->params,i)))((tfDeclareId(tfFollowArg(cl->params, i)))->str);
586 str_tmp = STRCAT(str_tmp,str);
587 }
588 cl->id.export = strCopy(str_tmp);
589
590 /* typeCpp */
591 str_tmp[0] = 0;
592 str_tmp = STRCAT(str_tmp,cl->id.basic);
593 str_tmp = STRCAT(str_tmp,"<");
594 for (i = 0; i < j; i++) {
595 str = symString(tfDeclareId(tfMultiArgN(cl->params,i)))((tfDeclareId(tfFollowArg(cl->params, i)))->str);
596 str_tmp = STRCAT(str_tmp,str);
597 if (i < j-1) str_tmp = STRCAT(str_tmp,",");
598 }
599 str_tmp = STRCAT(str_tmp,">");
600 cl->id.typeCpp = strCopy(str_tmp);
601
602 /* typeAldor */
603 str_tmp[0] = 0;
604 str_tmp = STRCAT(str_tmp,cl->id.basic);
605 str_tmp = STRCAT(str_tmp,"(");
606 for (i = 0; i < j; i++) {
607 str = symString(tfDeclareId(tfMultiArgN(cl->params,i)))((tfDeclareId(tfFollowArg(cl->params, i)))->str);
608 str_tmp = STRCAT(str_tmp,str);
609 if (i < j-1) str_tmp = STRCAT(str_tmp,",");
610 }
611 str_tmp = STRCAT(str_tmp,")");
612 cl->id.typeAldor = strCopy(str_tmp);
613
614 strFree(str_tmp);
615 }
616 }
617}
42
Returning without writing to 'cl->params', which participates in a condition later
43
Returning without writing to 'cl->methods'
618
619String BldId(AbSyn ab) {
620 String result;
621 String tmp2 = NULL((void*)0);
622 int i;
623
624 if (!abHasTag(ab,AB_Apply)((ab)->abHdr.tag == (AB_Apply))) return NULL((void*)0);
625
626 result = InitStr()strAlloc(500);
627
628 for (i = 0; i < abApplyArgc(ab)(((ab)->abHdr.argc)-1); i++) {
629 switch (abTag(abApplyArg(ab,i))((((ab)->abApply.argv[i]))->abHdr.tag)) {
630 case AB_Id:
631 if (result[0]) result = STRCAT(result,","); /* if (result[0]) then this is not the first time, so we need a comma */
632 result = STRCAT(result,abIdStr(abApplyArg(ab,i))((((ab)->abApply.argv[i]))->abId.sym->str));
633 break;
634 case AB_Apply:
635 tmp2 = BldId(abApplyArg(ab,i)((ab)->abApply.argv[i]));
636 if (!tmp2) { strFree(result); return NULL((void*)0); }
637 if (result[0]) result = STRCAT(result,","); /* for the comma */
638 result = STRCAT(result,abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str));
639 result = STRCAT(result,"<");
640 result = STRCAT(result,tmp2);
641 result = STRCAT(result,">");
642 strFree(tmp2);
643 break;
644 default:
645 break;
646 }
647 }
648 if (!(result[0])) { strFree(result); return NULL((void*)0); }
649 tmp2 = strCopy(result);
650 strFree(result);
651 return tmp2;
652}
653
654void BuildParentId(Ident *id, AbSyn ab) {
655 /* abTag(ab) should be AB_Apply */
656 String tmp;
657
658 if (abHasTag(ab,AB_Apply)((ab)->abHdr.tag == (AB_Apply))) {
659 id->basic = abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str);
660 id->export = id->basic;
661 tmp = BldId(ab);
662 if (tmp) {
663 id->typeAldor = strPrintf("%s(%s)",abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),tmp);
664 id->typeCpp = strPrintf("%s<%s,%s>",abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),CurrentClassCpp,tmp);
665 strFree(tmp);
666 }
667 }
668 else {
669 id->basic = abIdStr(ab)((ab)->abId.sym->str); /* ab is an abId */
670 id->export = id->basic;
671 id->typeAldor = strPrintf("%s",abIdStr(ab)((ab)->abId.sym->str));
672 id->typeCpp = strPrintf("%s<%s>",abIdStr(ab)((ab)->abId.sym->str),CurrentClassCpp);
673 }
674}
675
676/* ---------- END ID HANDLING ---------- */
677
678/* ---------- MAIN FUNCTIONS ---------- */
679
680void getParentsAbs(Class *cl, TForm tf, int isTmpl) {
681 AbSyn ab;
682 Ident *id;
683 int i;
684
685 switch (tfTag(tf)((tf)->tag)) {
686 case TF_Multiple:
687 return;
688 case TF_General:
689 if (!tfHasExpr(tf)((tf)->__absyn != 0)) return;
690 ab = tfGetExpr(tf)((tf)->__absyn);
691 switch (abTag(ab)((ab)->abHdr.tag)) {
692 case AB_Id:
693 id = alloc(Ident)(Ident *) stoAlloc(0,sizeof(Ident));
694 BuildParentIdAbs(id,ab);
695 Append(cl->parents,CT_PARENT,id);
696 break;
697 case AB_Apply:
698 id = alloc(Ident)(Ident *) stoAlloc(0,sizeof(Ident));
699 BuildParentIdAbs(id,ab);
700 Append(cl->parents,CT_PARENT,id);
701 break;
702 default:
703 break;
704 }
705 break;
706 case TF_With:
707 getParentsAbs(cl,tfWithBase(tf)tfFollowArg(tf, 0),isTmpl);
708 break;
709 case TF_Join:
710 for (i=0; i < tfJoinArgc(tf)((tf)->argc); i++) getParentsAbs(cl,tfJoinArgN(tf,i)tfFollowArg(tf, i),isTmpl);
711 break;
712 default:
713 fprintf(stderrstderr,"Error in building class (getParents): %d\n",tfTag(tf)((tf)->tag));
714 break;
715 }
716}
717
718Class *BuildAbstractClass(AbSyn ab, int isTmpl) {
719 /*
720 1. BuildAbstractClass is working for abTag(ab) == AB_Define
721
722 2. abDefine has two parts:
723 a) lhs => declaration (~ header == X: Category)
724 b) rhs => definition (~ body == Join(Y,Z) with {...})
725
726 3. BuildClass allocates CurrentClass
727 */
728
729 Class *cl;
730 TForm tf;
731
732 if (abTag(ab)((ab)->abHdr.tag) != AB_Define) return NULL((void*)0);
733
734 cl = InitClass();
735
736 /* ---- id */
737 cl->id.basic = abIdStr(abDeclareId(abDefineLhs(ab)))((((((ab)->abDefine.lhs))->abDeclare.id))->abId.sym->
str)
;
738
739 /* ---- Body ---- */
740 tf = abTUnique(abDefineLhs(ab))((((ab)->abDefine.lhs))->abHdr.type.unique);
741
742 /* -- params */
743 if (isTmpl) {
744 cl->params = tfMapArg(tf)tfFollowArg(tf, 0);
745 if (ToSkipClass(cl)) {
746 FreeClass(cl);
747 return NULL((void*)0);
748 }
749 }
750
751 /* -- methods */
752 if (isTmpl) tf=tfMapRet(tf)tfFollowArg(tf, 1);
753 tf = tfFollowDefDecl(tf);
754
755 if (!tfIsThird(tf)(((tf)->tag) == TF_Third)) return errorBuildClass(cl);
756
757 if (!tfThdExports(tf)) {
758 /* we are in this case when this is a template abstract class */
759 if (!tfArgc(tf)((tf)->argc)) return errorBuildClass(cl);
760 tf = tfThirdRestrictions(tf)tfFollowArg(tf, 0);
761 if (!tfIsWith(tf)(((tf)->tag) == TF_With)) return errorBuildClass(cl);
762 tf = tfTUnique(tf)((((tf)->__absyn))->abHdr.type.unique);
763 if (!tfIsThird(tf)(((tf)->tag) == TF_Third)) return errorBuildClass(cl);
764 if (!tfThdExports(tf)) return errorBuildClass(cl);
765 }
766
767 /* Here tfThdExports(tf) contains all the definitions of the methods */
768 cl->methods = tf;
769
770 /* ---- id */
771 BuildClassId(cl,isTmpl);
772
773 CurrentClassCpp = "PercentType";
774 CurrentClassAldor = cl->id.typeAldor;
775
776 /* -- Inheritance */
777
778 tf = abTUnique(abDefineLhs(ab))((((ab)->abDefine.lhs))->abHdr.type.unique);
779
780 if (isTmpl) tf = tfMapRet(tf)tfFollowArg(tf, 1);
781 tf = tfFollowDefDecl(tf);
782 tf = tfThirdRestrictions(tf)tfFollowArg(tf, 0);
783 getParentsAbs(cl,tf,isTmpl);
784
785
786 /* ---- free some memory */
787 if (Empty(cl->extraClasses)) { stoFree(cl->extraClasses); cl->extraClasses = NULL((void*)0);}
788 if (Empty(cl->parents)) { stoFree(cl->parents); cl->parents = NULL((void*)0);} /* we KNOW that cl->parents != NULL */
789
790 return cl;
791}
792
793Class *buildExtraClass(Class *cl, TForm tf, int isTmpl) {
794 String str_tmp;
795 String str_tmp2;
796 TForm tmp;
797 Class *extra = InitClass();
798
799 /* id */
800 extra->id.basic = strPrintf("ALDORCategory%s%d",cl->id.basic,cl->classCounter);
801
802 /* params */
803 if (isTmpl) extra->params = cl->params;
804
805 /* id is back */
806 BuildExtraClassId(cl,extra,isTmpl);
807
808 /* inheritance */
809 str_tmp = CurrentClassAldor;
810 str_tmp2 = CurrentClassCpp;
811 CurrentClassAldor = extra->id.typeAldor;
812 CurrentClassCpp = "PercentType";
813 getParents(extra,tfWithBase(tf)tfFollowArg(tf, 0),isTmpl);
814 CurrentClassAldor = str_tmp;
815 CurrentClassCpp = str_tmp2;
816
817 /* body */
818 tmp = tfWithWithin(tf)tfFollowArg(tf, 1);
819 if (!tfIsThird(tmp)(((tmp)->tag) == TF_Third)) {
820 tmp = tfTUnique(tmp)((((tmp)->__absyn))->abHdr.type.unique);
821 tmp = tfFollowDefDecl(tmp);
822 }
823 if (!tfIsThird(tmp)(((tmp)->tag) == TF_Third)) extra->methods = NULL((void*)0);
824 else extra->methods = tmp;
825
826 /* ---- free some memory */
827 if (Empty(extra->extraClasses)) { stoFree(extra->extraClasses); extra->extraClasses = NULL((void*)0); }
828 if (Empty(extra->parents)) { stoFree(extra->parents); extra->parents = NULL((void*)0); } /* we KNOW that extra->params != NULL */
829
830 return extra;
831}
832
833void getParents(Class *cl, TForm tf, int isTmpl) {
834 Class *extra;
835 AbSyn ab;
836 Ident *id;
837 int i;
838
839 switch (tfTag(tf)((tf)->tag)) {
47
Control jumps to 'case TF_With:' at line 860
840 case TF_Multiple:
841 return;
842 case TF_General:
843 if (!tfHasExpr(tf)((tf)->__absyn != 0)) return;
844 ab = tfGetExpr(tf)((tf)->__absyn);
845 switch (abTag(ab)((ab)->abHdr.tag)) {
846 case AB_Id:
847 id = alloc(Ident)(Ident *) stoAlloc(0,sizeof(Ident));
848 BuildParentId(id,ab);
849 Append(cl->parents,CT_PARENT,id);
850 break;
851 case AB_Apply:
852 id = alloc(Ident)(Ident *) stoAlloc(0,sizeof(Ident));
853 BuildParentId(id,ab);
854 Append(cl->parents,CT_PARENT,id);
855 break;
856 default:
857 break;
858 }
859 break;
860 case TF_With:
861 extra = buildExtraClass(cl,tf,isTmpl);
48
Value assigned to field 'methods'
862 if (extra) {
49
Assuming 'extra' is null
50
Taking false branch
51
Execution continues on line 862
863 Append(cl->extraClasses,CT_EXTRA,extra); /* Create extra Class Il peut y avoir plusieurs extra classes */
864 cl->classCounter++;
865 Append(cl->parents,CT_PARENT,&(extra->id));
866 }
867 break;
868 case TF_Join:
869 for (i=0; i < tfJoinArgc(tf)((tf)->argc); i++) getParents(cl,tfJoinArgN(tf,i)tfFollowArg(tf, i),isTmpl);
870 break;
871 default:
872 fprintf(stderrstderr,"Error in building class (getParents): %d\n",tfTag(tf)((tf)->tag));
873 break;
874 }
875}
876
877Class *BuildClass(AbSyn ab, int isTmpl) {
878 /*
879 1. BuildClass is working for abTag(ab) == AB_Define
880
881 2. abDefine has two parts:
882 a) lhs => declaration (~ header == X: some category)
883 b) rhs => definition (~ body == Y add {...})
884
885 3. BuildClass allocates CurrentClass
886 */
887
888 /* Variables declaration */
889 Class *cl;
890 TForm tf, tmp;
891
892 /* Source code */
893 if (abTag(ab)((ab)->abHdr.tag) != AB_Define) return NULL((void*)0);
20
Taking false branch
894
895 cl = InitClass();
896
897 /* ---- id */
898 cl->id.basic = abIdStr(abDeclareId(abDefineLhs(ab)))((((((ab)->abDefine.lhs))->abDeclare.id))->abId.sym->
str)
;
899
900 /* ---- Body */
901 tf = abTUnique(abDefineLhs(ab))((((ab)->abDefine.lhs))->abHdr.type.unique);
902
903 /* params */
904 if (isTmpl
20.1
'isTmpl' is 1
) {
21
Taking true branch
905 cl->params = tfMapArg(tf)tfFollowArg(tf, 0);
906 if (ToSkipClass(cl)) {
22
Calling 'ToSkipClass'
32
Returning from 'ToSkipClass'
33
Taking false branch
907 FreeClass(cl);
908 return NULL((void*)0);
909 }
910 }
911
912 /* Methods */
913 tmp = tf;
914 if (isTmpl
33.1
'isTmpl' is 1
) tmp = tfMapRet(tmp)tfFollowArg(tmp, 1);
34
Taking true branch
915 tmp = tfTUnique(tfFollowDefDecl(tmp))((((tfFollowDefDecl(tmp))->__absyn))->abHdr.type.unique
)
;
916 tmp = tfFollowDefDecl(tmp);
917
918 if (!tfIsThird(tmp)(((tmp)->tag) == TF_Third)) return errorBuildClass(cl);
35
Assuming field 'tag' is equal to TF_Third
36
Taking false branch
919
920 cl->methods = tmp;
921
922 /* ---- id */
923 BuildClassId(cl,isTmpl);
37
Calling 'BuildClassId'
44
Returning from 'BuildClassId'
924
925 CurrentClassAldor = cl->id.typeAldor;
926 CurrentClassCpp = cl->id.typeCpp;
927
928 /* Parents */
929 tmp = tf;
930 if (isTmpl
44.1
'isTmpl' is 1
) tmp = tfMapRet(tmp)tfFollowArg(tmp, 1);
45
Taking true branch
931 tmp = tfFollowDefDecl(tmp);
932 getParents(cl,tmp,isTmpl);
46
Calling 'getParents'
52
Returning from 'getParents'
933
934 /* ---- free some memory */
935 if (Empty(cl->extraClasses)) {stoFree(cl->extraClasses); cl->extraClasses = NULL((void*)0);}
53
Taking true branch
936 if (Empty(cl->parents)) {stoFree(cl->parents); cl->parents = NULL((void*)0);} /* we KNOW that cl->parents != NULL */
54
Taking true branch
937
938 return cl;
939}
940
941/* ---------- END MAIN FUNCTIONS ---------- */
942
943/* -------------------------------------------------------------- END BUILDING CLASSES ---------- */
944
945/*
946% ------------------------------------------------
947% Determination part
948% ------------------------------------------------
949*/
950
951
952cpp_types detCppType(AbSyn ab) {
953 TForm tf;
954
955 if (!ab) return AC_NONE;
956
957 tf = abTUnique(ab)((ab)->abHdr.type.unique); /* get the tform */
958
959 tf = tfFollowDefDecl(tf); /* get the interesting cell */
960
961 if (tfIsMap(tf)(((tf)->tag) == TF_Map)) {
962 tf = tfMapRet(tf)tfFollowArg(tf, 1); /* get the return type of the Map */
963
964 tf = tfFollowDefDecl(tf); /* get the interesting cell */
965
966 /* param category ? */
967 if (tfIsThird(tf)(((tf)->tag) == TF_Third)) return AC_ABS_TMPL_CLASS;
968
969 /* param domain ? */
970 tf = tfFollowDefDecl(tfTUnique(tf)((((tf)->__absyn))->abHdr.type.unique));
971 if (tfIsThird(tf)(((tf)->tag) == TF_Third)) return AC_TEMPL_CLASS;
972
973 /* still here ? well it is a function */
974 return AC_FUNCTION;
975 }
976
977 /* tf is not a TF_Map */
978
979 /* category ? */
980 if (tfIsThird(tf)(((tf)->tag) == TF_Third)) return AC_ABS_CLASS;
981
982 /* domain ? */
983 tf = tfFollowDefDecl(tfTUnique(tf)((((tf)->__absyn))->abHdr.type.unique));
984 if (tfIsThird(tf)(((tf)->tag) == TF_Third)) return AC_CLASS;
985
986 /* still here ? well it is a constant */
987 return AC_CST;
988}
989
990cpp_types GettypDefine(AbSyn ab) {
991
992 if (abTag(ab)((ab)->abHdr.tag) == AB_Local) return AC_VAR;
993 if (abTag(ab)((ab)->abHdr.tag) == AB_Default) return AC_VAR;
994 if (abTag(ab)((ab)->abHdr.tag) != AB_Define) return AC_NONE;
995 /* if the object is not a definition then we can't determine the type */
996
997#if !defined(NDEBUG)
998 if (abTag(abDefineLhs(ab))((((ab)->abDefine.lhs))->abHdr.tag) == AB_Declare)
999 fprintf(stderrstderr,"%s ",abIdStr(abDeclareId(abDefineLhs(ab)))((((((ab)->abDefine.lhs))->abDeclare.id))->abId.sym->
str)
);
1000#endif
1001
1002 return detCppType(abDefineLhs(ab)((ab)->abDefine.lhs));
1003}
1004
1005/* Bugs and to do:
1006. If SInt is specified without '$Machine' (using 'import from Machine;' for example), then
1007the program doesn't translate SInt to FiSInt
1008. Multiple return with a % in the list of returned things => just crash I think
1009. overloading discrimine sur type de retour
1010. function pointers
1011. default parameters
1012. value parameters for domains (like SI or SF)
1013. global variable
1014. Overloading resolved only on return type is not handled.
1015*/
1016
1017int scanForBelongsTo(String *paramList, int lgList, String toCompare) {
1018 int i;
1019 for (i=0 ; i < lgList; i++)
1020 if (!strcmp(toCompare,paramList[i])) return theTRUE;
1021 return theFALSE;
1022}
1023
1024int abBelongsTo(AbSyn ab, String *paramList, int lgList) {
1025
1026 int i;
1027
1028 switch (abTag(ab)((ab)->abHdr.tag)) {
1029 case AB_Id:
1030 return scanForBelongsTo(paramList,lgList,abIdStr(ab)((ab)->abId.sym->str));
1031 case AB_Apply:
1032 if (scanForBelongsTo(paramList,lgList,abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str))) return theTRUE;
1033 for (i = 0; i < abApplyArgc(ab)(((ab)->abHdr.argc)-1); i++)
1034 if (abBelongsTo(abApplyArg(ab,i)((ab)->abApply.argv[i]),paramList,lgList)) return theTRUE;
1035 return theFALSE;
1036 case AB_Nothing:
1037 return theFALSE;
1038 case AB_Comma:
1039 for (i=0; i < abArgc(ab)((ab)->abHdr.argc); i++)
1040 if (abBelongsTo(abCommaArg(ab,i)((ab)->abComma.argv[(i)]),paramList,lgList)) return theTRUE;
1041 return theFALSE;
1042 case AB_Qualify:
1043 if (abBelongsTo(ab->abQualify.what,paramList,lgList)) return theTRUE;
1044 if (abBelongsTo(ab->abQualify.origin,paramList,lgList)) return theTRUE;
1045 return theFALSE;
1046 case AB_Declare:
1047 if (abBelongsTo(abDeclareType(ab)((ab)->abDeclare.type),paramList,lgList)) return theTRUE;
1048 return theFALSE;
1049 default:
1050 return theFALSE;
1051 }
1052
1053}
1054
1055int BelongsTo(TForm type, String *paramList, int lgList) {
1056 /* two cases: either we get an absyn from the type,
1057 or it is a multiple value (A,B,C) */
1058 AbSyn ab = tfGetExpr(type)((type)->__absyn);
1059 int i, lg;
1060
1061 if (ab) return abBelongsTo(ab,paramList,lgList);
1062
1063 if (!tfIsMulti(type)(((type)->tag) == TF_Multiple)) return theFALSE; /* we don't know how to check so it doesn't belong to it */
1064 lg = tfMultiArgc(type);
1065 for (i = 0; i < lg; i++)
1066 if (BelongsTo(tfMultiArgN(type,i)tfFollowArg(type, i),paramList,lgList)) return theTRUE;
1067 return theFALSE;
1068}
1069
1070int HasDependentTypes(TForm tf) {
1071 int paramNb, returnNb;
1072 int actualParamNb, actualReturnNb;
1073 TForm args, rets;
1074 String *argsList;
1075 String *retsList;
1076
1077 /*
1078 We want to check if a function uses dependent types,
1079 (e.g f: (E: Type, a: E) -> E). If yes, then we will skip the function.
1080 To do that, we are going to consider the String values of the names
1081 of parameters. Here we store in an array the names of all parameters
1082 and then for each parameter and returned type, we check if its type
1083 is or uses any element of the array.
1084 To deal with things like:
1085 g: (a: E, E: Type) -> E
1086 we need to store all the parameters names, that is why we use an array.
1087 */
1088
1089 /* We get a pointer to the arguments and the number of arguments */
1090 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return theFALSE;
1091 args = tfMapArg(tf)tfFollowArg(tf, 0);
1092 paramNb = tfIsMulti(args)(((args)->tag) == TF_Multiple) ? tfMultiArgc(args) : 1;
1093
1094 /* We get a pointer to the returned values and the number of returned values */
1095 rets = tfMapRet(tf)tfFollowArg(tf, 1);
1096 returnNb = tfIsMulti(rets)(((rets)->tag) == TF_Multiple) ? tfMultiArgc(rets) : 1;
1097
1098 /* Let's fill the array for parameters */
1099 actualParamNb = 0;
1100 argsList = NULL((void*)0);
1101 if (paramNb) {
1102 argsList = (String *)stoAlloc(int0((int) 0),paramNb*sizeof(String));
1103 if (paramNb == 1) {
1104 if (tfIsDeclare(args)(((args)->tag) == TF_Declare)) argsList[actualParamNb++] = symString(tfDeclareId(args))((tfDeclareId(args))->str);
1105 /* should be a "tfDeclare", but it may be a function prototype, so if
1106 it is not a tfDeclare we don't do anything */
1107 } else {
1108 int i;
1109 for (i=0 ; i<paramNb; i++) {
1110 TForm tmp = tfMultiArgN(args,i)tfFollowArg(args, i);
1111 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) argsList[actualParamNb++] = symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str);
1112 /* should be a "tfDeclare", but it may be a function prototype, so if
1113 it is not a tfDeclare we don't do anything */
1114 }
1115 }
1116
1117
1118 /* Let's check the type of the parameters */
1119 if (paramNb == 1) {
1120 if (tfIsDeclare(args)(((args)->tag) == TF_Declare))
1121 if (BelongsTo(tfDeclareType(args)tfFollowArg(args, 0),argsList,actualParamNb)) {
1122 if (argsList) stoFree(argsList);
1123 return theTRUE;
1124 }
1125 /* should be a "tfDeclare", but it may be a function prototype, so if
1126 it is not a tfDeclare we don't do anything */
1127 } else {
1128 int i;
1129 for (i=0 ; i<paramNb; i++) {
1130 TForm tmp = tfMultiArgN(args,i)tfFollowArg(args, i);
1131 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare))
1132 if (BelongsTo(tfDeclareType(tmp)tfFollowArg(tmp, 0),argsList,actualParamNb)) {
1133 if (argsList) stoFree(argsList);
1134 return theTRUE;
1135 }
1136 /* should be a "tfDeclare", but it may be a function prototype, so if
1137 it is not a tfDeclare we don't do anything */
1138 }
1139 }
1140 }
1141
1142
1143 actualReturnNb = 0;
1144 retsList = NULL((void*)0);
1145 if (returnNb) {
1146
1147 int i;
1148 retsList = (String *)stoAlloc(int0((int) 0),(actualParamNb+returnNb)*sizeof(String));
1149
1150 /* we merge the list of parameters and the list of returned values */
1151 if (argsList) {
1152 for (i=0; i < actualParamNb; i++) retsList[i] = argsList[i];
1153 stoFree(argsList);
1154 argsList = NULL((void*)0);
1155 }
1156
1157 actualReturnNb = actualParamNb;
1158
1159 /* Filling array for return values */
1160 if (returnNb == 1) {
1161 if (tfIsDeclare(rets)(((rets)->tag) == TF_Declare)) retsList[actualReturnNb++] = symString(tfDeclareId(rets))((tfDeclareId(rets))->str);
1162 /* should be a "tfDeclare", but it may be a function prototype, so if
1163 it is not a tfDeclare we don't do anything */
1164 } else {
1165 int i;
1166 for (i=0 ; i<returnNb; i++) {
1167 TForm tmp = tfMultiArgN(rets,i)tfFollowArg(rets, i);
1168 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) retsList[actualReturnNb++] = symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str);
1169 /* should be a "tfDeclare", but it may be a function prototype, so if
1170 it is not a tfDeclare we don't do anything */
1171 }
1172 }
1173
1174 /* Let's check the return value */
1175 if (returnNb == 1) {
1176 if (BelongsTo(rets,retsList,actualReturnNb)) {
1177 if (retsList) stoFree(retsList);
1178 return theTRUE;
1179 }
1180 /* should be a "tfDeclare", but it may be a function prototype, so if
1181 it is not a tfDeclare we don't do anything */
1182 } else {
1183 int i;
1184 for (i=0 ; i<returnNb; i++) {
1185 TForm tmp = tfMultiArgN(rets,i)tfFollowArg(rets, i);
1186 if (BelongsTo(tmp,retsList,actualReturnNb)) {
1187 if (retsList) stoFree(retsList);
1188 return theTRUE;
1189 }
1190 /* should be a "tfDeclare", but it may be a function prototype, so if
1191 it is not a tfDeclare we don't do anything */
1192 }
1193 }
1194 }
1195
1196 /* Free the memory */
1197 if (argsList) stoFree(argsList);
1198 if (retsList) stoFree(retsList);
1199
1200 return theFALSE;
1201
1202}
1203
1204int CheckSkipClassParam(TForm tf) {
1205 /* Does tf describe an appropriate parameter for a class ? */
1206 /* return: theTRUE -> ok, we don't skip
1207 theFALSE -> not ok, we skip
1208 */
1209
1210 /* Rules:
1211 TF_Type => OK
1212 TF_General
1213 -> Look at tfUnique in absyn of tf
1214 -> TF_Third => OK
1215 -> else NOT OK
1216 else NOT OK
1217
1218 We should thus allow regular categories and parameterized categories.
1219 We don't allow function pointers, value, or inline categories.
1220 */
1221
1222 AbSyn ab;
1223 TForm tmp;
1224
1225 if (tfIsType(tf)(((tf)->tag) == TF_Type)) return theTRUE;
1226 if (!tfIsGeneral(tf)(((tf)->tag) == TF_General)) return theFALSE;
1227 ab = tfGetExpr(tf)((tf)->__absyn);
1228 if (!ab) return theFALSE; /* should not happen, it is safer to skip */
1229 tmp = abTUnique(ab)((ab)->abHdr.type.unique);
1230 if (!tmp) return theFALSE; /* should not happen, it is safer to skip */
1231 tmp = tfFollowDefDecl(tmp);
1232 if (!tmp) return theFALSE; /* should not happen, it is safer to skip */
1233 if (!tfIsThird(tmp)(((tmp)->tag) == TF_Third)) return theFALSE; /* something we don't handle */
1234 return theTRUE; /* TF_Third corresponds to a regular or parameterized non-inline category */
1235}
1236
1237int ToSkipClass(Class *cl) {
1238 /* precondition: the class cl has to be built */
1239
1240 /* We check if the parameters of a class are suitable
1241 for the interface, we skip everything which is not
1242 of type non-inline category (we don't handle things like:
1243 A(E: with { .... }) ...
1244 */
1245 /*
1246 Return: theTRUE -> to skip
1247 theFALSE -> no skip
1248 */
1249
1250 TForm tf = cl->params;
1251
1252 /* if the type is not parameterized, nothing has to be done here */
1253 if (!tf) return theFALSE;
23
Assuming 'tf' is non-null
1254
1255 /*
1256 parameters are either tfDeclare (1 param) or tfMulti (0 or more than 1 param)
1257 if not it is safer to skip that
1258 */
1259 if (!tfIsDeclare(tf)(((tf)->tag) == TF_Declare) && !tfIsMulti(tf)(((tf)->tag) == TF_Multiple)) return theTRUE;
24
Assuming field 'tag' is not equal to TF_Declare
25
Assuming field 'tag' is equal to TF_Multiple
26
Taking false branch
1260
1261 if (tfIsDeclare(tf)(((tf)->tag) == TF_Declare))
27
Taking false branch
1262 return (!CheckSkipClassParam(tfDeclareType(tf)tfFollowArg(tf, 0)));
1263 else {
1264 int i = 0;
1265 int sizeMulti = tfMultiArgc(tf);
1266
1267 for ( i=0 ; i < sizeMulti ; i++) {
28
Assuming 'i' is >= 'sizeMulti'
29
Loop condition is false. Execution continues on line 1273
1268 TForm tmp = tfMultiArgN(tf,i)tfFollowArg(tf, i);
1269 if (!tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) return theTRUE; /* should not happen, safer to skip */
1270 if (!CheckSkipClassParam(tfDeclareType(tmp)tfFollowArg(tmp, 0))) return theTRUE;
1271 }
1272 }
1273 return theFALSE;
30
Returning without writing to '->params', which participates in a condition later
31
Returning without writing to '->methods'
1274}
1275
1276int ToSkip(TForm tf) {
1277 int paramNb, returnNb;
1278 TForm args, rets;
1279
1280 /*
1281 We want to check if a function uses forbidden types,
1282 for that we use the array typesToSkip.
1283 */
1284
1285 /* We get a pointer to the arguments and the number of arguments */
1286 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return theFALSE;
1287 args = tfMapArg(tf)tfFollowArg(tf, 0);
1288 paramNb = tfIsMulti(args)(((args)->tag) == TF_Multiple) ? tfMultiArgc(args) : 1;
1289
1290 /* We get a pointer to the returned values and the number of returned values */
1291 rets = tfMapRet(tf)tfFollowArg(tf, 1);
1292 returnNb = tfIsMulti(rets)(((rets)->tag) == TF_Multiple) ? tfMultiArgc(rets) : 1;
1293
1294 if (paramNb) {
1295 if (paramNb == 1) {
1296 if (tfIsDeclare(args)(((args)->tag) == TF_Declare)) {
1297 if (BelongsTo(tfDeclareType(args)tfFollowArg(args, 0),typesToSkip,tTS_size)) return theTRUE;
1298 } else {
1299 if (BelongsTo(args,typesToSkip,tTS_size)) return theTRUE;
1300 }
1301 /* should be a "tfDeclare", but it may be a function prototype, so if
1302 it is not a tfDeclare we don't do anything */
1303 } else {
1304 int i;
1305 for (i=0 ; i<paramNb; i++) {
1306 TForm tmp = tfMultiArgN(args,i)tfFollowArg(args, i);
1307 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) {
1308 if (BelongsTo(tfDeclareType(tmp)tfFollowArg(tmp, 0),typesToSkip,tTS_size)) return theTRUE;
1309 } else {
1310 if (BelongsTo(tmp,typesToSkip,tTS_size)) return theTRUE;
1311 }
1312 }
1313 }
1314 }
1315
1316 if (!returnNb) return theFALSE;
1317
1318 if (returnNb == 1) {
1319 if (tfIsDeclare(rets)(((rets)->tag) == TF_Declare)) {
1320 if (BelongsTo(tfDeclareType(rets)tfFollowArg(rets, 0),typesToSkip,tTS_size)) return theTRUE;
1321 } else {
1322 if (BelongsTo(rets,typesToSkip,tTS_size)) return theTRUE;
1323 }
1324 } else {
1325 int i;
1326 for (i=0 ; i<returnNb; i++) {
1327 TForm tmp = tfMultiArgN(rets,i)tfFollowArg(rets, i);
1328 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) {
1329 if (BelongsTo(tfDeclareType(tmp)tfFollowArg(tmp, 0),typesToSkip,tTS_size)) return theTRUE;
1330 } else {
1331 if (BelongsTo(tmp,typesToSkip,tTS_size)) return theTRUE;
1332 }
1333 }
1334 }
1335
1336 return theFALSE;
1337}
1338
1339/* ---------- FUNCTION SIGNATURES ---------- */
1340
1341String GenAldorFnSig(TForm tf, String name, Class *cl, int tab, int isExported, int usePercent, int useTmplParms) {
1342 String str_tmp,result;
1343
1344 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
1345
1346 if (HasDependentTypes(tf)) return NULL((void*)0);
1347 if (ToSkip(tf)) return NULL((void*)0);
1348
1349 result = InitStr()strAlloc(500);
1350
1351 /* Function id */
1352 result = sprintTab(result,tab);
1353 str_tmp = GenAldorFuncName(name,cl,isExported);
1354 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1355 result = STRCAT(result,str_tmp); result = STRCAT(result,": ");
1356 strFree(str_tmp);
1357
1358 /* Parameters */
1359 str_tmp = GenAldorParams(tf,cl,BL_WithTypetheTRUE,!BL_WithNametheTRUE,!BL_InBodytheTRUE,usePercent,useTmplParms);
1360 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1361 result = STRCAT(result,str_tmp);
1362 strFree(str_tmp);
1363
1364 /* Return values */
1365 str_tmp = TFormToAldor(tfMapRet(tf)tfFollowArg(tf, 1),usePercent);
1366 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1367 result = STRCAT(result," -> ");
1368 result = STRCAT(result,str_tmp);
1369 result = STRCAT(result,";\n");
1370 strFree(str_tmp);
1371
1372 str_tmp = strCopy(result);
1373 strFree(result);
1374 return str_tmp;
1375}
1376
1377String GenCppFnSig(TForm tf, String name, Class *cl, int tab, int isExported) {
1378 String str_tmp;
1379 TForm tmp;
1380 String result;
1381
1382 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
1383
1384 if (HasDependentTypes(tf)) return NULL((void*)0);
1385 if (ToSkip(tf)) return NULL((void*)0);
1386
1387 result = InitStr()strAlloc(500);
1388
1389 result = sprintTab(result,tab);
1390
1391 /* return */
1392 tmp = tfMapRet(tf)tfFollowArg(tf, 1);
1393 if (tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple)) result = STRCAT(result,"void"); /* means multiple return or no return */
1394 else if (tfIsExit(tmp)(((tmp)->tag) == TF_Exit)) { strFree(result); return NULL((void*)0); }
1395 else if (tfIsGenerator(tmp)(((tmp)->tag) == TF_Generator)) { strFree(result); return NULL((void*)0); }
1396 else {
1397 /* If we have function pointers, this is a special case */
1398 if (tfIsFuncPtr(tmp))
1399 result = STRCAT(result, "void *");
1400 else {
1401 str_tmp = AbSynToCpp(tfGetExpr(tmp)((tmp)->__absyn));
1402 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1403 if (AbSynIsUserDef(tfGetExpr(tmp)((tmp)->__absyn)))
1404 result = STRCAT(result,"void *");
1405 /* currently (maybe for a long time !) it is void * and not the actual type,
1406 because: 1) it is easier 2) we don't need any type checking ... */
1407 else
1408 result = STRCAT(result,str_tmp);
1409 strFree(str_tmp);
1410 }
1411 }
1412
1413 result = STRCAT(result," ");
1414
1415 str_tmp = createFnIdExternC(name,cl);
1416 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1417 result = STRCAT(result,str_tmp);
1418 strFree(str_tmp);
1419
1420 str_tmp = GenCppParams(tf,cl,BL_WithTypetheTRUE,!BL_WithNametheTRUE,BL_IsStatictheTRUE,!BL_AbstracttheTRUE,BL_ExporttheTRUE);
1421 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1422 result = STRCAT(result,str_tmp); result = STRCAT(result,";\n");
1423 strFree(str_tmp);
1424
1425 if (strstr(result, "fputc") != NULL((void*)0))
1426 {
1427 str_tmp = InitStr()strAlloc(500);
1428 STRCAT(str_tmp, "extern int fputc();\n");
1429 }
1430
1431 str_tmp = strCopy(result);
1432 strFree(result);
1433 return str_tmp;
1434}
1435
1436/* ---------- END FUNCTION SIGNATURES ---------- */
1437
1438/* ---------- STUBS ---------- */
1439
1440String GenAldorStubs(TForm tf, String name, Class *cl, int Global, int tab) {
1441 String result,str_tmp;
1442 int isInfix;
1443
1444 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
1445
1446 if (HasDependentTypes(tf)) return NULL((void*)0);
1447 if (ToSkip(tf)) return NULL((void*)0);
1448
1449 result = InitStr()strAlloc(500);
1450
1451 /* function id */
1452 result = sprintTab(result,tab);
1453 str_tmp = GenAldorFuncName(name,cl,BL_ExportedtheTRUE);
1454 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1455 result = STRCAT(result,str_tmp);
1456 strFree(str_tmp);
1457
1458 /* params */
1459 str_tmp = GenAldorParams(tf,cl,BL_WithTypetheTRUE,BL_WithNametheTRUE,!BL_InBodytheTRUE,!BL_UsePercenttheTRUE,BL_UseTmplParmstheTRUE);
1460 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1461 result = STRCAT(result,str_tmp); result = STRCAT(result,": ");
1462 strFree(str_tmp);
1463
1464 /* return */
1465 str_tmp = TFormToAldor(tfMapRet(tf)tfFollowArg(tf, 1),theFALSE);
1466 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1467 result = STRCAT(result,str_tmp); result = STRCAT(result," == ");
1468 strFree(str_tmp);
1469
1470 /* body */
1471
1472 /* -- header */
1473 result = STRCAT(result,"{ \n");
1474 result = sprintTab(result,tab+1);
1475 if (!Global) {
1476 str_tmp = OutputDomNameAldor(cl->id.typeAldor);
1477 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1478 result = STRCAT(result,"import from "); result = STRCAT(result,str_tmp); result = STRCAT(result,";\n");
1479 strFree(str_tmp);
1480 result = sprintTab(result,tab+1);
1481 }
1482
1483 /* -- id */
1484
1485 /* ---- output */
1486 isInfix = IsInfixOperator(name);
1487
1488 if (!isInfix) {
1489
1490 String s = AldorifySpeSym(name);
1491 result = STRCAT(result,s);
1492 strFree(s);
1493
1494 /* -- params */
1495 str_tmp = GenAldorParams(tf,cl,!BL_WithTypetheTRUE,BL_WithNametheTRUE,BL_InBodytheTRUE,!BL_UsePercenttheTRUE,BL_UseTmplParmstheTRUE);
1496 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1497 result = STRCAT(result,str_tmp);
1498
1499 } else { /* Operator is infix */
1500
1501 int nbParams,cnt;
1502 tf = tfMapArg(tf)tfFollowArg(tf, 0);
1503 nbParams = tfIsMulti(tf)(((tf)->tag) == TF_Multiple) ? tfMultiArgc(tf) : 1;
1504
1505 /* nbParams == 1 or 2 */
1506 if (nbParams == 1) {
1507 result = STRCAT(result,name);
1508 cnt = 0;
1509 str_tmp = GenAldorOneParam(tf,!BL_WithTypetheTRUE,BL_WithNametheTRUE,cnt,!BL_UsePercenttheTRUE);
1510 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1511 result = STRCAT(result," ("); result = STRCAT(result,str_tmp); result = STRCAT(result,")");
1512 strFree(str_tmp);
1513 }
1514 else if (nbParams != 2) { strFree(result); return NULL((void*)0); }
1515 else {
1516 /* output first param */
1517 cnt = 0;
1518 str_tmp = GenAldorOneParam(tfMultiArgN(tf,(Length) 0)tfFollowArg(tf, (Length) 0),!BL_WithTypetheTRUE,BL_WithNametheTRUE,cnt,!BL_UsePercenttheTRUE);
1519 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1520 result = STRCAT(result,"("); result = STRCAT(result,str_tmp); result = STRCAT(result,") ");
1521 strFree(str_tmp);
1522
1523 /* output name */
1524 result = STRCAT(result, name);
1525
1526 /* output second param */
1527 cnt = 1;
1528 str_tmp = GenAldorOneParam(tfMultiArgN(tf,1)tfFollowArg(tf, 1),!BL_WithTypetheTRUE,BL_WithNametheTRUE,cnt,!BL_UsePercenttheTRUE);
1529 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1530 result = STRCAT(result," ("); result = STRCAT(result,str_tmp); result = STRCAT(result,")");
1531 strFree(str_tmp);
1532 }
1533
1534 }
1535
1536 result = STRCAT(result,";\n");
1537 result = sprintTab(result,tab);
1538 result = STRCAT(result,"}\n");
1539
1540 return result;
1541}
1542
1543/* ---------- END STUBS ---------- */
1544
1545/* ---------- GLOBAL FUNCTIONS ---------- */
1546
1547/* Check multiple return, params, ... for function pointers */
1548
1549/* Create the String corresponding to function pointer parameters */
1550String GenCppFunc_ParamsRetFnPtr(TForm tf, Class *cl, int isStatic, int abstract, int export) {
1551 TForm retType;
1552 String result, str_tmp, str_tmp2;
1553
1554 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
1555 retType = tfMapRet(tf)tfFollowArg(tf, 1);
1556 if (!tfIsFuncPtr(retType)) {
1557 /* base case */
1558 str_tmp = GenCppParams(tf,cl,BL_WithTypetheTRUE,!BL_WithNametheTRUE,isStatic,abstract,export);
1559 if (!str_tmp) return NULL((void*)0);
1560 result = InitStr()strAlloc(500);
1561 result = STRCAT(result,")"); result = STRCAT(result,str_tmp);
1562 strFree(str_tmp);
1563 }
1564 else {
1565 str_tmp2 = GenCppFunc_ParamsRetFnPtr(tfMapRet(tf)tfFollowArg(tf, 1),cl,isStatic,abstract,export);
1566 str_tmp = GenCppParams(tf,cl,BL_WithTypetheTRUE,!BL_WithNametheTRUE,isStatic,abstract,export);
1567 if (!str_tmp) return NULL((void*)0);
1568 result = InitStr()strAlloc(500);
1569 result = STRCAT(result,")"); result = STRCAT(result,str_tmp);
1570 result = STRCAT(result,str_tmp2);
1571 strFree(str_tmp);
1572 strFree(str_tmp2);
1573 }
1574
1575 str_tmp = strCopy(result);
1576 strFree(result);
1577 return str_tmp;
1578}
1579
1580/* Create the String corresponding to a function pointer return value */
1581String GenCppFunc_RetFnPtr(TForm tf) {
1582 String result;
1583 String str_tmp;
1584 TForm retType;
1585 AbSyn ab;
1586
1587 if (!tfIsFuncPtr(tf)) {
1588 /* base case: if ab is not a function pointer,
1589 then we translate directly */
1590 ab = tfGetExpr(tf)((tf)->__absyn);
1591 if (!ab) return NULL((void*)0);
1592 str_tmp = AbSynToCpp(ab);
1593 if (!str_tmp) return NULL((void*)0);
1594 result = InitStr()strAlloc(500);
1595 result = STRCAT(result,str_tmp);
1596 if (AbSynIsUserDef(ab)) result = STRCAT(result,"*");
1597 strFree(str_tmp);
1598 }
1599 else {
1600 /* general case: if the return type is a function pointer,
1601 we call recursively the function */
1602 retType = tfMapRet(tf)tfFollowArg(tf, 1);
1603 str_tmp = GenCppFunc_RetFnPtr(retType);
1604 if (!str_tmp) return NULL((void*)0);
1605 result = InitStr()strAlloc(500);
1606 result = STRCAT(result,str_tmp); result = STRCAT(result,"(*");
1607 strFree(str_tmp);
1608 }
1609
1610 str_tmp = strCopy(result);
1611 strFree(result);
1612 return str_tmp;
1613}
1614
1615String GenCppFunc(TForm tf, String name, Class *cl, int tab) {
1616 TForm tmp;
1617 String result, typeToAddToName = NULL((void*)0);
1618 String str_tmp;
1619 int flagIsFnPtr = theFALSE;
1620
1621 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
1622 if (HasDependentTypes(tf)) return NULL((void*)0);
1623 if (ToSkip(tf)) return NULL((void*)0);
1624
1625 result = InitStr()strAlloc(500);
1626
1627 result = sprintTab(result,tab);
1628
1629 /* Return */
1630 tmp = tfMapRet(tf)tfFollowArg(tf, 1);
1631 flagIsFnPtr = theFALSE;
1632 if (tfIsExit(tmp)(((tmp)->tag) == TF_Exit)) { strFree(result); return NULL((void*)0); }
1633 else if (tfIsGenerator(tmp)(((tmp)->tag) == TF_Generator)) { strFree(result); return NULL((void*)0); }
1634 else if (tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple)) {
1635 result = STRCAT(result,"void ");
1636 if (discriminationReturnType) {
1637 typeToAddToName = InitStr()strAlloc(500);
1638 typeToAddToName = STRCAT(typeToAddToName,"void");
1639 }
1640 }
1641 else {
1642 /* There will be no discrimation on the return type, if the return type
1643 is a function pointer */
1644 if (tfIsFuncPtr(tmp)) {
1645 flagIsFnPtr = theTRUE;
1646 str_tmp = GenCppFunc_RetFnPtr(tmp);
1647 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1648 result = STRCAT(result,str_tmp);
1649 }
1650 else {
1651 str_tmp = AbSynToCpp(tfGetExpr(tmp)((tmp)->__absyn));
1652 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1653 if (discriminationReturnType) {
1654 typeToAddToName = InitStr()strAlloc(500);
1655 typeToAddToName = STRCAT(typeToAddToName,str_tmp);
1656 }
1657 result = STRCAT(result,str_tmp); result = STRCAT(result," ");
1658 if (AbSynIsUserDef(tfGetExpr(tmp)((tmp)->__absyn))) {
1659 result = STRCAT(result,"*");
1660 if (discriminationReturnType) typeToAddToName = STRCAT(typeToAddToName,"*");
1661 }
1662 strFree(str_tmp);
1663 }
1664 }
1665
1666 /* Function name */
1667 str_tmp = createFnIdForCPP(name,NULL((void*)0));
1668 if (!str_tmp) result = STRCAT(result,name);
1669 else { result = STRCAT(result,name); strFree(str_tmp); }
1670
1671 if (discriminationReturnType) {
1672 String ToAdd = transOperatorLike(typeToAddToName);
1673 result = STRCAT(result,"_");
1674 result = STRCAT(result,ToAdd);
1675 strFree(typeToAddToName);
1676 strFree(ToAdd);
1677 }
1678
1679 /* Params */
1680 str_tmp = GenCppParams(tf,NULL((void*)0),BL_WithTypetheTRUE,BL_WithNametheTRUE,BL_IsStatictheTRUE,!BL_AbstracttheTRUE,!BL_ExporttheTRUE);
1681 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1682 result = STRCAT(result,str_tmp);
1683 strFree(str_tmp);
1684
1685 /* Parameters of the return type if the return type is a function pointer */
1686 if (flagIsFnPtr) {
1687 str_tmp = GenCppFunc_ParamsRetFnPtr(tmp,NULL((void*)0),BL_IsStatictheTRUE,!BL_AbstracttheTRUE,!BL_ExporttheTRUE);
1688 result = STRCAT(result,str_tmp);
1689 strFree(str_tmp);
1690 }
1691
1692 /* Body */
1693 str_tmp = GenCppBodyForMethods(tf,name,NULL((void*)0));
1694 if (!str_tmp) { strFree(result); return NULL((void*)0); }
1695 result = STRCAT(result,str_tmp);
1696 strFree(str_tmp);
1697
1698 str_tmp = strCopy(result);
1699 strFree(result);
1700 return str_tmp;
1701}
1702
1703void GenFunction(AbSyn ab, FILE *as, FILE *cc) {
1704 String toOutputAS, toOutputCC;
1705 String name;
1706 TForm tf;
1707
1708 /* --- Init --- */
1709 tf = abTUnique(abDefineLhs(ab))((((ab)->abDefine.lhs))->abHdr.type.unique);
1710 name = abIdStr(abDefineLhs(abDeclareId(ab)))((((((ab)->abDeclare.id))->abDefine.lhs))->abId.sym->
str)
;
1711 CurrentClassAldor = "Global";
1712 CurrentClassCpp = "Global";
1713
1714 /* --- Aldor --- */
1715 toOutputAS = GenAldorStubs(tf,name,NULL((void*)0),BL_GlobaltheTRUE,TabZero);
1716
1717 /* --- C++ --- */
1718 toOutputCC = GenCppFunc(tf,name,NULL((void*)0),TabZero);
1719
1720 CurrentClassAldor = NULL((void*)0);
1721 CurrentClassCpp = NULL((void*)0);
1722
1723 if (toOutputAS && toOutputCC) {
1724 fprintf(as,"%s",toOutputAS);
1725 fprintf(cc,"%s",toOutputCC);
1726 strFree(toOutputAS);
1727 strFree(toOutputCC);
1728 globalFuncCounter++;
1729 } else {
1730 if (toOutputAS) strFree(toOutputAS);
1731 if (toOutputCC) strFree(toOutputCC);
1732 }
1733}
1734
1735/* ---------- END GLOBAL FUNCTIONS ---------- */
1736
1737/* ---------- HEADER ---------- */
1738
1739void GenCppConstructors(Class *cl, int tab, FILE *cc) {
1740 printTab(cc,tab);
1741 fprintf(cc,"%s() { ptr = 0; }\n",cl->id.basic);
1742 printTab(cc,tab);
1743 fprintf(cc,"%s(%s",cl->id.basic,cl->id.typeCpp);
1744 fprintf(cc," *orig) { ptr = orig; }\n");
1745 printTab(cc,tab);
1746 fprintf(cc,"%s(void *orig) { ptr = reinterpret_cast<%s",cl->id.basic,cl->id.typeCpp);
1747 fprintf(cc," *>(orig); }\n");
1748}
1749
1750void GenCppDestructor(String name, int tab, FILE *cc) {
1751 printTab(cc,tab);
1752 fprintf(cc,"virtual ~%s() {}\n",name);
1753}
1754
1755void GenCppAccessToRealObj(Class *cl, int tab, FILE *cc) {
1756 printTab(cc,tab);
1757 fprintf(cc,"friend %s",cl->id.typeCpp);
1758 fprintf(cc," *realObject(%s",cl->id.typeCpp);
1759 fprintf(cc," *ob) { return ob->ptr; }\n");
1760}
1761
1762void GenCppGiveType(Class *cl, int tab, FILE *cc) {
1763 printTab(cc,tab);
1764 fprintf(cc,"static void *givetype() { return ");
1765 fprintf(cc,"ALDOR_givetype_%s(",cl->id.export);
1766 if (cl->params) {
1767 int i;
1768 TForm tmp = cl->params;
1769 int paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
1770 if (paramNb == 1) {
1771 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare))
1772 fprintf(cc,"%s::givetype()",symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str));
1773 }
1774 else
1775 for (i=0;i<paramNb;i++) {
1776 TForm tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
1777 if (tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare))
1778 fprintf(cc,"%s::givetype()",symString(tfDeclareId(tmp2))((tfDeclareId(tmp2))->str));
1779 if (i < paramNb-1) fprintf(cc,",");
1780 }
1781 }
1782 fprintf(cc,"); }\n");
1783}
1784
1785void GenHeaderForClass(Class *cl, FILE *cc) {
1786 TForm tmp;
1787 int paramNb;
1788 int i;
1789
1790 /* template */
1791 if (cl->params) {
1792 fprintf(cc,"template <");
1793 tmp = cl->params;
1794 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
1795 if (paramNb == 1) {
1796 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare))
1797 fprintf(cc,"class %s",symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str));
1798 }
1799 else
1800 for (i=0;i<paramNb;i++) {
1801 TForm tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
1802 if (tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare))
1803 fprintf(cc,"class %s",symString(tfDeclareId(tmp2))((tfDeclareId(tmp2))->str));
1804 if (i < paramNb-1) fprintf(cc,",");
1805 }
1806 fprintf(cc,">\n");
1807 }
1808
1809 /* class */
1810 fprintf(cc,"class %s",cl->id.basic);
1811 if (NotEmpty(cl->parents)) {
1812 fprintf(cc,": ");
1813 Rewind(cl->parents);
1814 while (!EOList(cl->parents)) {
1815 Ident *id = (Ident *)GetItem(cl->parents);
1816 fprintf(cc," virtual public %s",id->typeCpp);
1817 GotoNext(cl->parents);
1818 if (!EOList(cl->parents)) fprintf(cc,",");
1819 }
1820 }
1821
1822 /* standard members */
1823 fprintf(cc," {\n");
1824 fprintf(cc,"\t%s *ptr;\n",cl->id.typeCpp);
1825 fprintf(cc,"public:\n");
1826 GenCppConstructors(cl,1,cc);
1827 GenCppDestructor(cl->id.basic,1,cc);
1828 GenCppAccessToRealObj(cl,1,cc);
1829 GenCppGiveType(cl,1,cc);
1830}
1831
1832/* ---------- END HEADER ---------- */
1833
1834/* ---------- CLASS ---------- */
1835
1836void GenExtraClass(Class *cl, Class *extra, FILE *cc) {
1837 String str_tmp;
1838 String saveCurrent;
1839 SymeList meths;
1840 Syme meth;
1841
1842 saveCurrent = CurrentClassCpp;
1843 CurrentClassCpp = "PercentType";
1844
1845 /* parameters of the class */
1846 str_tmp = GCFC_HeaderTmpl(cl);
1847 if (!str_tmp) return;
1848 fprintf(cc,"%s",str_tmp);
1849 strFree(str_tmp);
1850
1851 /* header */
1852 fprintf(cc,"class %s",extra->id.basic);
1853
1854 /* inheritance */
1855 str_tmp = GCFC_HeaderInher(extra);
1856 if (!str_tmp) return;
1857 fprintf(cc,"%s",str_tmp);
1858 strFree(str_tmp);
1859
1860 fprintf(cc," {\n");
1861 fprintf(cc,"public:\n");
1862 fprintf(cc,"\tvirtual ~%s() {}\n",extra->id.basic);
1863
1864 /* methods */
1865
1866 if (!extra->methods) {
1867 fprintf(cc,"};\n");
1868 CurrentClassCpp = saveCurrent;
1869 return;
1870 }
1871
1872 extra->methCounter = 0;
1873 meths = tfThdExports(extra->methods) ? tfThdExports(extra->methods):tfParents(extra->methods)((extra->methods)->parents);
1874 for (; meths; meths = meths->rest) {
1875 meth = meths->first;
1876
1877 str_tmp = GCFC_Methods(extra,meth);
1878 if (!str_tmp) continue;
1879 fprintf(cc,"%s",str_tmp);
1880 strFree(str_tmp);
1881
1882 extra->methCounter++;
1883 }
1884
1885 fprintf(cc,"};\n");
1886 CurrentClassCpp = saveCurrent;
1887}
1888
1889
1890void GenClassesForDomains(AbSyn ab, int isTmpl, FILE *as, FILE *cc) {
1891
1892 /*
1893 Class generation
1894 ===================
1895 Creation of an intermediate "Class" structure
1896 Code generation
1897 Intermediate struct is freed
1898 */
1899
1900
1901 /*
1902 Regular types:
1903 -------------
1904 A: ACat with { .... } == add { ... }
1905 gets to
1906 class CategoryA: virtual public ACat {
1907 public:
1908 ....
1909 };
1910 class A: virtual public CategoryA {
1911 public:
1912 ...
1913 };
1914
1915 Parameterized types:
1916 -------------------
1917 A(T: TCat): ACat(T) with { .... } == add { ... }
1918 gets to
1919 template <class T>
1920 class CategoryA: virtual public ACat {
1921 public:
1922 ....
1923 };
1924 template <class T>
1925 class A: virtual public CategoryA<T> {
1926 public:
1927 ...
1928 };
1929 */
1930
1931
1932 Class *cl;
1933 SymeList meths;
1934 String str_tmp;
1935
1936 cl = BuildClass(ab,isTmpl);
1937 if (!cl) return;
1938
1939 /* ----- Generation ------ */
1940
1941 /* /// ALDOR stubs for methods /// */
1942 if (cl->methods) {
1943 cl->methCounter = 0;
1944 meths = tfThdExports(cl->methods) ? tfThdExports(cl->methods):tfParents(cl->methods)((cl->methods)->parents);
1945 for (; meths; meths = meths->rest) {
1946 str_tmp = GenAldorStubs(symeType(meths->first),symString(symeId(meths->first))((((meths->first)->id))->str),cl,!BL_GlobaltheTRUE,TabZero);
1947 if (str_tmp) { fprintf(as,"%s",str_tmp); strFree(str_tmp); cl->methCounter++; }
1948 }
1949 }
1950
1951 /* /// C++ classes /// */
1952
1953 /* Extra Class Generation */
1954
1955 if (NotEmpty(cl->extraClasses)) {
1956 for (Rewind(cl->extraClasses); !EOList(cl->extraClasses); GotoNext(cl->extraClasses))
1957 GenExtraClass(cl,(Class *)GetItem(cl->extraClasses),cc);
1958 }
1959
1960 /* Header */
1961 GenHeaderForClass(cl,cc);
1962
1963 /* methods */
1964 if (cl->methods)
1965 GenMethodsForClass(cl,cc);
1966
1967 /* End of the class */
1968 fprintf(cc,"};\n");
1969
1970 /* Free the memory */
1971 CurrentClassAldor = NULL((void*)0);
1972 CurrentClassCpp = NULL((void*)0);
1973 FreeClass(cl);
1974}
1975
1976
1977/*
1978
1979 ----------------------------------------------------
1980 ----------- GENERATION ABS.CLASS/CLASS -------------
1981 ----------------------------------------------------
1982
1983 */
1984
1985String GCFC_HeaderTmpl(Class *cl) {
1986 String str_tmp, result = InitStr()strAlloc(500);
1987 TForm tmp = cl->params;
1988 int paramNb;
1989
1990 /* To replace % in the declaration ... */
1991 result = STRCAT(result,"template <class PercentType");
1992
1993 /* For parameterized types */
1994 if (tmp) {
1995 result = STRCAT(result,",");
1996 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
1997 if (paramNb == 1) {
1998 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) {
1999 result = STRCAT(result,"class ");
2000 result = STRCAT(result,symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str));
2001 }
2002 }
2003 else {
2004 int i;
2005 for (i=0;i<paramNb;i++) {
2006 TForm tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
2007 if (tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare)) {
2008 result = STRCAT(result,"class ");
2009 result = STRCAT(result,symString(tfDeclareId(tmp2))((tfDeclareId(tmp2))->str));
2010 }
2011 if (i < paramNb-1) result = STRCAT(result,",");
2012 }
2013 }
2014 }
2015
2016 /* end of template part */
2017 result = STRCAT(result,">\n");
2018
2019 str_tmp = strCopy(result);
2020 strFree(result);
2021 return str_tmp;
2022}
2023
2024String GCFC_HeaderInher(Class *cl) {
2025 MyList *parents = cl->parents;
2026 String str_tmp, result = InitStr()strAlloc(500);
2027
2028 if (NotEmpty(parents)) {
2029 result = STRCAT(result,": ");
2030 Rewind(parents);
2031 while (!EOList(parents)) {
2032 Parent *par = (Parent *)GetItem(parents);
2033 result = STRCAT(result," virtual public ");
2034 result = STRCAT(result,par->id.typeCpp);
2035 GotoNext(parents);
2036 if (!EOList(cl->parents)) result = STRCAT(result,",");
2037 }
2038 }
2039
2040 str_tmp = strCopy(result);
2041 strFree(result);
2042 return str_tmp;
2043}
2044
2045String GCFC_Methods(Class *cl, Syme method) {
2046 String str_tmp, result;
2047 int flagIsFnPtr = theFALSE;
2048 String typeToAddToName = NULL((void*)0);
2049 int isStatic = theFALSE;
2050 TForm tmp;
2051
2052 /* Check if method has to be output */
2053 if (!method) return NULL((void*)0);
2054 if (strEqual(symString(symeId(method))((((method)->id))->str),"%%")) return NULL((void*)0);
2055 if (HasDependentTypes(symeType(method))) return NULL((void*)0);
2056 if (ToSkip(symeType(method))) return NULL((void*)0);
2057 if (!tfIsMap(symeType(method))(((symeType(method))->tag) == TF_Map)) return NULL((void*)0);
2058
2059 /* Static or not ? */
2060 isStatic = StaticOrNot(tfMapArg(symeType(method))tfFollowArg(symeType(method), 0),cl);
2061 if (isStatic) return NULL((void*)0);
2062
2063 /* Return type */
2064 tmp = tfMapRet(symeType(method))tfFollowArg(symeType(method), 1);
2065
2066 if (tfIsExit(tmp)(((tmp)->tag) == TF_Exit)) return NULL((void*)0);
2067 if (tfIsGenerator(tmp)(((tmp)->tag) == TF_Generator)) return NULL((void*)0);
2068
2069 result = InitStr()strAlloc(500);
2070 flagIsFnPtr = theFALSE;
2071
2072 if (tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple)) {
2073 result = STRCAT(result,"\tvirtual void ");
2074 if (discriminationReturnType) {
2075 typeToAddToName = InitStr()strAlloc(500);
2076 typeToAddToName = STRCAT(typeToAddToName,"void");
2077 }
2078 }
2079 else if (tfIsFuncPtr(tmp)) {
2080 flagIsFnPtr = theTRUE;
2081 str_tmp = GenCppFunc_RetFnPtr(tmp);
2082 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2083 result = STRCAT(result,"\tvirtual ");
2084 result = STRCAT(result,str_tmp);
2085 }
2086 else {
2087 str_tmp = AbSynToCpp(tfGetExpr(tmp)((tmp)->__absyn));
2088 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2089 if (discriminationReturnType) {
2090 typeToAddToName = InitStr()strAlloc(500);
2091 typeToAddToName = STRCAT(typeToAddToName,str_tmp);
2092 }
2093 result = STRCAT(result,"\tvirtual ");
2094 result = STRCAT(result,str_tmp);
2095 result = STRCAT(result," ");
2096 if (AbSynIsUserDef(tfGetExpr(tmp)((tmp)->__absyn))) {
2097 result = STRCAT(result,"*");
2098 if (discriminationReturnType) typeToAddToName = STRCAT(typeToAddToName,"*");
2099 }
2100 strFree(str_tmp);
2101 }
2102
2103 /* Function name */
2104 str_tmp = createFnIdForCPP(symString(symeId(method))((((method)->id))->str),cl);
2105 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2106 result = STRCAT(result," "); result = STRCAT(result,str_tmp);
2107 strFree(str_tmp);
2108
2109 if (discriminationReturnType) {
2110 String ToAdd = transOperatorLike(typeToAddToName);
2111 result = STRCAT(result,"_");
2112 result = STRCAT(result,ToAdd);
2113 strFree(typeToAddToName);
2114 strFree(ToAdd);
2115 }
2116
2117 /* Parameters */
2118 str_tmp = GenCppParams(symeType(method),cl,BL_WithTypetheTRUE,!BL_WithNametheTRUE,isStatic,BL_AbstracttheTRUE,!BL_ExporttheTRUE);
2119 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2120 result = STRCAT(result,str_tmp);
2121 strFree(str_tmp);
2122
2123 /* Parameters of the return type if the return type is a function pointer */
2124 if (flagIsFnPtr) {
2125 str_tmp = GenCppFunc_ParamsRetFnPtr(tmp,cl,BL_IsStatictheTRUE,BL_AbstracttheTRUE,!BL_ExporttheTRUE);
2126 result = STRCAT(result,str_tmp);
2127 strFree(str_tmp);
2128 }
2129 result = STRCAT(result," = 0;\n");
2130
2131 str_tmp = strCopy(result);
2132 strFree(result);
2133 return str_tmp;
2134}
2135
2136void GenClassForCategories(AbSyn ab, int isTmpl, FILE *as, FILE *cc) {
2137
2138 /*
2139 Class generation
2140 ===================
2141 Creation of an intermediate "Class" structure
2142 Code generation
2143 Intermediate struct is freed
2144 */
2145
2146 Class *cl;
2147 SymeList meths;
2148 Syme meth;
2149 String str_tmp;
2150
2151 /* ----- Creation of struct ----- */
2152
2153 cl = BuildAbstractClass(ab,isTmpl);
2154 if (!cl) return;
2155
2156 /* There should be no aldor code generated because, there is no function
2157 call and so no stub needed */
2158
2159 /* C++ class generation */
2160
2161 /* ---- HEADER */
2162
2163 /* Header params */
2164 str_tmp = GCFC_HeaderTmpl(cl);
2165 if (!str_tmp) {
2166 FreeClass(cl);
2167 CurrentClassAldor = NULL((void*)0);
2168 CurrentClassCpp = NULL((void*)0);
2169 return;
2170 }
2171 fprintf(cc,"%s",str_tmp);
2172 strFree(str_tmp);
2173
2174 /* Header name of class */
2175 fprintf(cc,"class %s",cl->id.basic);
2176
2177 /* Header inheritance */
2178 str_tmp = GCFC_HeaderInher(cl);
2179 if (!str_tmp) {
2180 FreeClass(cl);
2181 CurrentClassAldor = NULL((void*)0);
2182 CurrentClassCpp = NULL((void*)0);
2183 return;
2184 }
2185 fprintf(cc,"%s",str_tmp);
2186 strFree(str_tmp);
2187
2188 /* Header standard */
2189 fprintf(cc," {\n");
2190 fprintf(cc,"public:\n");
2191 fprintf(cc,"\tvirtual ~%s() {}\n",cl->id.basic);
2192
2193 /* ---- METHODS */
2194
2195 /* no method ? */
2196 if (!cl->methods) {
2197 fprintf(cc,"};\n");
2198 CurrentClassAldor = NULL((void*)0);
2199 CurrentClassCpp = NULL((void*)0);
2200 FreeClass(cl);
2201 return;
2202 }
2203
2204 /* output methods */
2205 cl->methCounter = 0;
2206 meths = tfThdExports(cl->methods) ? tfThdExports(cl->methods):tfParents(cl->methods)((cl->methods)->parents);
2207 for (; meths; meths = meths->rest) {
2208 meth = meths->first;
2209
2210 str_tmp = GCFC_Methods(cl,meth);
2211 if (!str_tmp) continue;
2212 fprintf(cc,"%s",str_tmp);
2213 strFree(str_tmp);
2214
2215 cl->methCounter++;
2216 }
2217
2218 /* the end */
2219 fprintf(cc,"};\n");
2220 CurrentClassAldor = NULL((void*)0);
2221 CurrentClassCpp = NULL((void*)0);
2222 FreeClass(cl);
2223}
2224
2225/* ---------- END CLASS ---------- */
2226
2227/* ---------- EXPORT / IMPORT ---------- */
2228
2229void GenExportClass(AbSyn ab, int isTmpl, FILE *as, FILE *cc) {
2230
2231 Class *cl;
2232 SymeList l;
2233 Syme item;
2234 String toOutputAS, toOutputCC;
2235
2236 cl = BuildClass(ab,isTmpl);
19
Calling 'BuildClass'
55
Returning from 'BuildClass'
2237 if (!cl
55.1
'cl' is non-null
) return;
56
Taking false branch
2238
2239 /* tfTag(cl->methods) => TF_Third */
2240 /* two cases: cl->methods->parents or cl->methods->thdExports */
2241
2242 if (!(cl->methods)) l = NULL((void*)0);
57
Assuming field 'methods' is null
58
Taking true branch
2243 else l = tfThdExports(cl->methods) ? tfThdExports(cl->methods):tfParents(cl->methods)((cl->methods)->parents);
2244
2245 for (; l; l = l->rest) {
59
Loop condition is false. Execution continues on line 2270
2246
2247 item = l->first;
2248 if (strEqual(symString(symeId(item))((((item)->id))->str),"%%")) continue;
2249
2250 /* --- ALDOR Export --- */
2251 toOutputAS = GenAldorFnSig(symeType(item),symString(symeId(item))((((item)->id))->str),
2252 cl,1,BL_ExportedtheTRUE,!BL_UsePercenttheTRUE,BL_UseTmplParmstheTRUE);
2253
2254 /* --- C++ extern --- */
2255 if (toOutputAS)
2256 toOutputCC = GenCppFnSig(symeType(item),symString(symeId(item))((((item)->id))->str),cl,1,BL_ExportedtheTRUE);
2257 else
2258 toOutputCC = 0;
2259
2260 if (toOutputAS && toOutputCC) {
2261 fprintf(as,"%s",toOutputAS);
2262 fprintf(cc,"%s",toOutputCC);
2263 strFree(toOutputAS);
2264 strFree(toOutputCC);
2265 cl->methCounter++;
2266 }
2267 }
2268
2269 /* "givetype" function for the class */
2270 GenGiveTypeForExport(cl,as,cc);
60
Calling 'GenGiveTypeForExport'
2271
2272 /* Memory stuff */
2273 FreeClass(cl);
2274}
2275
2276
2277void GenExportFunction(AbSyn ab, FILE *as, FILE *cc) {
2278 String toOutputAS, toOutputCC;
2279 TForm tf;
2280 String name;
2281
2282 /* --- Init --- */
2283 tf = abTUnique(abDefineLhs(ab))((((ab)->abDefine.lhs))->abHdr.type.unique);
2284 name = abIdStr(abDefineLhs(abDeclareId(ab)))((((((ab)->abDeclare.id))->abDefine.lhs))->abId.sym->
str)
;
2285
2286 /* --- ALDOR Export --- */
2287 toOutputAS = GenAldorFnSig(tf,name,NULL((void*)0),1,BL_ExportedtheTRUE,!BL_UsePercenttheTRUE,BL_UseTmplParmstheTRUE);
2288
2289 /* --- C++ extern --- */
2290 toOutputCC = GenCppFnSig(tf,name,NULL((void*)0),1,BL_ExportedtheTRUE);
2291
2292 if (toOutputAS && toOutputCC) {
2293 fprintf(as,"%s",toOutputAS);
2294 fprintf(cc,"%s",toOutputCC);
2295 strFree(toOutputAS);
2296 strFree(toOutputCC);
2297 globalFuncCounter++;
2298 } else {
2299 if (toOutputAS) strFree(toOutputAS);
2300 if (toOutputCC) strFree(toOutputCC);
2301 }
2302}
2303
2304/* ---------- END EXPORT / IMPORT ---------- */
2305
2306/* ---------- METHODS ---------- */
2307
2308String GenCppBodyForMethods(TForm tf, String name, Class *cl) {
2309 int isStatic;
2310 int returnIsUsrDef; /* if the return type is a user defined type then we need a 'new' */
2311 int returnIsFnPtr;
2312 AbSyn ab;
2313 String result,str_tmp;
2314
2315 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
2316
2317 result = InitStr()strAlloc(500);
2318
2319 /* Static or not ? */
2320 if (!cl) isStatic = theTRUE;
2321 else isStatic = StaticOrNot(tfMapArg(tf)tfFollowArg(tf, 0),cl);
2322
2323 /* body */
2324 ab = tfGetExpr(tfMapRet(tf))((tfFollowArg(tf, 1))->__absyn);
2325 returnIsUsrDef = AbSynIsUserDef(ab);
2326 returnIsFnPtr = tfIsFuncPtr(tfMapRet(tf)tfFollowArg(tf, 1));
2327 result = STRCAT(result," { ");
2328
2329 /* -- if multiple return, declare appropriate variables */
2330 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
2331 str_tmp = GenCppMultiRetLocalDecl(tf,BL_WithTypetheTRUE);
2332 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2333 result = STRCAT(result,"\n");
2334 result = STRCAT(result,str_tmp);
2335 result = STRCAT(result,"\n");
2336 }
2337
2338 /* -- call the stub */
2339 if (!AbSynIsVoid(ab) && !tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) result = STRCAT(result,"return ");
2340
2341 if (returnIsUsrDef) {
2342 str_tmp = AbSynToCpp(ab);
2343 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2344 result = STRCAT(result,"new "); result = STRCAT(result,str_tmp); result = STRCAT(result,"(");
2345 strFree(str_tmp);
2346 }
2347 else if (returnIsFnPtr) {
2348 str_tmp = outputCppFnPtrParms(tfMapRet(tf)tfFollowArg(tf, 1),cl,theTRUE,theFALSE,!BL_UsePercenttheTRUE,!BL_ExporttheTRUE, NULL((void*)0));
2349 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2350 result = STRCAT(result,"(");
2351 result = STRCAT(result,str_tmp);
2352 result = STRCAT(result,")");
2353 strFree(str_tmp);
2354 }
2355
2356 str_tmp = createFnIdExternC(name,cl);
2357 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2358 result = STRCAT(result,str_tmp);
2359 strFree(str_tmp);
2360
2361 if (!cl)
2362 str_tmp = GenCppParams_Global_Body(tf,name);
2363 else
2364 str_tmp = GenCppParams_Body(tf,name,cl,isStatic);
2365 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2366 result = STRCAT(result,str_tmp);
2367 strFree(str_tmp);
2368
2369 if (returnIsUsrDef) result = STRCAT(result,")");
2370
2371 result = STRCAT(result,"; ");
2372
2373 /* -- Multiple return: assign real variables */
2374 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
2375 str_tmp = GenCppMultiRetAssign(tf);
2376 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2377 result = STRCAT(result,str_tmp);
2378 }
2379
2380 result = sprintTab(result,1);
2381 result = STRCAT(result,"}\n");
2382 str_tmp = strCopy(result);
2383 strFree(result);
2384 return str_tmp;
2385}
2386
2387String GenCppBodyStaticPercentForMethods(Syme meth, Class *cl, int posPercent, int export) {
2388 int returnIsUsrDef; /* if the return type is a user defined type then we need a 'new' */
2389 AbSyn ab;
2390 String result,str_tmp;
2391 TForm tf = symeType(meth);
2392 String name = symString(symeId(meth))((((meth)->id))->str);
2393
2394 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
2395
2396 result = InitStr()strAlloc(500);
2397
2398 /* body */
2399 ab = tfGetExpr(tfMapRet(tf))((tfFollowArg(tf, 1))->__absyn);
2400 returnIsUsrDef = AbSynIsUserDef(ab);
2401 result = STRCAT(result," { ");
2402
2403 /* -- if multiple return, declare appropriate variables */
2404 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
2405 str_tmp = GenCppMultiRetLocalDecl(tf,BL_WithTypetheTRUE);
2406 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2407 result = STRCAT(result,"\n");
2408 result = STRCAT(result,str_tmp);
2409 result = STRCAT(result,"\n");
2410 }
2411
2412 /* -- call the stub */
2413 if (!AbSynIsVoid(ab) && !tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) result = STRCAT(result,"return ");
2414
2415 if (export && returnIsUsrDef) {
2416 str_tmp = AbSynToCpp(ab);
2417 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2418 result = STRCAT(result,"new "); result = STRCAT(result,str_tmp); result = STRCAT(result,"(");
2419 strFree(str_tmp);
2420 }
2421
2422 /* -- object */
2423 if (export) {
2424 str_tmp = createFnIdExternC(name,cl);
2425 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2426 result = STRCAT(result,str_tmp);
2427 strFree(str_tmp);
2428 } else {
2429 String str_tmp2 = createFnIdForCPP(name,cl);
2430 str_tmp = itoa_(posPercent-1);
2431 result = STRCAT(result,"parm");
2432 result = STRCAT(result,str_tmp);
2433 result = STRCAT(result,"->");
2434 result = STRCAT(result,str_tmp2);
2435 strFree(str_tmp2);
2436 strFree(str_tmp);
2437 }
2438
2439 if (export)
2440 str_tmp = GenCppParamsBody_VirtualForStatic(tf,cl,posPercent);
2441 else
2442 str_tmp = GenCppParamsStaticPercent(tf,cl,!BL_WithTypetheTRUE,BL_WithNametheTRUE,posPercent,export);
2443 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2444 result = STRCAT(result,str_tmp);
2445 strFree(str_tmp);
2446
2447 if (export && returnIsUsrDef) result = STRCAT(result,")");
2448
2449 result = STRCAT(result,"; ");
2450
2451 /* -- Assign real variables */
2452 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
2453 str_tmp = GenCppMultiRetAssign(tf);
2454 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2455 result = STRCAT(result,str_tmp);
2456 }
2457
2458 result = sprintTab(result,1);
2459 result = STRCAT(result,"}\n");
2460 str_tmp = strCopy(result);
2461 strFree(result);
2462 return str_tmp;
2463}
2464
2465String GenTwisterFunction(Class *cl, Syme meth, int posPercent) {
2466 String result, str_tmp;
2467 TForm tmp;
2468
2469 result = InitStr()strAlloc(500);
2470
2471 /* generation of the extra "twister" function */
2472 result = STRCAT(result,"protected:\n\tvirtual ");
2473
2474 /* Return type */
2475 tmp = tfMapRet(symeType(meth))tfFollowArg(symeType(meth), 1);
2476 if (tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple)) result = STRCAT(result,"void ");
2477 else {
2478 str_tmp = AbSynToCpp(tfGetExpr(tmp)((tmp)->__absyn));
2479 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2480 result = STRCAT(result,str_tmp);
2481 result = STRCAT(result," ");
2482 if (AbSynIsUserDef(tfGetExpr(tmp)((tmp)->__absyn)))
2483 result = STRCAT(result," *");
2484 strFree(str_tmp);
2485 }
2486
2487 /* Function name */
2488 str_tmp = createFnIdForCPP(symString(symeId(meth))((((meth)->id))->str),cl);
2489 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2490 result = STRCAT(result," "); result = STRCAT(result,str_tmp);
2491 strFree(str_tmp);
2492
2493 /* Parameters */
2494 str_tmp = GenCppParamsStaticPercent(symeType(meth),cl,BL_WithTypetheTRUE,BL_WithNametheTRUE,posPercent,!BL_ExportedtheTRUE);
2495 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2496 result = STRCAT(result,str_tmp);
2497 strFree(str_tmp);
2498
2499 /* Body */
2500 str_tmp = GenCppBodyStaticPercentForMethods(meth,cl,posPercent,BL_ExportedtheTRUE);
2501 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2502 result = STRCAT(result,str_tmp);
2503 strFree(str_tmp);
2504
2505 /* the end */
2506 str_tmp = strCopy(result);
2507 strFree(result);
2508 return str_tmp;
2509}
2510
2511
2512void GenMethodsForClass(Class *cl, FILE *cc) {
2513 String str_tmp;
2514 SymeList meths;
2515 Syme meth;
2516 TForm tmp;
2517 String result, typeToAddToName = NULL((void*)0);
2518 int isStatic, posPercent;
2519 int flagIsFnPtr = theFALSE;
2520
2521 if (!cl->methods) return;
2522
2523 result = InitStr()strAlloc(500);
2524
2525 cl->methCounter = 0;
2526 meths = tfThdExports(cl->methods) ? tfThdExports(cl->methods):tfParents(cl->methods)((cl->methods)->parents);
2527 for (; meths; meths = meths->rest) {
2528 meth = meths->first;
2529
2530 if (strEqual(symString(symeId(meth))((((meth)->id))->str),"%%")) { *result = '\0'; continue; }
2531 if (HasDependentTypes(symeType(meth))) { *result = '\0'; continue; }
2532 if (ToSkip(symeType(meth))) { *result = '\0'; continue; }
2533 if (!tfIsMap(symeType(meth))(((symeType(meth))->tag) == TF_Map)) { *result = '\0'; continue; }
2534
2535 /* Static or not ? */
2536 isStatic = StaticOrNot(tfMapArg(symeType(meth))tfFollowArg(symeType(meth), 0),cl);
2537 posPercent = PercentsInParms(tfMapArg(symeType(meth))tfFollowArg(symeType(meth), 0),cl);
2538
2539 /* Static or virtual */
2540 result = STRCAT(result, isStatic ? "\tstatic " : "\tvirtual ");
2541
2542 /* Return type */
2543 tmp = tfMapRet(symeType(meth))tfFollowArg(symeType(meth), 1);
2544 flagIsFnPtr = theFALSE;
2545 if (tfIsExit(tmp)(((tmp)->tag) == TF_Exit)) { *result = '\0'; continue; }
2546 else if (tfIsGenerator(tmp)(((tmp)->tag) == TF_Generator)) { *result = '\0'; continue; }
2547 else if (tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple)) {
2548 result = STRCAT(result,"void ");
2549 if (discriminationReturnType) {
2550 typeToAddToName = InitStr()strAlloc(500);
2551 typeToAddToName = STRCAT(typeToAddToName,"void");
2552 }
2553 }
2554 else {
2555 if (tfIsFuncPtr(tmp)) {
2556 flagIsFnPtr = theTRUE;
2557 str_tmp = GenCppFunc_RetFnPtr(tmp);
2558 if (!str_tmp) { *result = '\0'; continue; }
2559 result = STRCAT(result,str_tmp);
2560 } else {
2561 str_tmp = AbSynToCpp(tfGetExpr(tmp)((tmp)->__absyn));
2562 if (!str_tmp) { *result = '\0'; continue; }
2563 if (discriminationReturnType) {
2564 typeToAddToName = InitStr()strAlloc(500);
2565 typeToAddToName = STRCAT(typeToAddToName,str_tmp);
2566 }
2567 result = STRCAT(result,str_tmp);
2568 result = STRCAT(result," ");
2569 if (AbSynIsUserDef(tfGetExpr(tmp)((tmp)->__absyn))) {
2570 result = STRCAT(result,"*");
2571 if (discriminationReturnType) typeToAddToName = STRCAT(typeToAddToName,"*");
2572 }
2573 strFree(str_tmp);
2574 }
2575 }
2576
2577 /* Function name */
2578 str_tmp = createFnIdForCPP(symString(symeId(meth))((((meth)->id))->str),cl);
2579 if (!str_tmp) { *result = '\0'; continue; }
2580 result = STRCAT(result," "); result = STRCAT(result,str_tmp);
2581 strFree(str_tmp);
2582
2583 if (discriminationReturnType) {
2584 String ToAdd = transOperatorLike(typeToAddToName);
2585 result = STRCAT(result,"_");
2586 result = STRCAT(result,ToAdd);
2587 strFree(typeToAddToName);
2588 strFree(ToAdd);
2589 }
2590
2591 /* Parameters */
2592 str_tmp = GenCppParams(symeType(meth),cl,BL_WithTypetheTRUE,BL_WithNametheTRUE,isStatic,BL_AbstracttheTRUE,!BL_ExporttheTRUE);
2593 if (!str_tmp) { *result = '\0'; continue; }
2594 result = STRCAT(result,str_tmp);
2595 strFree(str_tmp);
2596
2597 /* Parameters of the return type if the return type is a function pointer */
2598 if (flagIsFnPtr) {
2599 str_tmp = GenCppFunc_ParamsRetFnPtr(tmp,NULL((void*)0),BL_IsStatictheTRUE,!BL_AbstracttheTRUE,!BL_ExporttheTRUE);
2600 result = STRCAT(result,str_tmp);
2601 strFree(str_tmp);
2602 }
2603
2604 /* Body */
2605 if (!isStatic || !posPercent) {
2606 str_tmp = GenCppBodyForMethods(symeType(meth),symString(symeId(meth))((((meth)->id))->str),cl);
2607 if (!str_tmp) { *result = '\0'; continue; }
2608 result = STRCAT(result,str_tmp);
2609 strFree(str_tmp);
2610 } else {
2611 /* body for static function with a % at position posPercent */
2612 str_tmp = GenCppBodyStaticPercentForMethods(meth,cl,posPercent,!BL_ExportedtheTRUE);
2613 if (!str_tmp) { *result = '\0'; continue; }
2614 result = STRCAT(result,str_tmp);
2615 result = STRCAT(result,"\n");
2616 strFree(str_tmp);
2617
2618 /* twister function */
2619 str_tmp = GenTwisterFunction(cl,meth,posPercent);
2620 if (!str_tmp) { *result = '\0'; continue; }
2621 result = STRCAT(result,str_tmp);
2622 strFree(str_tmp);
2623 result = STRCAT(result,"\npublic:\n");
2624 }
2625
2626 fprintf(cc,"%s",result);
2627 *result = '\0';
2628 cl->methCounter++;
2629 }
2630 strFree(result);
2631}
2632
2633/* ---------- END METHODS ---------- */
2634
2635/* ---------- MULTIPLE RETURN ---------- */
2636
2637String GenCppMultiRetLocalDecl(TForm tf, int withType) {
2638 int i;
2639 AbSyn tmp;
2640 String str_tmp,str_tmp2;
2641 String result;
2642 int cnt = 0;
2643
2644 if (!tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) return NULL((void*)0);
2645
2646 result = InitStr()strAlloc(500);
2647
2648 tf = tfMapRet(tf)tfFollowArg(tf, 1);
2649
2650 for (i=0; i < tfMultiArgc(tf); i++) {
2651
2652 tmp = tfGetExpr(tfMultiArgN(tf,i))((tfFollowArg(tf, i))->__absyn);
2653
2654 switch(abTag(tmp)((tmp)->abHdr.tag)) {
2655 case AB_Declare:
2656 if (!abHasTag(abDeclareType(tmp),AB_Id)((((tmp)->abDeclare.type))->abHdr.tag == (AB_Id))) { strFree(result); return NULL((void*)0); }
2657 str_tmp = RealTypeString(abDeclareType(tmp)((tmp)->abDeclare.type),!BL_ExporttheTRUE);
2658 if (!strEqual(str_tmp,"void *")) str_tmp[strlen(str_tmp) - 1] = '\0';
2659 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2660 str_tmp2 = itoa_(cnt);
2661 if (!withType) {
2662 result = STRCAT(result,"&local");
2663 result = STRCAT(result,str_tmp2);
2664 } else {
2665 result = STRCAT(result,str_tmp);
2666 result = STRCAT(result," local");
2667 result = STRCAT(result,str_tmp2);
2668 }
2669 strFree(str_tmp2);
2670 cnt++;
2671 strFree(str_tmp);
2672 break;
2673 case AB_Id:
2674 str_tmp = RealTypeString(tmp,!BL_ExporttheTRUE);
2675 if (!strEqual(str_tmp,"void *")) str_tmp[strlen(str_tmp) - 1] = '\0';
2676 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2677 str_tmp2 = itoa_(cnt);
2678 if (!withType) {
2679 result = STRCAT(result,"&local");
2680 result = STRCAT(result,str_tmp2);
2681 } else {
2682 result = STRCAT(result,str_tmp);
2683 result = STRCAT(result," local");
2684 result = STRCAT(result,str_tmp2);
2685 }
2686 strFree(str_tmp2);
2687 cnt++;
2688 strFree(str_tmp);
2689 break;
2690 case AB_Apply:
2691 str_tmp2 = itoa_(cnt);
2692 if (!withType) {
2693 result = STRCAT(result,"&local");
2694 result = STRCAT(result,str_tmp2);
2695 } else {
2696 result = STRCAT(result,"void *local");
2697 result = STRCAT(result,str_tmp2);
2698 }
2699 strFree(str_tmp2);
2700 cnt++;
2701 break;
2702 default:
2703 fprintf(stderrstderr,"GenCppMultiRetLocalDecl - Wrong tag - %d\n",abTag(tmp)((tmp)->abHdr.tag));
2704 strFree(result); return NULL((void*)0);
2705 break;
2706 }
2707 if (!withType && (i < tfMultiArgc(tf) - 1)) result = STRCAT(result,",");
2708 else if (withType) result = STRCAT(result,";");
2709 }
2710
2711 str_tmp = strCopy(result);
2712 strFree(result);
2713 return str_tmp;
2714}
2715
2716String GenCppMultiRetAssign(TForm tf) {
2717 int i, isUsrDef;
2718 AbSyn tmp;
2719 String str_tmp,str_tmp2,str_tmp3;
2720 String result;
2721 int cnt = 0;
2722
2723
2724 if (!tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) return NULL((void*)0);
2725
2726 result = InitStr()strAlloc(500);
2727
2728 result = STRCAT(result,"\n");
2729
2730 cnt = tfMapArgc(tf) - 1; /* we give numbers to the params by beginning with 0 */
2731
2732 tf = tfMapRet(tf)tfFollowArg(tf, 1);
2733
2734 for (i=0; i < tfMultiArgc(tf); i++,cnt++) {
2735
2736 tmp = tfGetExpr(tfMultiArgN(tf,i))((tfFollowArg(tf, i))->__absyn);
2737 str_tmp3 = itoa_(i);
2738 switch(abTag(tmp)((tmp)->abHdr.tag)) {
2739 case AB_Declare:
2740 if (!abHasTag(abDeclareType(tmp),AB_Id)((((tmp)->abDeclare.type))->abHdr.tag == (AB_Id))) { strFree(result); return NULL((void*)0); }
2741 isUsrDef = AbSynIsUserDef(abDeclareType(tmp)((tmp)->abDeclare.type));
2742 str_tmp2 = itoa_(cnt);
2743 if (!isUsrDef) {
2744 result = STRCAT(result,"*parm");
2745 result = STRCAT(result,str_tmp2);
2746 result = STRCAT(result," = local");
2747 result = STRCAT(result,str_tmp3);
2748 result = STRCAT(result,"; ");
2749 } else {
2750 str_tmp = AbSynToCpp(abDeclareType(tmp)((tmp)->abDeclare.type));
2751 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2752 result = STRCAT(result,"*parm");
2753 result = STRCAT(result,str_tmp2);
2754 result = STRCAT(result," = new ");
2755 result = STRCAT(result,str_tmp);
2756 result = STRCAT(result,"(local");
2757 result = STRCAT(result,str_tmp3);
2758 result = STRCAT(result,"); ");
2759 strFree(str_tmp);
2760 }
2761 strFree(str_tmp2);
2762 strFree(str_tmp3);
2763 break;
2764 case AB_Id:
2765 isUsrDef = AbSynIsUserDef(tmp);
2766 str_tmp2 = itoa_(cnt);
2767 if (!isUsrDef) {
2768 result = STRCAT(result,"*parm");
2769 result = STRCAT(result,str_tmp2);
2770 result = STRCAT(result," = local");
2771 result = STRCAT(result,str_tmp3);
2772 result = STRCAT(result,"; ");
2773 } else {
2774 str_tmp = AbSynToCpp(tmp);
2775 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2776 result = STRCAT(result,"*parm");
2777 result = STRCAT(result,str_tmp2);
2778 result = STRCAT(result," = new ");
2779 result = STRCAT(result,str_tmp);
2780 result = STRCAT(result,"(local");
2781 result = STRCAT(result,str_tmp3);
2782 result = STRCAT(result,"); ");
2783 strFree(str_tmp);
2784 }
2785 strFree(str_tmp2);
2786 strFree(str_tmp3);
2787 break;
2788 case AB_Apply:
2789 fprintf(stderrstderr,"Function pointers in a multiple return value are not handled ...\n");
2790 strFree(result); return NULL((void*)0);
2791 break;
2792 default:
2793 fprintf(stderrstderr,"GenCppMultiRetAssign - Wrong tag - %d\n",abTag(tmp)((tmp)->abHdr.tag));
2794 strFree(result); return NULL((void*)0);
2795 break;
2796 }
2797 }
2798
2799 str_tmp = strCopy(result);
2800 strFree(result);
2801 return str_tmp;
2802}
2803
2804
2805String GenCppMultiRet(TForm tf, int withType, int withName, int cnt, int export) {
2806 int i;
2807 AbSyn tmp;
2808 String str_tmp,str_tmp2,str_tmp3;
2809 String result;
2810
2811 result = InitStr()strAlloc(500);
2812
2813 tf = tfMapRet(tf)tfFollowArg(tf, 1);
2814
2815 for (i=0; i < tfMultiArgc(tf); i++) {
2816
2817 tmp = tfGetExpr(tfMultiArgN(tf,i))((tfFollowArg(tf, i))->__absyn);
2818 str_tmp2 = itoa_(cnt);
2819 str_tmp3 = itoa_(i);
2820 switch(abTag(tmp)((tmp)->abHdr.tag)) {
2821 case AB_Declare:
2822 if (!abHasTag(abDeclareType(tmp),AB_Id)((((tmp)->abDeclare.type))->abHdr.tag == (AB_Id))) { strFree(result); return NULL((void*)0); }
2823 str_tmp = RealTypeString(abDeclareType(tmp)((tmp)->abDeclare.type),export);
2824 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2825
2826 if (withName && withType) {
2827 result = STRCAT(result,str_tmp);
2828 result = STRCAT(result," parm");
2829 result = STRCAT(result,str_tmp2);
2830 strFree(str_tmp2);
2831 cnt++;
2832 } else if (withName) {
2833 result = STRCAT(result,"parm");
2834 result = STRCAT(result,str_tmp2);
2835 strFree(str_tmp2);
2836 cnt++;
2837 } else if (withType)
2838 result = STRCAT(result,str_tmp);
2839 strFree(str_tmp);
2840 break;
2841 case AB_Id:
2842 str_tmp = RealTypeString(tmp,export);
2843 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2844
2845 if (withName && withType) {
2846 result = STRCAT(result,str_tmp);
2847 result = STRCAT(result," parm");
2848 result = STRCAT(result,str_tmp2);
2849 strFree(str_tmp2);
2850 cnt++;
2851 } else if (withName) {
2852 result = STRCAT(result,"parm");
2853 result = STRCAT(result,str_tmp2);
2854 strFree(str_tmp2);
2855 cnt++;
2856 } else if (withType)
2857 result = STRCAT(result,str_tmp);
2858 strFree(str_tmp);
2859 break;
2860 case AB_Apply:
2861
2862 if (withName && withType) {
2863 result = STRCAT(result,"void *parm");
2864 result = STRCAT(result,str_tmp2);
2865 strFree(str_tmp2);
2866 cnt++;
2867 } else if (withName) {
2868 result = STRCAT(result,"parm");
2869 result = STRCAT(result,str_tmp2);
2870 strFree(str_tmp2);
2871 cnt++;
2872 } else if (withType)
2873 result = STRCAT(result,"void *");
2874 break;
2875 default:
2876 fprintf(stderrstderr,"GenCppMultiRet - Wrong tag - %d\n",abTag(tmp)((tmp)->abHdr.tag));
2877 strFree(result); return NULL((void*)0);
2878 break;
2879 }
2880 if (i < (tfMultiArgc(tf) - 1)) result = STRCAT(result,",");
2881 }
2882 str_tmp = strCopy(result);
2883 strFree(result);
2884 return str_tmp;
2885}
2886
2887/* ---------- END MULTIPLE RETURN ---------- */
2888
2889/* ---------- PARAMS HANDLING ---------- */
2890
2891/* -- Common Code for Aldor -- */
2892
2893String outputAldorTmplParms(TForm tf, int usePercent) {
2894 String result, str_tmp;
2895
2896 /* check */
2897 if (!tfIsDeclare(tf)(((tf)->tag) == TF_Declare)) return NULL((void*)0);
2898
2899 /* parameter */
2900 result = InitStr()strAlloc(500);
2901 result = STRCAT(result,symString(tfDeclareId(tf))((tfDeclareId(tf))->str));
2902 result = STRCAT(result,": ");
2903 str_tmp = TFormToAldor(tfDeclareType(tf)tfFollowArg(tf, 0),usePercent);
2904 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2905 result = STRCAT(result,str_tmp);
2906
2907 str_tmp = strCopy(result);
2908 strFree(result);
2909 return str_tmp;
2910}
2911
2912String outputAldorRegParms(TForm tf, int withType, int withName, int usePercent, String cnt, String result) {
2913 /* return: 0 - no problem / 1 - error */
2914 String str_tmp;
2915
2916 /* Type -> String */
2917 if (tfIsGeneral(tf)(((tf)->tag) == TF_General))
2918 str_tmp = TFormToAldor(tf,usePercent);
2919 else if (tfIsDeclare(tf)(((tf)->tag) == TF_Declare))
2920 str_tmp = TFormToAldor(tfDeclareType(tf)tfFollowArg(tf, 0),usePercent);
2921 else {
2922 strFree(result);
2923 return NULL((void*)0);
2924 }
2925
2926 /* output */
2927 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2928
2929 if (withName && withType) {
2930 result = STRCAT(result,"parm");
2931 result = STRCAT(result,cnt);
2932 result = STRCAT(result,": ");
2933 result = STRCAT(result,str_tmp);
2934 }
2935 else if (withName) {
2936 result = STRCAT(result,"parm");
2937 result = STRCAT(result,cnt);
2938 }
2939 else if (withType)
2940 result = STRCAT(result,str_tmp);
2941
2942 strFree(str_tmp);
2943 return result;
2944}
2945
2946/* -- End Common Code for Aldor -- */
2947
2948/* -- Aldor Params -- */
2949
2950String GenAldorParams(TForm tf, Class *cl, int withType, int withName, int inBody, int usePercent, int useTmplParms) {
2951 String str_tmp;
2952 String result,str_tmp2;
2953 int cnt;
2954 int paramNb;
2955 TForm tmp = NULL((void*)0);
2956 TForm tmp2 = NULL((void*)0);
2957 int i;
2958
2959 result = InitStr()strAlloc(500);
2960
2961 result = STRCAT(result,"(");
2962
2963 /* Template params */
2964 if (cl && useTmplParms) {
2965 tmp = cl->params;
2966 if (tmp && !inBody) {
2967 int i;
2968 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
2969 if (paramNb == 1) { /* TF_Declare */
2970 str_tmp = outputAldorTmplParms(tmp, usePercent);
2971 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2972 result = STRCAT(result, str_tmp);
2973 strFree(str_tmp);
2974 }
2975 else /* TF_Multiple */
2976 for (i=0;i<paramNb;i++) {
2977 tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
2978 str_tmp = outputAldorTmplParms(tmp2, usePercent);
2979 if (!str_tmp) { strFree(result); return NULL((void*)0); }
2980 result = STRCAT(result, str_tmp);
2981 strFree(str_tmp);
2982 if (i < paramNb-1) result = STRCAT(result,",");
2983 }
2984 }
2985 }
2986
2987 /* Regular params */
2988 tf = tfMapArg(tf)tfFollowArg(tf, 0);
2989
2990 paramNb = tfIsMulti(tf)(((tf)->tag) == TF_Multiple) ? tfMultiArgc(tf) : 1;
2991 if (paramNb && useTmplParms && cl && tmp && !inBody) result = STRCAT(result,",");
2992 if (paramNb == 1) { /* TF_Declare ou TF_General */
2993 result = outputAldorRegParms(tf,withType,withName,usePercent,"0",result);
2994 if (!result) return NULL((void*)0);
2995 }
2996 else
2997 for (i=0,cnt = 0; i < paramNb; i++, cnt++) {
2998 tmp = tfMultiArgN(tf,i)tfFollowArg(tf, i);
2999 str_tmp2 = itoa_(cnt);
3000 result = outputAldorRegParms(tmp,withType,withName,usePercent,str_tmp2,result);
3001 strFree(str_tmp2);
3002 if (!result) return NULL((void*)0);
3003 if (i < paramNb-1) result = STRCAT(result,",");
3004 }
3005
3006 result = STRCAT(result,")");
3007 str_tmp = strCopy(result);
3008 strFree(result);
3009 return str_tmp;
3010}
3011
3012String GenAldorOneParam(TForm tf, int withType, int withName, int cnt, int usePercent) {
3013 String result = NULL((void*)0), str_tmp;
3014
3015 if (tfIsGeneral(tf)(((tf)->tag) == TF_General)) str_tmp = TFormToAldor(tf,usePercent);
3016 else if (tfIsDeclare(tf)(((tf)->tag) == TF_Declare)) str_tmp = TFormToAldor(tfDeclareType(tf)tfFollowArg(tf, 0),usePercent);
3017 else return NULL((void*)0);
3018
3019 if (!str_tmp) return NULL((void*)0);
3020
3021 if (withName && withType) result = strPrintf("parm%d: %s",cnt,str_tmp);
3022 else if (withName) result = strPrintf("parm%d",cnt);
3023 else if (withType) result = strCopy(str_tmp);
3024
3025 strFree(str_tmp);
3026
3027 return result;
3028}
3029
3030/* -- End Aldor Params -- */
3031
3032/* -- Common Code for C++ -- */
3033
3034String outputCppFnPtrParms(TForm tf, Class *cl, int withType, int withName, int usePercent, int export, String cnt) {
3035 String result, str_tmp;
3036
3037 result = InitStr()strAlloc(500);
3038
3039 if (withName && withType) {
3040 str_tmp = GenCppFunc_RetFnPtr(tf);
3041 result = STRCAT(result,str_tmp);
3042 result = STRCAT(result," parm");
3043 result = STRCAT(result,cnt);
3044 strFree(str_tmp);
3045 str_tmp = GenCppFunc_ParamsRetFnPtr(tf,cl,!usePercent,!BL_AbstracttheTRUE, export);
3046 result = STRCAT(result,str_tmp);
3047 strFree(str_tmp);
3048 }
3049 else if (withName){
3050 result = STRCAT(result,"parm");
3051 result = STRCAT(result,cnt);
3052 }
3053 else if (withType) {
3054 str_tmp = GenCppFunc_RetFnPtr(tf);
3055 result = STRCAT(result,str_tmp);
3056 strFree(str_tmp);
3057 str_tmp = GenCppFunc_ParamsRetFnPtr(tf,cl,!usePercent,!BL_AbstracttheTRUE, export);
3058 result = STRCAT(result,str_tmp);
3059 strFree(str_tmp);
3060 }
3061
3062 str_tmp = strCopy(result);
3063 strFree(result);
3064 return str_tmp;
3065}
3066
3067
3068String outputCppRegParms(TForm tf, Class *cl, int withType, int withName, int usePercent, int export, String cnt, String result) {
3069 /* return: 0 - no problem / 1 - error */
3070 String str_tmp, str_tmp2;
3071 int isUsrDef;
3072 int flagFnPtr = theFALSE;
3073
3074 if (tfIsGeneral(tf)(((tf)->tag) == TF_General)) {
3075 if (tfIsFuncPtr(tf)) {
3076 flagFnPtr = theTRUE;
3077 str_tmp2 = outputCppFnPtrParms(tf, cl, withType, withName, usePercent, export, cnt);
3078 }
3079 else
3080 str_tmp2 = AbSynToCpp(tfGetExpr(tf)((tf)->__absyn));
3081 isUsrDef = AbSynIsUserDef(tfGetExpr(tf)((tf)->__absyn));
3082 } else if (tfIsDeclare(tf)(((tf)->tag) == TF_Declare)) {
3083 if (tfIsFuncPtr(tfDeclareType(tf)tfFollowArg(tf, 0))) {
3084 flagFnPtr = theTRUE;
3085 str_tmp2 = outputCppFnPtrParms(tfDeclareType(tf)tfFollowArg(tf, 0), cl, withType, withName, usePercent, export, cnt);
3086 }
3087 else
3088 str_tmp2 = AbSynToCpp(tfGetExpr(tfDeclareType(tf))((tfFollowArg(tf, 0))->__absyn));
3089 isUsrDef = AbSynIsUserDef(tfGetExpr(tfDeclareType(tf))((tfFollowArg(tf, 0))->__absyn));
3090 } else {
3091 strFree(result);
3092 return NULL((void*)0);
3093 }
3094
3095 if (!str_tmp2) { strFree(result); return NULL((void*)0); }
3096
3097 if (flagFnPtr)
3098 str_tmp = strCopy(str_tmp2);
3099 else {
3100 if (!isUsrDef) str_tmp = strCopy(str_tmp2);
3101 else str_tmp = export ? strCopy("void *") : strPrintf("%s *",str_tmp2);
3102 }
3103
3104 strFree(str_tmp2);
3105
3106 /* output param */
3107 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3108
3109 if (flagFnPtr)
3110 result = STRCAT(result,str_tmp);
3111 else {
3112 if (withName && withType) {
3113 result = STRCAT(result,str_tmp);
3114 result = STRCAT(result," parm");
3115 result = STRCAT(result,cnt);
3116 }
3117 else if (withName){
3118 result = STRCAT(result,"parm");
3119 result = STRCAT(result,cnt);
3120 } else if (withType)
3121 result = STRCAT(result,str_tmp);
3122 }
3123
3124 strFree(str_tmp);
3125
3126 return result;
3127}
3128
3129/* -- End Common Code for C++ -- */
3130
3131/* -- C++ Params -- */
3132
3133String GenCppParams(TForm tf, Class *cl, int withType, int withName, int isStatic, int abstract, int export) {
3134
3135 String str_tmp, str_tmp2;
3136 String result;
3137 int cnt = 0;
3138 int paramNb,start;
3139 TForm tmp = NULL((void*)0), tmp2;
3140
3141 result = InitStr()strAlloc(500);
3142
3143 result = STRCAT(result,"(");
3144
3145 /* Template params */
3146 if (cl) {
3147 tmp = cl->params;
3148 if (tmp && export) {
3149 int i;
3150 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
3151 for (i=0;i<paramNb;i++) {
3152 result = STRCAT(result,"void *");
3153 if (i < paramNb-1) result = STRCAT(result,",");
3154 }
3155 }
3156 }
3157
3158 /* Regular params */
3159 tmp2 = tfMapArg(tf)tfFollowArg(tf, 0);
3160 paramNb = tfIsMulti(tmp2)(((tmp2)->tag) == TF_Multiple) ? tfMultiArgc(tmp2) : 1;
3161 start = 0;
3162
3163 /* First parameter is special */
3164 if (paramNb) {
3165 /* If the function is a method (i.e not static) then if we are in class the first parameter is not output */
3166 if (!export && !isStatic) start++;
3167
3168 /* If some parameters have been output before (for templates) then we need a comma */
3169 if (cl && tmp && export) result = STRCAT(result,",");
3170 }
3171
3172 if ((paramNb == 1) && (!start)) {
3173 result = outputCppRegParms(tmp2,cl,withType,withName,!BL_UsePercenttheTRUE, export, "0", result);
3174 if (!result) return NULL((void*)0);
3175 } else if (paramNb > 1) {
3176 for (cnt = 0; start < paramNb; start++,cnt++) {
3177 tmp = tfMultiArgN(tmp2,start)tfFollowArg(tmp2, start);
3178 if (tfIsExit(tmp)(((tmp)->tag) == TF_Exit)) { strFree(result); return NULL((void*)0); }
3179 else if (tfIsGenerator(tmp)(((tmp)->tag) == TF_Generator)) { strFree(result); return NULL((void*)0); }
3180 str_tmp2 = itoa_(cnt);
3181 result = outputCppRegParms(tmp,cl,withType,withName,!BL_UsePercenttheTRUE, export, str_tmp2, result);
3182 strFree(str_tmp2);
3183 if (!result) return NULL((void*)0);
3184 if (start < paramNb - 1) result = STRCAT(result,",");
3185 }
3186 }
3187
3188 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
3189 if (paramNb) result = STRCAT(result,",");
3190 str_tmp = GenCppMultiRet(tf,withType,withName,cnt,export);
3191 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3192 result = STRCAT(result,str_tmp);
3193 strFree(str_tmp);
3194 }
3195 result = STRCAT(result,")");
3196 str_tmp = strCopy(result);
3197 strFree(result);
3198 return str_tmp;
3199}
3200
3201String GenCppParamsBody_VirtualForStatic(TForm tf, Class *cl, int posPercent) {
3202
3203 String str_tmp;
3204 String result;
3205 int isUsrDef;
3206 int paramNb,start;
3207 TForm tmp = NULL((void*)0), tmp2;
3208
3209 result = InitStr()strAlloc(500);
3210
3211 result = STRCAT(result,"(");
3212
3213 /* Template params */
3214 if (cl->params) {
3215 int i;
3216 tmp = cl->params;
3217 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
3218 if (paramNb == 1) {
3219 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) {
3220 result = STRCAT(result,symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str));
3221 result = STRCAT(result,"::givetype()");
3222 } else { fprintf(stderrstderr,"Error in GenGivetype (tmpl params): %d\n",tfTag(tmp)((tmp)->tag)); }
3223 }
3224 else
3225 for (i=0;i<paramNb;i++) {
3226 TForm tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
3227 if (tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare)) {
3228 result = STRCAT(result,symString(tfDeclareId(tmp2))((tfDeclareId(tmp2))->str));
3229 result = STRCAT(result,"::givetype()");
3230 } else { fprintf(stderrstderr,"Error in GenGivetype (tmpl params): %d\n",tfTag(tmp)((tmp)->tag)); }
3231 if (i < paramNb-1) result = STRCAT(result,",");
3232 }
3233 }
3234
3235 /* Regular params */
3236 tmp = NULL((void*)0);
3237 tmp2 = tfMapArg(tf)tfFollowArg(tf, 0);
3238 paramNb = tfIsMulti(tmp2)(((tmp2)->tag) == TF_Multiple) ? tfMultiArgc(tmp2) : 1;
3239
3240 if (paramNb && (cl->params)) result = STRCAT(result,",");
3241
3242 /* paramNb > 1 because we call this function for the body of the extra protected virtual method
3243 created if we have a function with a % not in first position */
3244
3245
3246 for (start = 0; start < paramNb; start++) {
3247
3248 /* Is it the position of the first % parameter ? */
3249 if (start == posPercent - 1) {
3250 if (start < (paramNb-1)) result = STRCAT(result,"ptr,");
3251 else result = STRCAT(result,",ptr");
3252 continue;
3253 }
3254
3255 /* get the parameter */
3256 tmp = tfMultiArgN(tmp2,start)tfFollowArg(tmp2, start);
3257
3258 if (tfIsExit(tmp)(((tmp)->tag) == TF_Exit)) { strFree(result); return NULL((void*)0); }
3259 if (tfIsGenerator(tmp)(((tmp)->tag) == TF_Generator)) { strFree(result); return NULL((void*)0); }
3260
3261 isUsrDef = AbSynIsUserDef(tfGetExpr(tmp)((tmp)->__absyn));
3262
3263 /* output param */
3264 str_tmp = itoa_(start);
3265 if (isUsrDef) {
3266 result = STRCAT(result,"realObject(parm");
3267 result = STRCAT(result,str_tmp);
3268 result = STRCAT(result,")");
3269 } else {
3270 result = STRCAT(result,"parm");
3271 result = STRCAT(result,str_tmp);
3272 }
3273 strFree(str_tmp);
3274
3275 if (start < (paramNb-2)) result = STRCAT(result,",");
3276 else if ((start == (paramNb-2)) && (posPercent != paramNb)) result = STRCAT(result,",");
3277 }
3278
3279 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
3280 if (paramNb) result = STRCAT(result,",");
3281 str_tmp = GenCppMultiRet(tf,!BL_WithTypetheTRUE,BL_WithNametheTRUE,start,!BL_ExportedtheTRUE);
3282 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3283 result = STRCAT(result,str_tmp);
3284 strFree(str_tmp);
3285 }
3286 result = STRCAT(result,")");
3287 str_tmp = strCopy(result);
3288 strFree(result);
3289 return str_tmp;
3290}
3291
3292String GenCppParamsStaticPercent(TForm tf, Class *cl, int withType, int withName, int posPercent, int export) {
3293
3294 String str_tmp, str_tmp2;
3295 String result;
3296 int isUsrDef;
3297 int paramNb,start;
3298 TForm tmp = NULL((void*)0), tmp2;
3299
3300 result = InitStr()strAlloc(500);
3301
3302 result = STRCAT(result,"(");
3303
3304 /* Regular params */
3305 tmp2 = tfMapArg(tf)tfFollowArg(tf, 0);
3306 paramNb = tfIsMulti(tmp2)(((tmp2)->tag) == TF_Multiple) ? tfMultiArgc(tmp2) : 1;
3307 start = 0;
3308
3309 if (posPercent == 1) start++;
3310
3311 if ((paramNb == 1) && (!start)) {
3312 if (tfIsGeneral(tmp2)(((tmp2)->tag) == TF_General)) {
3313 str_tmp2 = AbSynToCpp(tfGetExpr(tmp2)((tmp2)->__absyn));
3314 isUsrDef = AbSynIsUserDef(tfGetExpr(tmp2)((tmp2)->__absyn));
3315 } else if (tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare)) {
3316 str_tmp2 = AbSynToCpp(tfGetExpr(tfDeclareType(tmp2))((tfFollowArg(tmp2, 0))->__absyn));
3317 isUsrDef = AbSynIsUserDef(tfGetExpr(tfDeclareType(tmp2))((tfFollowArg(tmp2, 0))->__absyn));
3318 } else {
3319 strFree(result);
3320 return NULL((void*)0);
3321 }
3322
3323 if (!str_tmp2) { strFree(result); return NULL((void*)0); }
3324
3325 str_tmp = (isUsrDef) ? strPrintf("%s *",str_tmp2) : strCopy(str_tmp2);
3326
3327 if (withName && withType) { result = STRCAT(result,str_tmp); result = STRCAT(result," parm0"); }
3328 else if (withName) { result = STRCAT(result,"parm0"); }
3329 else if (withType) { result = STRCAT(result,str_tmp); }
3330 strFree(str_tmp);
3331 strFree(str_tmp2);
3332 } else if (paramNb > 1) {
3333 for (; start < paramNb; start++) {
3334
3335 if (start == posPercent - 1) {
3336 if (export) {
3337 if (start < (paramNb-1)) result = STRCAT(result,"ptr,");
3338 else result = STRCAT(result,",ptr");
3339 }
3340 continue;
3341 }
3342
3343 tmp = tfMultiArgN(tmp2,start)tfFollowArg(tmp2, start);
3344
3345 if (tfIsExit(tmp)(((tmp)->tag) == TF_Exit)) { strFree(result); return NULL((void*)0); }
3346 if (tfIsGenerator(tmp)(((tmp)->tag) == TF_Generator)) { strFree(result); return NULL((void*)0); }
3347
3348 str_tmp2 = AbSynToCpp(tfGetExpr(tmp)((tmp)->__absyn));
3349
3350 if (!str_tmp2) { strFree(result); return NULL((void*)0); }
3351 isUsrDef = AbSynIsUserDef(tfGetExpr(tmp)((tmp)->__absyn));
3352
3353 /* init type name */
3354 str_tmp = isUsrDef ? strPrintf("%s *",str_tmp2) : strCopy(str_tmp2);
3355
3356 strFree(str_tmp2);
3357
3358 str_tmp2 = itoa_(start);
3359
3360 /* output param */
3361 if (withName && withType) {
3362 result = STRCAT(result,str_tmp);
3363 result = STRCAT(result," parm");
3364 result = STRCAT(result,str_tmp2);
3365 strFree(str_tmp2);
3366 }
3367 else if (withName){
3368 result = STRCAT(result,"parm");
3369 result = STRCAT(result,str_tmp2);
3370 strFree(str_tmp2);
3371 }
3372 else if (withType)
3373 result = STRCAT(result,str_tmp);
3374
3375 strFree(str_tmp);
3376
3377 if (start < (paramNb-2)) result = STRCAT(result,",");
3378 else if ((start == (paramNb-2)) && (posPercent != paramNb)) result = STRCAT(result,",");
3379 }
3380 }
3381
3382 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
3383 if (paramNb) result = STRCAT(result,",");
3384 str_tmp = GenCppMultiRet(tf,withType,withName,start,!BL_ExportedtheTRUE);
3385 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3386 result = STRCAT(result,str_tmp);
3387 strFree(str_tmp);
3388 }
3389 result = STRCAT(result,")");
3390 str_tmp = strCopy(result);
3391 strFree(result);
3392 return str_tmp;
3393}
3394
3395String GenCppParams_Body(TForm tf, String name, Class *cl, int isStatic) {
3396 TForm tmp;
3397 int cnt = 0;
3398 int start;
3399 int paramNb;
3400 String result, str_tmp;
3401
3402 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
3403
3404 result = InitStr()strAlloc(500);
3405
3406 result = STRCAT(result,"(");
3407
3408 /* Template params */
3409 if (cl->params) {
3410 int i;
3411 tmp = cl->params;
3412 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
3413 if (paramNb == 1) {
3414 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) {
3415 result = STRCAT(result,symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str));
3416 result = STRCAT(result,"::givetype()");
3417 } else { fprintf(stderrstderr,"Error in GenGivetype (tmpl params): %d\n",tfTag(tmp)((tmp)->tag)); }
3418 }
3419 else
3420 for (i=0;i<paramNb;i++) {
3421 TForm tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
3422 if (tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare)) {
3423 result = STRCAT(result,symString(tfDeclareId(tmp2))((tfDeclareId(tmp2))->str));
3424 result = STRCAT(result,"::givetype()");
3425 } else { fprintf(stderrstderr,"Error in GenGivetype (tmpl params): %d\n",tfTag(tmp)((tmp)->tag)); }
3426 if (i < paramNb-1) result = STRCAT(result,",");
3427 }
3428 }
3429
3430 /* First parameter is special */
3431 tmp = tfMapArg(tf)tfFollowArg(tf, 0);
3432 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
3433 start = 0;
3434 if (paramNb) {
3435 if (cl->params) result = STRCAT(result,",");
3436 if (!isStatic) {
3437 result = STRCAT(result,"ptr");
3438 start = 1;
3439 if (paramNb > 1) result = STRCAT(result,",");
3440 }
3441 }
3442
3443 if ((paramNb == 1) && (start == 0)) {
3444 AbSyn ab = tfGetExpr(tmp)((tmp)->__absyn);
3445 int usrdef;
3446
3447 /* user type or not ? if yes => get the real object */
3448 if ((usrdef=AbSynIsUserDef(ab))) {
3449 str_tmp = AbSynToCpp(ab);
3450 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3451 result = STRCAT(result,"realObject(");
3452 strFree(str_tmp);
3453 }
3454
3455 /* output param */
3456 str_tmp = itoa_(cnt);
3457 result = STRCAT(result,"parm");
3458 result = STRCAT(result,str_tmp);
3459 strFree(str_tmp);
3460 cnt++;
3461
3462 if (usrdef) result = STRCAT(result,")");
3463 }
3464 else if (paramNb > 1) {
3465 for (; start < paramNb; start++) {
3466 int usrdef;
3467 TForm tmp2 = tfMultiArgN(tmp,start)tfFollowArg(tmp, start);
3468 AbSyn ab = tfGetExpr(tmp2)((tmp2)->__absyn);
3469
3470 /* user type or not ? if yes => get the real object */
3471 if ((usrdef=AbSynIsUserDef(ab))) {
3472 str_tmp = AbSynToCpp(ab);
3473 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3474 result = STRCAT(result,"realObject(");
3475 strFree(str_tmp);
3476 }
3477
3478 /* output param */
3479 str_tmp = itoa_(cnt);
3480 result = STRCAT(result,"parm");
3481 result = STRCAT(result,str_tmp);
3482 strFree(str_tmp);
3483 cnt++;
3484
3485 if (usrdef) result = STRCAT(result,")");
3486
3487 if (start < paramNb-1) result = STRCAT(result,",");
3488 }
3489 }
3490
3491 /* Extra parameters if multiple return */
3492 if (tfIsMultiReturn(tfMapRet(tf))((((tfFollowArg(tf, 1))->tag) == TF_Multiple) && tfMultiArgc
(tfFollowArg(tf, 1)))
) {
3493 if (paramNb) result = STRCAT(result,",");
3494 str_tmp = GenCppMultiRetLocalDecl(tf,!BL_WithTypetheTRUE);
3495 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3496 result = STRCAT(result,str_tmp);
3497 strFree(str_tmp);
3498 }
3499
3500 result = STRCAT(result,")");
3501 str_tmp = strCopy(result);
3502 strFree(result);
3503 return str_tmp;
3504}
3505
3506String GenCppParams_Global_Body(TForm tf, String name) {
3507 int cnt = 0;
3508 String result, str_tmp;
3509
3510 if (!tfIsMap(tf)(((tf)->tag) == TF_Map)) return NULL((void*)0);
3511
3512 result = InitStr()strAlloc(500);
3513
3514 tf = tfMapArg(tf)tfFollowArg(tf, 0);
3515
3516 result = STRCAT(result,"(");
3517
3518 if (tfIsDeclare(tf)(((tf)->tag) == TF_Declare) || tfIsGeneral(tf)(((tf)->tag) == TF_General)) {
3519 int usrdef;
3520 AbSyn ab = tfGetExpr(tf)((tf)->__absyn);
3521
3522 /* user type or not ? if yes => get the real object */
3523 if ((usrdef=AbSynIsUserDef(ab))) result = STRCAT(result,"realObject(");
3524
3525 /* output param */
3526 str_tmp = itoa_(cnt);
3527 result = STRCAT(result,"parm");
3528 result = STRCAT(result,str_tmp);
3529 strFree(str_tmp);
3530 cnt++;
3531
3532 if (usrdef) result = STRCAT(result,")");
3533 }
3534 else if (!tfIsMulti(tf)(((tf)->tag) == TF_Multiple)) { strFree(result); return NULL((void*)0); }
3535 else if (tfMultiArgc(tf)) {
3536 int i;
3537 int paramNb = tfMultiArgc(tf);
3538
3539 for (i=0; i<paramNb; i++) {
3540 int usrdef;
3541 TForm tmp = tfMultiArgN(tf,i)tfFollowArg(tf, i);
3542 AbSyn ab = tfGetExpr(tmp)((tmp)->__absyn);
3543
3544 /* user type or not ? if yes => get the real object */
3545 if ((usrdef=AbSynIsUserDef(ab))) result = STRCAT(result,"realObject(");
3546
3547 /* output param */
3548 str_tmp = itoa_(cnt);
3549 result = STRCAT(result,"parm");
3550 result = STRCAT(result,str_tmp);
3551 cnt++;
3552
3553 if (usrdef) result = STRCAT(result,")");
3554
3555 if (i < paramNb - 1) result = STRCAT(result,",");
3556 }
3557 }
3558
3559 result = STRCAT(result,")");
3560 str_tmp = strCopy(result);
3561 strFree(result);
3562 return str_tmp;
3563}
3564/* -- End C++ Params -- */
3565
3566/* ---------- END PARAMS ---------- */
3567
3568/* ---------- TYPES ---------- */
3569
3570/* -- Basic -- */
3571
3572int IsBasicType(String s) {
3573 int i;
3574 for (i = 0; i < bAT_size; i++)
3575 if (strEqual(s,basicAldorTypes[i])) return theTRUE;
3576 return theFALSE;
3577}
3578
3579String MappingTypes(String s) {
3580 int i;
3581
3582 for (i = 0; i < bAT_size; i++)
3583 if (strEqual(s,basicAldorTypes[i])) return strCopy(basicCppTypes[i]);
3584 return NULL((void*)0);
3585}
3586
3587String MachineToCpp(AbSyn ab) {
3588 if (!abHasTag(ab,AB_Id)((ab)->abHdr.tag == (AB_Id))) return NULL((void*)0);
3589 return (strEqual(abIdStr(ab)((ab)->abId.sym->str),"XByte")) ? strPrintf("FiByte") : strPrintf("Fi%s",abIdStr(ab)((ab)->abId.sym->str));
3590}
3591
3592/* -- End Basic -- */
3593
3594/* -- AbSyn -- */
3595
3596/* Deals with items like A->B->C ... */
3597String FunctionPtrToAldor(AbSyn ab, int usePercent) {
3598 /* When the operator of an apply is "->", argc is 2 */
3599 String s1, s2, str_tmp, result;
3600
3601 s1 = AbSynToAldor(abApplyArg(ab,(int) 0)((ab)->abApply.argv[(int) 0]), usePercent); /* Parameter of the function */
3602 if (!s1) return NULL((void*)0);
3603 s2 = AbSynToAldor(abApplyArg(ab,1)((ab)->abApply.argv[1]), usePercent); /* Return type of the function */
3604 if (!s2) { strFree(s1); return NULL((void*)0); }
3605
3606 result = InitStr()strAlloc(500);
3607
3608 /* s1 -> s2 */
3609 result = STRCAT(result,"(");
3610 result = STRCAT(result,s1);
3611 result = STRCAT(result," -> ");
3612 result = STRCAT(result,s2);
3613 result = STRCAT(result,")");
3614
3615 /* to avoid wasting of memory */
3616 str_tmp = strCopy(result);
3617 strFree(result);
3618
3619 /* result */
3620 return str_tmp;
3621}
3622
3623String ApplyToAldor(AbSyn ab, int usePercent) {
3624 /* l should be initialised */
3625 /* abTag(ab) == AB_Apply */
3626 int i;
3627 String result, str_tmp;
3628 int useName = theFALSE;
3629
3630 if (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"->")) return FunctionPtrToAldor(ab, usePercent);
3631
3632 result = InitStr()strAlloc(500);
3633 result = STRCAT(result,abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str));
3634 if (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"Record")) useName = theTRUE;
3635 result = STRCAT(result,"(");
3636
3637 for (i = 0; i < abApplyArgc(ab)(((ab)->abHdr.argc)-1); i++) {
3638 AbSyn arg = abApplyArg(ab,i)((ab)->abApply.argv[i]);
3639 switch (abTag(arg)((arg)->abHdr.tag)) {
3640 case AB_Id:
3641 str_tmp = AbSynToAldor(arg,usePercent);
3642 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3643 result = STRCAT(result,str_tmp);
3644 strFree(str_tmp);
3645 break;
3646 case AB_Apply:
3647 str_tmp = ApplyToAldor(abApplyArg(ab,i)((ab)->abApply.argv[i]),usePercent);
3648 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3649 result = STRCAT(result,str_tmp);
3650 strFree(str_tmp);
3651 break;
3652 case AB_Declare:
3653 if (useName) {
3654 result = STRCAT(result,abIdStr(abDeclareId(arg))((((arg)->abDeclare.id))->abId.sym->str));
3655 result = STRCAT(result,": ");
3656 }
3657 str_tmp = AbSynToAldor(abDeclareType(arg)((arg)->abDeclare.type),usePercent);
3658 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3659 result = STRCAT(result,str_tmp);
3660 strFree(str_tmp);
3661 break;
3662 default:
3663 strFree(result);
3664 return NULL((void*)0);
3665 break;
3666 }
3667 if (i < abApplyArgc(ab)(((ab)->abHdr.argc)-1) - 1) result = STRCAT(result,",");
3668 }
3669 result = STRCAT(result,")");
3670
3671 str_tmp = strCopy(result);
3672 strFree(result);
3673
3674 return str_tmp;
3675}
3676
3677String CommaToAldor(AbSyn ab, int usePercent) {
3678 AbSyn tmp;
3679 String result, str_tmp;
3680 int i;
3681
3682 if (!ab->abHdr.argc)
3683 return strCopy("()");
3684
3685 /* create string */
3686 result = InitStr()strAlloc(500);
3687 result = STRCAT(result,"(");
3688 for (i=0; i < abArgc(ab)((ab)->abHdr.argc); i++) {
3689 tmp = abCommaArg(ab,i)((ab)->abComma.argv[(i)]);
3690 switch (abTag(tmp)((tmp)->abHdr.tag)) {
3691 case AB_Id:
3692 case AB_Declare:
3693 str_tmp = AbSynToAldor(tmp,usePercent);
3694 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3695 result = STRCAT(result,str_tmp);
3696 strFree(str_tmp);
3697 break;
3698 case AB_Apply:
3699 str_tmp = ApplyToAldor(ab,usePercent);
3700 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3701 result = STRCAT(result,str_tmp);
3702 strFree(str_tmp);
3703 break;
3704 default:
3705 fprintf(stderrstderr,"CommaToAldor - Bad Tag - %d\n",abTag(tmp)((tmp)->abHdr.tag));
3706 break;
3707 }
3708 if (i < abArgc(ab)((ab)->abHdr.argc) - 1) result = STRCAT(result,",");
3709 }
3710 result = STRCAT(result,")");
3711
3712 str_tmp = strCopy(result);
3713 strFree(result);
3714 return str_tmp;
3715}
3716
3717String QualifyToString(AbSyn ab, int usePercent) {
3718 String result,str_tmp;
3719
3720 if (!abHasTag(ab->abQualify.what,AB_Id)((ab->abQualify.what)->abHdr.tag == (AB_Id))) return NULL((void*)0);
3721 result = InitStr()strAlloc(500);
3722 result = STRCAT(result,abIdStr(ab->abQualify.what)((ab->abQualify.what)->abId.sym->str));
3723 result = STRCAT(result,"$");
3724 str_tmp = AbSynToAldor(ab->abQualify.origin,usePercent);
3725 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3726 result = STRCAT(result,str_tmp);
3727 strFree(str_tmp);
3728 str_tmp = strCopy(result);
3729 strFree(result);
3730 return str_tmp;
3731}
3732
3733String AbSynToAldor(AbSyn ab, int usePercent) {
3734
3735 if (!ab) return NULL((void*)0);
3736
3737 switch (abTag(ab)((ab)->abHdr.tag)) {
3738 case AB_Id:
3739 if (IsBasicType(abIdStr(ab)((ab)->abId.sym->str))) return strCopy(abIdStr(ab)((ab)->abId.sym->str));
3740 else { /* Usr type ... */
3741 if (strEqual(abIdStr(ab)((ab)->abId.sym->str),"%") && !usePercent)
3742 return OutputDomNameAldor(CurrentClassAldor);
3743 else if (strEqual(abIdStr(ab)((ab)->abId.sym->str),"%"))
3744 return strCopy("%%"); /* to get a real % because of fprintf ... */
3745 else
3746 return strCopy(abIdStr(ab)((ab)->abId.sym->str));
3747 }
3748 break;
3749 case AB_Apply:
3750 if (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"Enumeration")) return NULL((void*)0);
3751 return ApplyToAldor(ab,usePercent);
3752 case AB_Nothing:
3753 return strCopy("()");
3754 case AB_Comma:
3755 return CommaToAldor(ab,usePercent);
3756 case AB_Qualify:
3757 return QualifyToString(ab,usePercent);
3758 case AB_Declare:
3759 return AbSynToAldor(abDeclareType(ab)((ab)->abDeclare.type),usePercent);
3760 default:
3761 fprintf(stderrstderr,"AbSynToAldor - Don't deal with abTag(ab) == %d\n",abTag(ab)((ab)->abHdr.tag));
3762 return NULL((void*)0);
3763 }
3764}
3765
3766String ApplyArgToTmplCpp(AbSyn ab) {
3767 int paramNb, i;
3768 String result, str_tmp;
3769
3770 if (!ab) return NULL((void*)0);
3771 if (!abIsApply(ab)((ab)->abHdr.tag == (AB_Apply))) return NULL((void*)0);
3772 paramNb = abApplyArgc(ab)(((ab)->abHdr.argc)-1);
3773 result = InitStr()strAlloc(500);
3774 result = STRCAT(result,"<");
3775 for (i = 0; i < paramNb; i++) {
3776 str_tmp = AbSynToCpp(abApplyArg(ab,i)((ab)->abApply.argv[i]));
3777 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3778 result = STRCAT(result,str_tmp);
3779 strFree(str_tmp);
3780 if (i < (paramNb-1)) result = STRCAT(result,",");
3781 }
3782 result = STRCAT(result,">");
3783 str_tmp = strCopy(result);
3784 strFree(result);
3785 return str_tmp;
3786}
3787
3788String AbSynToCpp(AbSyn ab) {
3789 String str_tmp, result;
3790
3791 if (!ab) return NULL((void*)0);
3792
3793 switch (abTag(ab)((ab)->abHdr.tag)) {
3794 case AB_Id:
3795 str_tmp = MappingTypes(abIdStr(ab)((ab)->abId.sym->str));
3796 if (!str_tmp) { /* Usr type ... */
3797 if (strEqual(abIdStr(ab)((ab)->abId.sym->str),"%")) return strCopy(CurrentClassCpp);
3798 return strCopy(abIdStr(ab)((ab)->abId.sym->str));
3799 }
3800 return str_tmp;
3801 case AB_Apply:
3802 if (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"->")) return NULL((void*)0);
3803 if (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"Enumeration")) return NULL((void*)0);
3804 /* assuming we have now parameterized types */
3805 result = InitStr()strAlloc(500);
3806 str_tmp = strCopy(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str));
3807 result = STRCAT(result,str_tmp);
3808 strFree(str_tmp);
3809 str_tmp = ApplyArgToTmplCpp(ab);
3810 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3811 result = STRCAT(result,str_tmp);
3812 strFree(str_tmp);
3813 str_tmp = strCopy(result);
3814 strFree(result);
3815 return str_tmp;
3816 case AB_Nothing:
3817 return strCopy("void");
3818 case AB_Comma:
3819 if (!abArgc(ab)((ab)->abHdr.argc)) return strCopy("void");
3820 fprintf(stderrstderr,"Function pointers with multiple return are not handled\n");
3821 return NULL((void*)0);
3822 case AB_Define:
3823 return AbSynToCpp(tfGetExpr(abTUnique(abDefineLhs(ab)))((((((ab)->abDefine.lhs))->abHdr.type.unique))->__absyn
)
);
3824 case AB_Declare:
3825 return AbSynToCpp(abDeclareType(ab)((ab)->abDeclare.type));
3826 case AB_Qualify:
3827 if (abHasTag(ab->abQualify.origin,AB_Id)((ab->abQualify.origin)->abHdr.tag == (AB_Id)) && (strEqual(abIdStr(ab->abQualify.origin)((ab->abQualify.origin)->abId.sym->str),"Machine")))
3828 return MachineToCpp(ab->abQualify.what);
3829 return strCopy("void *");
3830 default:
3831 fprintf(stderrstderr,"AbSynToCpp - Don't deal with abTag(ab) == %d\n",abTag(ab)((ab)->abHdr.tag));
3832 return NULL((void*)0);
3833 }
3834}
3835
3836
3837int AbSynIsUserDef(AbSyn ab) {
3838 /* Tells whether the type is a basic one or a user defined ... */
3839 /* Deal only with AB_Id */
3840
3841 if (!ab) return theFALSE;
3842
3843 switch (abTag(ab)((ab)->abHdr.tag)) {
3844 case AB_Id:
3845 return !(IsBasicType(abIdStr(ab)((ab)->abId.sym->str)));
3846 case AB_Apply:
3847 if (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"->")) return theFALSE;
3848 if (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"Enumeration")) return theFALSE;
3849 return theTRUE;
3850 case AB_Nothing:
3851 return theFALSE;
3852 case AB_Comma:
3853 return theFALSE; /* To be completed ! */
3854 case AB_Qualify:
3855 return theFALSE;
3856 case AB_Declare:
3857 return AbSynIsUserDef(abDeclareType(ab)((ab)->abDeclare.type));
3858 case AB_Define:
3859 return AbSynIsUserDef(tfGetExpr(abTUnique(abDefineLhs(ab)))((((((ab)->abDefine.lhs))->abHdr.type.unique))->__absyn
)
);
3860 default:
3861 fprintf(stderrstderr,"AbSynIsUserDef - Don't deal with abTag(ab) == %d\n",abTag(ab)((ab)->abHdr.tag));
3862 return theFALSE;
3863 }
3864}
3865
3866int AbSynIsVoid(AbSyn ab) {
3867 /* Tells whether the type corresponds to 'void' */
3868 String str_tmp;
3869
3870 if (!ab) return theFALSE;
3871
3872 switch (abTag(ab)((ab)->abHdr.tag)) {
3873 case AB_Id:
3874 str_tmp = MappingTypes(abIdStr(ab)((ab)->abId.sym->str));
3875 if (!str_tmp) return theFALSE;
3876 if (!strEqual(str_tmp,"void")) {
3877 strFree(str_tmp);
3878 return theFALSE;
3879 }
3880 strFree(str_tmp);
3881 return theTRUE;
3882 case AB_Apply:
3883 return theFALSE;
3884 case AB_Nothing:
3885 return theTRUE;
3886 case AB_Comma:
3887 return (!ab->abHdr.argc); /* We don't deal with multiple return values */
3888 case AB_Define:
3889 return AbSynIsVoid(tfGetExpr(abTUnique(abDefineLhs(ab)))((((((ab)->abDefine.lhs))->abHdr.type.unique))->__absyn
)
);
3890 case AB_Qualify:
3891 return theFALSE;
3892 default:
3893 fprintf(stderrstderr,"AbSynIsVoid - Don't deal with abTag(ab) == %d\n",abTag(ab)((ab)->abHdr.tag));
3894 return theFALSE;
3895 }
3896}
3897
3898/* -- End AbSyn -- */
3899
3900/* -- TForm -- */
3901
3902String TFormToAldor(TForm tf, int usePercent) {
3903 String str_tmp,result;
3904 AbSyn ab = tfGetExpr(tf)((tf)->__absyn);
3905 int i;
3906 int lg;
3907
3908 if (tfIsExit(tf)(((tf)->tag) == TF_Exit)) return NULL((void*)0);
3909 if (tfIsGenerator(tf)(((tf)->tag) == TF_Generator)) return NULL((void*)0);
3910
3911 if (ab) return AbSynToAldor(ab,usePercent);
3912
3913 /* Function pointer ? */
3914 if (tfIsMap(tf)(((tf)->tag) == TF_Map)) {
3915 result = InitStr()strAlloc(500);
3916 str_tmp = TFormToAldor(tfMapArg(tf)tfFollowArg(tf, 0),usePercent);
3917 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3918 result = STRCAT(result,"(");
3919 result = STRCAT(result,str_tmp);
3920 result = STRCAT(result," -> ");
3921 strFree(str_tmp);
3922 str_tmp = TFormToAldor(tfMapRet(tf)tfFollowArg(tf, 1),usePercent);
3923 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3924 result = STRCAT(result,str_tmp);
3925 result = STRCAT(result,")");
3926 strFree(str_tmp);
3927 str_tmp = strCopy(result);
3928 strFree(result);
3929 return str_tmp;
3930 }
3931
3932 /* Multiple value ? */
3933 if (tfIsMulti(tf)(((tf)->tag) == TF_Multiple)) {
3934 lg = tfMultiArgc(tf);
3935 result = InitStr()strAlloc(500);
3936 result = STRCAT(result,"(");
3937 for (i = 0; i < lg; i++) {
3938 str_tmp = TFormToAldor(tfMultiArgN(tf,i)tfFollowArg(tf, i),usePercent);
3939 if (!str_tmp) { strFree(result); return NULL((void*)0); }
3940 result = STRCAT(result,str_tmp);
3941 strFree(str_tmp);
3942 if (i < lg-1) result = STRCAT(result,",");
3943 }
3944 result = STRCAT(result,")");
3945 str_tmp = strCopy(result);
3946 strFree(result);
3947 return str_tmp;
3948 }
3949
3950 return NULL((void*)0);
3951}
3952
3953TForm tfMakeSubst(TForm tf) {
3954 TForm tmp = tfSubst(tfSubstSigma(tf)((tf)->sigma),tf);
3955 if (!tfIsSubst(tmp)(((tmp)->tag) == TF_Subst)) return tmp;
3956 tmp = tfSubstArg(tf)tfFollowArg(tf, 0);
3957 /* I don't remember why this is here, I replace by 'return tmp;'
3958 if (!tfIsThird(tmp)) return tmp;
3959 tmp = tfThirdRestrictions(tmp);
3960 if (!tfIsWith(tmp)) return tf;
3961 return tfTUnique(tmp);
3962 */
3963 return tmp;
3964}
3965
3966TForm tfFollowDefDecl(TForm tf) {
3967 assert(tf != NULL)do { if (!(tf != ((void*)0))) _do_assert(("tf != NULL"),"gencpp.c"
,3967); } while (0)
;
3968 if (tfIsSubst(tf)(((tf)->tag) == TF_Subst)) tf = tfMakeSubst(tf);
3969 if (!tfIsDefine(tf)(((tf)->tag) == TF_Define) && !tfIsForward(tf)(((tf)->tag) == TF_Forward)) {
3970 if (tfIsSubst(tf)(((tf)->tag) == TF_Subst)) tf = tfMakeSubst(tf);
3971 return tf;
3972 }
3973 while (tfIsForward(tf)(((tf)->tag) == TF_Forward)) tfFollow(tf)((tf) = tfFollowFn(tf));
3974 if (tfIsSubst(tf)(((tf)->tag) == TF_Subst)) tf = tfMakeSubst(tf);
3975 if (!tfIsDefine(tf)(((tf)->tag) == TF_Define)) {
3976 if (tfIsSubst(tf)(((tf)->tag) == TF_Subst)) tf = tfMakeSubst(tf);
3977 return tf;
3978 }
3979 tf = tfDeclareType(tfDefineDecl(tf))tfFollowArg(tfFollowArg(tf, 0), 0);
3980 if (tfIsSubst(tf)(((tf)->tag) == TF_Subst)) tf = tfMakeSubst(tf);
3981 while (tfIsForward(tf)(((tf)->tag) == TF_Forward)) tfFollow(tf)((tf) = tfFollowFn(tf));
3982 if (tfIsSubst(tf)(((tf)->tag) == TF_Subst)) tf = tfMakeSubst(tf);
3983 return tf;
3984}
3985
3986/* -- End TForm -- */
3987
3988
3989/* -- Import/Export -- */
3990
3991String GiveTypeAldorExport(Class *cl, int tab) {
3992 String result,str_tmp;
3993 TForm tmp,tmp2;
3994 int paramNb;
3995 int several = theFALSE;
3996 int cnt, cnt2;
3997 SymeList meths, meths2;
3998 Syme meth;
3999
4000 result = InitStr()strAlloc(500);
4001
4002 /* header */
4003 result = sprintTab(result,tab);
4004 str_tmp = addUnderScore(cl->id.export);
4005 result = STRCAT(result,"ALDOR__givetype__");
4006 result = STRCAT(result,str_tmp);
4007 result = STRCAT(result,"(");
4008 strFree(str_tmp);
4009
4010 /* template params */
4011 if (cl->params) {
62
Assuming field 'params' is null
63
Taking false branch
4012 int i;
4013 tmp = cl->params;
4014 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
4015 if (paramNb == 1) {
4016 if (!tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) { strFree(result); return NULL((void*)0); }
4017 result = STRCAT(result,symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str));
4018 result = STRCAT(result,": ");
4019 str_tmp = TFormToAldor(tmp,!BL_UsePercenttheTRUE);
4020 if (!str_tmp) result = STRCAT(result,"Pointer");
4021 else result = STRCAT(result,str_tmp);
4022 }
4023 else
4024 for (i=0;i<paramNb;i++) {
4025 tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
4026 if (!tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare)) { strFree(result); return NULL((void*)0); }
4027 result = STRCAT(result,symString(tfDeclareId(tmp2))((tfDeclareId(tmp2))->str));
4028 result = STRCAT(result,": ");
4029 str_tmp = TFormToAldor(tmp2,!BL_UsePercenttheTRUE);
4030 if (!str_tmp) result = STRCAT(result,"Pointer");
4031 else result = STRCAT(result,str_tmp);
4032 if (i < paramNb-1) result = STRCAT(result,",");
4033 }
4034 }
4035
4036 result = STRCAT(result,"): ");
4037
4038 /* parents */
4039
4040 for (Rewind(cl->extraClasses); !EOList(cl->extraClasses); GotoNext(cl->extraClasses)) {
64
Assuming the condition is true
65
Loop condition is true. Entering loop body
4041 /* type of domain is of kind: Cat with ... or Join(Cat1,Cat2) with ... */
4042 Class *extra = (Class *) GetItem(cl->extraClasses);
4043
4044 /* several parents ? */
4045 Rewind(extra->parents);
4046 if (!EOList(extra->parents)) {
66
Assuming the condition is false
67
Taking false branch
4047 GotoNext(extra->parents);
4048 if (!EOList(extra->parents)) { /* means several parents ... */
4049 result = STRCAT(result,"Join(");
4050 several = theTRUE;
4051 }
4052 }
4053
4054 /* output parents */
4055 Rewind(extra->parents);
4056 while (!EOList(extra->parents)) {
68
Assuming the condition is false
69
Loop condition is false. Execution continues on line 4066
4057 Parent *p = (Parent *)GetItem(extra->parents);
4058 str_tmp = OutputDomNameAldor(p->id.typeAldor);
4059 result = STRCAT(result,str_tmp);
4060 strFree(str_tmp);
4061 GotoNext(extra->parents);
4062 if (!EOList(extra->parents)) result = STRCAT(result,",");
4063 }
4064
4065 /* end parents - begin body */
4066 if (several
69.1
'several' is 0
) result = STRCAT(result,") with {\n");
70
Taking false branch
4067 else result = STRCAT(result," with {\n ");
4068
4069 /* methods from extra class */
4070 cl->methCounter = 0;
4071 meths = tfThdExports(cl->methods) ? tfThdExports(cl->methods):tfParents(cl->methods)((cl->methods)->parents);
71
Assuming the condition is false
72
'?' condition is false
73
Access to field 'parents' results in a dereference of a null pointer (loaded from field 'methods')
4072 meths2 = meths;
4073 /* get the number of '%%' to be able to output only the last set of funtions
4074 the rest is taken care of by the inheritance */
4075 for (cnt = 0; meths; meths = meths->rest) {
4076 meth = meths->first;
4077 if (!strcmp(symString(symeId(meth))((((meth)->id))->str),"%%")) cnt++;
4078 }
4079 /* go to the last '%%' */
4080 meths = meths2;
4081 for (cnt2 = 0; cnt2 < cnt; meths = meths->rest) {
4082 meth = meths->first;
4083 if (!strcmp(symString(symeId(meth))((((meth)->id))->str),"%%")) cnt2++;
4084 }
4085 /* output the remaining functions */
4086 for (; meths; meths = meths->rest) {
4087 meth = meths->first;
4088 str_tmp = GenAldorFnSig(symeType(meth),symString(symeId(meth))((((meth)->id))->str),extra,2,!BL_ExportedtheTRUE,BL_UsePercenttheTRUE,!BL_UseTmplParmstheTRUE);
4089 if (!str_tmp) continue;
4090 result = STRCAT(result,str_tmp);
4091 strFree(str_tmp);
4092 }
4093
4094 result = sprintTab(result,tab);
4095 result = STRCAT(result,"}");
4096 }
4097
4098 if (!cl->extraClasses) {
4099 Rewind(cl->parents);
4100 if (!EOList(cl->parents)) {
4101 GotoNext(cl->parents);
4102 if (!EOList(cl->parents)) { /* means several parents ... */
4103 result = STRCAT(result,"Join(");
4104 several = theTRUE;
4105 }
4106 }
4107 Rewind(cl->parents);
4108 while (!EOList(cl->parents)) {
4109 Ident *id = (Ident *)GetItem(cl->parents);
4110 str_tmp = OutputDomNameAldor(id->typeAldor);
4111 result = STRCAT(result,str_tmp);
4112 strFree(str_tmp);
4113 GotoNext(cl->parents);
4114 if (!EOList(cl->parents)) result = STRCAT(result,",");
4115 }
4116
4117 /* end parents - begin body */
4118 if (several) result = STRCAT(result,")");
4119
4120 }
4121
4122 result = STRCAT(result," == ");
4123
4124 /* body == domain */
4125 str_tmp = OutputDomNameAldor(cl->id.typeAldor);
4126 result = STRCAT(result,str_tmp); result = STRCAT(result,";\n");
4127 strFree(str_tmp);
4128
4129 str_tmp = strCopy(result);
4130 strFree(result);
4131 return str_tmp;
4132}
4133
4134String GiveTypeCppExtern(Class *cl, int tab) {
4135 String result,str_tmp;
4136 TForm tmp,tmp2;
4137 int paramNb;
4138
4139 result = InitStr()strAlloc(500);
4140 result = sprintTab(result,tab);
4141
4142 result = STRCAT(result,"void *ALDOR_givetype_");
4143 result = STRCAT(result,cl->id.export);
4144 result = STRCAT(result,"(");
4145
4146 /* template params */
4147 if (cl->params) {
4148 int i;
4149 tmp = cl->params;
4150 paramNb = tfIsMulti(tmp)(((tmp)->tag) == TF_Multiple) ? tfMultiArgc(tmp) : 1;
4151 if (paramNb == 1) {
4152 if (!tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) { strFree(result); return NULL((void*)0); }
4153 result = STRCAT(result,"void *");
4154 }
4155 else
4156 for (i=0;i<paramNb;i++) {
4157 tmp2 = tfMultiArgN(tmp,i)tfFollowArg(tmp, i);
4158 if (!tfIsDeclare(tmp2)(((tmp2)->tag) == TF_Declare)) { strFree(result); return NULL((void*)0); }
4159 result = STRCAT(result,"void *");
4160 if (i < paramNb - 1) result = STRCAT(result,",");
4161 }
4162 }
4163
4164 result = STRCAT(result,");\n");
4165 str_tmp = strCopy(result);
4166 strFree(result);
4167 return str_tmp;
4168}
4169
4170void GenGiveTypeForExport(Class *cl, FILE *as, FILE *cc) {
4171 String toOutputAS = NULL((void*)0), toOutputCC = NULL((void*)0);
4172
4173 toOutputAS = GiveTypeAldorExport(cl,1);
61
Calling 'GiveTypeAldorExport'
4174 if (toOutputAS) toOutputCC = GiveTypeCppExtern(cl,1);
4175
4176 if (toOutputAS && toOutputCC) {
4177 fprintf(as,"%s",toOutputAS);
4178 fprintf(cc,"%s",toOutputCC);
4179 strFree(toOutputAS);
4180 strFree(toOutputCC);
4181 } else {
4182 if (toOutputAS) strFree(toOutputAS);
4183 if (toOutputCC) strFree(toOutputCC);
4184 }
4185}
4186
4187/* -- End Import/Export -- */
4188
4189/* ---------- END TYPES ---------- */
4190
4191/* Bugs and to do:
4192 . If SInt is specified without '$Machine' (using 'import from Machine;' for example), then
4193 the program doesn't translate SInt to FiSInt
4194 . Multiple return with a % in the list of returned things => just crash I think
4195 . overloading discrimine sur type de retour
4196 . function pointers
4197 . default parameters
4198 . value parameters for domains (like SI or SF)
4199 . global variable
4200 . Overloading resolved only on return type is not handled.
4201 */
4202
4203/* ---------- UTILS ---------- */
4204
4205/* -- String -- */
4206
4207void printTab(FILE *f, int tab) {
4208 int i;
4209 for (i = 0; i < tab; i++)
4210 fprintf(f,"\t");
4211}
4212
4213
4214String sprintTab(String s, int tab) {
4215 int i;
4216 for (i = 0; i < tab; i++)
4217 s = STRCAT(s,"\t");
4218 return s;
4219}
4220
4221
4222String itoa_(int i) {
4223 return strPrintf("%d",i);
4224}
4225
4226
4227String OutputDomNameAldor(String id) {
4228 Length lg = strLength(id);
4229 int i;
4230 String tmp = strCopy(id);
4231
4232 for (i=0; i < lg; i++)
4233 if (id[i] == '<') tmp[i] = '(';
4234 else if (id[i] == '>') tmp[i] = ')';
4235
4236 return tmp;
4237}
4238
4239
4240String addUnderScore(String s) {
4241 Length j = strLength(s);
4242 String t = InitStr()strAlloc(500);
4243 int i,k;
4244 String res;
4245
4246 for (i=0,k=0;i<j;i++,k++)
4247 if (s[i] != '_') t[k]=s[i];
4248 else {
4249 t[k]='_';
4250 k++;
4251 t[k]='_';
4252 }
4253 t[k] = '\0';
4254
4255 res = strCopy(t);
4256 strFree(t);
4257 return res;
4258}
4259
4260
4261String transOperatorLike(String s) {
4262 Length j = strLength(s);
4263 String t = InitStr()strAlloc(500);
4264 int i;
4265 String res;
4266
4267 for (i=0 ; i<j ; i++) {
4268 if ((res = GetStringForSpecialSymbol(s[i],theTRUE)))
4269 t = STRCAT(t,res);
4270 else {
4271 Length m = strLength(t);
4272 t[m] = s[i];
4273 t[m+1] = '\0';
4274 }
4275 }
4276
4277 res = strCopy(t);
4278 strFree(t);
4279 return res;
4280}
4281
4282
4283String AldorifySpeSym(String s) {
4284 /* For each 'special symbol' an _ is placed before */
4285
4286 Length lg = strLength(s);
4287 String t = InitStr()strAlloc(500);
4288 int i,k;
4289 String res;
4290
4291 for (i=0,k=0;i<lg;i++,k++) {
4292 if (IsSpecialSymbol(s[i],theFALSE)) {
4293 t[k]='_';
4294 k++;
4295 }
4296 t[k]=s[i];
4297 }
4298 t[k]='\0';
4299
4300 res = strCopy(t);
4301 strFree(t);
4302 return res;
4303}
4304
4305
4306String RealTypeString(AbSyn ab, int export) {
4307 String str_tmp, str_tmp2;
4308 int isUsrDef;
4309
4310 str_tmp2 = AbSynToCpp(ab);
4311 isUsrDef = AbSynIsUserDef(ab);
4312
4313 if (!isUsrDef) str_tmp = strPrintf("%s *",str_tmp2);
4314 else if (export) str_tmp = strPrintf("void *");
4315 else str_tmp = strPrintf("%s **",str_tmp2);
4316
4317 strFree(str_tmp2);
4318 return str_tmp;
4319}
4320
4321int abIsFuncPtr(AbSyn ab) {
4322 if (!ab) return theFALSE;
4323 if (!abIsApply(ab)((ab)->abHdr.tag == (AB_Apply))) return theFALSE;
4324 return (strEqual(abIdStr(abApplyOp(ab))((((ab)->abApply.op))->abId.sym->str),"->"));
4325}
4326
4327int tfIsFuncPtr(TForm tf) {
4328 if (!tf) return theFALSE;
4329 return (tfIsMap(tf)(((tf)->tag) == TF_Map));
4330}
4331
4332int IsCommonOperator(String s) {
4333 int i;
4334 for (i=0 ; i<CO_size ; i++)
4335 if (strEqual(commonOperators[i],s)) return theTRUE;
4336 return theFALSE;
4337}
4338
4339int IsInfixOperator(String s) {
4340 int i;
4341 for (i=0 ; i<IO_size ; i++)
4342 if (strEqual(infixOps[i],s)) return theTRUE;
4343 return theFALSE;
4344}
4345
4346int IsSpecialSymbol(char c, int all) {
4347 /* the option 'all' is to be set when communicating with C (export) */
4348 if (GetStringForSpecialSymbol(c,all) == NULL((void*)0))
4349 return theFALSE;
4350 else
4351 return theTRUE;
4352}
4353
4354String GetStringForSpecialSymbol(char c, int all) {
4355 /* the option 'all' is to be set when communicating with C (export) */
4356 int i;
4357
4358 if (all)
4359 for (i=0 ; ccSpecCharIdTable[i].ch != 0 ; i++) {
4360 if (c == ccSpecCharIdTable[i].ch)
4361 return ccSpecCharIdTable[i].str;
4362 }
4363 else
4364 for (i=0 ; ccSpecCharIdTable[i].ch != 0 ; i++) {
4365 if ((c == ccSpecCharIdTable[i].ch)
4366 && (c != BANG'!')
4367 && (c != QMARK'?'))
4368 return ccSpecCharIdTable[i].str;
4369 }
4370
4371 return NULL((void*)0);
4372}
4373
4374/* -- End String -- */
4375
4376/* -- Test -- */
4377
4378int PercentsInParms(TForm tf, Class *cl) {
4379 /*
4380 * Returns the position of the % in the list of params
4381 * position is starting from 1
4382 * returns 0 if no %
4383 */
4384 if (!tfIsMulti(tf)(((tf)->tag) == TF_Multiple)) {
4385 if (tfIsDeclare(tf)(((tf)->tag) == TF_Declare)) {
4386 if (strEqual(symString(tfDeclareId(tf))((tfDeclareId(tf))->str),"%")) return 1;
4387 if (strEqual(symString(tfDeclareId(tf))((tfDeclareId(tf))->str),cl->id.basic)) return 1;
4388 } else if (tfIsGeneral(tf)(((tf)->tag) == TF_General)) {
4389 AbSyn ab = tfGetExpr(tf)((tf)->__absyn);
4390 String s = AbSynToAldor(ab,BL_UsePercenttheTRUE);
4391 if (!s) return 0;
4392 if (strEqual(s,"%%")) return 1;
4393 if (strEqual(s,cl->id.basic)) return 1;
4394 strFree(s);
4395 }
4396 } else { /* tfIsMulti(tf) */
4397 int i,j;
4398 if ((i=tfMultiArgc(tf))) {
4399 for (j = 0; j < i; j++) {
4400 TForm tmp = tfMultiArgN(tf,j)tfFollowArg(tf, j);
4401 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) {
4402 if (strEqual(symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str),"%")) return j+1;
4403 if (strEqual(symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str),cl->id.basic)) return j+1;
4404 }
4405 else if (tfIsGeneral(tmp)(((tmp)->tag) == TF_General)) {
4406 AbSyn ab = tfGetExpr(tmp)((tmp)->__absyn);
4407 String s = AbSynToAldor(ab,BL_UsePercenttheTRUE);
4408 if (s) {
4409 if (strEqual(s,"%%")) return j+1;
4410 if (strEqual(s,cl->id.basic)) return j+1;
4411 strFree(s);
4412 }
4413 }
4414 }
4415 }
4416 }
4417 return 0;
4418}
4419
4420
4421int StaticOrNot(TForm tf, Class *cl) {
4422 if (!tfIsMulti(tf)(((tf)->tag) == TF_Multiple)) {
4423 if (tfIsDeclare(tf)(((tf)->tag) == TF_Declare)) {
4424 if (strEqual(symString(tfDeclareId(tf))((tfDeclareId(tf))->str),"%")) return theFALSE;
4425 else return !strEqual(symString(tfDeclareId(tf))((tfDeclareId(tf))->str),cl->id.basic);
4426 } else if (tfIsGeneral(tf)(((tf)->tag) == TF_General)) {
4427 AbSyn ab = tfGetExpr(tf)((tf)->__absyn);
4428 if (!ab) return theTRUE;
4429 if (!abHasTag(ab,AB_Id)((ab)->abHdr.tag == (AB_Id))) return theTRUE;
4430 if (strEqual(abIdStr(ab)((ab)->abId.sym->str),"%")) return theFALSE;
4431 return !strEqual(abIdStr(ab)((ab)->abId.sym->str),cl->id.basic);
4432 } else return theTRUE;
4433 } else {
4434 if (!tfMultiArgc(tf)) return theTRUE;
4435 else {
4436 TForm tmp = tfMultiArgN(tf,(Length) 0)tfFollowArg(tf, (Length) 0);
4437 if (tfIsDeclare(tmp)(((tmp)->tag) == TF_Declare)) {
4438 if (strEqual(symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str),"%")) return theFALSE;
4439 return !strEqual(symString(tfDeclareId(tmp))((tfDeclareId(tmp))->str),cl->id.basic);
4440 }
4441 else if (tfIsGeneral(tmp)(((tmp)->tag) == TF_General)) {
4442 AbSyn ab = tfGetExpr(tmp)((tmp)->__absyn);
4443 if (!ab) return theTRUE;
4444 if (!abHasTag(ab,AB_Id)((ab)->abHdr.tag == (AB_Id))) return theTRUE;
4445 if (strEqual(abIdStr(ab)((ab)->abId.sym->str),"%")) return theFALSE;
4446 return !strEqual(abIdStr(ab)((ab)->abId.sym->str),cl->id.basic);
4447 } else return theTRUE;
4448 }
4449 }
4450}
4451
4452
4453int SpecialCppFunc(String s) {
4454 if (strEqual(s,"char")) return theTRUE;
4455 return theFALSE;
4456}
4457
4458/* -- End Test -- */
4459
4460/* -- ID Handling -- */
4461
4462
4463String operatorForC(String func_id) {
4464 /* Get for the "extern C" a suitable string representing
4465 the operator */
4466 /* pre: func_id[0] is a Special Symbol */
4467
4468 String s;
4469 String res;
4470
4471 if (!(IsCommonOperator(func_id)))
4472 return transOperatorLike(func_id);
4473
4474 s = InitStr()strAlloc(500);
4475 s = STRCAT(s,"Op");
4476 s = STRCAT(s,GetStringForSpecialSymbol(func_id[0],theTRUE));
4477 res = strCopy(s);
4478 strFree(s);
4479 return res;
4480}
4481
4482
4483String createFnIdExternC(String s, Class *cl) {
4484 String str_tmp1,str_tmp2,str_tmp3;
4485 const char ALSTR[]="ALDOR_";
4486 int cnt;
4487 int status;
4488 String func_id = s;
4489 int i;
4490 Length k;
4491
4492 /* Check if operator */
4493 status = REGULAR;
4494
4495 if (IsCommonOperator(func_id)) status = OPERATOR;
4496 else { /* try to see if SPECIAL_SYM */
4497 k = strLength(func_id);
4498 for (i=0 ; i<k ; i++) {
4499 if (IsSpecialSymbol(func_id[i],theTRUE)) {
4500 status = SPECIAL_SYM;
4501 break;
4502 }
4503 }
4504 }
4505
4506 /* Format: ALDORMeth_ClassCnt */
4507 cnt = cl ? cl->methCounter : globalFuncCounter;
4508 str_tmp1 = strCopy(cl ? cl->id.export : "Global");
4509 str_tmp2 = (status != REGULAR) ? operatorForC(func_id) : strCopy(func_id);
4510 str_tmp3 = strPrintf("%s%s_%s%d",ALSTR,str_tmp2,str_tmp1,cnt);
4511 strFree(str_tmp2);
4512 strFree(str_tmp1);
4513
4514 return str_tmp3;
4515}
4516
4517
4518String createFnIdExportC(String s, Class *cl) {
4519 String str_tmp = createFnIdExternC(s,cl);
4520 String str_tmp2 = addUnderScore(str_tmp);
4521 strFree(str_tmp);
4522 return str_tmp2;
4523}
4524
4525
4526String createFnIdForCPP(String func_id, Class *cl) {
4527 String s,res;
4528 OpState status;
4529 int i;
4530 Length k;
4531
4532 /* Check if operator */
4533 status = REGULAR;
4534
4535 if (IsCommonOperator(func_id)) status = OPERATOR;
4536 else { /* try to see if SPECIAL_SYM */
4537 k = strLength(func_id);
4538 for (i=0 ; i<k ; i++) {
4539 if (IsSpecialSymbol(func_id[i],theTRUE)) {
4540 status = SPECIAL_SYM;
4541 break;
4542 }
4543 }
4544 }
4545
4546 /* Output */
4547 s = InitStr()strAlloc(500);
4548 if (status == OPERATOR) { s = STRCAT(s,"operator"); s = STRCAT(s,func_id); }
4549 else if (status == SPECIAL_SYM) {
4550 String t = operatorForC(func_id);
4551 s = STRCAT(s,t);
4552 strFree(t);
4553 } else if (SpecialCppFunc(func_id)) {
4554 s = STRCAT(s,func_id); s = STRCAT(s,cl->id.basic);
4555 }
4556 else s = STRCAT(s,func_id);
4557
4558 if (scanForBelongsTo(cppKeywords,CK_size,s)) {
4559 res = InitStr()strAlloc(500);
4560 res = STRCAT(res,"_");
4561 res = STRCAT(res,s);
4562 res = STRCAT(res,"_");
4563 s = strCopy(res);
4564 strFree(res);
4565 }
4566
4567 res = strCopy(s);
4568 strFree(s);
4569 return res;
4570}
4571
4572String GenAldorFuncNameReg(String s) {
4573 /* this function will use AldorifySpeSym to ensure any function id
4574 to be in the right format */
4575
4576 if (IsCommonOperator(s)) return strCopy(s);
4577 if (IsInfixOperator(s)) return strCopy(s); /* to deal with /\ for example */
4578 return AldorifySpeSym(s); /* *+ -> _*_+, round+ -> round_+ */
4579}
4580
4581
4582String GenAldorFuncName(String s, Class *cl, int isExported) {
4583 /* this function assumes that CurrentClass is set if isExported is theTRUE */
4584 return (isExported ? createFnIdExportC(s,cl) : GenAldorFuncNameReg(s));
4585}
4586
4587
4588String GetIdFromAbSyn(AbSyn ab) {
4589 if (abTag(ab)((ab)->abHdr.tag) == AB_Define) return abIdStr(abDeclareId(abDefineLhs(ab)))((((((ab)->abDefine.lhs))->abDeclare.id))->abId.sym->
str)
;
4590 else return NULL((void*)0);
4591}
4592
4593/* -- End ID Handling -- */
4594
4595/* ---------- END UTILS ---------- */
4596
4597/* -------------------- INIT FOR ALL STRUCTS ----------------------- */
4598/* InitList is in the "List management" section ... */
4599
4600Function *InitFunc() {
4601 Function *fn = alloc(Function)(Function *) stoAlloc(0,sizeof(Function));
4602 fn->id = NULL((void*)0);
4603 fn->params = NULL((void*)0);
4604 fn->ret_typ = NULL((void*)0);
4605 fn->isStatic = theTRUE;
4606 return fn;
4607}
4608
4609Class *InitClass() {
4610 Class *cl = alloc(Class)(Class *) stoAlloc(0,sizeof(Class));
4611 cl->parents = InitList();
4612 cl->extraClasses = InitList();
4613 cl->methods = NULL((void*)0);
4614 cl->params = NULL((void*)0);
4615 cl->methCounter = 0;
4616 cl->classCounter = 0;
4617 return cl;
4618}
4619
4620String STRCAT(String s1, String s2) {
4621 String s = strConcat(s1,s2);
4622 strFree(s1);
4623 return s;
4624}
4625
4626/* -------------------- LIST MANAGEMENT -------------------------- */
4627
4628MyList *InitList() {
4629 MyList *lst;
4630
4631 lst = alloc(MyList)(MyList *) stoAlloc(0,sizeof(MyList));
4632 lst->head = NULL((void*)0);
4633 lst->tail = NULL((void*)0);
4634 lst->current = NULL((void*)0);
4635
4636 return lst;
4637}
4638
4639void Append(MyList *lst, CellType ct, void *elem) {
4640 Cell *tmp;
4641
4642 if (!lst) { fprintf(stderrstderr, "Append: List not initialized\n"); exit((int) 0); }
4643
4644 /* Creation of the cell to append */
4645 tmp = alloc(Cell)(Cell *) stoAlloc(0,sizeof(Cell));
4646 tmp->Item = elem;
4647 tmp->ct = ct;
4648 tmp->next = NULL((void*)0);
4649
4650 /* Append the cell to the end of the list */
4651 if (!(lst->head)) {
4652 lst->tail = tmp;
4653 lst->current = tmp;
4654 lst->head = tmp;
4655 } else {
4656 lst->tail->next = tmp;
4657 lst->tail = tmp;
4658 }
4659}
4660
4661void Rewind(MyList *l) {
4662 if (!l) return;
4663 l->current = l->head;
4664}
4665
4666void *GetItem(MyList *l) {
4667 if (!l) return NULL((void*)0);
4668 if (!l->current) return NULL((void*)0);
4669 return l->current->Item;
4670}
4671
4672void GotoNext(MyList *l) {
4673 if (!l) return;
4674 if (!l->current) return;
4675 l->current = l->current->next;
4676}
4677
4678void HeadToNext(MyList *l) {
4679 if (!l) return;
4680 if (!l->current) return;
4681 l->head = l->current->next;
4682}
4683
4684int Empty(MyList *l) {
4685 return (!l || !l->head);
4686}
4687
4688int NotEmpty(MyList *l) {
4689 return (l && l->head);
4690}
4691
4692int EOList(MyList *l) {
4693 if (!l) return theTRUE;
4694 return !(l->current);
4695}
4696
4697/* -------------------- MEMORY MANAGEMENT -------------------------- */
4698
4699void FreeList(MyList *l) {
4700 if (!l) return;
4701 if (Empty(l)) { stoFree(l); return; }
4702 Rewind(l);
4703 while (!EOList(l)) {
4704 HeadToNext(l);
4705 stoFree(l->current);
4706 Rewind(l);
4707 }
4708 stoFree(l);
4709}
4710
4711void FreeFunction(Function *fn) {
4712 if (!fn) return;
4713}
4714
4715void FreeClass(Class *cl) {
4716 if (!cl) return;
4717
4718 FreeList(cl->extraClasses);
4719 FreeList(cl->parents);
4720 stoFree(cl);
4721}