Bug Summary

File:src/gf_add.c
Warning:line 331, column 7
Dereference of null pointer

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 gf_add.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 gf_add.c
1/*****************************************************************************
2 *
3 * gf_add.c: Foam code generation for "add", "with", and default packages.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9#include "debug.h"
10#include "fluid.h"
11#include "genfoam.h"
12#include "gf_util.h"
13#include "gf_prog.h"
14#include "gf_add.h"
15#include "gf_imps.h"
16#include "gf_rtime.h"
17#include "gf_seq.h"
18#include "of_util.h"
19#include "optinfo.h"
20#include "spesym.h"
21#include "stab.h"
22#include "store.h"
23#include "util.h"
24#include "sefo.h"
25#include "lib.h"
26#include "tfsat.h"
27#include "ablogic.h"
28#include "abpretty.h"
29#include "comsg.h"
30#include "strops.h"
31#include "table.h"
32#include "ti_top.h"
33
34localstatic Foam gen0AddBody1 (AbSyn, Stab, AbSyn);
35localstatic void gen0AddImportedDomain (TForm, Foam, AInt);
36localstatic Foam gen0CombineHash (Foam hash1, Foam hash2);
37localstatic AbSyn gen0FindDefaults (AbSyn with);
38localstatic Foam gen0GetDomainDomain (TForm);
39localstatic Foam gen0MakeDefaultHash (void);
40localstatic Foam gen0RtDomainHash (Foam);
41localstatic void gen0MakeDomainSelf (void);
42localstatic void gen0TypeAddDefaultSelfSlot (void);
43localstatic void gen0MakeDomainDefaults (Foam);
44localstatic void gen0MakeCategoryParents(AbSyn);
45localstatic int gen0MakeCatParents0 (AbSyn, Foam, int);
46localstatic int gen0MakeCatParentsIf (AbSyn, Foam, int);
47localstatic void gen0MakeDomainParents (AbSyn);
48localstatic void gen0MakeTypeParents (Length, AbSyn *, String, AbSyn);
49localstatic void gen0MakeTypeParent (AbSyn, Length, Foam, AbSyn);
50
51localstatic void gen0TypeInitDomain (AbSyn, AbSyn);
52localstatic void gen0TypeInitDefaults (void);
53localstatic ExportState gen0TypeInit (void);
54localstatic void gen0TypeOpen (Foam, String);
55localstatic void gen0TypeFini (void);
56localstatic Foam gen0MakeTypeExportMap (SymeList);
57
58localstatic Foam gen0BuildExporterName (AbSyn exporter);
59localstatic Foam gen0SeenImportedDomain (TForm, AInt);
60localstatic void gen0SetInitUsage (Foam, AInt);
61
62localstatic AbSynList gen0CollectAux (AbSyn);
63localstatic AbSyn gen0CollectWithImports (AbSyn);
64
65localstatic Foam gen0Join (AbSyn);
66localstatic Foam gen0Map (AbSyn);
67localstatic Foam gen0Enum (AbSyn);
68localstatic Foam gen0ApplySpecialOthers (AbSyn);
69localstatic Bool gen0AllSymesAllocated (AbSyn);
70
71localstatic Foam gen0RtTypeHash (TForm, TForm);
72localstatic Foam gen0RtTypeHashWith (TForm, TForm, String);
73localstatic Foam gen0RtSefoHashExporter (Sefo);
74localstatic Foam gen0RtSefoHash (Sefo, Sefo);
75
76localstatic void gen0InitExports (void);
77localstatic void gen0InitConditionalExport (Syme);
78localstatic SymeList gen0AddExportedSymes (void);
79localstatic Foam gen0HasJoin (Foam, int, AbSyn *);
80localstatic Foam gen0HasCat (Foam, AbSyn);
81localstatic Foam gen0HasCatBit (Foam, AbSyn);
82localstatic Foam gen0HasImports (Foam, SymeList, Foam);
83localstatic Foam gen0HasImport (Foam, Syme);
84
85localstatic void gen0StrRegister (int, String);
86
87static ExportState gen0ExportState;
88static Foam gen0HasSelf;
89
90Bool genfExportDebug = false((int) 0);
91Bool gfaddDebug = false((int) 0);
92
93#define genfExportDEBUGif (!genfExportDebug) { } else afprintf DEBUG_IF(genfExport)if (!genfExportDebug) { } else afprintf
94#define gfaddDEBUGif (!gfaddDebug) { } else afprintf DEBUG_IF(gfadd)if (!gfaddDebug) { } else afprintf
95
96localstatic void
97gen0ClashCheck(AbSyn ab)
98{
99 Foam stmt, rhs;
100 Foam seentab, arg1, arg2, arg3, arg4;
101 TForm dom = abTForm(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->tform : 0);
102 /* Check ALL exports of this domain ... */
103 SymeList symes = dom ? tfGetDomExports(dom) : 0;
104 AbSyn exporter = gen0ProgGetExporter();
105 String exp = exporter ? abPretty(exporter) : "(unknown)";
106 long nelts = listLength(Syme)(Syme_listPointer->_Length)(symes);
107
108 /* seentab = fiNewExportTable() */
109 seentab = gen0TempLocal(FOAM_Word)gen0TempLocal0(FOAM_Word, 4);
110 rhs = foamNew(FOAM_BCall, 3, FOAM_BVal_NewExportTable,
111 gen0CharArray(exp), foamNewSInt(nelts)foamNew(FOAM_SInt, 1, (AInt)(nelts)));
112 stmt = foamNewSet(seentab, rhs)foamNew(FOAM_Set, 2, seentab, rhs);
113 gen0AddStmt(stmt, ab);
114
115 /* Add each export to the table (may generate runtime warning) */
116 for (; symes; symes = cdr(symes)((symes)->rest)) {
117 Syme syme = car(symes)((symes)->first);
118 TForm tf = symeType(syme);
119 String str = symString(symeId(syme))((((syme)->id))->str);
120 String tfp = tfPretty(tf);
121
122 arg1 = foamNewSInt(gen0StrHash(str))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(str)));
123 arg2 = gen0TypeHash(tf, tf, str);
124 arg3 = gen0CharArray(str);
125 arg4 = gen0CharArray(tfp);
126 strFree(tfp);
127 stmt = foamNew(FOAM_BCall, 6, FOAM_BVal_AddToExportTable,
128 foamCopy(seentab), arg1, arg2, arg3, arg4);
129 gen0AddStmt(stmt, ab);
130 }
131
132
133 /* fiFreeExportTable() */
134 stmt = foamNew(FOAM_BCall, 2, FOAM_BVal_FreeExportTable,
135 foamCopy(seentab));
136 gen0AddStmt(stmt, ab);
137}
138
139
140/*
141 * Create a getter function for a package.
142 */
143
144Foam
145genAdd(AbSyn absyn)
146{
147 foamProgSetGetter(gen0State->program)((gen0State->program)->foamProg.infoBits |= (1 <<
3))
;
148 return gen0AddBody0(absyn, abStab(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->stab :
0)
, tfExpr(gen0AbType(absyn))tfToAbSyn(gen0AbType(absyn)));
149}
150
151/*
152 * This function generates code for add bodies.
153 *
154 * A domain is represented by an Aldor record. See axllib/runtime.as
155 * for the detail of domain representation. When first created, domains
156 * contain only a single function, that, when called fills in the hash code
157 * for the domain, and another function. When the second function is called,
158 * the domain get fully instantiated, and all the export slots are filled.
159 * This is all done in a lazy way, so that requestors of information from a
160 * domain need not worry about it. Gen0AddBody0 creates this first function,
161 * and gen0AddBody1 creates the second.
162 *
163 * The arguments:
164 * base: The left hand side of the add or with being processed, this
165 * is the parent of the domain or category.
166 * body: This is the code to be run when instantiating the type.
167 * stab: The symbol table for the body.
168 * defaultsAb: AbSyn for the defaults package.
169 *
170 */
171
172Foam
173gen0AddBody0(AbSyn ab, Stab stab, AbSyn defaultsAb)
174{
175 AbSyn body = ab->abAdd.capsule;
176 AInt index;
177 Foam foam, clos;
178 Length argc = 1;
179 String argv[1];
180
181 argv[0] = "domain";
182
183 clos = gen0ProgClosEmpty();
184 foam = gen0ProgInitEmpty("addLevel0", NULL((void*)0));
185
186 index = gen0FormatNum;
187 gen0ProgPushState(stab, GF_Add0);
188
189 if (genIsRuntime()(gen0IsRuntime))
190 gen0Vars(stab);
191 else
192 gen0ProgAddParams(argc, argv);
193
194 gen0PushFormat(index);
195
196 gen0State->program = foam;
197 gen0State->program->foamProg.infoBits = IB_SIDE(1 << 0);
198
199 if (genIsRuntime()(gen0IsRuntime)) {
200 genFoamStmt(body);
201 gen0AddStmt(foamNewReturn(foamNewNil())foamNew(FOAM_Return, 1, foamNew(FOAM_Nil, (int) 0)), NULL((void*)0));
202 }
203 else {
204 AbSyn exporter = gen0ProgGetExporter();
205 Foam rtHashCode = gen0SefoHashExporter(exporter);
206 Foam stmt;
207
208 stmt = gen0BuiltinCCall(FOAM_Word, "domainAddNameFn!",
209 "runtime",
210 2, foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))),
211 gen0BuildExporterName(exporter));
212 gen0AddStmt(stmt, NULL((void*)0));
213 stmt = gen0BuiltinCCall(FOAM_Word, "domainAddHash!", "runtime",
214 2, foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))), rtHashCode);
215 gen0AddStmt(stmt, NULL((void*)0));
216 stmt = foamNewReturn(gen0AddBody1(ab,stab,defaultsAb))foamNew(FOAM_Return, 1, gen0AddBody1(ab,stab,defaultsAb));
217 gen0AddStmt(stmt, NULL((void*)0));
218 }
219
220 gen0IssueDCache();
221 gen0ProgAddStateFormat(index);
222 gen0ProgFiniEmpty(foam, FOAM_Clos, int0((int) 0));
223
224 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(gen0State->stab, foam, NULL((void*)0), false((int) 0));
225 foamProgSetGetter(foam)((foam)->foamProg.infoBits |= (1 << 3));
226
227 gen0ProgPopState();
228
229 if (!genIsRuntime()(gen0IsRuntime)) {
230 clos = gen0BuiltinCCall(FOAM_Word, "domainMake", "runtime",
231 1, clos);
232 foamPure(clos)((clos)->hdr.info.pure) = true1;
233 }
234 return clos;
235}
236
237Foam
238gen0AddBody1(AbSyn ab, Stab stab, AbSyn defaultsAb)
239{
240 Scope("gen0AddBody1")String scopeName = ("gen0AddBody1"); int fluidLevel0 = (scopeLevel
++, fluidLevel)
;
241 AbSyn base = ab->abAdd.base;
242 AbSyn body = ab->abAdd.capsule;
243 ExportState fluid(gen0ExportState)fluidSave_gen0ExportState = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(gen0ExportState
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_gen0ExportState
, fluidStack[fluidLevel].size = sizeof(gen0ExportState), fluidLevel
++, (gen0ExportState) )
;
244 SymeList symes = listNil(Syme)((SymeList) 0);
245 Foam clos, foam;
246 int index;
247 Length argc = 2;
248 String argv[2];
249
250 argv[0] = "domain";
251 argv[1] = "hashcode";
252
253 clos = gen0ProgClosEmpty();
254 foam = gen0ProgInitEmpty("addLevel1", body);
255
256 index = gen0FormatNum;
257 gen0ProgPushState(stab, GF_Add1);
258
259 gen0ProgAddParams(argc, argv);
260
261 gen0Vars(stab);
262
263 gen0PushFormat(index);
264
265 gen0State->program = foam;
266 gen0State->program->foamProg.infoBits = IB_SIDE(1 << 0);
267
268 gen0FindUncondSymes(body, symes);
269 /* Add parents and defaults */
270 gen0ExportState = gen0TypeInit();
271 gen0TypeInitDomain(base, defaultsAb);
272
273 /* generate code for add body. */
274 gen0DefTypeSequence(body, gen0ExportState->domExportList);
275
276 /* Generate code to check for export clashes */
277 if (genHashcheck()(gen0Hashcheck)) gen0ClashCheck(ab);
278
279 gen0TypeFini();
280
281 gen0AddStmt(foamNewReturn(foamNewPar(int0))foamNew(FOAM_Return, 1, foamNew(FOAM_Par, 1, (AInt)(((int) 0)
)))
, NULL((void*)0));
282
283 gen0State->hasTemps = true1;
284
285 gen0ProgAddStateFormat(index);
286 gen0ProgFiniEmpty(foam, FOAM_Word, int0((int) 0));
287
288 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(gen0State->stab, foam, NULL((void*)0), false((int) 0));
289 foamProgSetGetter(foam)((foam)->foamProg.infoBits |= (1 << 3));
290
291 gen0ProgPopState();
292
293 Return(clos){ fluidUnwind(fluidLevel0, ((int) 0)); return clos;; };
294}
295
296Foam
297gen0MakeDefaultPackage(AbSyn base, Stab stab, Bool inCatForm, Syme syme)
298{
299 Scope("gen0MakeDefaultPackage")String scopeName = ("gen0MakeDefaultPackage"); int fluidLevel0
= (scopeLevel++, fluidLevel)
;
300 ExportState fluid(gen0ExportState)fluidSave_gen0ExportState = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(gen0ExportState
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_gen0ExportState
, fluidStack[fluidLevel].size = sizeof(gen0ExportState), fluidLevel
++, (gen0ExportState) )
;
4
Assuming 'fluidLevel' is not equal to 'fluidLimit'
5
'?' condition is false
301 AbSyn defs = NULL((void*)0);
302 Syme self = stabGetSelf(stab);
303 SymeList symes = listNil(Syme)((SymeList) 0);
304 Foam foam, clos;
305 int index, j;
306 Foam hasher;
307
308 Length argc = 2;
309 String argv[2];
310 argv[0] = "self";
311 argv[1] = "dom";
312
313 if (base
5.1
'base' is non-null
&& abTag(base)((base)->abHdr.tag) == AB_With) {
6
Assuming field 'tag' is equal to AB_With
7
Taking true branch
314 defs = gen0FindDefaults(base->abWith.within);
315 base = gen0CollectWithImports(base);
8
Value assigned to 'base'
316 }
317
318 if (base && abIsJoin(base)(((base)->abHdr.tag == (AB_Apply)) && (((((base)->
abApply.op))->abHdr.tag == (AB_Id)) && ((((base)->
abApply.op))->abId.sym)==(ssymJoin)))
) {
9
Assuming 'base' is null
319 Length jargc = abApplyArgc(base)(((base)->abHdr.argc)-1);
320 if (jargc == 0)
321 base = abNewNothing(sposNone)abNew(AB_Nothing, sposNone,0 );
322 if (jargc == 1)
323 base = abApplyArg(base, int0)((base)->abApply.argv[((int) 0)]);
324 }
325
326 if ((base
9.1
'base' is equal to NULL
== NULL((void*)0) || abIsNothing(base)((base)->abHdr.tag == (AB_Nothing))) &&
327 (defs
9.2
'defs' is not equal to NULL
== NULL((void*)0) || abIsNothing(defs)((defs)->abHdr.tag == (AB_Nothing))) &&
328 !inCatForm)
329 Return(foamNewNil()){ fluidUnwind(fluidLevel0, ((int) 0)); return foamNew(FOAM_Nil
, (int) 0);; }
;
330
331 if (!abIsJoin(base)(((base)->abHdr.tag == (AB_Apply)) && (((((base)->
abApply.op))->abHdr.tag == (AB_Id)) && ((((base)->
abApply.op))->abId.sym)==(ssymJoin)))
&&
10
Dereference of null pointer
332 (defs == NULL((void*)0) || abIsNothing(defs)((defs)->abHdr.tag == (AB_Nothing))) &&
333 (abIsId(base)((base)->abHdr.tag == (AB_Id)) || abIsApply(base)((base)->abHdr.tag == (AB_Apply))) &&
334#if 0
335 (self == NULL((void*)0) || symeUnused(self)(((UShort) ((((((self)->kind == SYME_Trigger ? libGetAllSymes
((self)->lib) : ((void*)0)), (self))->locmask) & (1
<< (SYFI_UsedDepth))) ? ((self)->fieldv)[symeIndex(
self,SYFI_UsedDepth)] : (symeFieldInfo[SYFI_UsedDepth].def)))
== (0x7FFF))
) &&
336#endif
337 !inCatForm)
338 Return(genFoamType(base)){ fluidUnwind(fluidLevel0, ((int) 0)); return genFoamType(base
);; }
;
339
340 hasher = gen0MakeDefaultHash();
341
342 clos = gen0ProgClosEmpty();
343 foam = gen0ProgInitEmpty(gen0ProgName, base);
344
345 index = gen0FormatNum;
346 gen0ProgPushState(stab, inCatForm ? GF_DefaultCat : GF_Default);
347
348 gen0State->type = tfCategory;
349 gen0State->stab = stab;
350
351 gen0State->program = foam;
352 gen0State->program->foamProg.infoBits = IB_SIDE(1 << 0);
353
354 gen0ProgAddParams(argc, argv);
355 if (self) symeSetUsedDeeply(self)(((((self)->kind == SYME_Trigger ? libGetAllSymes((self)->
lib) : ((void*)0)), (self))->bits) |= (0x0004))
;
356 gen0Vars(stab);
357 gen0PushFormat(index);
358
359 if (defs)
360 gen0FindUncondSymes(defs, symes);
361
362 gen0ExportState = gen0TypeInit();
363
364 if (self) {
365 gen0ExportState->self = gen0Syme(self);
366 gen0ExportState->selfSyme = self;
367 }
368 else {
369 j = gen0AddLex(foamNewDecl(FOAM_Word, strCopy("self"),foamNew(FOAM_Decl,4,(AInt)(FOAM_Word),strCopy("self"), (AInt)
(0x7FFF), 4)
370 emptyFormatSlot)foamNew(FOAM_Decl,4,(AInt)(FOAM_Word),strCopy("self"), (AInt)
(0x7FFF), 4)
);
371 gen0ExportState->self = foamNewLex(int0, j)foamNew(FOAM_Lex, 2, (AInt)(((int) 0)), (AInt)(j));
372 }
373 gen0AddInit(foamNewDef(foamCopy(gen0ExportState->self),foamNew(FOAM_Def, 2, foamCopy(gen0ExportState->self), foamNew
(FOAM_Par, 1, (AInt)(1)))
374 foamNewPar(1))foamNew(FOAM_Def, 2, foamCopy(gen0ExportState->self), foamNew
(FOAM_Par, 1, (AInt)(1)))
);
375 gen0ExportState->selfHash = gen0TempLex(FOAM_SInt)gen0TempLex0(FOAM_SInt, 4);
376 gen0AddInit(foamNewSet(foamCopy(gen0ExportState->selfHash),foamNew(FOAM_Set, 2, foamCopy(gen0ExportState->selfHash), gen0RtDomainHash
(gen0ExportState->self))
377 gen0RtDomainHash(gen0ExportState->self))foamNew(FOAM_Set, 2, foamCopy(gen0ExportState->selfHash), gen0RtDomainHash
(gen0ExportState->self))
);
378
379 gen0TypeInitDefaults();
380 gen0MakeCategoryParents(base);
381
382 if (defs)
383 gen0DefTypeSequence(defs, gen0ExportState->domExportList);
384
385 gen0TypeFini();
386
387 gen0AddStmt(foamNewReturn(foamNew(FOAM_Values, int0))foamNew(FOAM_Return, 1, foamNew(FOAM_Values, ((int) 0))), NULL((void*)0));
388
389 gen0ProgAddStateFormat(index);
390 gen0ProgFiniEmpty(foam, FOAM_NOp, int0((int) 0));
391
392 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(gen0State->stab, foam, syme, false((int) 0));
393 foamProgSetGetter(foam)((foam)->foamProg.infoBits |= (1 << 3));
394 if (foam->foamProg.levels->foamDEnv.argv[0] != emptyFormatSlot4)
395 foamProgUnsetLeaf(foam)((foam)->foamProg.infoBits &= ~(1 << 1));
396 /*gen0ComputeSideEffects(foam);*/
397 gen0ProgPopState();
398
399
400 foam = gen0BuiltinCCall(FOAM_Word,
401 "categoryMake", "runtime", 3, clos,
402 hasher,
403 gen0BuildExporterName(gen0ProgGetExporter()));
404 Return(foam){ fluidUnwind(fluidLevel0, ((int) 0)); return foam;; };
405}
406
407localstatic Foam
408gen0MakeDefaultHash()
409{
410 AbSyn exp = gen0ProgGetExporter();
411 Foam hashCode;
412
413 if (exp == NULL((void*)0) || abTag(exp)((exp)->abHdr.tag) == AB_Id) {
414 hashCode = gen0SefoHashExporter(exp);
415 return gen0BuiltinCCall(FOAM_Clos, "rtConstSIntFn",
416 "runtime", 1, hashCode);
417 }
418 else {
419 GenFoamState saved;
420 Foam foam, clos;
421 GenFoamTag oldTag = gen0State->tag;
422
423 clos = gen0ProgClosEmpty();
424 foam = gen0ProgInitEmpty("defhash0", NULL((void*)0));
425
426 saved = gen0ProgSaveState(PT_ExFn);
427 gen0State->tag = GF_Lambda;
428 hashCode = gen0SefoHashExporter(exp);
429
430 gen0AddStmt(foamNewReturn(hashCode)foamNew(FOAM_Return, 1, hashCode), NULL((void*)0));
431
432 gen0ProgPushFormat(emptyFormatSlot4);
433 gen0ProgFiniEmpty(foam, FOAM_SInt, int0((int) 0));
434 gen0AddLexLevels(foam, 1);
435 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
436
437 gen0ProgRestoreState(saved);
438 gen0State->tag = oldTag;
439
440 return clos;
441 }
442}
443
444
445
446localstatic void
447gen0TypeInitDomain(AbSyn base, AbSyn defaultsAb)
448{
449 Stab nstab;
450 Foam defaults;
451
452 gen0TypeOpen(foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))), "domainAddExports!");
453
454 gen0MakeDomainSelf();
455
456 nstab = defaultsAb ? abStab(defaultsAb)((defaultsAb)->abHdr.seman ? (defaultsAb)->abHdr.seman->
stab : 0)
: NULL((void*)0);
457 defaults = gen0MakeDefaultPackage(defaultsAb, nstab, false((int) 0), NULL((void*)0));
458
459 gen0MakeDomainDefaults(defaults);
460
461 gen0MakeDomainParents(base);
462}
463
464localstatic void
465gen0TypeInitDefaults()
466{
467 gen0TypeOpen(foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))), "categoryAddExports!");
468
469 if (gen0IsCatDefForm(gen0State))
470 gen0TypeAddDefaultSelfSlot();
471
472}
473
474/* COND-DEF */
475localstatic Hash
476gen0CondHash(GfCond cond)
477{
478 return (Hash)ptrCanon(cond->syme)((Pointer)(cond->syme));
479}
480
481localstatic Bool
482gen0CondEq(GfCond a, GfCond b)
483{
484 if ((a->syme) != (b->syme)) return false((int) 0);
485 return ablogEqual(a->condition, b->condition);
486}
487
488localstatic ExportState
489gen0TypeInit()
490{
491 ExportState exportState;
492 SymeList symes;
493 Foam szVar = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
494 Foam names, types, vals;
495 FoamList place;
496
497 /* collect the exports. */
498 if (gen0State->stab)
499 symes = gen0AddExportedSymes();
500 else
501 symes = 0;
502 /* set for array sizes */
503 gen0AddInit(foamNewNOp()foamNew(FOAM_NOp, (int) 0));
504 place = gen0State->inits;
505
506 /* Create the foam arrays for the domain vectors. */
507 names = gen0TempLocal0(FOAM_Arr, FOAM_Word);
508 types = gen0TempLocal0(FOAM_Arr, FOAM_Word);
509 vals = gen0TempLocal0(FOAM_Arr, FOAM_Word);
510
511 gen0AddInit(foamNewSet(names, foamNewANew(FOAM_Word,foamNew(FOAM_Set, 2, names, foamNew(FOAM_ANew, 2, FOAM_Word, foamCopy
(szVar)))
512 foamCopy(szVar)))foamNew(FOAM_Set, 2, names, foamNew(FOAM_ANew, 2, FOAM_Word, foamCopy
(szVar)))
);
513 gen0AddInit(foamNewSet(types, foamNewANew(FOAM_Word,foamNew(FOAM_Set, 2, types, foamNew(FOAM_ANew, 2, FOAM_Word, foamCopy
(szVar)))
514 foamCopy(szVar)))foamNew(FOAM_Set, 2, types, foamNew(FOAM_ANew, 2, FOAM_Word, foamCopy
(szVar)))
);
515 gen0AddInit(foamNewSet(vals, foamNewANew(FOAM_Word,foamNew(FOAM_Set, 2, vals, foamNew(FOAM_ANew, 2, FOAM_Word, foamCopy
(szVar)))
516 foamCopy(szVar)))foamNew(FOAM_Set, 2, vals, foamNew(FOAM_ANew, 2, FOAM_Word, foamCopy
(szVar)))
);
517
518 exportState = (ExportState) stoAlloc(OB_Other0, sizeof(*exportState));
519
520 exportState->foamLevel = gen0State->foamLevel;
521 exportState->domExportList = symes;
522 exportState->domInittedTbl = tblNew(NULL((void*)0), NULL((void*)0));
523 /* COND-DEF */
524 exportState->domCondTbl = tblNew((TblHashFun)gen0CondHash,
525 (TblEqFun)gen0CondEq);
526 exportState->defMap = gen0MakeTypeExportMap(symes);
527 exportState->setPlace = place;
528 exportState->szVar = szVar;
529 exportState->size = 0;
530 exportState->names = names;
531 exportState->types = types;
532 exportState->vals = vals;
533 exportState->selfSyme = NULL((void*)0);
534 return exportState;
535}
536
537localstatic void
538gen0TypeOpen(Foam type, String exporterName)
539{
540 Foam size = gen0ExportState->szVar;
541 Foam names, types, vals;
542
543 /* Create the Aldor arrays for the domain vectors. */
544 names = gen0MakeArray(foamCopy(size), gen0ExportState->names, NULL((void*)0));
545 types = gen0MakeArray(foamCopy(size), gen0ExportState->types, NULL((void*)0));
546 vals = gen0MakeArray(foamCopy(size), gen0ExportState->vals, NULL((void*)0));
547
548 gen0AddStmt(gen0BuiltinCCall(FOAM_NOp, exporterName, "runtime", 4,
549 type, names, types, vals), NULL((void*)0));
550}
551
552localstatic void
553gen0TypeFini()
554{
555 gen0InitExports();
556
557 gen0IssueDCache();
558
559 setcar(gen0ExportState->setPlace,((gen0ExportState->setPlace)->first = (foamNew(FOAM_Set
, 2, foamCopy(gen0ExportState->szVar), foamNew(FOAM_SInt, 1
, (AInt)(gen0ExportState->size)))))
560 foamNewSet(foamCopy(gen0ExportState->szVar),((gen0ExportState->setPlace)->first = (foamNew(FOAM_Set
, 2, foamCopy(gen0ExportState->szVar), foamNew(FOAM_SInt, 1
, (AInt)(gen0ExportState->size)))))
561 foamNewSInt(gen0ExportState->size)))((gen0ExportState->setPlace)->first = (foamNew(FOAM_Set
, 2, foamCopy(gen0ExportState->szVar), foamNew(FOAM_SInt, 1
, (AInt)(gen0ExportState->size)))))
;
562
563 listFree(Syme)(Syme_listPointer->Free)(gen0ExportState->domExportList);
564 tblFree(gen0ExportState->domInittedTbl);
565
566 stoFree(gen0ExportState);
567}
568
569void
570gen0TypeAddExportSlot(Syme syme)
571{
572 TForm tf = symeType(syme);
573 Foam name, type, val, lhs;
574 int posn;
575 String str = symString(symeId(syme))((((syme)->id))->str);
576
577 if (!gen0IsDomLevel(gen0State->tag)((gen0State->tag) >= GF_START_TYPE && (gen0State
->tag) <= GF_END_TYPE)
|| gen0State->tag == GF_File)
578 return;
579
580 /* Get the location which holds the value of the export */
581 lhs = gen0SymeInit(syme);
582 if (!lhs)
583 {
584 AbSyn ab = (AbSyn)NULL((void*)0);
585 String etype = tfPretty(tf);
586 comsgFatal(ab, ALDOR_F_BugExportSymeNotInit368, str, etype);
587 }
588
589
590 /*
591 * Conditional exports get a flag so that runtime checks can be
592 * made to determine whether or not they have been initialised.
593 */
594 if (!symeUnconditional(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x0020))
) {
595 gen0AddInit(foamNewSet(gen0ExpMapRef(syme),foamNew(FOAM_Set, 2, gen0ExpMapRef(syme), foamNew(FOAM_Bool, 1
, (AInt)(((int) 0))))
596 foamNewBool(false))foamNew(FOAM_Set, 2, gen0ExpMapRef(syme), foamNew(FOAM_Bool, 1
, (AInt)(((int) 0))))
);
597 gen0AddStmt(foamNewSet(gen0ExpMapRef(syme),foamNew(FOAM_Set, 2, gen0ExpMapRef(syme), foamNew(FOAM_Bool, 1
, (AInt)(1)))
598 foamNewBool(true))foamNew(FOAM_Set, 2, gen0ExpMapRef(syme), foamNew(FOAM_Bool, 1
, (AInt)(1)))
, NULL((void*)0));
599 }
600 posn = gen0ExportState->size++;
601 name = foamNewSInt(gen0StrHash(str))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(str)));
602 type = gen0TypeHash(tf, tf, str);
603
604
605 /* COND-DEF */
606 if (!symeUnconditional(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x0020))
) {
607 Foam def, rhs;
608
609
610 /* Get the local holding the export value */
611 rhs = gen0SymeCond(syme);
612
613
614 /* Safety check */
615 assert(rhs)do { if (!(rhs)) _do_assert(("rhs"),"gf_add.c",615); } while (
0)
;
616
617
618 /* Create definition for this export */
619 def = foamNewDef(foamCopy(lhs), foamCopy(rhs))foamNew(FOAM_Def, 2, foamCopy(lhs), foamCopy(rhs));
620
621
622 /* Retrieve the DefnId stashed by gen0Define */
623 def->foamDef.hdr.defnId = rhs->foamGen.hdr.defnId;
624
625
626#if 0
627 /* Debugging output */
628 (void)fprintf(dbOut, "--- [%d] ", def->foamDef.hdr.defnId);
629 foamPrintDb(rhs);
630 (void)fprintf(dbOut, " ");
631 symePrintDb(syme);
632 (void)fprintf(dbOut, " ");
633 ablogPrintDb(gfCondKnown);
634#endif
635
636
637 /* Define the export */
638 gen0AddStmt(def, NULL((void*)0));
639
640 }
641
642 val = foamCopy(lhs);
643
644
645 /* Wrap non-word exports */
646 if (gen0Type(tf, NULL((void*)0)) != FOAM_Word)
647 val = foamNewCast(FOAM_Word, val)foamNew(FOAM_Cast, 2, FOAM_Word, val);
648
649 gen0AddStmt(gen0ASet(gen0ExportState->names,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(posn)),foamCopy(gen0ExportState->names
)), foamNew(FOAM_Cast, 2, FOAM_Word, name))
650 posn, FOAM_Word, foamNewCast(FOAM_Word, name))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(posn)),foamCopy(gen0ExportState->names
)), foamNew(FOAM_Cast, 2, FOAM_Word, name))
,
651 NULL((void*)0));
652 gen0AddStmt(gen0ASet(gen0ExportState->types,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(posn)),foamCopy(gen0ExportState->types
)), foamNew(FOAM_Cast, 2, FOAM_Word, type))
653 posn, FOAM_Word, foamNewCast(FOAM_Word, type))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(posn)),foamCopy(gen0ExportState->types
)), foamNew(FOAM_Cast, 2, FOAM_Word, type))
,
654 NULL((void*)0));
655 gen0AddStmt(gen0ASet(gen0ExportState->vals,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(posn)),foamCopy(gen0ExportState->vals
)), val)
656 posn, FOAM_Word, val)foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(posn)),foamCopy(gen0ExportState->vals
)), val)
, NULL((void*)0));
657
658 gen0StrRegister(name->foamSInt.SIntData, str);
659
660 return;
661}
662
663/*
664 * Walk the tree looking for symes at top level. We ought to
665 * do this in scobind and we ought to deal with implicit
666 * exports as well. For now we assume that implicit exports
667 * are unconditional and mark them in gen0DefTypeSequence().
668 */
669void
670gen0FindUncondSymes(AbSyn absyn, SymeList symes)
671{
672 int i, argc;
673 AbSyn lhs, *argv;
674 Syme syme;
675
676 switch(abTag(absyn)((absyn)->abHdr.tag)) {
677 case AB_Define:
678 lhs = absyn->abDefine.lhs;
679 if (abTag(lhs)((lhs)->abHdr.tag) == AB_Comma) {
680 argc = abArgc(lhs)((lhs)->abHdr.argc);
681 argv = lhs->abComma.argv;
682 }
683 else {
684 argc = 1;
685 argv = &lhs;
686 }
687 for (i=0; i< argc; i++) {
688 if (abTag(argv[i])((argv[i])->abHdr.tag)==AB_Declare)
689 syme = abSyme(argv[i]->abDeclare.id)((argv[i]->abDeclare.id)->abHdr.seman ? (argv[i]->abDeclare
.id)->abHdr.seman->syme : 0)
;
690 else {
691 assert(abTag(argv[i])==AB_Id)do { if (!(((argv[i])->abHdr.tag)==AB_Id)) _do_assert(("abTag(argv[i])==AB_Id"
),"gf_add.c",691); } while (0)
;
692 syme = abSyme(argv[i])((argv[i])->abHdr.seman ? (argv[i])->abHdr.seman->syme
: 0)
;
693 }
694 if (symeIsExport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Export)
||symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
)
695 symeSetUnconditional(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) |= (0x0020))
;
696 }
697 break;
698 case AB_Where:
699 gen0FindUncondSymes(absyn->abWhere.expr, symes);
700 break;
701 case AB_Default:
702 case AB_Sequence:
703 for (i=0; i<abArgc(absyn)((absyn)->abHdr.argc); i++) {
704 if (abTag(abArgv(absyn)[i])((((absyn)->abGen.data.argv)[i])->abHdr.tag) == AB_Exit) break;
705 gen0FindUncondSymes(abArgv(absyn)((absyn)->abGen.data.argv)[i], symes);
706 }
707 break;
708 case AB_Local:
709 for (i=0; i<abArgc(absyn)((absyn)->abHdr.argc); i++) {
710 gen0FindUncondSymes(abArgv(absyn)((absyn)->abGen.data.argv)[i], symes);
711 }
712 break;
713 default:
714 break;
715 }
716}
717
718/*
719 * Create a local for self for a domain if needed.
720 */
721localstatic void
722gen0MakeDomainSelf()
723{
724 SymeList sl;
725 Foam result, set;
726
727 gen0ExportState->self = gen0TempLocal(FOAM_Word)gen0TempLocal0(FOAM_Word, 4);
728 result = gen0BuiltinCCall(FOAM_Word, "domainMakeDispatch",
729 "runtime", 1, foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))));
730 foamPure(result)((result)->hdr.info.pure) = true1;
731 gen0AddInit(foamNewSet(foamCopy(gen0ExportState->self), result)foamNew(FOAM_Set, 2, foamCopy(gen0ExportState->self), result
)
);
732 /* Tacky --- stabGetSelf gives an inner version,
733 so we go look for outer */
734 sl = gen0ExportState->domExportList;
735 while (sl && symeId(car(sl))((((sl)->first))->id) != ssymSelf)
736 sl = cdr(sl)((sl)->rest);
737
738 /* This was conditional on (sl && !symeUnused(car(sl)))
739 * ie. used deeply. The optimisations for self in tfFloat
740 * break this.
741 */
742 if (sl) {
743 set = gen0Syme(car(sl)((sl)->first));
744 gen0AddInit(foamNewSet(set,foamNew(FOAM_Set, 2, set, foamCopy(gen0ExportState->self))
745 foamCopy(gen0ExportState->self))foamNew(FOAM_Set, 2, set, foamCopy(gen0ExportState->self)));
746 gen0SymeSetInit(car(sl)((sl)->first), set);
747 symeSetUnconditional(car(sl))(((((((sl)->first))->kind == SYME_Trigger ? libGetAllSymes
((((sl)->first))->lib) : ((void*)0)), (((sl)->first)
))->bits) |= (0x0020))
;
748 }
749
750 gen0ExportState->selfSyme = sl ? car(sl)((sl)->first) : NULL((void*)0);
751 gen0ExportState->selfHash = gen0TempLex(FOAM_SInt)gen0TempLex0(FOAM_SInt, 4);
752 gen0AddInit(foamNewDef(gen0ExportState->selfHash, foamNewCast(FOAM_SInt,foamNew(FOAM_Def, 2, gen0ExportState->selfHash, foamNew(FOAM_Cast
, 2, FOAM_SInt, foamNew(FOAM_Par, 1, (AInt)(1))))
753 foamNewPar(1)))foamNew(FOAM_Def, 2, gen0ExportState->selfHash, foamNew(FOAM_Cast
, 2, FOAM_SInt, foamNew(FOAM_Par, 1, (AInt)(1))))
);
754}
755
756Bool
757gen0HasDefaults(AbSyn absyn)
758{
759 int i;
760 AbSyn within = absyn->abWith.within;
761
762 for(i=0; i<abArgc(within)((within)->abHdr.argc); i++) {
763 if (abTag(abArgv(within)[i])((((within)->abGen.data.argv)[i])->abHdr.tag) == AB_Default)
764 return true1;
765 /* Test should be improved.. */
766 if (abTag(abArgv(within)[i])((((within)->abGen.data.argv)[i])->abHdr.tag) == AB_If)
767 return true1;
768 }
769 return false((int) 0);
770}
771
772localstatic void
773gen0TypeAddDefaultSelfSlot()
774{
775 AbSyn abType = gen0ProgGetExporter();
776 Foam rtHash;
777 int i;
778
779 if (DEBUG(phase)phaseDebug) {
780 fprintf(dbOut, "Make slot: exporter is:\n");
781 abWrSExpr(dbOut, abType,int0((int) 0));
782 }
783
784 assert(gen0ExportState->self)do { if (!(gen0ExportState->self)) _do_assert(("gen0ExportState->self"
),"gf_add.c",784); } while (0)
;
785 rtHash = gen0SefoHashExporter(abType);
786
787 i = gen0ExportState->size++;
788 gen0AddStmt(gen0ASet(gen0ExportState->names, i, FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(gen0ExportState->names)
), foamNew(FOAM_Cast, 2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt
)(gen0StrHash("%%")))))
789 foamNewCast(FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(gen0ExportState->names)
), foamNew(FOAM_Cast, 2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt
)(gen0StrHash("%%")))))
790 foamNewSInt(gen0StrHash("%%"))))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(gen0ExportState->names)
), foamNew(FOAM_Cast, 2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt
)(gen0StrHash("%%")))))
,
791 NULL((void*)0));
792 gen0AddStmt(gen0ASet(gen0ExportState->types, i, FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(gen0ExportState->types)
), foamNew(FOAM_Cast, 2, FOAM_Word, rtHash))
793 foamNewCast(FOAM_Word, rtHash))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(gen0ExportState->types)
), foamNew(FOAM_Cast, 2, FOAM_Word, rtHash))
,
794 NULL((void*)0));
795 gen0AddStmt(gen0ASet(gen0ExportState->vals, i, FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(gen0ExportState->vals))
, foamCopy(gen0ExportState->self))
796 foamCopy(gen0ExportState->self))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(gen0ExportState->vals))
, foamCopy(gen0ExportState->self))
,
797 NULL((void*)0));
798 assert(foamTag(gen0ExportState->self) == FOAM_Lex)do { if (!(((gen0ExportState->self)->hdr.tag) == FOAM_Lex
)) _do_assert(("foamTag(gen0ExportState->self) == FOAM_Lex"
),"gf_add.c",798); } while (0)
;
799 gen0UseStackedFormat(gen0ExportState->self->foamLex.level);
800}
801
802/*
803 * Create the defaults for a domain.
804 */
805localstatic void
806gen0MakeDomainDefaults(Foam defaults)
807{
808 Foam result;
809
810 if (!defaults || foamTag(defaults)((defaults)->hdr.tag) == FOAM_Nil) return;
811
812 result = gen0BuiltinCCall(FOAM_Word, "domainAddDefaults!",
813 "runtime", 3, foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))), defaults,
814 foamCopy(gen0ExportState->self));
815 gen0AddStmt(result, NULL((void*)0));
816
817 gen0SetInitUsage(defaults, int0((int) 0));
818}
819
820/*
821 * Evaluate the parents of a domain.
822 */
823localstatic void
824gen0MakeCategoryParents(AbSyn base)
825{
826 Foam pars, result;
827 FoamList place;
828 int sz;
829
830 assert(base)do { if (!(base)) _do_assert(("base"),"gf_add.c",830); } while
(0)
;
831 if (abIsNothing(base)((base)->abHdr.tag == (AB_Nothing))) return;
832
833 pars = gen0TempLocal0(FOAM_Arr, FOAM_Word);
834 gen0AddInit(foamNewNOp()foamNew(FOAM_NOp, (int) 0));
835 place = gen0State->inits;
836 sz = gen0MakeCatParents0(base, pars, int0((int) 0));
837 /* fixup */
838 if (sz == 0)
839 return;
840 setcar(place,((place)->first = (foamNew(FOAM_Set, 2, foamCopy(pars), foamNew
(FOAM_ANew, 2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt)(sz))))
))
841 foamNewSet(foamCopy(pars),((place)->first = (foamNew(FOAM_Set, 2, foamCopy(pars), foamNew
(FOAM_ANew, 2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt)(sz))))
))
842 foamNewANew(FOAM_Word, foamNewSInt(sz))))((place)->first = (foamNew(FOAM_Set, 2, foamCopy(pars), foamNew
(FOAM_ANew, 2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt)(sz))))
))
;
843
844 /* Create the Aldor array for the parents. */
845 pars = gen0MakeArray(foamNewSInt(sz)foamNew(FOAM_SInt, 1, (AInt)(sz)), foamCopy(pars), base);
846
847 result = gen0BuiltinCCall(FOAM_Word, "categoryAddParents!",
848 "runtime", 3,
849 foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))), pars,
850 foamCopy(gen0ExportState->self));
851 gen0AddStmt(result, NULL((void*)0));
852}
853
854localstatic int
855gen0MakeCatParents0(AbSyn ab, Foam pars, int idx)
856{
857 int i;
858 if (abIsJoin(ab)(((ab)->abHdr.tag == (AB_Apply)) && (((((ab)->abApply
.op))->abHdr.tag == (AB_Id)) && ((((ab)->abApply
.op))->abId.sym)==(ssymJoin)))
) {
859 for (i=0; i<abApplyArgc(ab)(((ab)->abHdr.argc)-1) ; i++) {
860 idx = gen0MakeCatParents0(abApplyArg(ab, i)((ab)->abApply.argv[i]),
861 pars, idx);
862 }
863 }
864 else switch (abTag(ab)((ab)->abHdr.tag)) {
865 case AB_Sequence:
866 for (i=0; i<abArgc(ab)((ab)->abHdr.argc) ; i++)
867 idx = gen0MakeCatParents0(abArgv(ab)((ab)->abGen.data.argv)[i],
868 pars, idx);
869 break;
870 case AB_If:
871 idx = gen0MakeCatParentsIf(ab, pars, idx);
872 break;
873 case AB_Default:
874 gen0DefTypeSequence(ab,
875 gen0ExportState->domExportList);
876 break;
877 case AB_Declare:
878 case AB_Export:
879 case AB_Nothing:
880 break;
881 case AB_Comma:
882 assert(abArgc(ab) == 0)do { if (!(((ab)->abHdr.argc) == 0)) _do_assert(("abArgc(ab) == 0"
),"gf_add.c",882); } while (0)
;
883 break;
884 default:
885 gen0MakeTypeParent(ab, idx, foamCopy(pars), NULL((void*)0));
886 idx ++;
887 }
888 return idx;
889}
890
891
892localstatic int
893gen0MakeCatParentsIf(AbSyn ab, Foam pars, int idx)
894{
895 FoamList topLines;
896 Foam low;
897 int l1 = gen0State->labelNo++, l2 = gen0State->labelNo++;
898 int l3 = gen0State->labelNo++, l4 = gen0State->labelNo++;
899 int idx1, idx2;
900 Bool flag;
901
902 /* COND-DEF */
903 AbLogic saveCond;
904 AbSyn nTest;
905 Stab stab = abStab(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->stab : 0) ? abStab(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->stab : 0) : stabFile();
906 extern AbSyn abExpandDefs(Stab, AbSyn);
907
908 flag = gen0AddImportPlace(&topLines);
909
910 nTest = abExpandDefs(stab, (ab->abIf.test)); /* COND-DEF */
911
912 /*
913 * Plan is:
914 * (if cond L1)
915 * idx1 := Fill <else> part from idx
916 * low := idx1
917 * goto L2
918 * L1:
919 * idx2 := Fill <then> part from idx
920 * low := idx2
921 * L2:
922 * high := max(idx1, idx2)
923 * L3:
924 * if (high = low) L4;
925 * arr.low := NIL;
926 * low++;
927 * L4
928 */
929 low = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
930
931 gen0AddStmt(foamNewIf(genFoamBit(ab->abIf.test), l1)foamNew(FOAM_If, 2, genFoamBit(ab->abIf.test), l1), ab);
932 ablogAndPush(&gfCondKnown, &saveCond, nTest, false((int) 0)); /* COND-DEF */
933 idx1 = gen0MakeCatParents0(ab->abIf.elseAlt, pars, idx);
934 ablogAndPop (&gfCondKnown, &saveCond); /* COND-DEF */
935 gen0AddStmt(foamNewSet(foamCopy(low), foamNewSInt(idx1))foamNew(FOAM_Set, 2, foamCopy(low), foamNew(FOAM_SInt, 1, (AInt
)(idx1)))
, ab);
936
937 gen0AddStmt(foamNewGoto(l2)foamNew(FOAM_Goto, 1, (AInt)(l2)), ab);
938 gen0AddStmt(foamNewLabel(l1)foamNew(FOAM_Label, 1, (AInt)(l1)), ab);
939
940 ablogAndPush(&gfCondKnown, &saveCond, nTest, true1); /* COND-DEF */
941 idx2 = gen0MakeCatParents0(ab->abIf.thenAlt, pars, idx);
942 ablogAndPop (&gfCondKnown, &saveCond); /* COND-DEF */
943 gen0AddStmt(foamNewSet(foamCopy(low), foamNewSInt(idx2))foamNew(FOAM_Set, 2, foamCopy(low), foamNew(FOAM_SInt, 1, (AInt
)(idx2)))
, ab);
944 gen0AddStmt(foamNewLabel(l2)foamNew(FOAM_Label, 1, (AInt)(l2)), ab);
945
946 idx = idx1>idx2 ? idx1 : idx2;
947
948 gen0AddStmt(foamNewLabel(l3)foamNew(FOAM_Label, 1, (AInt)(l3)), ab);
949 gen0AddStmt(foamNewIf(foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ,foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ, foamNew
(FOAM_SInt, 1, (AInt)(idx)), foamCopy(low)), l4)
950 foamNewSInt(idx),foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ, foamNew
(FOAM_SInt, 1, (AInt)(idx)), foamCopy(low)), l4)
951 foamCopy(low)),foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ, foamNew
(FOAM_SInt, 1, (AInt)(idx)), foamCopy(low)), l4)
952 l4)foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ, foamNew
(FOAM_SInt, 1, (AInt)(idx)), foamCopy(low)), l4)
, ab);
953 gen0AddStmt(foamNewSet(foamNewAElt(FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy
(low),foamCopy(pars)), foamNew(FOAM_Cast, 2, FOAM_Word, foamNew
(FOAM_Nil, (int) 0)))
954 foamCopy(low),foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy
(low),foamCopy(pars)), foamNew(FOAM_Cast, 2, FOAM_Word, foamNew
(FOAM_Nil, (int) 0)))
955 foamCopy(pars)),foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy
(low),foamCopy(pars)), foamNew(FOAM_Cast, 2, FOAM_Word, foamNew
(FOAM_Nil, (int) 0)))
956 foamNewCast(FOAM_Word, foamNewNil()))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy
(low),foamCopy(pars)), foamNew(FOAM_Cast, 2, FOAM_Word, foamNew
(FOAM_Nil, (int) 0)))
,
957 ab);
958 gen0AddStmt(foamNewSet(foamCopy(low),foamNew(FOAM_Set, 2, foamCopy(low), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntNext
, foamCopy(low)))
959 foamNew(FOAM_BCall, 2,foamNew(FOAM_Set, 2, foamCopy(low), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntNext
, foamCopy(low)))
960 FOAM_BVal_SIntNext,foamNew(FOAM_Set, 2, foamCopy(low), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntNext
, foamCopy(low)))
961 foamCopy(low)))foamNew(FOAM_Set, 2, foamCopy(low), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntNext
, foamCopy(low)))
,
962 ab);
963 gen0AddStmt(foamNewGoto(l3)foamNew(FOAM_Goto, 1, (AInt)(l3)), ab);
964 gen0AddStmt(foamNewLabel(l4)foamNew(FOAM_Label, 1, (AInt)(l4)), ab);
965
966 foamFree(low);
967 if (flag) gen0ResetImportPlace(topLines);
968
969 return idx;
970}
971
972localstatic void
973gen0MakeDomainParents(AbSyn base)
974{
975 if (abIsNothing(base)((base)->abHdr.tag == (AB_Nothing))) return;
976
977 gen0MakeTypeParents(1, &base, "domainAddParents!", base);
978}
979
980
981localstatic void
982gen0MakeTypeParents(Length argc, AbSyn *argv, String adderName, AbSyn base)
983{
984 Foam pars, result;
985 Length i;
986
987 /* Create the foam array for the parent vector. */
988 pars = gen0TempLocal0(FOAM_Arr, FOAM_Word);
989 gen0AddStmt(gen0ANew(pars, FOAM_Word, argc)foamNew(FOAM_Set, 2, foamCopy(pars), foamNew(FOAM_ANew, 2, FOAM_Word
, foamNew(FOAM_SInt, 1, (AInt)(argc))))
, base);
990
991 /* Fill the slots in the foam array. */
992 for (i = 0; i < argc; i += 1)
993 gen0MakeTypeParent(argv[i], i, pars, base);
994
995 /* Create the Aldor array for the domain parents. */
996 pars = gen0MakeArray(foamNewSInt(argc)foamNew(FOAM_SInt, 1, (AInt)(argc)), pars, base);
997
998 result = gen0BuiltinCCall(FOAM_Word, adderName, "runtime", 3,
999 foamNewPar(int0)foamNew(FOAM_Par, 1, (AInt)(((int) 0))), pars,
1000 foamCopy(gen0ExportState->self));
1001 gen0AddStmt(result, NULL((void*)0));
1002}
1003
1004/*
1005 * Stuff the parent vector slot for a single parent in the add/with chain.
1006 */
1007localstatic void
1008gen0MakeTypeParent(AbSyn elt, Length i, Foam pars, AbSyn absyn)
1009{
1010 FoamTag type = gen0Type(gen0AbType(elt), NULL((void*)0));
1011 Foam par;
1012
1013 par = genFoamVal(elt);
1014 if (type != FOAM_Word)
1015 par = foamNewCast(FOAM_Word, par)foamNew(FOAM_Cast, 2, FOAM_Word, par);
1016
1017 gen0AddStmt(gen0ASet(pars, i, FOAM_Word, par)foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(pars)), par)
, absyn);
1018}
1019
1020localstatic Foam
1021gen0MakeTypeExportMap(SymeList symes)
1022{
1023 Foam mapVar;
1024
1025 mapVar = gen0Temp0(FOAM_Arr, FOAM_Bool);
1026 gen0AddInit(gen0ANew(mapVar, FOAM_Bool, listLength(Syme)(symes))foamNew(FOAM_Set, 2, foamCopy(mapVar), foamNew(FOAM_ANew, 2, FOAM_Bool
, foamNew(FOAM_SInt, 1, (AInt)((Syme_listPointer->_Length)
(symes)))))
);
1027 return mapVar;
1028}
1029
1030int
1031gen0ExpMapPos(Syme syme)
1032{
1033 return listPosq(Syme)(Syme_listPointer->Posq)(gen0ExportState->domExportList, syme);
1034}
1035
1036Foam
1037gen0ExpMapRef(Syme syme)
1038{ /* !! Assumes syme came from gen0ExportState->domExports */
1039 return foamNewAElt(FOAM_Bool, foamNewSInt(gen0ExpMapPos(syme)),foamNew(FOAM_AElt,3,(AInt)(FOAM_Bool),foamNew(FOAM_SInt, 1, (
AInt)(gen0ExpMapPos(syme))),foamCopy(gen0ExportState->defMap
))
1040 foamCopy(gen0ExportState->defMap))foamNew(FOAM_AElt,3,(AInt)(FOAM_Bool),foamNew(FOAM_SInt, 1, (
AInt)(gen0ExpMapPos(syme))),foamCopy(gen0ExportState->defMap
))
;
1041}
1042
1043localstatic void
1044gen0InitExports()
1045{
1046 SymeList sl;
1047
1048 for (sl = gen0ExportState->domExportList; sl ; sl=cdr(sl)((sl)->rest)) {
1049 Syme syme = car(sl)((sl)->first);
1050 /* !! Eek */
1051 if (symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
)
1052 continue;
1053 /*
1054 * The game we play with defaults is to assign them to
1055 * locals (see gen0Define), export them and then use
1056 * InitExports to pull in then binding.
1057 * !!Unfortunately, this fails if the export is
1058 * something that isn't lazy.
1059 */
1060 if (symeHasDefault(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x0080))
&& gen0SymeInit(syme))
1061 gen0InitExport(syme);
1062 else if (symeUsed(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x0040))
&& !symeUnconditional(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x0020))
&&
1063 gen0SymeInit(syme) != NULL((void*)0))
1064 gen0InitConditionalExport(syme);
1065 else if (symeUsed(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x0040))
&& gen0SymeInit(syme) == NULL((void*)0))
1066 gen0InitExport(syme);
1067 }
1068}
1069
1070localstatic void
1071gen0InitConditionalExport(Syme syme)
1072{
1073 int label;
1074
1075 if (!gen0IsDomLevel(gen0State->tag)((gen0State->tag) >= GF_START_TYPE && (gen0State
->tag) <= GF_END_TYPE)
|| gen0State->tag == GF_File)
1076 return;
1077
1078 label = gen0State->labelNo++;
1079
1080 gen0AddStmt(foamNewIf(gen0ExpMapRef(syme), label)foamNew(FOAM_If, 2, gen0ExpMapRef(syme), label), NULL((void*)0));
1081 gen0InitExport(syme);
1082 gen0AddStmt(foamNewLabel(label)foamNew(FOAM_Label, 1, (AInt)(label)), NULL((void*)0));
1083}
1084
1085/*
1086 * This code generator tries to avoid domain lookup failures
1087 * by testing for an export before attempting to forcing the
1088 * lazy version. If the export is not found then no forcing
1089 * is performed and (SInt 0) returned. Hopefully by the time
1090 * that the export really is needed we will have initialised
1091 * it by some other route.
1092 *
1093 * We want to generate the following code:
1094 *
1095 * if (self has foo) L0;
1096 * tmpvar = (SInt 0);
1097 * goto L1;
1098 * L0: tmpvar = lazyForceExport! val;
1099 * L1: ...
1100 *
1101 * This trick helps to avoid bug #1221: while building % we
1102 * try to initialise another domain parameterised by %. This
1103 * domain is actually a domain-valued function and eagerly
1104 * asks us a question. Unfortunately this causes us to force
1105 * a simple (non-lambda) export that we haven't been able to
1106 * create yet. Luckily the forced export isn't needed yet:
1107 * if it was then we are in trouble.
1108 */
1109localstatic Foam
1110gen0TryForceLazy(Foam self, Syme syme, Foam lazy)
1111{
1112 Bool flag;
1113 Foam test, tmpvar, val;
1114 FoamList topLines;
1115 int l1, l2;
1116 AbSyn absyn = (AbSyn)NULL((void*)0);
1117 FoamTag type = gen0Type(symeType(syme), NULL((void*)0));
1118
1119 /* Get some labels */
1120 l1 = gen0State->labelNo++;
1121 l2 = gen0State->labelNo++;
1122
1123
1124 /* Standard guff */
1125 flag = gen0AddImportPlace(&topLines);
1126
1127
1128 /* Export values must fit into a word */
1129 tmpvar = gen0TempLocal(FOAM_Word)gen0TempLocal0(FOAM_Word, 4);
1130
1131
1132 /* Create the "has" test */
1133 test = gen0HasImport(foamCopy(self), syme);
1134 test = foamNewCast(FOAM_Bool, test)foamNew(FOAM_Cast, 2, FOAM_Bool, test);
1135
1136
1137 /* Test for the export that we want to force */
1138 gen0AddStmt(foamNewIf(test, l1)foamNew(FOAM_If, 2, test, l1), absyn);
1139
1140
1141 /* Export not found: use a neutral value/bad pointer */
1142 val = foamNewCast(FOAM_Word, foamNeutralValue(type))foamNew(FOAM_Cast, 2, FOAM_Word, foamNeutralValue(type));
1143 gen0AddStmt(foamNewSet(foamCopy(tmpvar), val)foamNew(FOAM_Set, 2, foamCopy(tmpvar), val), absyn);
1144
1145
1146 /* Jump to the place where we update the export */
1147 gen0AddStmt(foamNewGoto(l2)foamNew(FOAM_Goto, 1, (AInt)(l2)), absyn);
1148
1149
1150 /* Target for the successful if-test */
1151 gen0AddStmt(foamNewLabel(l1)foamNew(FOAM_Label, 1, (AInt)(l1)), absyn);
1152
1153
1154 /* Force the lazy export */
1155 val = gen0LazyValue(lazy, syme);
1156 gen0AddStmt(foamNewSet(foamCopy(tmpvar), val)foamNew(FOAM_Set, 2, foamCopy(tmpvar), val), absyn);
1157
1158
1159 /* Target for the export update */
1160 gen0AddStmt(foamNewLabel(l2)foamNew(FOAM_Label, 1, (AInt)(l2)), absyn);
1161
1162
1163 /* Standard guff */
1164 if (flag) gen0ResetImportPlace(topLines);
1165
1166
1167 /* Return the value of the export */
1168 return tmpvar;
1169}
1170
1171void
1172gen0InitExport(Syme syme)
1173{
1174 Foam self, val;
1175
1176 assert(symeIsExport(syme)||symeIsExtend(syme))do { if (!((((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->kind) == SYME_Export
)||(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme
)->lib) : ((void*)0)), (syme))->kind) == SYME_Extend)))
_do_assert(("symeIsExport(syme)||symeIsExtend(syme)"),"gf_add.c"
,1176); } while (0)
;
1177 assert(gen0ExportState->self)do { if (!(gen0ExportState->self)) _do_assert(("gen0ExportState->self"
),"gf_add.c",1177); } while (0)
;
1178
1179 self = foamCopy(gen0ExportState->self);
1180 val = gen0GetDomImport(syme, self);
1181
1182 foamSyme(val)((val)->hdr.syme) = syme;
1183
1184 if (gen0IsLazyConst(symeType(syme)))
1185 val = gen0TryForceLazy(self, syme, val);
1186
1187 gen0AddStmt(foamNewSet(gen0Syme(syme), val)foamNew(FOAM_Set, 2, gen0Syme(syme), val), NULL((void*)0));
1188 if (foamTag(self)((self)->hdr.tag) == FOAM_Lex)
1189 gen0UseStackedFormat(self->foamLex.level);
1190}
1191
1192localstatic SymeList
1193gen0AddExportedSymes()
1194{
1195 SymeList symes;
1196
1197 if (gen0State->parent &&
1198 gen0State->parent->parent &&
1199 gen0State->parent->parent->tag == GF_Lambda &&
1200 gen0State->parent->parent->stab) {
1201 symes = stabGetExportedSymes(gen0State->parent->parent->stab);
1202 symes = listConcat(Syme)(Syme_listPointer->Concat)(stabGetExportedSymes(gen0State->stab),
1203 symes);
1204 }
1205 else symes = stabGetExportedSymes(gen0State->stab);
1206
1207 return symes;
1208}
1209
1210
1211void
1212gen0SymeSetInit(Syme syme, Foam foam)
1213{
1214 tblSetElt(gen0ExportState->domInittedTbl, syme, foam);
1215}
1216
1217Foam
1218gen0SymeInit(Syme syme)
1219{
1220 return (Foam) tblElt(gen0ExportState->domInittedTbl, syme, NULL((void*)0));
1221}
1222
1223
1224/* Conditional export */
1225/* COND-DEF */
1226Foam
1227gen0SymeCond(Syme syme)
1228{
1229 Foam result;
1230 _GfCond cond;
1231
1232 cond.syme = syme;
1233 cond.condition = gfCondKnown;
1234
1235 result = (Foam) tblElt(gen0ExportState->domCondTbl, &cond, NULL((void*)0));
1236 return result;
1237}
1238
1239/* COND-DEF */
1240void
1241gen0SymeSetCond(Syme syme, Foam foam)
1242{
1243 GfCond cond = (GfCond)stoAlloc(OB_Other0, sizeof(*cond));
1244
1245 cond->syme = syme;
1246 cond->condition = ablogCopy(gfCondKnown);
1247
1248 tblSetElt(gen0ExportState->domCondTbl, cond, foam);
1249}
1250
1251
1252/* Return a simpler sefo with the same type */
1253
1254Sefo
1255gen0EqualMods(Sefo sefo)
1256{
1257 Bool changed = (sefo != NULL((void*)0));
1258
1259 while (changed)
1260 switch (abTag(sefo)((sefo)->abHdr.tag)) {
1261 case AB_PretendTo:
1262 sefo = sefo->abPretendTo.expr;
1263 break;
1264 case AB_RestrictTo:
1265 sefo = sefo->abRestrictTo.expr;
1266 break;
1267 case AB_Qualify:
1268 sefo = sefo->abQualify.what;
1269 break;
1270 case AB_Assign:
1271 sefo = sefo->abAssign.lhs;
1272 break;
1273 case AB_Define:
1274 sefo = sefo->abDefine.lhs;
1275 break;
1276 case AB_Documented:
1277 sefo = sefo->abDocumented.expr;
1278 break;
1279 case AB_Declare:
1280 sefo = sefo->abDeclare.id;
1281 break;
1282 case AB_For:
1283 sefo = sefo->abFor.lhs;
1284 break;
1285 case AB_Local:
1286 case AB_Free:
1287 case AB_Sequence:
1288 case AB_Comma:
1289 if (abArgc(sefo)((sefo)->abHdr.argc) == 1)
1290 sefo = abArgv(sefo)((sefo)->abGen.data.argv)[0];
1291 else
1292 changed = false((int) 0);
1293 break;
1294 default:
1295 changed = false((int) 0);
1296 break;
1297 }
1298
1299 /*
1300 * AB_Except is a bit of an oddity - in this case, the lhs won't be
1301 * simplified, which may mean this function doesn't quite work.
1302 */
1303 assert(sefo == NULL ||do { if (!(sefo == ((void*)0) || ((sefo)->abHdr.tag) == AB_Id
|| ((sefo)->abHdr.tag) == AB_Apply || ((sefo)->abHdr.tag
) == AB_Except || ((sefo)->abHdr.tag) == AB_Add || ((sefo)
->abHdr.tag) == AB_With || ((((sefo)->abHdr.tag) < AB_NODE_START
) && ((sefo)->abHdr.seman ? (sefo)->abHdr.seman
->syme : 0)))) _do_assert(("sefo == NULL || abTag(sefo) == AB_Id || abTag(sefo) == AB_Apply || abTag(sefo) == AB_Except || abTag(sefo) == AB_Add || abTag(sefo) == AB_With || (abIsLeaf(sefo) && abSyme(sefo))"
),"gf_add.c",1309); } while (0)
1304 abTag(sefo) == AB_Id ||do { if (!(sefo == ((void*)0) || ((sefo)->abHdr.tag) == AB_Id
|| ((sefo)->abHdr.tag) == AB_Apply || ((sefo)->abHdr.tag
) == AB_Except || ((sefo)->abHdr.tag) == AB_Add || ((sefo)
->abHdr.tag) == AB_With || ((((sefo)->abHdr.tag) < AB_NODE_START
) && ((sefo)->abHdr.seman ? (sefo)->abHdr.seman
->syme : 0)))) _do_assert(("sefo == NULL || abTag(sefo) == AB_Id || abTag(sefo) == AB_Apply || abTag(sefo) == AB_Except || abTag(sefo) == AB_Add || abTag(sefo) == AB_With || (abIsLeaf(sefo) && abSyme(sefo))"
),"gf_add.c",1309); } while (0)
1305 abTag(sefo) == AB_Apply ||do { if (!(sefo == ((void*)0) || ((sefo)->abHdr.tag) == AB_Id
|| ((sefo)->abHdr.tag) == AB_Apply || ((sefo)->abHdr.tag
) == AB_Except || ((sefo)->abHdr.tag) == AB_Add || ((sefo)
->abHdr.tag) == AB_With || ((((sefo)->abHdr.tag) < AB_NODE_START
) && ((sefo)->abHdr.seman ? (sefo)->abHdr.seman
->syme : 0)))) _do_assert(("sefo == NULL || abTag(sefo) == AB_Id || abTag(sefo) == AB_Apply || abTag(sefo) == AB_Except || abTag(sefo) == AB_Add || abTag(sefo) == AB_With || (abIsLeaf(sefo) && abSyme(sefo))"
),"gf_add.c",1309); } while (0)
1306 abTag(sefo) == AB_Except ||do { if (!(sefo == ((void*)0) || ((sefo)->abHdr.tag) == AB_Id
|| ((sefo)->abHdr.tag) == AB_Apply || ((sefo)->abHdr.tag
) == AB_Except || ((sefo)->abHdr.tag) == AB_Add || ((sefo)
->abHdr.tag) == AB_With || ((((sefo)->abHdr.tag) < AB_NODE_START
) && ((sefo)->abHdr.seman ? (sefo)->abHdr.seman
->syme : 0)))) _do_assert(("sefo == NULL || abTag(sefo) == AB_Id || abTag(sefo) == AB_Apply || abTag(sefo) == AB_Except || abTag(sefo) == AB_Add || abTag(sefo) == AB_With || (abIsLeaf(sefo) && abSyme(sefo))"
),"gf_add.c",1309); } while (0)
1307 abTag(sefo) == AB_Add ||do { if (!(sefo == ((void*)0) || ((sefo)->abHdr.tag) == AB_Id
|| ((sefo)->abHdr.tag) == AB_Apply || ((sefo)->abHdr.tag
) == AB_Except || ((sefo)->abHdr.tag) == AB_Add || ((sefo)
->abHdr.tag) == AB_With || ((((sefo)->abHdr.tag) < AB_NODE_START
) && ((sefo)->abHdr.seman ? (sefo)->abHdr.seman
->syme : 0)))) _do_assert(("sefo == NULL || abTag(sefo) == AB_Id || abTag(sefo) == AB_Apply || abTag(sefo) == AB_Except || abTag(sefo) == AB_Add || abTag(sefo) == AB_With || (abIsLeaf(sefo) && abSyme(sefo))"
),"gf_add.c",1309); } while (0)
1308 abTag(sefo) == AB_With ||do { if (!(sefo == ((void*)0) || ((sefo)->abHdr.tag) == AB_Id
|| ((sefo)->abHdr.tag) == AB_Apply || ((sefo)->abHdr.tag
) == AB_Except || ((sefo)->abHdr.tag) == AB_Add || ((sefo)
->abHdr.tag) == AB_With || ((((sefo)->abHdr.tag) < AB_NODE_START
) && ((sefo)->abHdr.seman ? (sefo)->abHdr.seman
->syme : 0)))) _do_assert(("sefo == NULL || abTag(sefo) == AB_Id || abTag(sefo) == AB_Apply || abTag(sefo) == AB_Except || abTag(sefo) == AB_Add || abTag(sefo) == AB_With || (abIsLeaf(sefo) && abSyme(sefo))"
),"gf_add.c",1309); } while (0)
1309 (abIsLeaf(sefo) && abSyme(sefo)))do { if (!(sefo == ((void*)0) || ((sefo)->abHdr.tag) == AB_Id
|| ((sefo)->abHdr.tag) == AB_Apply || ((sefo)->abHdr.tag
) == AB_Except || ((sefo)->abHdr.tag) == AB_Add || ((sefo)
->abHdr.tag) == AB_With || ((((sefo)->abHdr.tag) < AB_NODE_START
) && ((sefo)->abHdr.seman ? (sefo)->abHdr.seman
->syme : 0)))) _do_assert(("sefo == NULL || abTag(sefo) == AB_Id || abTag(sefo) == AB_Apply || abTag(sefo) == AB_Except || abTag(sefo) == AB_Add || abTag(sefo) == AB_With || (abIsLeaf(sefo) && abSyme(sefo))"
),"gf_add.c",1309); } while (0)
;
1310 return sefo;
1311}
1312
1313
1314Foam
1315gen0LocalSelf()
1316{
1317 Foam foam = foamCopy(gen0ExportState->self);
1318
1319 if (gen0HasSelf)
1320 return foamCopy(gen0HasSelf);
1321
1322 gen0AddLexLevels(foam,
1323 gen0State->foamLevel
1324 - gen0ExportState->foamLevel);
1325 return foam;
1326
1327}
1328
1329Syme
1330gen0LocalSelfSyme()
1331{
1332 if (gen0ExportState == NULL((void*)0))
1333 return NULL((void*)0);
1334 return gen0ExportState->selfSyme;
1335}
1336
1337/*****************************************************************************
1338 *
1339 * :: Selection of an appropriate hashing scheme, and delayed
1340 * export hashcode finding
1341 *
1342 ****************************************************************************/
1343
1344localstatic Bool gen0SefoListIsCachable (SefoList);
1345localstatic Foam gen0DCacheAddItem (HashType, Pointer, Pointer);
1346localstatic Bool gen0DCacheMatch (DomainCache dc,
1347 HashType type,
1348 Pointer arg0, Pointer arg1);
1349localstatic void gen0IssueDCache1 (void);
1350static Bool gen0DCacheInIssue = false((int) 0);
1351
1352Foam
1353gen0TypeHash(TForm tf, TForm otf, String name)
1354{
1355 SefoList sfl = gen0GetSefoInnerSefos(tfExpr(tf)tfToAbSyn(tf));
1356
1357 if (tfTag(otf)((otf)->tag) == TF_With)
1358 gen0RtTypeHashWith(tf, otf, name);
1359
1360 if (!gen0DCacheInIssue && gen0SefoListIsCachable(sfl)) {
1361 listFree(Sefo)(Sefo_listPointer->Free)(sfl);
1362 return gen0DCacheAddItem(HT_TFormHash, tf, otf);
1363 }
1364 listFree(Sefo)(Sefo_listPointer->Free)(sfl);
1365 return gen0RtTypeHash(tf, otf);
1366}
1367
1368Foam
1369gen0SefoHashExporter(Sefo sf)
1370{
1371 return gen0RtSefoHashExporter(sf);
1372}
1373
1374Foam
1375gen0SefoHash(Sefo sf, Sefo osf)
1376{
1377 SefoList sfl = gen0GetSefoInnerSefos(sf);
1378
1379 if (!gen0DCacheInIssue && gen0SefoListIsCachable(sfl)) {
1380 listFree(Sefo)(Sefo_listPointer->Free)(sfl);
1381 return gen0DCacheAddItem(HT_SefoHash, sf, osf);
1382 }
1383 listFree(Sefo)(Sefo_listPointer->Free)(sfl);
1384 return gen0RtSefoHash(sf, osf);
1385}
1386
1387/* Can we make a cache at the start of a function... */
1388localstatic Bool
1389gen0SefoListIsCachable(SefoList sfl)
1390{
1391 Sefo sf;
1392 Syme syme;
1393
1394 while (sfl != listNil(Sefo)((SefoList) 0)) {
1395 sf = car(sfl)((sfl)->first);
1396 if (abTag(sf)((sf)->abHdr.tag) != AB_Id)
1397 return false((int) 0);
1398 syme = abSyme(sf)((sf)->abHdr.seman ? (sf)->abHdr.seman->syme : 0);
1399 if (!syme)
1400 return false((int) 0);
1401 if (!symeIsSelf(syme)(((syme)->id) == ssymSelf)
1402 && !symeIsParam(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Param)
)
1403 return false((int) 0);
1404 /* In 'has' expression => Weird self */
1405 if (symeIsSelf(syme)(((syme)->id) == ssymSelf) && gen0HasSelf) return false((int) 0);
1406 sfl = cdr(sfl)((sfl)->rest);
1407 }
1408 return true1;
1409}
1410
1411localstatic Foam
1412gen0DCacheAddItem(HashType type, Pointer arg0, Pointer arg1)
1413{
1414 DomainCacheList dcl;
1415 DomainCache cache, dc;
1416 Foam tmp;
1417
1418 dcl = gen0State->domCache;
1419
1420 while (dcl != listNil(DomainCache)((DomainCacheList) 0)) {
1421 dc = car(dcl)((dcl)->first);
1422 if (gen0DCacheMatch(dc, type, arg0, arg1))
1423 return foamCopy(dc->hashVar);
1424
1425 dcl = cdr(dcl)((dcl)->rest);
1426 }
1427
1428 tmp = gen0Temp(FOAM_SInt)gen0Temp0(FOAM_SInt, 4);
1429
1430 cache = (DomainCache) stoAlloc(OB_Other0, sizeof(*cache));
1431 cache->hashVar = tmp;
1432 cache->type = type;
1433 cache->args[0] = arg0;
1434 cache->args[1] = arg1;
1435
1436 if (type == HT_Id)
1437 gen0State->domCache =
1438 listNConcat(DomainCache)(DomainCache_listPointer->NConcat)
1439 (gen0State->domCache,
1440 listCons(DomainCache)(DomainCache_listPointer->Cons)(cache,
1441 listNil(DomainCache)((DomainCacheList) 0)));
1442 else
1443 gen0State->domCache =
1444 listCons(DomainCache)(DomainCache_listPointer->Cons)(cache, gen0State->domCache);
1445
1446 return foamCopy(tmp);
1447}
1448
1449localstatic Bool
1450gen0DCacheMatch(DomainCache dc, HashType type, Pointer arg0, Pointer arg1)
1451{
1452 if (dc->type != type)
1453 return false((int) 0);
1454
1455 if (dc->args[0] == arg0 &&
1456 dc->args[1] == arg1)
1457 return true1;
1458 if (type == HT_SefoHash)
1459 return sefoEqual((Sefo)(dc->args[0]), (Sefo) arg0);
1460 if (type == HT_TFormHash)
1461 return tfEqual((TForm)(dc->args[0]), (TForm) arg0);
1462
1463 return false((int) 0);
1464}
1465
1466/* Flushing the cache */
1467void
1468gen0IssueDCache()
1469{
1470 gen0IssueDCache1();
1471 /* HT_Id's may appear */
1472 if (gen0State->domCache)
1473 gen0IssueDCache1();
1474
1475 assert(gen0State->domCache == NULL)do { if (!(gen0State->domCache == ((void*)0))) _do_assert(
("gen0State->domCache == NULL"),"gf_add.c",1475); } while (
0)
;
1476}
1477
1478localstatic void
1479gen0IssueDCache1()
1480{
1481 DomainCacheList dcl = listNReverse(DomainCache)(DomainCache_listPointer->NReverse)(gen0State->domCache);
1482 DomainCache dc;
1483 FoamList stmts;
1484 Foam set, rhs = NULL((void*)0);
1485
1486 gen0DCacheInIssue = true1;
1487 stmts = gen0State->lines;
1488 gen0State->lines = NULL((void*)0);
1489 gen0State->domCache = listNil(DomainCache)((DomainCacheList) 0);
1490
1491 while (dcl != listNil(DomainCache)((DomainCacheList) 0)) {
1492 dc = car(dcl)((dcl)->first);
1493 switch (dc->type) {
1494 case HT_TFormHash:
1495 rhs = gen0RtTypeHash((TForm) (dc->args[0]),
1496 (TForm) (dc->args[1]));
1497 break;
1498 case HT_SefoHash:
1499 rhs = gen0RtSefoHash((Sefo) (dc->args[0]),
1500 (Sefo) (dc->args[1]));
1501 break;
1502 case HT_SefoHashExporter:
1503 rhs = gen0RtSefoHashExporter((Sefo) (dc->args[0]));
1504 break;
1505 case HT_Id:
1506 rhs = gen0RtDomainHash(gen0Syme((Syme)(dc->args[0])));
1507 break;
1508 default:
1509 bug("Unexpected hash-kind");
1510 break;
1511 }
1512 set = foamNewDef(dc->hashVar, rhs)foamNew(FOAM_Def, 2, dc->hashVar, rhs);
1513 gen0AddStmt(set, NULL((void*)0));
1514 dcl = cdr(dcl)((dcl)->rest);
1515 }
1516
1517 gen0State->lines = listNConcat(Foam)(Foam_listPointer->NConcat)(stmts, gen0State->lines);
1518 listFree(DomainCache)(DomainCache_listPointer->Free)(dcl);
1519 gen0DCacheInIssue = false((int) 0);
1520}
1521
1522
1523/*****************************************************************************
1524 *
1525 * :: Foam code generation for (runtime) hash values
1526 *
1527 ****************************************************************************/
1528
1529#define foamNewProgInfo(x)foamNew(FOAM_PRef, 2, 0, foamNew(FOAM_CProg, 1, x)) foamNewPRef(0, foamNewCProg(x))foamNew(FOAM_PRef, 2, 0, foamNew(FOAM_CProg, 1, x))
1530
1531localstatic Foam gen0RtTypeHashAsGeneral (TForm);
1532localstatic Foam gen0RtTypeHashTuple (Sefo, Foam);
1533localstatic Foam gen0RtTypeHashMap (TForm, TForm);
1534localstatic Bool gen0RtSefoIsSpecialOp (AbSyn);
1535localstatic Foam gen0RtSefoHashSpecialExporter (Sefo, Sefo);
1536localstatic Foam gen0RtSefoHashId (Sefo, Sefo);
1537localstatic Foam gen0RtSefoHashApply (Sefo, Sefo);
1538localstatic Foam gen0RtSefoHashStdApply (Sefo, Sefo);
1539localstatic Foam gen0RtSefoHashSpecialApply (Sefo);
1540localstatic Foam gen0RtSefoHashEnum (Sefo, SefoList);
1541localstatic Foam gen0RtSefoHashList (SefoList, SefoList, Foam);
1542localstatic SefoList gen0RtSefoMakeArgList (Sefo);
1543localstatic Foam gen0RtTypeHashAsGeneral (TForm);
1544localstatic Foam gen0RtTypeHashAsGeneralMap (TForm);
1545localstatic void gen0RtUseDeclares (SefoList);
1546localstatic SefoList gen0RtSefoListUnComma (SefoList);
1547localstatic Foam gen0RtIsProgInfoNull (Foam);
1548localstatic Foam gen0RtSefoHashExpr (Sefo, Sefo);
1549
1550Foam
1551gen0RtSetProgHash(Foam clos, AInt hash)
1552{
1553 return foamNewSet(foamNewProgInfo(clos),foamNew(FOAM_Set, 2, foamNew(FOAM_PRef, 2, 0, foamNew(FOAM_CProg
, 1, clos)), foamNew(FOAM_SInt, 1, (AInt)(hash)))
1554 foamNewSInt(hash))foamNew(FOAM_Set, 2, foamNew(FOAM_PRef, 2, 0, foamNew(FOAM_CProg
, 1, clos)), foamNew(FOAM_SInt, 1, (AInt)(hash)))
;
1555}
1556
1557static unsigned long gen0RtArgHashSeed = 74755L;
1558static unsigned long *gen0RtArgHashMask = (unsigned long *)NULL((void*)0);
1559
1560/*
1561 * A trivial random number generator: it doesn't have to be good
1562 * (it isn't), it just has to generate exactly the same sequence
1563 * of pseudo-random numbers on every platform the compiler runs on.
1564 * It returns a 15-bit unsigned number but must be able to perform
1565 * unsigned arithmetic on 27-bit numbers without overflow.
1566 */
1567unsigned long gen0RtRand(void)
1568{
1569 gen0RtArgHashSeed = (gen0RtArgHashSeed*1309L + 13849L) & 65535L;
1570 return gen0RtArgHashSeed;
1571}
1572
1573localstatic void
1574gen0RtInitRand(void)
1575{
1576 gen0RtArgHashSeed = 74755L;
1577}
1578
1579
1580/* Allocate and populate gen0RtArgHashMask */
1581localstatic void
1582gen0RtInitHashMask(void)
1583{
1584 int i;
1585 unsigned long required;
1586
1587 /* Do nothing if already initialised */
1588 if (gen0RtArgHashMask) return;
1589
1590 /* How many bytes of store are needed? */
1591 required = ((int)TF_LIMIT)*sizeof(unsigned long);
1592 gen0RtArgHashMask = (unsigned long *)stoAlloc(int0((int) 0), required);
1593
1594 /* Reset the random number generator */
1595 gen0RtInitRand();
1596
1597 /* Generate a hash mask for each tform type */
1598 for (i = 0; i < TF_LIMIT; i++) gen0RtArgHashMask[i] = gen0RtRand();
1599}
1600
1601localstatic Foam
1602gen0RtTypeHash(TForm tf, TForm otf)
1603{
1604 TFormList tfl = 0, otfl = 0, l, ol;
1605 Foam hash = 0;
1606 int code, i;
1607
1608 if (genIsRuntime()(gen0IsRuntime))
1609 return foamNewSInt(int0)foamNew(FOAM_SInt, 1, (AInt)(((int) 0)));
1610 /* first fill tfl with the tforms we want to combine */
1611 tf = tfDefineeType(tf);
1612 otf = tfDefineeType(otf);
1613
1614 code = gen0StrHash(tformSyntax(tfTag(tf))tformInfoTable[(int)(((tf)->tag)) - (int)TF_START].syntax);
1615
1616 if (tfTag(otf)((otf)->tag) == TF_General && tfTag(tf)((tf)->tag) != TF_General)
1617 return gen0RtTypeHashAsGeneral(tf);
1618
1619 if (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
) {
1620 return gen0RtTypeHashMap(tf, otf);
1621 }
1622
1623 if (tfArgc(otf)((otf)->argc) != tfArgc(tf)((tf)->argc))
1624 otf = tf;
1625
1626 switch (tfTag(otf)((otf)->tag)) {
1627 case TF_Map:
1628 case TF_PackedMap:
1629 bug("Unreachable");
1630 break;
1631 case TF_RawRecord:
1632 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1632); } while (0)
;
1633 for (i = 0; i < tfRawRecordArgc(tf); i++) {
1634 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfRawRecordArgN(tf, i)tfFollowArg(tf, i), tfl);
1635 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfRawRecordArgN(otf, i)tfFollowArg(otf, i), otfl);
1636 }
1637 break;
1638 case TF_Record:
1639 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1639); } while (0)
;
1640 for (i = 0; i < tfRecordArgc(tf); i++) {
1641 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfRecordArgN(tf, i)tfFollowArg(tf, i), tfl);
1642 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfRecordArgN(otf, i)tfFollowArg(otf, i), otfl);
1643 }
1644 break;
1645 case TF_Union:
1646 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1646); } while (0)
;
1647 for (i = 0; i < tfUnionArgc(tf); i++) {
1648 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfUnionArgN(tf, i)tfFollowArg(tf, i), tfl);
1649 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfUnionArgN(otf, i)tfFollowArg(otf, i), otfl);
1650 }
1651 break;
1652 case TF_Cross:
1653 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1653); } while (0)
;
1654 for (i = 0; i < tfCrossArgc(tf); i++) {
1655 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfCrossArgN(tf, i)tfFollowArg(tf, i), tfl);
1656 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfCrossArgN(otf, i)tfFollowArg(otf, i), otfl);
1657 }
1658 break;
1659 case TF_Multiple:
1660 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1660); } while (0)
;
1661 for (i = 0; i < tfMultiArgc(tf); i++) {
1662 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfMultiArgN(tf, i)tfFollowArg(tf, i), tfl);
1663 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfMultiArgN(otf, i)tfFollowArg(otf, i), otfl);
1664 }
1665 break;
1666 case TF_Tuple:
1667 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1667); } while (0)
;
1668 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfTupleArg( tf)tfFollowArg(tf, 0), listNil(TForm)((TFormList) 0));
1669 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfTupleArg(otf)tfFollowArg(otf, 0), listNil(TForm)((TFormList) 0));
1670 break;
1671 case TF_Generator:
1672 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1672); } while (0)
;
1673 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfGeneratorArg( tf)tfFollowArg(tf, 0), listNil(TForm)((TFormList) 0));
1674 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfGeneratorArg(otf)tfFollowArg(otf, 0), listNil(TForm)((TFormList) 0));
1675 break;
1676 case TF_Reference:
1677 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1677); } while (0)
;
1678 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfReferenceArg( tf)tfFollowArg(tf, 0), listNil(TForm)((TFormList) 0));
1679 otfl = listCons(TForm)(TForm_listPointer->Cons)(tfReferenceArg(otf)tfFollowArg(otf, 0), listNil(TForm)((TFormList) 0));
1680 break;
1681 case TF_Enumerate:
1682 assert(tfTag(tf) == tfTag(otf))do { if (!(((tf)->tag) == ((otf)->tag))) _do_assert(("tfTag(tf) == tfTag(otf)"
),"gf_add.c",1682); } while (0)
;
1683 hash = foamNewSInt(code)foamNew(FOAM_SInt, 1, (AInt)(code));
1684 for (i = 0; i < tfEnumArgc(tf); i++) {
1685 String lit;
1686 AbSyn tfi = abDefineeId(tfExpr(tfEnumArgN(tf, i))tfToAbSyn(tfFollowArg(tf, i)));
1687 assert(abTag(tfi) == AB_Id)do { if (!(((tfi)->abHdr.tag) == AB_Id)) _do_assert(("abTag(tfi) == AB_Id"
),"gf_add.c",1687); } while (0)
;
1688 lit = tfi->abId.sym->str;
1689 hash = gen0CombineHash(foamNewSInt(gen0StrHash(lit))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(lit))),
1690 hash);
1691 }
1692 break;
1693 case TF_Literal:
1694 break;
1695
1696 case TF_With:
1697 code = 0;
1698 break;
1699 case TF_General:
1700 hash = gen0RtSefoHash(tfExpr(tf)tfToAbSyn(tf), tfExpr(otf)tfToAbSyn(otf));
1701 default:
1702 break;
1703 }
1704 if (!hash)
1705 hash = foamNewSInt(code)foamNew(FOAM_SInt, 1, (AInt)(code));
1706 tfl = listNReverse(TForm)(TForm_listPointer->NReverse)(tfl);
1707 otfl = listNReverse(TForm)(TForm_listPointer->NReverse)(otfl);
1708
1709 for (i = 0, l = tfl, ol = otfl; l; i++, l = cdr(l)((l)->rest), ol = cdr(ol)((ol)->rest)) {
1710 hash = gen0CombineHash(gen0RtTypeHash(car(l)((l)->first), car(ol)((ol)->first)), hash);
1711 foamPure(hash)((hash)->hdr.info.pure) = true1;
1712 }
1713
1714 return hash;
1715}
1716
1717localstatic Bool
1718tfMapArgIsTuple(TForm tf)
1719{
1720 if (tfMapArgc(tf) != 1)
1721 return false((int) 0);
1722 if (abTUnique(tfExpr(tfMapArg(tf)))((tfToAbSyn(tfFollowArg(tf, 0)))->abHdr.type.unique) == NULL((void*)0))
1723 return false((int) 0);
1724 return tfIsTypeTuple(abTUnique(tfExpr(tfMapArg(tf)))((tfToAbSyn(tfFollowArg(tf, 0)))->abHdr.type.unique));
1725}
1726
1727localstatic Bool
1728tfMapRetIsTuple(TForm tf)
1729{
1730 if (tfMapRetc(tf) != 1)
1731 return false((int) 0);
1732 if (abTUnique(tfExpr(tfMapRet(tf)))((tfToAbSyn(tfFollowArg(tf, 1)))->abHdr.type.unique) == NULL((void*)0))
1733 return false((int) 0);
1734 return tfIsTypeTuple(abTUnique(tfExpr(tfMapRet(tf)))((tfToAbSyn(tfFollowArg(tf, 1)))->abHdr.type.unique));
1735}
1736
1737localstatic Foam
1738gen0RtTypeHashMap(TForm tf, TForm otf)
1739{
1740 int code = gen0StrHash(tformSyntax(tfTag(tf))tformInfoTable[(int)(((tf)->tag)) - (int)TF_START].syntax);
1741 Foam hash, twist;
1742 int i;
1743 assert(tfIsAnyMap(tf))do { if (!(((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
)))) _do_assert(("tfIsAnyMap(tf)"),"gf_add.c",1743); } while (
0)
;
1744 assert(tfIsAnyMap(otf))do { if (!(((((otf)->tag) == TF_Map) || (((otf)->tag) ==
TF_PackedMap)))) _do_assert(("tfIsAnyMap(otf)"),"gf_add.c",1744
); } while (0)
;
1745
1746 if (!gen0RtArgHashMask) gen0RtInitHashMask();
1747
1748 hash = foamNewSInt(code)foamNew(FOAM_SInt, 1, (AInt)(code));
1749
1750 if (tfMapArgIsTuple(tf)) {
1751 hash = gen0RtTypeHashTuple(tfExpr(tfMapArg(tf))tfToAbSyn(tfFollowArg(tf, 0)), hash);
1752 }
1753 else {
1754 TForm otfX = (tfMapArgIsTuple(otf)) ? tf : otf;
1755 for(i=0; i<tfMapArgc(tf); i++) {
1756 TForm ptf = tfMapArgN(tf, i);
1757 TForm potf = tfMapArgN(otfX, i);
1758 Foam val = gen0RtTypeHash(ptf, potf);
1759 hash = gen0CombineHash(val, hash);
1760 foamPure(hash)((hash)->hdr.info.pure) = true1;
1761 }
1762 }
1763 twist = foamNewSInt(gen0RtArgHashMask[tfTag(otf)])foamNew(FOAM_SInt, 1, (AInt)(gen0RtArgHashMask[((otf)->tag
)]))
;
1764 foamPure(twist)((twist)->hdr.info.pure) = true1;
1765
1766 hash = gen0CombineHash(twist, hash);
1767 foamPure(hash)((hash)->hdr.info.pure) = true1;
1768
1769 if (tfMapRetIsTuple(tf)) {
1770 hash = gen0RtTypeHashTuple(tfExpr(tfMapRet(tf))tfToAbSyn(tfFollowArg(tf, 1)), hash);
1771 }
1772 else {
1773 TForm otfX = (tfMapArgIsTuple(otf)) ? tf : otf;
1774 for(i=0; i<tfMapRetc(tf); i++) {
1775 TForm ptf = tfMapRetN(tf, i);
1776 TForm potf = tfMapRetN(otfX, i);
1777 Foam val = gen0RtTypeHash(ptf, potf);
1778 hash = gen0CombineHash(val, hash);
1779 foamPure(hash)((hash)->hdr.info.pure) = true1;
1780 }
1781 }
1782 return hash;
1783}
1784
1785localstatic Foam
1786gen0RtTypeHashAsGeneralMap(TForm tf)
1787{
1788 int code = gen0StrHash(tformSyntax(tfTag(tf))tformInfoTable[(int)(((tf)->tag)) - (int)TF_START].syntax);
1789 Foam hash, twist;
1790 int i;
1791 assert(tfIsAnyMap(tf))do { if (!(((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
)))) _do_assert(("tfIsAnyMap(tf)"),"gf_add.c",1791); } while (
0)
;
1792
1793 if (!gen0RtArgHashMask) gen0RtInitHashMask();
1794
1795 hash = foamNewSInt(code)foamNew(FOAM_SInt, 1, (AInt)(code));
1796
1797 if (tfMapArgIsTuple(tf)) {
1798 hash = gen0RtTypeHashTuple(tfExpr(tfMapArg(tf))tfToAbSyn(tfFollowArg(tf, 0)), hash);
1799 }
1800 else {
1801 for(i=0; i<tfMapArgc(tf); i++) {
1802 TForm ptf = tfMapArgN(tf, i);
1803 Foam val = gen0RtTypeHash(ptf, ptf);
1804 hash = gen0CombineHash(val, hash);
1805 foamPure(hash)((hash)->hdr.info.pure) = true1;
1806 }
1807 }
1808 twist = foamNewSInt(gen0RtArgHashMask[tfTag(tf)])foamNew(FOAM_SInt, 1, (AInt)(gen0RtArgHashMask[((tf)->tag)
]))
;
1809 foamPure(twist)((twist)->hdr.info.pure) = true1;
1810
1811 hash = gen0CombineHash(twist, hash);
1812 foamPure(hash)((hash)->hdr.info.pure) = true1;
1813
1814 if (tfMapRetIsTuple(tf)) {
1815 hash = gen0RtTypeHashTuple(tfExpr(tfMapRet(tf))tfToAbSyn(tfFollowArg(tf, 1)), hash);
1816 }
1817 else {
1818 for(i=0; i<tfMapRetc(tf); i++) {
1819 TForm ptf = tfMapRetN(tf, i);
1820 Foam val = gen0RtTypeHash(ptf, ptf);
1821 hash = gen0CombineHash(val, hash);
1822 foamPure(hash)((hash)->hdr.info.pure) = true1;
1823 }
1824 }
1825 return hash;
1826}
1827
1828
1829/*
1830 * Left as a function, as the hashcode for a TF_With is odd.
1831 */
1832
1833localstatic Foam
1834gen0RtTypeHashWith(TForm tf, TForm otf, String name)
1835{
1836 if (name)
1837 return foamNewSInt(gen0StrHash(name))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(name)));
1838 else
1839 return foamNewSInt(int0)foamNew(FOAM_SInt, 1, (AInt)(((int) 0)));
1840}
1841
1842localstatic Foam
1843gen0RtTypeHashAsGeneral(TForm tf)
1844{
1845 TFormList tfl = listNil(TForm)((TFormList) 0);
1846 Foam hash = NULL((void*)0);
1847 int code, i;
1848
1849 code = gen0StrHash(tformSyntax(tfTag(tf))tformInfoTable[(int)(((tf)->tag)) - (int)TF_START].syntax);
1850
1851 if (tfIsSym(tf)( (((tf)->tag)) < TF_SYM_LIMIT) || tfIsThird(tf)(((tf)->tag) == TF_Third))
1852 return gen0RtSefoHash(tfExpr(tf)tfToAbSyn(tf), tfExpr(tf)tfToAbSyn(tf));
1853
1854 if (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
) {
1855 return gen0RtTypeHashAsGeneralMap(tf);
1856 }
1857
1858 switch(tfTag(tf)((tf)->tag)) {
1859 case TF_Map:
1860 case TF_PackedMap:
1861 bug("unreachable");
1862 break;
1863 case TF_RawRecord:
1864 for (i = 0; i < tfRawRecordArgc(tf); i += 1) {
1865 TForm tfi = tfRawRecordArgN(tf, i)tfFollowArg(tf, i);
1866 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfDefineeType(tfi), tfl);
1867 }
1868 break;
1869 case TF_Record:
1870 for (i = 0; i < tfRecordArgc(tf); i += 1) {
1871 TForm tfi = tfRecordArgN(tf, i)tfFollowArg(tf, i);
1872 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfDefineeType(tfi), tfl);
1873 }
1874 break;
1875 case TF_Union:
1876 for (i = 0; i < tfUnionArgc(tf); i += 1) {
1877 TForm tfi = tfUnionArgN(tf, i)tfFollowArg(tf, i);
1878 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfDefineeType(tfi), tfl);
1879 }
1880 break;
1881 case TF_Cross:
1882 for (i = 0; i < tfCrossArgc(tf); i += 1)
1883 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfCrossArgN(tf, i)tfFollowArg(tf, i), tfl);
1884 break;
1885 case TF_Tuple:
1886 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfTupleArg(tf)tfFollowArg(tf, 0), listNil(TForm)((TFormList) 0));
1887 break;
1888 case TF_Reference:
1889 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfReferenceArg(tf)tfFollowArg(tf, 0), listNil(TForm)((TFormList) 0));
1890 break;
1891 case TF_Generator:
1892 tfl = listCons(TForm)(TForm_listPointer->Cons)(tfGeneratorArg(tf)tfFollowArg(tf, 0), listNil(TForm)((TFormList) 0));
1893 break;
1894 case TF_Enumerate:
1895 hash = foamNewSInt(code)foamNew(FOAM_SInt, 1, (AInt)(code));
1896 for (i = 0; i < tfEnumArgc(tf); i++) {
1897 String lit;
1898 AbSyn tfi = abDefineeId(tfExpr(tfEnumArgN(tf, i))tfToAbSyn(tfFollowArg(tf, i)));
1899 lit = tfi->abId.sym->str;
1900 hash = gen0CombineHash(foamNewSInt(gen0StrHash(lit))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(lit))),
1901 hash);
1902 }
1903 break;
1904 default:
1905 tfPrintDb(tf);
1906 bug("unhandled special type used in value context");
1907 }
1908
1909 tfl = listNReverse(TForm)(TForm_listPointer->NReverse)(tfl);
1910 if (hash == NULL((void*)0))
1911 hash = foamNewSInt(code)foamNew(FOAM_SInt, 1, (AInt)(code));
1912
1913 for(i = 0; tfl; i++, tfl = cdr(tfl)((tfl)->rest)) {
1914 hash = gen0CombineHash(gen0RtTypeHash(car(tfl)((tfl)->first),car(tfl)((tfl)->first)),hash);
1915 foamPure(hash)((hash)->hdr.info.pure) = true1;
1916 }
1917
1918
1919 return hash;
1920}
1921
1922localstatic Foam
1923gen0RtSefoHashExporter(Sefo sf)
1924{
1925 Foam hash, hi;
1926
1927 if (genIsRuntime()(gen0IsRuntime) || sf == NULL((void*)0) || abHasTag(sf, AB_With)((sf)->abHdr.tag == (AB_With)))
1928 return foamNewSInt(int0)foamNew(FOAM_SInt, 1, (AInt)(((int) 0)));
1929
1930 sf = gen0EqualMods(sf);
1931
1932 switch(abTag(sf)((sf)->abHdr.tag)) {
1933 case AB_Id:
1934 hash = foamNewSInt(gen0StrHash(symString(abIdSym(sf))))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(((((sf)->abId.sym
))->str))))
;
1935 break;
1936 case AB_Apply:
1937 if (gen0RtSefoIsSpecialOp(sf))
1938 hash = gen0RtSefoHashSpecialExporter(sf, NULL((void*)0));
1939 else {
1940 Length i;
1941 hash = gen0RtSefoHashExporter(abApplyOp(sf)((sf)->abApply.op));
1942
1943 for (i = 0; i < abApplyArgc(sf)(((sf)->abHdr.argc)-1); i += 1) {
1944 hi = gen0RtSefoHash(abApplyArg(sf, i)((sf)->abApply.argv[i]), NULL((void*)0));
1945 hash = gen0CombineHash(hi, hash);
1946 }
1947 }
1948 break;
1949 case AB_LitInteger:
1950 case AB_LitFloat:
1951 case AB_LitString:
1952 default:
1953 comsgFatal((AbSyn)sf, ALDOR_F_Bug365, "unexpected exporter");
1954 NotReached(hash = 0){(void)bug("Not supposed to reach line %d in file: %s\n",1954
, "gf_add.c");}
;
1955 }
1956
1957 return hash;
1958}
1959
1960/*
1961 * This nonsense is to get the definition of Record(T:Tuple) == add
1962 * to generate the same hash code as the use of Record(A,B,C,D)
1963 */
1964localstatic Bool
1965gen0RtSefoIsSpecialOp(AbSyn ab)
1966{
1967 AbSyn op = abApplyOp(ab)((ab)->abApply.op);
1968 Symbol sym = abIsId(op)((op)->abHdr.tag == (AB_Id)) ? abIdSym(op)((op)->abId.sym) : NULL((void*)0);
1969
1970 return sym == ssymArrow ||
1971 sym == ssymPackedArrow ||
1972 sym == ssymCross ||
1973 sym == ssymRawRecord ||
1974 sym == ssymRecord ||
1975 sym == ssymUnion ||
1976 sym == ssymEnum;
1977}
1978
1979/* Convert special operation into a tform tag */
1980localstatic int
1981gen0RtSymSpecialTag(Symbol sym)
1982{
1983 /* We aren't interested in every special */
1984 if (sym == ssymArrow) return (int)TF_Map;
1985 if (sym == ssymPackedArrow) return (int)TF_PackedMap;
1986 if (sym == ssymCross) return (int)TF_Cross;
1987 if (sym == ssymRawRecord) return (int)TF_RawRecord;
1988 if (sym == ssymRecord) return (int)TF_Record;
1989 if (sym == ssymUnion) return (int)TF_Union;
1990 if (sym == ssymEnum) return (int)TF_START;
1991
1992 /* All other specials are ignored */
1993 return (int)TF_START;
1994}
1995
1996/*
1997 * Generate this code:
1998 *
1999 * Th := hash(operatorString);
2000 * ** for each arg **
2001 * Tt := arg.i;
2002 * Tn := #Tt;
2003 * Ti := 0;
2004 * TS: if (Ti = Tn) goto TE;
2005 * Th := gen0CombineHash(getDomainHash! tuple.i, Th);
2006 * Ti := Ti + 1;
2007 * goto TS
2008 * TE: nop
2009 * ** end for each arg **
2010 * ** genFoamVal is Th **
2011 */
2012
2013#define GSTAT(x)gen0AddStmt(x, ((void*)0)) gen0AddStmt(x, NULL((void*)0))
2014#define GSET(l,r)foamNew(FOAM_Set, 2, foamCopy(l), r) foamNewSet(foamCopy(l),r)foamNew(FOAM_Set, 2, foamCopy(l), r)
2015
2016localstatic Foam
2017gen0RtSefoHashSpecialExporter(Sefo sf, Sefo osf)
2018{
2019 Foam Tt = gen0TempLocal0(FOAM_Rec, gen0MakeTupleFormat());
2020 Foam Tn = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
2021 Foam Ti = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
2022 Foam Th = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
2023 int i;
2024 AbSyn op;
2025 Bool inEnum;
2026
2027 int hashPoint = 0;
2028 int hashMask;
2029 Symbol opsym;
2030 Foam twist = (Foam)NULL((void*)0);
2031
2032 op = abApplyOp(sf)((sf)->abApply.op);
2033 opsym = op->abId.sym;
2034 inEnum = (opsym == ssymEnum);
2035 hashMask = gen0RtSymSpecialTag(opsym);
2036
2037 assert(abTag(sf) == AB_Apply && abTag(abApplyOp(sf)) == AB_Id)do { if (!(((sf)->abHdr.tag) == AB_Apply && ((((sf
)->abApply.op))->abHdr.tag) == AB_Id)) _do_assert(("abTag(sf) == AB_Apply && abTag(abApplyOp(sf)) == AB_Id"
),"gf_add.c",2037); } while (0)
;
2038 /* I don't think we ought to ever see this ... */
2039 if ((opsym == ssymArrow) || (opsym == ssymPackedArrow))
2040 hashPoint = 1; /* Only insert hash mask for maps */
2041
2042 /* Ensure that we have hash masks */
2043 if (!gen0RtArgHashMask) gen0RtInitHashMask();
2044
2045 GSTAT(GSET(Th,foamNewSInt(gen0StrHash(symString(op->abId.sym)))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Th), foamNew(FOAM_SInt
, 1, (AInt)(gen0StrHash(((op->abId.sym)->str))))), ((void
*)0))
;
2046
2047 for (i = 0; i < abApplyArgc(sf)(((sf)->abHdr.argc)-1); i++) {
2048 int TS = gen0State->labelNo++;
2049 int TE = gen0State->labelNo++;
2050 AbSyn arg = abApplyArg(sf, i)((sf)->abApply.argv[i]);
2051 Foam val;
2052
2053 assert(abTag(arg) == AB_Declare)do { if (!(((arg)->abHdr.tag) == AB_Declare)) _do_assert((
"abTag(arg) == AB_Declare"),"gf_add.c",2053); } while (0)
;
2054 arg = arg->abDeclare.id;
2055
2056 GSTAT(GSET(Tt, foamNewCast(FOAM_Rec, genFoamVal(arg))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Tt), foamNew(FOAM_Cast
, 2, FOAM_Rec, genFoamVal(arg))), ((void*)0))
;
2057 GSTAT(GSET(Tn, gen0NewTupleSizeRef(foamCopy(Tt))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Tn), foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(((int) 0)))), ((void*)0))
;
2058 GSTAT(GSET(Ti, foamNewSInt(int0)))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Ti), foamNew(FOAM_SInt
, 1, (AInt)(((int) 0)))), ((void*)0))
;
2059 GSTAT(foamNewLabel(TS))gen0AddStmt(foamNew(FOAM_Label, 1, (AInt)(TS)), ((void*)0));
2060 GSTAT(foamNewIf(foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ,gen0AddStmt(foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ
, foamCopy(Ti), foamCopy(Tn)), TE), ((void*)0))
2061 foamCopy(Ti), foamCopy(Tn)), TE))gen0AddStmt(foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ
, foamCopy(Ti), foamCopy(Tn)), TE), ((void*)0))
;
2062 /* Extra hash code merged in at the correct moment */
2063 if (hashPoint && (i == hashPoint)) {
2064 twist = foamNewSInt(gen0RtArgHashMask[hashMask])foamNew(FOAM_SInt, 1, (AInt)(gen0RtArgHashMask[hashMask]));
2065 GSTAT(GSET(Th, gen0CombineHash(twist, foamCopy(Th))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Th), gen0CombineHash
(twist, foamCopy(Th))), ((void*)0))
;
2066 }
2067 val = foamNewAElt(FOAM_Word,foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(Ti),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(1)))
2068 foamCopy(Ti),foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(Ti),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(1)))
2069 gen0NewTupleValsRef(foamCopy(Tt)))foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(Ti),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(1)))
;
2070 if (inEnum)
2071 val = gen0BuiltinCCall(FOAM_SInt, "stringHash", "runtime", 1,
2072 val);
2073 else
2074 val = gen0RtDomainHash(val);
2075 GSTAT(GSET(Th, gen0CombineHash(val, foamCopy(Th))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Th), gen0CombineHash
(val, foamCopy(Th))), ((void*)0))
;
2076 GSTAT(GSET(Ti, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntPlus,gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Ti), foamNew(FOAM_BCall
, 3, FOAM_BVal_SIntPlus, foamCopy(Ti), foamNew(FOAM_SInt, 1, (
AInt)(1)))), ((void*)0))
2077 foamCopy(Ti), foamNewSInt(1))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Ti), foamNew(FOAM_BCall
, 3, FOAM_BVal_SIntPlus, foamCopy(Ti), foamNew(FOAM_SInt, 1, (
AInt)(1)))), ((void*)0))
;
2078 GSTAT(foamNewGoto(TS))gen0AddStmt(foamNew(FOAM_Goto, 1, (AInt)(TS)), ((void*)0));
2079 GSTAT(foamNewLabel(TE))gen0AddStmt(foamNew(FOAM_Label, 1, (AInt)(TE)), ((void*)0));
2080 }
2081
2082 /* Add a dash of lime if not done so already */
2083 if (!twist && hashPoint) {
2084 twist = foamNewSInt(gen0RtArgHashMask[hashMask])foamNew(FOAM_SInt, 1, (AInt)(gen0RtArgHashMask[hashMask]));
2085 GSTAT(GSET(Th, gen0CombineHash(twist, foamCopy(Th))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Th), gen0CombineHash
(twist, foamCopy(Th))), ((void*)0))
;
2086 }
2087
2088 foamFree(Tt);
2089 foamFree(Ti);
2090 foamFree(Tn);
2091
2092 return Th;
2093}
2094
2095
2096localstatic Foam
2097gen0RtTypeHashTuple(Sefo sefo, Foam init)
2098{
2099 Foam Tt = gen0TempLocal0(FOAM_Rec, gen0MakeTupleFormat());
2100 Foam Tn = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
2101 Foam Ti = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
2102 Foam Th = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
2103 int TS = gen0State->labelNo++;
2104 int TE = gen0State->labelNo++;
2105 Foam val;
2106
2107 sefo = abDefineeTypeOrElse(sefo, sefo);
2108
2109 GSTAT(GSET(Th, init))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Th), init), ((void*
)0))
;
2110
2111 GSTAT(GSET(Tt, foamNewCast(FOAM_Rec, genFoamVal(sefo))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Tt), foamNew(FOAM_Cast
, 2, FOAM_Rec, genFoamVal(sefo))), ((void*)0))
;
2112 GSTAT(GSET(Tn, gen0NewTupleSizeRef(foamCopy(Tt))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Tn), foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(((int) 0)))), ((void*)0))
;
2113 GSTAT(GSET(Ti, foamNewSInt(int0)))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Ti), foamNew(FOAM_SInt
, 1, (AInt)(((int) 0)))), ((void*)0))
;
2114 GSTAT(foamNewLabel(TS))gen0AddStmt(foamNew(FOAM_Label, 1, (AInt)(TS)), ((void*)0));
2115 GSTAT(foamNewIf(foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ,gen0AddStmt(foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ
, foamCopy(Ti), foamCopy(Tn)), TE), ((void*)0))
2116 foamCopy(Ti), foamCopy(Tn)), TE))gen0AddStmt(foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntEQ
, foamCopy(Ti), foamCopy(Tn)), TE), ((void*)0))
;
2117 val = foamNewAElt(FOAM_Word,foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(Ti),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(1)))
2118 foamCopy(Ti),foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(Ti),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(1)))
2119 gen0NewTupleValsRef(foamCopy(Tt)))foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(Ti),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(foamCopy(Tt)),(AInt
)(1)))
;
2120
2121 val = gen0RtDomainHash(val);
2122
2123 GSTAT(GSET(Th, gen0CombineHash(val, foamCopy(Th))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Th), gen0CombineHash
(val, foamCopy(Th))), ((void*)0))
;
2124 GSTAT(GSET(Ti, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntPlus,gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Ti), foamNew(FOAM_BCall
, 3, FOAM_BVal_SIntPlus, foamCopy(Ti), foamNew(FOAM_SInt, 1, (
AInt)(1)))), ((void*)0))
2125 foamCopy(Ti), foamNewSInt(1))))gen0AddStmt(foamNew(FOAM_Set, 2, foamCopy(Ti), foamNew(FOAM_BCall
, 3, FOAM_BVal_SIntPlus, foamCopy(Ti), foamNew(FOAM_SInt, 1, (
AInt)(1)))), ((void*)0))
;
2126 GSTAT(foamNewGoto(TS))gen0AddStmt(foamNew(FOAM_Goto, 1, (AInt)(TS)), ((void*)0));
2127 GSTAT(foamNewLabel(TE))gen0AddStmt(foamNew(FOAM_Label, 1, (AInt)(TE)), ((void*)0));
2128
2129 return Th;
2130}
2131/* extract the hash code from a domain. */
2132
2133localstatic Foam
2134gen0RtDomainHash(Foam dom)
2135{
2136 Foam foam;
2137
2138 foam = gen0BuiltinCCall(FOAM_SInt, "domainHash!", "runtime", 1, dom);
2139 foamPure(foam)((foam)->hdr.info.pure) = true1;
2140 return foam;
2141}
2142
2143localstatic Foam
2144gen0RtSefoHash(Sefo sf, Sefo osf)
2145{
2146 TForm tf;
2147
2148 if (genIsRuntime()(gen0IsRuntime) || sf == NULL((void*)0) || abHasTag(sf, AB_With)((sf)->abHdr.tag == (AB_With)))
2149 return foamNewSInt(int0)foamNew(FOAM_SInt, 1, (AInt)(((int) 0)));
2150
2151 sf = gen0EqualMods(sf);
2152 osf = gen0EqualMods(osf);
2153
2154 tiTopFns()->tiSefo(stabFile(), sf);
2155 tf = gen0AbType(sf);
2156
2157 if (tf && !tfSatDom(tf) && !tfSatCat(tf))
2158 return foamNewSInt(7)foamNew(FOAM_SInt, 1, (AInt)(7));
2159
2160 return gen0RtSefoHashExpr(sf, osf);
2161}
2162
2163localstatic Foam
2164gen0RtSefoHashExpr(Sefo sf, Sefo osf)
2165{
2166 Foam hash;
2167 String msg;
2168
2169 switch(abTag(sf)((sf)->abHdr.tag)) {
2170 case AB_Id:
2171 hash = gen0RtSefoHashId(sf, osf);
2172 break;
2173 case AB_Apply:
2174 hash = gen0RtSefoHashApply(sf, osf);
2175 break;
2176 case AB_Lambda:
2177 default:
2178 msg = "gen0RtSefoHash got wierd type";
2179 comsgFatal((AbSyn)sf, ALDOR_F_Bug365, msg);
2180 NotReached(hash = 0){(void)bug("Not supposed to reach line %d in file: %s\n",2180
, "gf_add.c");}
;
2181 }
2182
2183 return hash;
2184}
2185
2186localstatic Foam
2187gen0RtSefoHashId(Sefo sf, Sefo osf)
2188{
2189 Syme syme = abSyme(sf)((sf)->abHdr.seman ? (sf)->abHdr.seman->syme : 0);
2190 Foam hash;
2191 FoamTag kind = symeFoamKind(syme)((FoamTag) (SYFI_FoamKind < (8 * sizeof(int)) && !
(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->hasmask) & (1 << (SYFI_FoamKind
))) ? (symeFieldInfo[SYFI_FoamKind].def) : (((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_FoamKind))) ?
((((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)
->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_FoamKind))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_FoamKind
)] : (symeFieldInfo[SYFI_FoamKind].def)) : symeGetFieldFn(syme
,SYFI_FoamKind)))
;
2192
2193 /* % --> my hashcode */
2194 if (gen0HasSelf && symeIsSelf(syme)(((syme)->id) == ssymSelf))
2195 hash = gen0RtDomainHash(foamCopy(gen0HasSelf));
2196 else if (gen0ExportState && symeIsSelf(syme)(((syme)->id) == ssymSelf)) {
2197 hash = foamCopy(gen0ExportState->selfHash);
2198 gen0AddLexLevels(hash,
2199 gen0State->foamLevel - gen0ExportState->foamLevel);
2200 }
2201 else if (symeIsSelf(syme)(((syme)->id) == ssymSelf)) {
2202 /*
2203 * This seems to only occur during -gloop. We
2204 * don't actually achieve anything by this since
2205 * gen0Syme will segfault anyway ... The problem
2206 * is that cascaded exports don't get added to
2207 * gen0ExportState properly leaving it NULL.
2208 */
2209 hash = gen0RtDomainHash(foamCopy(gen0Syme(syme)));
2210 if (DEBUG(genfHash)genfHashDebug) {
2211 (void)fprintf(dbOut, "!!! Warning: inventing hash for %%: ");
2212 symePrintDb(syme);
2213 }
2214 }
2215
2216
2217 else if (symeIsImport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Import)
) {
2218 if (kind == FOAM_LIMIT) gen0Syme(syme);
2219 hash = gen0RtDomainHash(genFoamType(sf));
2220 }
2221
2222 else if (symeIsExport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Export)
|| symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
) {
2223 if (kind == FOAM_LIMIT && !symeLib(syme)((syme)->lib)) {
2224 if (DEBUG(genfHash)genfHashDebug) {
2225 fprintf(dbOut, "Ugh: Found unhackable syme: ");
2226 symePrintDb(syme);
2227 }
2228 return foamNewSInt(gen0StrHash(symeString(syme)))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(((((syme)->id))->
str))))
;
2229 }
2230 hash = gen0RtDomainHash(genFoamType(sf));
2231 }
2232 else if (abTForm(sf)((sf)->abHdr.seman ? (sf)->abHdr.seman->tform : 0) && tfIsJavaImport(abTForm(sf)((sf)->abHdr.seman ? (sf)->abHdr.seman->tform : 0))) {
2233 hash = foamNewSInt(gen0StrHash(symeString(syme)))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(((((syme)->id))->
str))))
;
2234 }
2235 else if (kind == FOAM_LIMIT) {
2236 if (DEBUG(genfHash)genfHashDebug) {
2237 fprintf(dbOut, "Ugh: Found weird syme: ");
2238 symePrintDb(syme);
2239 }
2240 hash = foamNewSInt(int0)foamNew(FOAM_SInt, 1, (AInt)(((int) 0)));
2241 }
2242
2243 else if (symeIsParam(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Param)
&&
2244 !stabHasMeaning(gen0State->stab, symeOriginal(syme)))
2245 hash = foamNewSInt(int0)foamNew(FOAM_SInt, 1, (AInt)(((int) 0)));
2246 /* We can cache non-local parameters and lexicals used in types,
2247 providing we are in an add or with clause */
2248 else if (symeIsParam(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Param)
&&
2249 gen0State->tag >= GF_START_TYPE &&
2250 gen0State->tag <= GF_END_TYPE)
2251 hash = gen0DCacheAddItem(HT_Id, syme, NULL((void*)0));
2252 else
2253 hash = gen0RtDomainHash(genFoamType(sf));
2254
2255 return hash;
2256}
2257
2258localstatic Foam
2259gen0RtSefoHashApply(Sefo sf, Sefo osf)
2260{
2261 if (gen0RtSefoIsSpecialOp(sf))
2262 return gen0RtSefoHashSpecialApply(sf);
2263 else if (abTForm(sf)((sf)->abHdr.seman ? (sf)->abHdr.seman->tform : 0) && tfIsJavaImport(abTForm(sf)((sf)->abHdr.seman ? (sf)->abHdr.seman->tform : 0))) {
2264 return foamNewSInt(999)foamNew(FOAM_SInt, 1, (AInt)(999));
2265 }
2266 else
2267 return gen0RtSefoHashStdApply(sf, osf);
2268}
2269
2270localstatic Foam
2271gen0RtSefoHashStdApply(Sefo sf, Sefo osf)
2272{
2273 SefoList sfl = listNil(Sefo)((SefoList) 0), osfl = listNil(Sefo)((SefoList) 0);
2274 AbSyn op = abApplyOp(sf)((sf)->abApply.op);
2275 FoamList topLines;
2276 Foam opFoam, dom, hash;
2277 Foam result = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
2278 int askLabel = gen0State->labelNo++;
2279 int outLabel = gen0State->labelNo++;
2280 Bool flag, buildable;
2281
2282 sfl = gen0RtSefoMakeArgList(sf);
2283
2284 if (osf && abIsApply(osf)((osf)->abHdr.tag == (AB_Apply)))
2285 osfl = gen0RtSefoMakeArgList(osf);
2286
2287 flag = gen0AddImportPlace(&topLines);
2288
2289 /*
2290 * Check to see if all the symes have been classified (their
2291 * kind is believable. Unfortunately this isn't a good test
2292 * of whether a domain can be constructed. Some domains can
2293 * be constructed without having all their symes allocated
2294 * while others can't.
2295 */
2296 buildable = gen0AllSymesAllocated(sf);
2297
2298 opFoam = genFoamType(op);
2299 if (abTag(op)((op)->abHdr.tag) != AB_Id) {
2300 Foam loc = gen0TempLocal(FOAM_Word)gen0TempLocal0(FOAM_Word, 4);
2301 gen0AddStmt(foamNewSet(foamCopy(loc), opFoam)foamNew(FOAM_Set, 2, foamCopy(loc), opFoam), NULL((void*)0));
2302 opFoam = loc;
2303 }
2304
2305 /*
2306 * Force the type to be unlazied: We have to do this
2307 * to avoid creating at least one domain per imported
2308 * constructor. See gen0MakeLazyGlo{Dom,Cat}
2309 */
2310 gen0AddStmt(foamNewEEnsure(foamNewCEnv(foamCopy(opFoam)))foamNew(FOAM_EEnsure, 1, foamNew(FOAM_CEnv, 1, foamCopy(opFoam
)))
,
2311 NULL((void*)0));
2312
2313
2314#if AXL_EDIT_1_1_12p6_14 /* DO NOT ENABLE THIS (see editlevels.h) */
2315 /*
2316 * Always ask unless we can't build: this is because a bug in
2317 * this code means that we peek the hash code from the wrong
2318 * object when given a curried domain. Until this bug is fixed
2319 * we MUST create the domain and ask for its hash code.
2320 */
2321 if (!buildable) {
2322 gen0AddStmt(foamNewIf(gen0RtIsProgInfoNull(opFoam), askLabel)foamNew(FOAM_If, 2, gen0RtIsProgInfoNull(opFoam), askLabel),
2323 NULL((void*)0));
2324 hash = foamNewProgInfo(foamCopy(opFoam))foamNew(FOAM_PRef, 2, 0, foamNew(FOAM_CProg, 1, foamCopy(opFoam
)))
;
2325 hash = gen0RtSefoHashList(sfl, osfl, hash);
2326 gen0AddStmt(foamNewSet(foamCopy(result), hash)foamNew(FOAM_Set, 2, foamCopy(result), hash), NULL((void*)0));
2327 gen0AddStmt(foamNewGoto(outLabel)foamNew(FOAM_Goto, 1, (AInt)(outLabel)), NULL((void*)0));
2328
2329 /* When all else fails, try asking... */
2330 gen0AddStmt(foamNewLabel(askLabel)foamNew(FOAM_Label, 1, (AInt)(askLabel)), NULL((void*)0));
2331 }
2332#else
2333 /*
2334 * If we can read a pre-computed hash code then do so. If we
2335 * cannot then we build the domain and ask it for the hash.
2336 */
2337 gen0AddStmt(foamNewIf(gen0RtIsProgInfoNull(opFoam), askLabel)foamNew(FOAM_If, 2, gen0RtIsProgInfoNull(opFoam), askLabel),
2338 NULL((void*)0));
2339 hash = foamNewProgInfo(foamCopy(opFoam))foamNew(FOAM_PRef, 2, 0, foamNew(FOAM_CProg, 1, foamCopy(opFoam
)))
;
2340 hash = gen0RtSefoHashList(sfl, osfl, hash);
2341 gen0AddStmt(foamNewSet(foamCopy(result), hash)foamNew(FOAM_Set, 2, foamCopy(result), hash), NULL((void*)0));
2342 gen0AddStmt(foamNewGoto(outLabel)foamNew(FOAM_Goto, 1, (AInt)(outLabel)), NULL((void*)0));
2343
2344
2345 /* When all else fails, try asking... */
2346 gen0AddStmt(foamNewLabel(askLabel)foamNew(FOAM_Label, 1, (AInt)(askLabel)), NULL((void*)0));
2347#endif
2348
2349 if (buildable) {
2350 /*
2351 * We assume that this will give us the hash code. Luckily
2352 * if we don't get the hash code then we didn't actually need
2353 * it! This begs the question, why did we ask for it in the
2354 * first place?
2355 */
2356 dom = gen0RtDomainHash(genFoamType(sf));
2357 gen0AddStmt(foamNewSet(foamCopy(result), dom)foamNew(FOAM_Set, 2, foamCopy(result), dom), NULL((void*)0));
2358 }
2359 else {
2360/*
2361 * We ought to generate this compiler warning but it happens
2362 * too often in situations where it may not actually cause
2363 * any problems.
2364 */
2365#if 0
2366 /*
2367 * Issue a compiler warning if we are able to link
2368 * this bit of sefo with some source code.
2369 */
2370 if (abPos((AbSyn)sf)(spstackFirst(((AbSyn)sf)->abHdr.pos)))
2371 comsgWarning((AbSyn)sf, ALDOR_W_ChkBadDependent84);
2372#endif
2373
2374 gen0AddStmt(foamNew(FOAM_BCall, 2,
2375 FOAM_BVal_Halt,
2376 foamNewSInt(FOAM_Halt_BadDependentType)foamNew(FOAM_SInt, 1, (AInt)(FOAM_Halt_BadDependentType))), NULL((void*)0));
2377 gen0AddStmt(foamNewSet(foamCopy(result),foamNew(FOAM_Set, 2, foamCopy(result), foamNew(FOAM_SInt, 1, (
AInt)(((int) 0))))
2378 foamNewSInt(int0))foamNew(FOAM_Set, 2, foamCopy(result), foamNew(FOAM_SInt, 1, (
AInt)(((int) 0))))
, NULL((void*)0));
2379 }
2380
2381 gen0AddStmt(foamNewLabel(outLabel)foamNew(FOAM_Label, 1, (AInt)(outLabel)), NULL((void*)0));
2382 if (flag) gen0ResetImportPlace(topLines);
2383 hash = result;
2384
2385 listFree(Sefo)(Sefo_listPointer->Free)(sfl);
2386 listFree(Sefo)(Sefo_listPointer->Free)(osfl);
2387 return hash;
2388}
2389
2390localstatic Foam
2391gen0RtSefoHashSpecialMap(Sefo sf)
2392{
2393 Sefo arg;
2394 Sefo *argv;
2395 AbSyn op = abApplyOp(sf)((sf)->abApply.op);
2396 Symbol sym = abIdSym(op)((op)->abId.sym);
2397 Foam hash, twist, hi;
2398 int argc;
2399 int i;
2400 int hashMask = gen0RtSymSpecialTag(sym);
2401
2402 /* Ensure that we have hash masks */
2403 if (!gen0RtArgHashMask) gen0RtInitHashMask();
2404
2405 /* Hash the operator ... */
2406 hash = foamNewSInt(gen0StrHash(symString(sym)))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(((sym)->str))));
2407
2408 arg = abApplyArg(sf, int0)((sf)->abApply.argv[((int) 0)]);
2409 argv = abArgvAs(AB_Comma, arg)(((arg)->abHdr.tag == (AB_Comma)) ? ((arg)->abGen.data.
argv) : &(arg))
;
2410 argc = abArgcAs(AB_Comma, arg)(((arg)->abHdr.tag == (AB_Comma)) ? ((arg)->abHdr.argc)
: 1)
;
2411 for (i = 0; i < argc; i++) {
2412 Sefo argi = argv[i];
2413
2414 if (abTag(argi)((argi)->abHdr.tag) != AB_Id)
2415 argi = abDefineeTypeOrElse(argi, argi);
2416 hi = gen0RtSefoHash(argi, (Sefo)NULL((void*)0));
2417 foamPure(hi)((hi)->hdr.info.pure) = true1;
2418 hash = gen0CombineHash(hi, hash);
2419 foamPure(hash)((hash)->hdr.info.pure) = true1;
2420 }
2421 /* Fold in the map hash mask */
2422 twist = foamNewSInt(gen0RtArgHashMask[hashMask])foamNew(FOAM_SInt, 1, (AInt)(gen0RtArgHashMask[hashMask]));
2423 foamPure(twist)((twist)->hdr.info.pure) = true1;
2424 hash = gen0CombineHash(twist, hash);
2425 foamPure(hash)((hash)->hdr.info.pure) = true1;
2426
2427 /* Process the map return types */
2428 arg = abApplyArg(sf, 1)((sf)->abApply.argv[1]);
2429 argv = abArgvAs(AB_Comma, arg)(((arg)->abHdr.tag == (AB_Comma)) ? ((arg)->abGen.data.
argv) : &(arg))
;
2430 argc = abArgcAs(AB_Comma, arg)(((arg)->abHdr.tag == (AB_Comma)) ? ((arg)->abHdr.argc)
: 1)
;
2431 for (i = 0; i < argc; i++) {
2432 Sefo argi = argv[i];
2433
2434 if (abTag(argi)((argi)->abHdr.tag) != AB_Id)
2435 argi = abDefineeTypeOrElse(argi, argi);
2436 hi = gen0RtSefoHash(argi, (Sefo)NULL((void*)0));
2437 foamPure(hi)((hi)->hdr.info.pure) = true1;
2438 hash = gen0CombineHash(hi, hash);
2439 foamPure(hash)((hash)->hdr.info.pure) = true1;
2440 }
2441
2442 return hash;
2443}
2444
2445localstatic Foam
2446gen0RtSefoHashSpecialApply(Sefo sf)
2447{
2448 SefoList sfl = listNil(Sefo)((SefoList) 0);
2449 AbSyn op = abApplyOp(sf)((sf)->abApply.op);
2450 Symbol sym = abIdSym(op)((op)->abId.sym);
2451 Foam hash;
2452 int argc = abApplyArgc(sf)(((sf)->abHdr.argc)-1);
2453 int i;
2454
2455 if (abIsAnyMap(sf)(((((sf)->abHdr.tag == (AB_Apply)) && (((((sf)->
abApply.op))->abHdr.tag == (AB_Id)) && ((((sf)->
abApply.op))->abId.sym)==(ssymArrow))) && (((sf)->
abHdr.argc)-1) == 2) || ((((sf)->abHdr.tag == (AB_Apply)) &&
(((((sf)->abApply.op))->abHdr.tag == (AB_Id)) &&
((((sf)->abApply.op))->abId.sym)==(ssymPackedArrow))) &&
(((sf)->abHdr.argc)-1) == 2))
)
2456 return gen0RtSefoHashSpecialMap(sf);
2457
2458 for (i = 0; i < argc; i += 1)
2459 sfl = listCons(Sefo)(Sefo_listPointer->Cons)(abApplyArg(sf, i)((sf)->abApply.argv[i]), sfl);
2460 sfl = listNReverse(Sefo)(Sefo_listPointer->NReverse)(sfl);
2461
2462 if (sym == ssymEnum)
2463 return gen0RtSefoHashEnum(sf, sfl);
2464
2465 gen0RtUseDeclares(sfl);
2466
2467 hash = foamNewSInt(gen0StrHash(symString(sym)))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(((sym)->str))));
2468 hash = gen0RtSefoHashList(sfl, listNil(Sefo)((SefoList) 0), hash);
2469 listFree(Sefo)(Sefo_listPointer->Free)(sfl);
2470 return hash;
2471}
2472
2473localstatic Foam
2474gen0RtSefoHashEnum(Sefo sf, SefoList sfl)
2475{
2476 AbSyn op = abApplyOp(sf)((sf)->abApply.op);
2477 Symbol sym = abIdSym(op)((op)->abId.sym);
2478 Foam hash, hi;
2479
2480 hash = foamNewSInt(gen0StrHash(symString(sym)))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(((sym)->str))));
2481 for (; sfl; sfl = cdr(sfl)((sfl)->rest)) {
2482 sym = abIdSym(abDefineeId(car(sfl)))((abDefineeId(((sfl)->first)))->abId.sym);
2483 hi = foamNewSInt(gen0StrHash(symString(sym)))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(((sym)->str))));
2484 hash = gen0CombineHash(hi, hash);
2485 }
2486
2487 return hash;
2488}
2489
2490localstatic Foam
2491gen0RtSefoHashList(SefoList sfl, SefoList osfl, Foam hash)
2492{
2493 Sefo sf, osf;
2494
2495 assert(!osfl || listLength(Sefo)(sfl) == listLength(Sefo)(osfl))do { if (!(!osfl || (Sefo_listPointer->_Length)(sfl) == (Sefo_listPointer
->_Length)(osfl))) _do_assert(("!osfl || listLength(Sefo)(sfl) == listLength(Sefo)(osfl)"
),"gf_add.c",2495); } while (0)
;
2496 while (sfl) {
2497 sf = car(sfl)((sfl)->first);
2498 osf = osfl ? car(osfl)((osfl)->first) : NULL((void*)0);
2499
2500 hash = gen0CombineHash(gen0RtSefoHash(sf, osf), hash);
2501 foamPure(hash)((hash)->hdr.info.pure) = true1;
2502
2503 sfl = cdr(sfl)((sfl)->rest);
2504 osfl = osfl ? cdr(osfl)((osfl)->rest) : NULL((void*)0);
2505 }
2506 return hash;
2507}
2508
2509localstatic SefoList
2510gen0RtSefoListUnComma(SefoList sfl)
2511{
2512 SefoList lst = listNil(Sefo)((SefoList) 0);
2513
2514 while (sfl) {
2515 Sefo sf = car(sfl)((sfl)->first);
2516 Sefo *argv = abArgvAs(AB_Comma, sf)(((sf)->abHdr.tag == (AB_Comma)) ? ((sf)->abGen.data.argv
) : &(sf))
;
2517 Length i, argc = abArgcAs(AB_Comma, sf)(((sf)->abHdr.tag == (AB_Comma)) ? ((sf)->abHdr.argc) :
1)
;
2518
2519 for (i = 0; i < argc; i += 1)
2520 lst = listCons(Sefo)(Sefo_listPointer->Cons)(argv[i], lst);
2521 sfl = cdr(sfl)((sfl)->rest);
2522 }
2523 return listNReverse(Sefo)(Sefo_listPointer->NReverse)(lst);
2524}
2525
2526localstatic SefoList
2527gen0RtSefoMakeArgList(Sefo sf)
2528{
2529 SefoList sfl = listNil(Sefo)((SefoList) 0);
2530 TForm opTf = gen0AbType(abApplyOp(sf)((sf)->abApply.op));
2531 int argc = tfMapArgc(opTf);
2532 int i;
2533
2534 for (i = 0; i < argc; i += 1) {
2535 AbSyn sfi = tfMapSelectArg(opTf, sf, i);
2536 sfl = listCons(Sefo)(Sefo_listPointer->Cons)(sfi, sfl);
2537 }
2538 sfl = listNReverse(Sefo)(Sefo_listPointer->NReverse)(sfl);
2539
2540 return sfl;
2541}
2542
2543localstatic void
2544gen0RtUseDeclares(SefoList sfl)
2545{
2546 while (sfl) {
2547 Sefo sf = car(sfl)((sfl)->first);
2548 if (abTag(sf)((sf)->abHdr.tag) != AB_Id)
2549 car(sfl)((sfl)->first) = abDefineeTypeOrElse(sf, sf);
2550 sfl = cdr(sfl)((sfl)->rest);
2551 }
2552}
2553
2554localstatic Foam
2555gen0RtIsProgInfoNull(Foam foam)
2556{
2557 return foamNew(FOAM_BCall, 2, FOAM_BVal_SIntIsZero,
2558 foamNewProgInfo(foam)foamNew(FOAM_PRef, 2, 0, foamNew(FOAM_CProg, 1, foam)));
2559}
2560
2561
2562/* A 28 or 30 bit prime */
2563
2564#define HashModulus(gen0SmallHashCodes ? 0x07FFFFD9 : 0x3FFFFFDD) (gen0SmallHashCodes ? 0x07FFFFD9 : 0x3FFFFFDD)
2565#define ShiftMask0x00FFFFFF 0x00FFFFFF
2566
2567localstatic Foam
2568gen0CombineHash(Foam hash1, Foam hash0)
2569{
2570 Foam bcall;
2571#if 0
2572/*!! use when inlining from callbacks works */
2573 return gen0BuiltinCCall(FOAM_SInt, "combineHash", "runtime",
2574 hash1, hash0);
2575#endif
2576 bcall = foamNew(FOAM_BCall, 3, FOAM_BVal_SIntHashCombine, hash1, hash0);
2577
2578 return bcall;
2579}
2580
2581int
2582gen0StrHash(String s)
2583{
2584 return strHash(s) % HashModulus(gen0SmallHashCodes ? 0x07FFFFD9 : 0x3FFFFFDD);
2585}
2586
2587Foam
2588genWith(AbSyn absyn)
2589{
2590 return gen0MakeDefaultPackage(absyn, abStab(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->stab :
0)
, false((int) 0), NULL((void*)0))
;
1
Assuming field 'seman' is null
2
'?' condition is false
3
Calling 'gen0MakeDefaultPackage'
2591}
2592
2593/*
2594 * Construct calls to Join/Map/Enumeration/Cross/Record/Union.
2595 */
2596Bool
2597gen0IsSpecialType(AbSyn ab)
2598{
2599 AbSyn op = abApplyOp(ab)((ab)->abApply.op);
2600 Symbol sym = abIsId(op)((op)->abHdr.tag == (AB_Id)) ? abIdSym(op)((op)->abId.sym) : NULL((void*)0);
2601
2602 return sym == ssymJoin ||
2603 sym == ssymArrow ||
2604 sym == ssymPackedArrow ||
2605 sym == ssymCross ||
2606 sym == ssymRawRecord ||
2607 sym == ssymRecord ||
2608 sym == ssymUnion ||
2609 sym == ssymEnum;
2610}
2611
2612Foam
2613gen0ApplySpecialType(AbSyn absyn)
2614{
2615 if (abIsJoin(absyn)(((absyn)->abHdr.tag == (AB_Apply)) && (((((absyn)
->abApply.op))->abHdr.tag == (AB_Id)) && ((((absyn
)->abApply.op))->abId.sym)==(ssymJoin)))
)
2616 return gen0Join(absyn);
2617 else if (abIsAnyMap(absyn)(((((absyn)->abHdr.tag == (AB_Apply)) && (((((absyn
)->abApply.op))->abHdr.tag == (AB_Id)) && ((((absyn
)->abApply.op))->abId.sym)==(ssymArrow))) && ((
(absyn)->abHdr.argc)-1) == 2) || ((((absyn)->abHdr.tag ==
(AB_Apply)) && (((((absyn)->abApply.op))->abHdr
.tag == (AB_Id)) && ((((absyn)->abApply.op))->abId
.sym)==(ssymPackedArrow))) && (((absyn)->abHdr.argc
)-1) == 2))
)
2618 return gen0Map(absyn);
2619 else if (abIsApplyOf(absyn, ssymEnum)(((absyn)->abHdr.tag == (AB_Apply)) && (((((absyn)
->abApply.op))->abHdr.tag == (AB_Id)) && ((((absyn
)->abApply.op))->abId.sym)==(ssymEnum)))
)
2620 return gen0Enum(absyn);
2621 else
2622 return gen0ApplySpecialOthers(absyn);
2623}
2624
2625localstatic Foam
2626gen0Join(AbSyn absyn)
2627{
2628 return gen0MakeDefaultPackage(absyn, abStab(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->stab :
0)
, false((int) 0), NULL((void*)0));
2629}
2630
2631localstatic Foam
2632gen0Map(AbSyn absyn)
2633{
2634 Foam opFoam, argFoam, retFoam, foam;
2635 AbSyn arg = abMapArg(absyn)((absyn)->abApply.argv[0]);
2636 AbSyn ret = abMapRet(absyn)((absyn)->abApply.argv[1]);
2637 AbSyn *argv;
2638 Length argc;
2639
2640 argv = abArgvAs(AB_Comma, arg)(((arg)->abHdr.tag == (AB_Comma)) ? ((arg)->abGen.data.
argv) : &(arg))
;
2641 argc = abArgcAs(AB_Comma, arg)(((arg)->abHdr.tag == (AB_Comma)) ? ((arg)->abHdr.argc)
: 1)
;
2642 argFoam = gen0MakeTuple(argc, argv, arg);
2643
2644 argv = abArgvAs(AB_Comma, ret)(((ret)->abHdr.tag == (AB_Comma)) ? ((ret)->abGen.data.
argv) : &(ret))
;
2645 argc = abArgcAs(AB_Comma, ret)(((ret)->abHdr.tag == (AB_Comma)) ? ((ret)->abHdr.argc)
: 1)
;
2646 retFoam = gen0MakeTuple(argc, argv, ret);
2647
2648 opFoam = genFoamVal(abApplyOp(absyn)((absyn)->abApply.op));
2649
2650 foam = foamNew(FOAM_CCall, 4, FOAM_Word, opFoam, argFoam, retFoam);
2651 foamPure(foam)((foam)->hdr.info.pure) = true1;
2652 return foam;
2653}
2654
2655localstatic Foam
2656gen0Enum(AbSyn absyn)
2657{
2658 Foam vars[2], tupl, elts, elt, opFoam, foam;
2659 Length i, argc = abApplyArgc(absyn)(((absyn)->abHdr.argc)-1);
2660 AbSyn *argv = abApplyArgv(absyn)((absyn)->abApply.argv);
2661
2662 gen0MakeEmptyTuple(foamNewSInt(argc)foamNew(FOAM_SInt, 1, (AInt)(argc)), vars, absyn);
2663 tupl = vars[0];
2664 elts = vars[1];
2665
2666 for (i = 0; i < argc; i += 1) {
2667 AbSyn arg = abDefineeId(argv[i]);
2668 elt = foamNewCast(FOAM_Word, gen0CharArray(arg->abId.sym->str))foamNew(FOAM_Cast, 2, FOAM_Word, gen0CharArray(arg->abId.sym
->str))
;
2669 gen0AddStmt(gen0ASet(elts, (AInt) i, FOAM_Word, elt)foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)((AInt) i)),foamCopy(elts)), elt)
, absyn);
2670 }
2671
2672 opFoam = genFoamVal(abApplyOp(absyn)((absyn)->abApply.op));
2673 foam = foamNew(FOAM_CCall, 3, FOAM_Word, opFoam, tupl);
2674 foamPure(foam)((foam)->hdr.info.pure) = true1;
2675 return foam;
2676}
2677
2678/*
2679 * This function is only called when Record() etc are used as values,
2680 * eg on the RHS of a definition. When used as a type constructor the
2681 * functor never actually gets applied.
2682 */
2683localstatic Foam
2684gen0ApplySpecialOthers(AbSyn absyn)
2685{
2686 Foam vars[2], tupl, elts, elt, foam;
2687 Length i, argc = abApplyArgc(absyn)(((absyn)->abHdr.argc)-1);
2688 AbSyn *argv = abApplyArgv(absyn)((absyn)->abApply.argv);
2689 AbSyn op = abApplyOp(absyn)((absyn)->abApply.op);
2690
2691 assert(abIdSym(op) == ssymCross ||do { if (!(((op)->abId.sym) == ssymCross || ((op)->abId
.sym) == ssymRawRecord || ((op)->abId.sym) == ssymRecord ||
((op)->abId.sym) == ssymUnion)) _do_assert(("abIdSym(op) == ssymCross || abIdSym(op) == ssymRawRecord || abIdSym(op) == ssymRecord || abIdSym(op) == ssymUnion"
),"gf_add.c",2694); } while (0)
2692 abIdSym(op) == ssymRawRecord ||do { if (!(((op)->abId.sym) == ssymCross || ((op)->abId
.sym) == ssymRawRecord || ((op)->abId.sym) == ssymRecord ||
((op)->abId.sym) == ssymUnion)) _do_assert(("abIdSym(op) == ssymCross || abIdSym(op) == ssymRawRecord || abIdSym(op) == ssymRecord || abIdSym(op) == ssymUnion"
),"gf_add.c",2694); } while (0)
2693 abIdSym(op) == ssymRecord ||do { if (!(((op)->abId.sym) == ssymCross || ((op)->abId
.sym) == ssymRawRecord || ((op)->abId.sym) == ssymRecord ||
((op)->abId.sym) == ssymUnion)) _do_assert(("abIdSym(op) == ssymCross || abIdSym(op) == ssymRawRecord || abIdSym(op) == ssymRecord || abIdSym(op) == ssymUnion"
),"gf_add.c",2694); } while (0)
2694 abIdSym(op) == ssymUnion)do { if (!(((op)->abId.sym) == ssymCross || ((op)->abId
.sym) == ssymRawRecord || ((op)->abId.sym) == ssymRecord ||
((op)->abId.sym) == ssymUnion)) _do_assert(("abIdSym(op) == ssymCross || abIdSym(op) == ssymRawRecord || abIdSym(op) == ssymRecord || abIdSym(op) == ssymUnion"
),"gf_add.c",2694); } while (0)
;
2695
2696 gen0MakeEmptyTuple(foamNewSInt(argc)foamNew(FOAM_SInt, 1, (AInt)(argc)), vars, absyn);
2697 tupl = vars[0];
2698 elts = vars[1];
2699
2700 for (i = 0; i < argc; i += 1) {
2701 AbSyn arg = abDefineeTypeOrElse(argv[i], argv[i]);
2702
2703 if (gen0AllSymesAllocated(arg))
2704 elt = genFoamType(arg);
2705 else
2706 elt = foamNewNil()foamNew(FOAM_Nil, (int) 0);
2707
2708 gen0AddStmt(gen0ASet(elts, (AInt) i, FOAM_Word, elt)foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)((AInt) i)),foamCopy(elts)), elt)
, absyn);
2709 }
2710
2711 foam = foamNew(FOAM_CCall, 3, FOAM_Word, genFoamVal(op), tupl);
2712 foamPure(foam)((foam)->hdr.info.pure) = true1;
2713 return foam;
2714}
2715
2716/* Return true if we can generate complete foam for 'ab'.
2717 * This should check for formal arguments, symes from
2718 * dependant types, and so on.
2719 * As lazy symbol meanings are handled later (see gen0SymeGeneric),
2720 * we test for and and ignore them here.
2721 */
2722localstatic Bool
2723gen0AllSymesAllocated(AbSyn ab)
2724{
2725 Bool result = true1;
2726
2727 if (abTag(ab)((ab)->abHdr.tag) == AB_Declare)
2728 result = gen0AllSymesAllocated(ab->abDeclare.type);
2729 else if (abIsLeaf(ab)(((ab)->abHdr.tag) < AB_NODE_START)) {
2730 Syme syme = abSyme(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0);
2731
2732 /* Unallocated symes normally cause false return value. */
2733 result = !(syme && gen0FoamKind(syme)((((FoamTag) (SYFI_FoamKind < (8 * sizeof(int)) &&
!(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)
->lib) : ((void*)0)), (syme))->hasmask) & (1 <<
(SYFI_FoamKind))) ? (symeFieldInfo[SYFI_FoamKind].def) : (((
((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->locmask) & (1 << (SYFI_FoamKind
))) ? ((((((syme)->kind == SYME_Trigger ? libGetAllSymes((
syme)->lib) : ((void*)0)), (syme))->locmask) & (1 <<
(SYFI_FoamKind))) ? ((syme)->fieldv)[symeIndex(syme,SYFI_FoamKind
)] : (symeFieldInfo[SYFI_FoamKind].def)) : symeGetFieldFn(syme
,SYFI_FoamKind))) != FOAM_LIMIT) ? ((FoamTag) (SYFI_FoamKind <
(8 * sizeof(int)) && !(((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
hasmask) & (1 << (SYFI_FoamKind))) ? (symeFieldInfo
[SYFI_FoamKind].def) : (((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->locmask) & (1
<< (SYFI_FoamKind))) ? ((((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
locmask) & (1 << (SYFI_FoamKind))) ? ((syme)->fieldv
)[symeIndex(syme,SYFI_FoamKind)] : (symeFieldInfo[SYFI_FoamKind
].def)) : symeGetFieldFn(syme,SYFI_FoamKind))) : ((FoamTag) (
SYFI_FoamKind < (8 * sizeof(int)) && !(((((symeOriginal
(syme))->kind == SYME_Trigger ? libGetAllSymes((symeOriginal
(syme))->lib) : ((void*)0)), (symeOriginal(syme)))->hasmask
) & (1 << (SYFI_FoamKind))) ? (symeFieldInfo[SYFI_FoamKind
].def) : (((((symeOriginal(syme))->kind == SYME_Trigger ? libGetAllSymes
((symeOriginal(syme))->lib) : ((void*)0)), (symeOriginal(syme
)))->locmask) & (1 << (SYFI_FoamKind))) ? ((((((
symeOriginal(syme))->kind == SYME_Trigger ? libGetAllSymes
((symeOriginal(syme))->lib) : ((void*)0)), (symeOriginal(syme
)))->locmask) & (1 << (SYFI_FoamKind))) ? ((symeOriginal
(syme))->fieldv)[symeIndex(symeOriginal(syme),SYFI_FoamKind
)] : (symeFieldInfo[SYFI_FoamKind].def)) : symeGetFieldFn(symeOriginal
(syme),SYFI_FoamKind))))
== FOAM_LIMIT);
2734
2735 if (DEBUG(gfadd)gfaddDebug) {
2736 fprintf(dbOut, "syme [%c]: ", result ? ' ' :
2737 symeLib(syme)((syme)->lib) &&
2738 (symeIsExport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Export)
|| symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
) ?
2739 '-' : '?');
2740 symePrintDb(syme);
2741 }
2742
2743 if (syme && symeLib(syme)((syme)->lib) &&
2744 (symeIsExport(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Export)
|| symeIsExtend(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Extend)
))
2745 result = true1;
2746 }
2747 else {
2748 Length i;
2749 for (i = 0; result && i < abArgc(ab)((ab)->abHdr.argc); i += 1)
2750 result = gen0AllSymesAllocated(abArgv(ab)((ab)->abGen.data.argv)[i]);
2751 }
2752 return result;
2753}
2754
2755/*
2756 * Collect the defaults from the body of a with.
2757 */
2758localstatic AbSyn
2759gen0FindDefaults(AbSyn with)
2760{
2761 Length i;
2762 Length defc = 0;
2763 AbSyn defs = NULL((void*)0), *argv;
2764
2765 if (abTag(with)((with)->abHdr.tag) == AB_Default)
2766 return with;
2767 if (abTag(with)((with)->abHdr.tag) != AB_Sequence)
2768 return abNewNothing(sposNone)abNew(AB_Nothing, sposNone,0 );
2769
2770 argv = with->abSequence.argv;
2771 for (i = 0; i < abArgc(with)((with)->abHdr.argc); i += 1)
2772 if (abTag(argv[i])((argv[i])->abHdr.tag) == AB_Default) {
2773 defs = argv[i];
2774 defc += 1;
2775 }
2776
2777 if (defc == 0)
2778 return abNewNothing(sposNone)abNew(AB_Nothing, sposNone,0 );
2779 if (defc == 1)
2780 return defs;
2781
2782 defs = abNewEmpty(AB_Sequence, defc);
2783 for (i = 0, defc = 0; i < abArgc(with)((with)->abHdr.argc); i += 1)
2784 if (abTag(argv[i])((argv[i])->abHdr.tag) == AB_Default)
2785 abArgv(defs)((defs)->abGen.data.argv)[defc++] = abArgv(argv[i])((argv[i])->abGen.data.argv)[0];
2786
2787 return defs;
2788}
2789
2790/*
2791 * Return the code for the getter function from a domain.
2792 */
2793
2794Foam
2795gen0GetDomain(TForm exporter, int levOffset)
2796{
2797 int i;
2798 String name;
2799 Foam getter, var, decl, ini;
2800
2801 /* if already imported return variable where stored. */
2802 var = gen0SeenImportedDomain(exporter, int0((int) 0));
2803 if (var)
2804 return var;
2805
2806 name = strPrintf("dom");
2807 getter = gen0GetDomainDomain(exporter);
2808
2809 decl = foamNewDecl(FOAM_Word, name, emptyFormatSlot)foamNew(FOAM_Decl,4,(AInt)(FOAM_Word),name, (AInt) (0x7FFF), 4
)
;
2810 i = gen0AddLexNth(decl, int0((int) 0), levOffset);
2811
2812 var = gen0NewLex(levOffset, i);
2813
2814 /* if offsets are the same, then we should not be importing twice */
2815 gen0AddImportedDomain(exporter, foamCopy(var), int0((int) 0));
2816 ini = foamNewDef(foamCopy(var), getter)foamNew(FOAM_Def, 2, foamCopy(var), getter);
2817 gen0SetInitUsage(ini, int0((int) 0));
2818 gen0AddStmt(ini, NULL((void*)0));
2819 return foamCopy(var);
2820}
2821
2822localstatic void
2823gen0AddImportedDomain(TForm exporter, Foam var, AInt level)
2824{
2825 GenFoamState s = gen0NthState(level);
2826 s->domImportList = listCons(TForm)(TForm_listPointer->Cons)(exporter, s->domImportList);
2827 s->domList = listCons(Foam)(Foam_listPointer->Cons)(var, s->domList);
2828}
2829
2830localstatic Foam
2831gen0SeenImportedDomain(TForm dom, AInt level)
2832{
2833 GenFoamState s = gen0NthState(level);
2834 TFormList dl = s->domImportList;
2835 FoamList vl = s->domList;
2836
2837 for(; dl; dl = cdr(dl)((dl)->rest), vl = cdr(vl)((vl)->rest))
2838 if (tfEqual(dom, car(dl)((dl)->first)))
2839 return foamCopy(car(vl)((vl)->first));
2840 return 0;
2841}
2842
2843localstatic Foam
2844gen0GetDomainDomain(TForm exporter)
2845{
2846 return genFoamType(tfExpr(exporter)tfToAbSyn(exporter));
2847}
2848
2849localstatic void
2850gen0SetInitUsage(Foam getter, AInt level)
2851{
2852 SlotUsageList lu;
2853 AIntList ls;
2854
2855 lu = gen0NthState(level)->formatUsage;
2856 ls = gen0NthState(level)->formatStack;
2857 gen0SetUsage(getter, lu, ls);
2858}
2859
2860void
2861gen0SetUsage(Foam foam, SlotUsageList lu, AIntList ls)
2862{
2863 foamIter(foam, arg, gen0SetUsage(*arg, lu, ls)){ { String argf = (foamInfoTable [(int)(((foam)->hdr.tag))
-(int)FOAM_START]).argf; Length _i; for (_i = 0; _i < ((foam
)->hdr.argc); _i++, argf++) { if (*argf == '*') argf--; if
(*argf == 'C') { Foam *arg = (Foam *) ((foam)->foamGen.argv
)+_i; { gen0SetUsage(*arg, lu, ls); }; } } }; }
;
2864 if (foamTag(foam)((foam)->hdr.tag) == FOAM_Lex) {
2865 AInt level = foam->foamLex.level;
2866 while(level > 0) {
2867 assert(ls != 0)do { if (!(ls != 0)) _do_assert(("ls != 0"),"gf_add.c",2867);
} while (0)
;
2868 assert(lu != 0)do { if (!(lu != 0)) _do_assert(("lu != 0"),"gf_add.c",2868);
} while (0)
;
2869 ls = cdr(ls)((ls)->rest);
2870 lu = cdr(lu)((lu)->rest);
2871 level -= 1;
2872 }
2873 assert(ls != 0)do { if (!(ls != 0)) _do_assert(("ls != 0"),"gf_add.c",2873);
} while (0)
;
2874 assert(lu != 0)do { if (!(lu != 0)) _do_assert(("lu != 0"),"gf_add.c",2874);
} while (0)
;
2875 car(lu)((lu)->first) = suFrFormat(car(ls))(((((ls)->first)) << 2) | 2);
2876 }
2877 else if (foamTag(foam)((foam)->hdr.tag) == FOAM_Env) {
2878 AInt level = foam->foamEnv.level;
2879 while(level > 0) {
2880 assert(lu != 0)do { if (!(lu != 0)) _do_assert(("lu != 0"),"gf_add.c",2880);
} while (0)
;
2881 lu = cdr(lu)((lu)->rest);
2882 level -= 1;
2883 }
2884 assert(lu != 0)do { if (!(lu != 0)) _do_assert(("lu != 0"),"gf_add.c",2884);
} while (0)
;
2885 if (car(lu)((lu)->first) == emptyFormatSlot4)
2886 car(lu)((lu)->first) = suFrFormat(envUsedSlot)(((0) << 2) | 2);
2887 }
2888}
2889
2890localstatic AbSyn
2891gen0CollectWithImports(AbSyn with)
2892{
2893 AbSynList lst;
2894 AbSyn base = with->abWith.base;
2895 int i;
2896
2897 lst = gen0CollectAux(with->abWith.within);
2898
2899 if (!lst)
2900 return with->abWith.base;
2901
2902 if (abIsJoin(base)(((base)->abHdr.tag == (AB_Apply)) && (((((base)->
abApply.op))->abHdr.tag == (AB_Id)) && ((((base)->
abApply.op))->abId.sym)==(ssymJoin)))
) {
2903 for (i=abApplyArgc(base)(((base)->abHdr.argc)-1)-1; i >= 0; i--)
2904 lst = listCons(AbSyn)(AbSyn_listPointer->Cons)(abApplyArg(base,i)((base)->abApply.argv[i]), lst);
2905 }
2906 else if (!abIsNothing(base)((base)->abHdr.tag == (AB_Nothing)))
2907 lst = listCons(AbSyn)(AbSyn_listPointer->Cons)(base, lst);
2908
2909 return abNewApplyL(abPos(with), abNewId(sposNone, ssymJoin), lst)abNewOfOpAndList(AB_Apply,(spstackFirst((with)->abHdr.pos)
),abNew(AB_Id, sposNone,1, ssymJoin),lst)
;
2910}
2911
2912localstatic AbSynList
2913gen0CollectAux(AbSyn absyn)
2914{
2915 AbSynList lst = listNil(AbSyn)((AbSynList) 0);
2916 int i;
2917
2918 switch (abTag(absyn)((absyn)->abHdr.tag)) {
2919 case AB_Sequence:
2920 for (i=0; i<abArgc(absyn)((absyn)->abHdr.argc); i++)
2921 lst = listNConcat(AbSyn)(AbSyn_listPointer->NConcat)
2922 (gen0CollectAux(abArgv(absyn)((absyn)->abGen.data.argv)[i]),
2923 lst);
2924 return lst;
2925 case AB_Default:
2926 case AB_Declare:
2927 return listNil(AbSyn)((AbSynList) 0);
2928 case AB_Export:
2929 case AB_Nothing:
2930 case AB_Comma:
2931 return listNil(AbSyn)((AbSynList) 0);
2932 default:
2933 return listCons(AbSyn)(AbSyn_listPointer->Cons)(absyn, lst);
2934 }
2935}
2936
2937/* Has questions */
2938
2939Foam
2940genHas(AbSyn absyn)
2941{
2942 AbSyn dom, cat, lhs, *argv;
2943 SymeList symes = listNil(Syme)((SymeList) 0);
2944 Foam foam, self;
2945 int argc;
2946
2947 assert(abTag(absyn) == AB_Has)do { if (!(((absyn)->abHdr.tag) == AB_Has)) _do_assert(("abTag(absyn) == AB_Has"
),"gf_add.c",2947); } while (0)
;
2948
2949 dom = absyn->abHas.expr;
2950 cat = absyn->abHas.property;
2951
2952 /* should replace with tfSubstHasSelf */
2953 self = gen0Temp(FOAM_Word)gen0Temp0(FOAM_Word, 4);
2954 gen0HasSelf = self;
2955
2956 gen0AddStmt(foamNewSet(self, genFoamVal(dom))foamNew(FOAM_Set, 2, self, genFoamVal(dom)), absyn);
2957
2958 if (abTag(cat)((cat)->abHdr.tag) == AB_With) {
2959 symes = stabGetExportedSymes(abStab(cat)((cat)->abHdr.seman ? (cat)->abHdr.seman->stab : 0));
2960 lhs = gen0CollectWithImports(cat);
2961 }
2962 else
2963 lhs = cat;
2964
2965 if (abIsJoin(lhs)(((lhs)->abHdr.tag == (AB_Apply)) && (((((lhs)->
abApply.op))->abHdr.tag == (AB_Id)) && ((((lhs)->
abApply.op))->abId.sym)==(ssymJoin)))
) {
2966 argc = abApplyArgc(lhs)(((lhs)->abHdr.argc)-1);
2967 argv = abApplyArgv(lhs)((lhs)->abApply.argv);
2968 }
2969 else if (abIsNothing(lhs)((lhs)->abHdr.tag == (AB_Nothing))) {
2970 argc = 0;
2971 argv = NULL((void*)0);
2972 }
2973 else {
2974 argc = 1;
2975 argv = &lhs;
2976 }
2977 if (argc == 0)
2978 foam = foamNewBool(true)foamNew(FOAM_Bool, 1, (AInt)(1));
2979 else if (argc == 1)
2980 foam = gen0HasCat(self, argv[0]);
2981 else
2982 foam = gen0HasJoin(self, argc, argv);
2983
2984 if (symes) {
2985 foam = gen0HasImports(self, symes, foam);
2986 }
2987
2988 gen0HasSelf = NULL((void*)0);
2989 return(foam);
2990}
2991
2992localstatic Foam
2993gen0HasJoin(Foam dom, int argc, AbSyn *argv)
2994{
2995 Foam resultVar = gen0Temp(FOAM_Bool)gen0Temp0(FOAM_Bool, 4);
2996 int falseLabel = gen0State->labelNo++;
2997 int endLabel = gen0State->labelNo++;
2998 int i;
2999
3000 for (i = 0; i < argc ; i++) {
3001 int nextLabel = gen0State->labelNo++;
3002 gen0AddStmt(foamNewIf(gen0HasCatBit(dom, argv[i]), nextLabel)foamNew(FOAM_If, 2, gen0HasCatBit(dom, argv[i]), nextLabel), NULL((void*)0));
3003 gen0AddStmt(foamNewGoto(falseLabel)foamNew(FOAM_Goto, 1, (AInt)(falseLabel)), NULL((void*)0));
3004 gen0AddStmt(foamNewLabel(nextLabel)foamNew(FOAM_Label, 1, (AInt)(nextLabel)), NULL((void*)0));
3005 }
3006 gen0AddStmt(foamNewSet(foamCopy(resultVar), foamNewBool(true))foamNew(FOAM_Set, 2, foamCopy(resultVar), foamNew(FOAM_Bool, 1
, (AInt)(1)))
, NULL((void*)0));
3007 gen0AddStmt(foamNewGoto(endLabel)foamNew(FOAM_Goto, 1, (AInt)(endLabel)), NULL((void*)0));
3008 gen0AddStmt(foamNewLabel(falseLabel)foamNew(FOAM_Label, 1, (AInt)(falseLabel)), NULL((void*)0));
3009 gen0AddStmt(foamNewSet(foamCopy(resultVar), foamNewBool(false))foamNew(FOAM_Set, 2, foamCopy(resultVar), foamNew(FOAM_Bool, 1
, (AInt)(((int) 0))))
, NULL((void*)0));
3010 gen0AddStmt(foamNewLabel(endLabel)foamNew(FOAM_Label, 1, (AInt)(endLabel)), NULL((void*)0));
3011 return resultVar;
3012}
3013
3014localstatic Foam
3015gen0HasCat(Foam dom, AbSyn cat)
3016{
3017 return foamNewCast(FOAM_Word, gen0HasCatBit(dom, cat))foamNew(FOAM_Cast, 2, FOAM_Word, gen0HasCatBit(dom, cat));
3018}
3019
3020localstatic Foam
3021gen0HasCatBit(Foam dom, AbSyn cat)
3022{
3023 Foam foam;
3024 if (DEBUG(genf)genfDebug) {
3025 fprintf(dbOut, "Hash:\n");
3026 sefoPrintDb(cat);
3027 tfPrintDb(abTForm(cat)((cat)->abHdr.seman ? (cat)->abHdr.seman->tform : 0));
3028 }
3029 foam = gen0BuiltinCCall(FOAM_Bool,"domainTestExport!",
3030 "runtime", 3,
3031 foamCopy(dom),
3032 foamNewSInt(gen0StrHash("%%"))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash("%%"))),
3033 gen0SefoHash(cat, cat));
3034 foamPure(foam)((foam)->hdr.info.pure) = true1;
3035 return foam;
3036}
3037
3038localstatic Foam
3039gen0HasImports(Foam dom, SymeList symes, Foam startTest)
3040{
3041 Foam resultVar = gen0Temp(FOAM_Bool)gen0Temp0(FOAM_Bool, 4);
3042 int falseLabel = gen0State->labelNo++;
3043 int startLabel = gen0State->labelNo++;
3044 int endLabel = gen0State->labelNo++;
3045
3046 gen0AddStmt(foamNewIf(startTest, startLabel)foamNew(FOAM_If, 2, startTest, startLabel), NULL((void*)0));
3047 gen0AddStmt(foamNewGoto(falseLabel)foamNew(FOAM_Goto, 1, (AInt)(falseLabel)), NULL((void*)0));
3048 gen0AddStmt(foamNewLabel(startLabel)foamNew(FOAM_Label, 1, (AInt)(startLabel)), NULL((void*)0));
3049
3050 for ( ; symes ; symes = cdr(symes)((symes)->rest)) {
3051 int nextLabel;
3052 assert(symeIsExport(car(symes)))do { if (!((((((((symes)->first))->kind == SYME_Trigger
? libGetAllSymes((((symes)->first))->lib) : ((void*)0)
), (((symes)->first)))->kind) == SYME_Export))) _do_assert
(("symeIsExport(car(symes))"),"gf_add.c",3052); } while (0)
;
3053
3054 nextLabel = gen0State->labelNo++;
3055 gen0AddStmt(foamNewIf(foamNewCast(FOAM_Bool, gen0HasImport(dom, car(symes))),foamNew(FOAM_If, 2, foamNew(FOAM_Cast, 2, FOAM_Bool, gen0HasImport
(dom, ((symes)->first))), nextLabel)
3056 nextLabel)foamNew(FOAM_If, 2, foamNew(FOAM_Cast, 2, FOAM_Bool, gen0HasImport
(dom, ((symes)->first))), nextLabel)
, NULL((void*)0));
3057 gen0AddStmt(foamNewGoto(falseLabel)foamNew(FOAM_Goto, 1, (AInt)(falseLabel)), NULL((void*)0));
3058 gen0AddStmt(foamNewLabel(nextLabel)foamNew(FOAM_Label, 1, (AInt)(nextLabel)), NULL((void*)0));
3059 }
3060 gen0AddStmt(foamNewSet(foamCopy(resultVar), foamNewBool(true))foamNew(FOAM_Set, 2, foamCopy(resultVar), foamNew(FOAM_Bool, 1
, (AInt)(1)))
, NULL((void*)0));
3061 gen0AddStmt(foamNewGoto(endLabel)foamNew(FOAM_Goto, 1, (AInt)(endLabel)), NULL((void*)0));
3062 gen0AddStmt(foamNewLabel(falseLabel)foamNew(FOAM_Label, 1, (AInt)(falseLabel)), NULL((void*)0));
3063 gen0AddStmt(foamNewSet(foamCopy(resultVar), foamNewBool(false))foamNew(FOAM_Set, 2, foamCopy(resultVar), foamNew(FOAM_Bool, 1
, (AInt)(((int) 0))))
, NULL((void*)0));
3064 gen0AddStmt(foamNewLabel(endLabel)foamNew(FOAM_Label, 1, (AInt)(endLabel)), NULL((void*)0));
3065 return resultVar;
3066}
3067
3068localstatic Foam
3069gen0HasImport(Foam dom, Syme syme)
3070{
3071 Foam foam;
3072 TForm tf;
3073 String str = symeString(syme)((((syme)->id))->str);
3074
3075 tf = symeType(syme);
3076
3077 foam = gen0BuiltinCCall(FOAM_Bool, "domainTestExport!",
3078 "runtime", 3,
3079 foamCopy(dom),
3080 foamNewSInt(gen0StrHash(str))foamNew(FOAM_SInt, 1, (AInt)(gen0StrHash(str))),
3081 gen0TypeHash(tf, tf, str));
3082 foamPure(foam)((foam)->hdr.info.pure) = true1;
3083
3084 return foamNewCast(FOAM_Word, foam)foamNew(FOAM_Cast, 2, FOAM_Word, foam);
3085}
3086
3087/*****************************************************************************
3088 *
3089 * :: gen0NameType: Given an exporter, return a name-constuctor
3090 *
3091 ****************************************************************************/
3092
3093localstatic Foam gen0BuildExporterNameFn (AbSyn);
3094
3095localstatic Foam gen0NameType (AbSyn, Bool, Bool);
3096localstatic Foam gen0NameApply (AbSyn, Bool);
3097localstatic Foam gen0NameId (AbSyn, Bool, Bool);
3098localstatic Foam gen0NameTuple (Syme, TForm, Bool);
3099
3100localstatic Foam gen0NameConst (String);
3101localstatic Bool gen0NameIsSingleParam (AbSyn);
3102localstatic Foam gen0NameSingleParam (String, Foam);
3103localstatic Foam gen0NameCombineParts (int argc, Foam *argv);
3104localstatic Foam gen0NamePartFrString (String s);
3105
3106
3107localstatic Foam
3108gen0BuildExporterName(AbSyn exporter)
3109{
3110 if (!exporter)
3111 return gen0NameConst("Anonymous");
3112
3113 else if (abTag(exporter)((exporter)->abHdr.tag) == AB_Id)
3114 return gen0NameConst(symString(exporter->abId.sym)((exporter->abId.sym)->str));
3115
3116 else if (gen0NameIsSingleParam(exporter)) {
3117 AbSyn op = abApplyOp(exporter)((exporter)->abApply.op);
3118 AbSyn arg = abApplyArg(exporter, int0)((exporter)->abApply.argv[((int) 0)]);
3119 return gen0NameSingleParam(symString(op->abId.sym)((op->abId.sym)->str),
3120 genFoamVal(arg));
3121 }
3122 else
3123 return gen0BuildExporterNameFn(exporter);
3124}
3125
3126localstatic Bool
3127gen0NameIsSingleParam(AbSyn exporter)
3128{
3129 TForm tf;
3130
3131 if (!(abIsApply(exporter)((exporter)->abHdr.tag == (AB_Apply)) && abApplyArgc(exporter)(((exporter)->abHdr.argc)-1) == 1))
3132 return false((int) 0);
3133 if (gen0RtSefoIsSpecialOp(exporter))
3134 return false((int) 0);
3135
3136 if (!abIsId(abApplyOp(exporter))((((exporter)->abApply.op))->abHdr.tag == (AB_Id)))
3137 return false((int) 0);
3138
3139 tf = gen0AbType(gen0EqualMods(abApplyArg(exporter, int0)((exporter)->abApply.argv[((int) 0)])));
3140 return tfSatCat(tf) || tfSatDom(tf);
3141}
3142
3143localstatic Foam
3144gen0BuildExporterNameFn(AbSyn exporter)
3145{
3146 GenFoamState saved;
3147 Foam foam, clos;
3148
3149 clos = foamNewClos(foamNewEnv(int0), foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(((int) 0))),
foamNew(FOAM_Const, 1, (AInt)(gen0NumProgs)))
;
3150 foam = gen0ProgInitEmpty(strCopy("addNameFn"), NULL((void*)0));
3151
3152 saved = gen0ProgSaveState(PT_Gener);
3153
3154 gen0AddStmt(foamNewReturn(gen0NameType(exporter, true, false))foamNew(FOAM_Return, 1, gen0NameType(exporter, 1, ((int) 0))), NULL((void*)0));
3155
3156 gen0ProgPushFormat(emptyFormatSlot4);
3157 gen0ProgFiniEmpty(foam, FOAM_Word, int0((int) 0));
3158
3159 gen0AddLexLevels(foam, 1);
3160
3161 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
3162
3163 gen0ProgRestoreState(saved);
3164
3165 return clos;
3166}
3167
3168
3169localstatic Foam
3170gen0NameType(AbSyn ab, Bool atExporter, Bool isEnum)
3171{
3172 Foam foam;
3173 String msg;
3174
3175 ab = gen0EqualMods(ab);
3176
3177 switch(abTag(ab)((ab)->abHdr.tag)) {
3178 case AB_Apply:
3179 foam = gen0NameApply(ab, atExporter);
3180 break;
3181 case AB_Id:
3182 foam = gen0NameId(ab, atExporter, isEnum);
3183 break;
3184 default:
3185 msg = "gen0NameType found unhandled exporter type";
3186 comsgFatal(ab, ALDOR_F_Bug365, msg);
3187 NotReached(foam = 0){(void)bug("Not supposed to reach line %d in file: %s\n",3187
, "gf_add.c");}
;
3188#if 0
3189 printf("unhandled exporter type");
3190 abWrSExpr(dbOut, ab,int0((int) 0));
3191 bug("unhandled exporter type");
3192 foam = gen0NamePartFrString(abPretty(ab));
3193#endif
3194 }
3195 return foam;
3196}
3197
3198localstatic Foam
3199gen0NameApply(AbSyn app, Bool atExporter)
3200{
3201 AbSyn op = app->abApply.op;
3202 Foam foam;
3203 Foam *fmArgv;
3204 Bool isEnum;
3205 int argc = abApplyArgc(app)(((app)->abHdr.argc)-1);
3206 int i;
3207
3208 isEnum = abTag(op)((op)->abHdr.tag) == AB_Id && op->abId.sym == ssymEnum;
3209
3210 fmArgv = (Foam *) stoAlloc(OB_Other0, (1 + argc)*sizeof(Foam));
3211
3212 fmArgv[0] = gen0NameType(op, atExporter, false((int) 0));
3213
3214 for (i=0; i<argc; i++) {
3215 fmArgv[i+1] = gen0NameType(abApplyArg(app, i)((app)->abApply.argv[i]), false((int) 0), isEnum);
3216 }
3217
3218 foam = gen0NameCombineParts(1 + argc, fmArgv);
3219 stoFree(fmArgv);
3220 return foam;
3221}
3222
3223localstatic Foam
3224gen0NameId(AbSyn id, Bool atExporter, Bool isEnum)
3225{
3226 Syme syme;
3227 TForm tf;
3228
3229 Foam foam;
3230 if (atExporter)
3231 return gen0NamePartFrString(symString(id->abId.sym)((id->abId.sym)->str));
3232
3233 syme = abSyme(id)((id)->abHdr.seman ? (id)->abHdr.seman->syme : 0);
3234 tf = symeType(syme);
3235 if (tfSatDom(tf))
3236 foam = gen0BuiltinCCall(FOAM_Word, "domainName", "runtime",
3237 1, genFoamVal(id));
3238 else if (tfIsTuple(tf)(((tf)->tag) == TF_Tuple))
3239 foam = gen0NameTuple(syme, tfTupleArg(tf)tfFollowArg(tf, 0), isEnum);
3240 else if (tfSatCat(tf))
3241 foam = gen0BuiltinCCall(FOAM_Word, "categoryName", "runtime",
3242 1, genFoamVal(id));
3243 else
3244 foam = gen0BuiltinCCall(FOAM_Word, "namePartFrOther",
3245 "runtime", 1, genFoamVal(id));
3246 return foam;
3247}
3248
3249localstatic Foam
3250gen0NameTuple(Syme id, TForm tf, Bool isEnum)
3251{
3252 Foam tuple, n, newarr, foam, refexpr;
3253 Foam t2[2];
3254 int l1 = gen0State->labelNo++;
3255 int l2 = gen0State->labelNo++;
3256
3257 tuple = foamNewCast(FOAM_Rec, gen0Syme(id))foamNew(FOAM_Cast, 2, FOAM_Rec, gen0Syme(id));
3258 n = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
3259
3260 /*
3261 * Generate:
3262 * n := size(tuple);
3263 * t2 := Tuple(n);
3264 * l1:
3265 * n := n - 1;
3266 * if negative? n goto l2;
3267 * t2.n := domainName tuple.n;
3268 * goto l1;
3269 * l2:
3270 * buildName(t2);
3271 */
3272 gen0AddStmt(foamNewSet(foamCopy(n),foamNew(FOAM_Set, 2, foamCopy(n), foamNew(FOAM_RElt,3,(AInt)(
gen0MakeTupleFormat()),foamCopy(tuple),(AInt)(((int) 0))))
3273 gen0NewTupleSizeRef(tuple))foamNew(FOAM_Set, 2, foamCopy(n), foamNew(FOAM_RElt,3,(AInt)(
gen0MakeTupleFormat()),foamCopy(tuple),(AInt)(((int) 0))))
, NULL((void*)0));
3274 gen0MakeEmptyTuple(foamCopy(n), t2, NULL((void*)0));
3275 newarr = t2[1];
3276 gen0AddStmt(foamNewLabel(l1)foamNew(FOAM_Label, 1, (AInt)(l1)), NULL((void*)0));
3277 gen0AddStmt(foamNewSet(foamCopy(n),foamNew(FOAM_Set, 2, foamCopy(n), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntPrev
, foamCopy(n)))
3278 foamNew(FOAM_BCall, 2,foamNew(FOAM_Set, 2, foamCopy(n), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntPrev
, foamCopy(n)))
3279 FOAM_BVal_SIntPrev,foamNew(FOAM_Set, 2, foamCopy(n), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntPrev
, foamCopy(n)))
3280 foamCopy(n)))foamNew(FOAM_Set, 2, foamCopy(n), foamNew(FOAM_BCall, 2, FOAM_BVal_SIntPrev
, foamCopy(n)))
,
3281 NULL((void*)0));
3282 gen0AddStmt(foamNewIf(foamNew(FOAM_BCall, 2, FOAM_BVal_SIntIsNeg,foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 2, FOAM_BVal_SIntIsNeg
, foamCopy(n)), l2)
3283 foamCopy(n)), l2)foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 2, FOAM_BVal_SIntIsNeg
, foamCopy(n)), l2)
, NULL((void*)0));
3284
3285 refexpr = foamNewAElt(FOAM_Word, foamCopy(n),foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(n),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(tuple),(AInt)(1)))
3286 gen0NewTupleValsRef(tuple))foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy(n),foamNew(FOAM_RElt
,3,(AInt)(gen0MakeTupleFormat()),foamCopy(tuple),(AInt)(1)))
;
3287
3288 if (isEnum)
3289 refexpr = gen0BuiltinCCall(FOAM_Word, "namePartFrString",
3290 "runtime",
3291 1, refexpr);
3292 else if (tfSatDom(tf) || tfSatCat(tf))
3293 refexpr = gen0BuiltinCCall(FOAM_Word, "domainName", "runtime",
3294 1, refexpr);
3295 else
3296 refexpr = gen0BuiltinCCall(FOAM_Word, "namePartFrOther",
3297 "runtime", 1, refexpr);
3298
3299 gen0AddStmt(foamNewSet(foamNewAElt(FOAM_Word, foamCopy(n),foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy
(n),foamCopy(newarr)), refexpr)
3300 foamCopy(newarr)), refexpr)foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamCopy
(n),foamCopy(newarr)), refexpr)
,
3301 NULL((void*)0));
3302 gen0AddStmt(foamNewGoto(l1)foamNew(FOAM_Goto, 1, (AInt)(l1)), NULL((void*)0));
3303 gen0AddStmt(foamNewLabel(l2)foamNew(FOAM_Label, 1, (AInt)(l2)), NULL((void*)0));
3304
3305 foam = gen0BuiltinCCall(FOAM_Word, "namePartConcat", "runtime", 2,
3306 foamNewBool(1)foamNew(FOAM_Bool, 1, (AInt)(1)), foamCopy(t2[0]));
3307 foamFree(n);
3308
3309 return foam;
3310}
3311
3312localstatic Foam
3313gen0NameConst(String s)
3314{
3315 return gen0BuiltinCCall(FOAM_Word, "rtConstNameFn", "runtime", 1,
3316 gen0CharArray(s));
3317}
3318
3319localstatic Foam
3320gen0NameSingleParam(String s, Foam foam)
3321{
3322 return gen0BuiltinCCall(FOAM_Word,
3323 "rtSingleParamNameFn", "runtime", 2,
3324 gen0CharArray(s),
3325 foam);
3326}
3327
3328localstatic Foam
3329gen0NameCombineParts(int argc, Foam *argv)
3330{
3331 return gen0BuiltinCCall(FOAM_Word, "namePartConcat", "runtime", 2,
3332 foamNewBool(false)foamNew(FOAM_Bool, 1, (AInt)(((int) 0))),
3333 gen0MakeTupleFromFoam(argc, argv));
3334}
3335
3336localstatic Foam
3337gen0NamePartFrString(String s)
3338{
3339 return gen0BuiltinCCall(FOAM_Word, "namePartFrString",
3340 "runtime", 1, gen0CharArray(s));
3341}
3342
3343/*****************************************************************************
3344 *
3345 * :: Hash<->String value management
3346 *
3347 ****************************************************************************/
3348
3349/* hash values are placed in a table, and it is assumed that collisions never occur
3350 * [get assumes this too]
3351 */
3352static Table gen0StringTable;
3353
3354void
3355gen0StringsInit()
3356{
3357 gen0StringTable = tblNew((TblHashFun) NULL((void*)0), (TblEqFun) NULL((void*)0));
3358}
3359
3360void
3361gen0StringsFini()
3362{
3363 FoamList body;
3364 Foam str1, str2;
3365 Foam int1, int2;
3366 TableIterator iter;
3367 int size = tblSize(gen0StringTable);
3368 int i=0;
3369
3370 if (size == 0) {
3371 tblFree(gen0StringTable);
3372 return;
3373 }
3374 body = gen0State->lines;
3375 gen0State->lines = listNil(Foam)((FoamList) 0);
3376
3377 int1 = gen0TempLocal0(FOAM_Arr, FOAM_Word);
3378 str1 = gen0TempLocal0(FOAM_Arr, FOAM_Word);
3379
3380 gen0AddStmt(gen0ANew(int1, FOAM_Word, size)foamNew(FOAM_Set, 2, foamCopy(int1), foamNew(FOAM_ANew, 2, FOAM_Word
, foamNew(FOAM_SInt, 1, (AInt)(size))))
, NULL((void*)0));
3381 gen0AddStmt(gen0ANew(str1, FOAM_Word, size)foamNew(FOAM_Set, 2, foamCopy(str1), foamNew(FOAM_ANew, 2, FOAM_Word
, foamNew(FOAM_SInt, 1, (AInt)(size))))
, NULL((void*)0));
3382
3383 for (tblITER(iter, gen0StringTable)_tblITER(&(iter), gen0StringTable); tblMORE(iter)((iter).curr <= (iter).last); tblSTEP(iter)((((iter).link=(iter).link->next))==0 ? _tblSTEP(&(iter
)) : 1)
) {
3384 gen0AddStmt(gen0ASet(int1, i, FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(int1)), foamNew(FOAM_Cast,
2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt)((AInt) ((iter).link
->key)))))
3385 foamNewCast(FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(int1)), foamNew(FOAM_Cast,
2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt)((AInt) ((iter).link
->key)))))
3386 foamNewSInt((AInt) tblKEY(iter))))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(int1)), foamNew(FOAM_Cast,
2, FOAM_Word, foamNew(FOAM_SInt, 1, (AInt)((AInt) ((iter).link
->key)))))
, NULL((void*)0));
3387 gen0AddStmt(gen0ASet(str1, i, FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(str1)), foamNew(FOAM_Cast,
2, FOAM_Word, gen0CharArray((String) ((iter).link->elt)))
)
3388 foamNewCast(FOAM_Word,foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(str1)), foamNew(FOAM_Cast,
2, FOAM_Word, gen0CharArray((String) ((iter).link->elt)))
)
3389 gen0CharArray((String) tblELT(iter))))foamNew(FOAM_Set, 2, foamNew(FOAM_AElt,3,(AInt)(FOAM_Word),foamNew
(FOAM_SInt, 1, (AInt)(i)),foamCopy(str1)), foamNew(FOAM_Cast,
2, FOAM_Word, gen0CharArray((String) ((iter).link->elt)))
)
,
3390 NULL((void*)0));
3391 i++;
3392 }
3393 int2 = gen0MakeArray(foamNewSInt(size)foamNew(FOAM_SInt, 1, (AInt)(size)), int1, NULL((void*)0));
3394 str2 = gen0MakeArray(foamNewSInt(size)foamNew(FOAM_SInt, 1, (AInt)(size)), str1, NULL((void*)0));
3395
3396 gen0AddStmt(gen0BuiltinCCall(FOAM_NOp, "rtAddStrings", "runtime",
3397 2,
3398 foamNewCast(FOAM_Word, int2)foamNew(FOAM_Cast, 2, FOAM_Word, int2),
3399 foamNewCast(FOAM_Word, str2)foamNew(FOAM_Cast, 2, FOAM_Word, str2)), NULL((void*)0));
3400
3401 gen0State->lines = listNConcat(Foam)(Foam_listPointer->NConcat)(body, gen0State->lines);
3402
3403 tblFree(gen0StringTable);
3404}
3405
3406localstatic void
3407gen0StrRegister(int hash, String s)
3408{
3409 tblSetElt(gen0StringTable, (TblKey) (long) hash, (TblElt) s);
3410}
3411