Bug Summary

File:src/gf_gener.c
Warning:line 328, column 2
Value stored to 'type' is never read

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_gener.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_gener.c
1/*****************************************************************************
2 *
3 * gf_gener.c: Foam code generation for generators.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9#include "fluid.h"
10#include "genfoam.h"
11#include "gf_util.h"
12#include "gf_prog.h"
13#include "gf_gener.h"
14#include "of_inlin.h"
15#include "of_util.h"
16#include "optinfo.h"
17#include "store.h"
18#include "tform.h"
19#include "comsg.h"
20#include "util.h"
21
22#define GenerBetterGuesses
23
24typedef struct GenBoundCalc *GenBoundCalc;
25typedef struct GenerGenInfo *GenerGenInfo;
26
27localstatic Foam gen0GenerBodyFun (AbSyn, TForm);
28localstatic Foam gen0GenerSelect (int);
29localstatic Foam gen0GenerDoneFun (void);
30localstatic Foam gen0GenerStepFun (AbSyn, TForm);
31localstatic Foam gen0GenerValueFun (FoamTag, TForm);
32localstatic Foam gen0GenerBoundFun (AbSyn, GenBoundCalc);
33localstatic Foam gen0MakeGenerVars (TForm);
34localstatic Foam gen0GetGenerVar (Foam env, int id);
35
36#ifdef GenerBetterGuesses
37localstatic GenBoundCalc gen0MakeBoundInit(AbSyn);
38localstatic Foam gen0ComputeBoundFunction(GenBoundCalc);
39localstatic void gen0ComputeGeners(void);
40#endif
41
42static Foam gen0GenVars;
43static GenerGenInfo gen0GenInfo;
44
45#define gen0RetFormatSize4 4
46static String gen0RetFormatNames[] = { "done?", "step!", "value", "bound" };
47static FoamTag gen0RetFormatTypes[] = { FOAM_Clos, FOAM_Clos, FOAM_Clos, FOAM_Clos };
48static AInt gen0RetFormatFmts[] = { emptyFormatSlot4, emptyFormatSlot4,
49 emptyFormatSlot4, emptyFormatSlot4};
50
51#define yieldDoneLoc0 0
52#define yieldPlaceLoc1 1
53#define yieldValueLoc2 2
54
55#define yieldDoneVargen0GetGenerVar(gen0GenVars, 0) gen0GetGenerVar(gen0GenVars, yieldDoneLoc0)
56#define yieldPlaceVargen0GetGenerVar(gen0GenVars, 1) gen0GetGenerVar(gen0GenVars, yieldPlaceLoc1)
57#define yieldValVargen0GetGenerVar(gen0GenVars, 2) gen0GetGenerVar(gen0GenVars, yieldValueLoc2)
58
59#define stepperFName()("generStepper") ("generStepper")
60#define doneFName()("generDone?") ("generDone?")
61#define boundFName()("generBound") ("generBound")
62#define valueFName()("generValue") ("generValue")
63
64#define boundPlace3 3
65
66/*
67 * Generate code for a yield.
68 */
69
70Foam
71gen0Yield(AbSyn absyn)
72{
73 /* set the place variable */
74 gen0AddStmt(foamNewSet(yieldPlaceVar,foamNew(FOAM_Set, 2, gen0GetGenerVar(gen0GenVars, 1), foamNew
(FOAM_SInt, 1, (AInt)(++gen0State->yieldCount)))
75 foamNewSInt(++gen0State->yieldCount))foamNew(FOAM_Set, 2, gen0GetGenerVar(gen0GenVars, 1), foamNew
(FOAM_SInt, 1, (AInt)(++gen0State->yieldCount)))
, absyn);
76 gen0AddStmt(foamNewSet(foamCopy(gen0State->yieldValueVar),foamNew(FOAM_Set, 2, foamCopy(gen0State->yieldValueVar), genFoamVal
(absyn->abYield.value))
77 genFoamVal(absyn->abYield.value))foamNew(FOAM_Set, 2, foamCopy(gen0State->yieldValueVar), genFoamVal
(absyn->abYield.value))
, absyn);
78 gen0AddStmt(foamNewGoto(gen0State->yieldPlace)foamNew(FOAM_Goto, 1, (AInt)(gen0State->yieldPlace)), absyn);
79
80 gen0AddStmt(foamNewLabel(gen0State->labelNo)foamNew(FOAM_Label, 1, (AInt)(gen0State->labelNo)), absyn);
81 gen0State->yieldLabels = listCons(AInt)(AInt_listPointer->Cons)(gen0State->labelNo++,
82 gen0State->yieldLabels);
83 return 0;
84}
85
86/*
87 * Generate a generator body (a body containing yields)
88 */
89
90Foam
91gen0Generate(AbSyn iter)
92{
93 foamProgUnsetLeaf(gen0State->program)((gen0State->program)->foamProg.infoBits &= ~(1 <<
1))
;
94 return gen0GenerBodyFun(iter, tfGeneratorArg(gen0AbType(iter))tfFollowArg(gen0AbType(iter), 0));
95}
96
97/*
98 * generate the code for the first level of a generator function.
99 */
100
101localstatic Foam
102gen0GenerBodyFun(AbSyn iter, TForm tf)
103{
104 Scope("genBody0")String scopeName = ("genBody0"); int fluidLevel0 = (scopeLevel
++, fluidLevel)
;
105 FoamList topLines;
106 Bool flag;
107 GenerGenInfo fluid(gen0GenInfo)fluidSave_gen0GenInfo = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(gen0GenInfo
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_gen0GenInfo
, fluidStack[fluidLevel].size = sizeof(gen0GenInfo), fluidLevel
++, (gen0GenInfo) )
;
108 GenBoundCalc calc = NULL((void*)0);
109 AbSyn body = iter->abGenerate.body;
110 AbSyn bound = iter->abGenerate.count;
111 FoamTag retType = gen0Type(tf, NULL((void*)0));
112 Foam fluid(gen0GenVars)fluidSave_gen0GenVars = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(gen0GenVars
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_gen0GenVars
, fluidStack[fluidLevel].size = sizeof(gen0GenVars), fluidLevel
++, (gen0GenVars) )
;
113
114 GenFoamState saved;
115 Foam foam, clos, stmt;
116 Foam done, step, bnd, value;
117
118 gen0GenInfo = NULL((void*)0);
119#ifdef GenerBetterGuesses
120 if (!bound || abTag(bound)((bound)->abHdr.tag) == AB_Nothing) {
121 calc = gen0MakeBoundInit(body);
122 gen0ComputeGeners();
123 }
124#endif
125 flag = gen0AddImportPlace(&topLines);
126
127 clos = gen0ProgClosEmpty();
128 foam = gen0ProgInitEmpty("generBaseFn", body);
129
130 saved = gen0ProgSaveState(PT_Gener);
131
132 gen0GenVars = gen0MakeGenerVars(tf);
133
134 step = gen0GenerStepFun(body, tf);
135 done = gen0GenerDoneFun();
136 value = gen0GenerValueFun(retType, tf);
137 bnd = gen0GenerBoundFun(bound, calc);
138
139 stmt = foamNewReturn(foamNew(FOAM_Values, 4, done, step, value, bnd))foamNew(FOAM_Return, 1, foamNew(FOAM_Values, 4, done, step, value
, bnd))
;
140 gen0AddStmt(stmt, body);
141
142 gen0UseStackedFormat(int0((int) 0));
143 gen0ProgPushFormat(int0((int) 0));
144 gen0ProgFiniEmpty(foam, FOAM_NOp, int0((int) 0));
145 foam->foamProg.format = gen0MakeGenerRetFormat();
146
147 gen0AddLexLevels(foam, 1);
148
149 foam->foamProg.infoBits = IB_SIDE(1 << 0) | IB_INLINEME(1 << 4);
150 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
151
152 if (gen0GenInfo) stoFree(gen0GenInfo);
153
154 gen0ProgRestoreState(saved);
155
156 if (flag) gen0ResetImportPlace(topLines);
157
158 stmt = foamNewSet(yieldPlaceVar, foamNewSInt(int0))foamNew(FOAM_Set, 2, gen0GetGenerVar(gen0GenVars, 1), foamNew
(FOAM_SInt, 1, (AInt)(((int) 0))))
;
159 gen0AddStmt(stmt, iter);
160
161 foamFree(gen0GenVars);
162 gen0GenVars = NULL((void*)0);
163
164 Return(clos){ fluidUnwind(fluidLevel0, ((int) 0)); return clos;; };
165}
166
167/*
168 * Generate the code for the second level of a generator function.
169 */
170
171localstatic Foam
172gen0GenerStepFun(AbSyn body, TForm tf)
173{
174 GenFoamState saved;
175 Foam foam, clos, tmp;
176 FoamTag yieldType;
177 AInt startLabel;
178 AInt fmtSlot;
179 clos = foamNewClos(foamNewEnv(-1), foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(-1)), foamNew
(FOAM_Const, 1, (AInt)(gen0NumProgs)))
;
180 foam = gen0ProgInitEmpty(stepperFName()("generStepper"), body);
181
182 saved = gen0ProgSaveState(PT_Gener);
183
184 startLabel = gen0State->labelNo++;
185 gen0State->yieldPlace = gen0State->labelNo++;
186
187 tf = tfDefineeType(tf);
188 yieldType = gen0Type(tf, &fmtSlot);
189
190 gen0State->yieldValueVar = gen0TempLocal0(yieldType, fmtSlot);
191
192 tmp = foamNewNOp()foamNew(FOAM_NOp, (int) 0);
193 gen0AddStmt(tmp, NULL((void*)0)); /* filled by gen0GenerSelect */
194 gen0AddStmt(foamNewLabel(startLabel)foamNew(FOAM_Label, 1, (AInt)(startLabel)), NULL((void*)0));
195 gen0AddStmt(foamNewSet(yieldDoneVar, foamNewBool(int0))foamNew(FOAM_Set, 2, gen0GetGenerVar(gen0GenVars, 0), foamNew
(FOAM_Bool, 1, (AInt)(((int) 0))))
, NULL((void*)0));
196 genFoamStmt(body);
197 gen0AddStmt(foamNewSet(yieldDoneVar, foamNewBool(1))foamNew(FOAM_Set, 2, gen0GetGenerVar(gen0GenVars, 0), foamNew
(FOAM_Bool, 1, (AInt)(1)))
, NULL((void*)0));
198 gen0AddStmt(foamNewReturn(foamNew(FOAM_Values, int0))foamNew(FOAM_Return, 1, foamNew(FOAM_Values, ((int) 0))), NULL((void*)0));
199 gen0AddStmt(foamNewLabel(gen0State->yieldPlace)foamNew(FOAM_Label, 1, (AInt)(gen0State->yieldPlace)), NULL((void*)0));
200 gen0AddStmt(foamNewSet(yieldValVar, gen0State->yieldValueVar)foamNew(FOAM_Set, 2, gen0GetGenerVar(gen0GenVars, 2), gen0State
->yieldValueVar)
, NULL((void*)0));
201 gen0AddStmt(foamNewReturn(foamNew(FOAM_Values, int0))foamNew(FOAM_Return, 1, foamNew(FOAM_Values, ((int) 0))), NULL((void*)0));
202
203 gen0UseStackedFormat(int0((int) 0));
204 gen0ProgPushFormat(emptyFormatSlot4);
205 gen0ProgPushFormat(emptyFormatSlot4);
206 gen0ProgFiniEmpty(foam, FOAM_NOp, int0((int) 0));
207
208 /* fill in the select statement */
209 foam->foamProg.body->foamSeq.argv[0] = gen0GenerSelect(startLabel);
210 foamFree(tmp);
211 gen0AddLexLevels(foam, 2);
212
213 foam->foamProg.infoBits = IB_SIDE(1 << 0) | IB_INLINEME(1 << 4);
214 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(gen0State->stab, foam, NULL((void*)0), true1);
215
216 gen0ProgRestoreState(saved);
217 return clos;
218}
219
220/*
221 * Generate the select statement for generator body dispatching.
222 */
223
224localstatic Foam
225gen0GenerSelect(int startLabel)
226{
227 Foam select = foamNewEmpty(FOAM_Select, gen0State->yieldCount+2);
228 int i;
229
230 select->foamSelect.op = yieldPlaceVargen0GetGenerVar(gen0GenVars, 1);
231 gen0State->yieldLabels = listNReverse(AInt)(AInt_listPointer->NReverse)(gen0State->yieldLabels);
232 select->foamSelect.argv[0] = startLabel;
233 for(i=1;
234 i <= gen0State->yieldCount;
235 i++, gen0State->yieldLabels = cdr(gen0State->yieldLabels)((gen0State->yieldLabels)->rest))
236 select->foamSelect.argv[i] = car(gen0State->yieldLabels)((gen0State->yieldLabels)->first);
237 return select;
238}
239
240/*
241 * Make the lexical environment for a generator.
242 */
243
244localstatic Foam
245gen0MakeGenerVars(TForm retType)
246{
247 Foam done, place, value;
248 FoamTag type;
249 AInt fmt;
250
251 done = gen0Temp(FOAM_Bool)gen0Temp0(FOAM_Bool, 4);
252 place = gen0Temp(FOAM_SInt)gen0Temp0(FOAM_SInt, 4);
253 /* multi-valued gens not supported yet */
254 type = gen0Type(retType, &fmt);
255 assert(!tfIsMulti(retType))do { if (!(!(((retType)->tag) == TF_Multiple))) _do_assert
(("!tfIsMulti(retType)"),"gf_gener.c",255); } while (0)
;
256 value = gen0Temp0(type, fmt);
257
258 return foamNew(FOAM_Values, 3, done, place, value);
259}
260
261localstatic Foam
262gen0GetGenerVar(Foam env, int id)
263{
264 return foamCopy(env->foamValues.argv[id]);
265}
266
267AInt
268gen0MakeGenerRetFormat()
269{
270 if (gen0GenerRetFormat) return gen0GenerRetFormat;
271
272 gen0GenerRetFormat = gen0StdDeclFormat(gen0RetFormatSize4, gen0RetFormatNames,
273 gen0RetFormatTypes, gen0RetFormatFmts);
274 gen0SetDDeclUsage(gen0GenerRetFormat, FOAM_DDecl_Multi);
275 return gen0GenerRetFormat;
276}
277
278localstatic Foam
279gen0GenerDoneFun()
280{
281 return gen0BuildFunFromFoam(doneFName()("generDone?"), FOAM_Bool, yieldDoneVargen0GetGenerVar(gen0GenVars, 0));
282}
283
284localstatic Foam
285gen0GenerBoundFun(AbSyn bound, GenBoundCalc calc)
286{
287 if (calc)
288 return gen0ComputeBoundFunction(calc);
289 else if (!bound || abTag(bound)((bound)->abHdr.tag) == AB_Nothing)
290 return gen0BuildFunFromFoam(boundFName()("generBound"), FOAM_SInt,
291 foamNewSInt(-1)foamNew(FOAM_SInt, 1, (AInt)(-1)));
292 else {
293 GenFoamState saved;
294 Foam foam, clos, ret;
295
296 clos = foamNewClos(foamNewEnv(-1), foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(-1)), foamNew
(FOAM_Const, 1, (AInt)(gen0NumProgs)))
;
297 foam = gen0ProgInitEmpty(boundFName()("generBound"), bound);
298
299 saved = gen0ProgSaveState(PT_ExFn);
300
301 ret = genFoamVal(bound);
302 if (ret) gen0AddStmt(foamNewReturn(ret)foamNew(FOAM_Return, 1, ret), bound);
303
304 gen0UseStackedFormat(int0((int) 0));
305 gen0ProgPushFormat(emptyFormatSlot4);
306 gen0ProgPushFormat(emptyFormatSlot4);
307 gen0ProgFiniEmpty(foam, gen0Type(gen0AbType(bound), NULL((void*)0)), int0((int) 0));
308
309 gen0AddLexLevels(foam, 2);
310
311 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
312
313 foam->foamProg.infoBits |= IB_INLINEME(1 << 4);
314
315 gen0ProgRestoreState(saved);
316 return clos;
317 }
318}
319
320localstatic Foam
321gen0GenerValueFun(FoamTag retType, TForm tf)
322{
323 GenFoamState saved;
324 Foam foam, clos;
325 AInt fmt;
326 FoamTag type;
327
328 type = gen0Type(tf, &fmt);
Value stored to 'type' is never read
329 clos = foamNewClos(foamNewEnv(-1), foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(-1)), foamNew
(FOAM_Const, 1, (AInt)(gen0NumProgs)))
;
330 foam = gen0ProgInitEmpty(valueFName()("generValue"), NULL((void*)0));
331
332 saved = gen0ProgSaveState(PT_Gener);
333
334 gen0AddStmt(foamNewReturn(foamNewCast(FOAM_Word, yieldValVar))foamNew(FOAM_Return, 1, foamNew(FOAM_Cast, 2, FOAM_Word, gen0GetGenerVar
(gen0GenVars, 2)))
, NULL((void*)0));
335
336 gen0UseStackedFormat(int0((int) 0));
337 gen0ProgPushFormat(emptyFormatSlot4);
338 gen0ProgPushFormat(emptyFormatSlot4);
339 gen0ProgFiniEmpty(foam, FOAM_Word, emptyFormatSlot4);
340
341 gen0AddLexLevels(foam, 2);
342
343 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0));
344
345 gen0ProgRestoreState(saved);
346 return clos;
347}
348
349/******************************************************************************
350 *
351 * :: Lifting free generators, and computing bounds
352 *
353 *****************************************************************************/
354
355DECLARE_LIST(GenBoundCalc)typedef struct GenBoundCalcListCons { GenBoundCalc first; struct
GenBoundCalcListCons *rest; } *GenBoundCalcList; struct GenBoundCalc_listOpsStruct
{ GenBoundCalcList (*Cons) (GenBoundCalc, GenBoundCalcList);
GenBoundCalcList (*Singleton) (GenBoundCalc); GenBoundCalcList
(*List) (int n, ...); GenBoundCalcList (*Listv) (va_list argp
); GenBoundCalcList (*ListNull) (GenBoundCalc, ...); Bool (*Equal
) (GenBoundCalcList, GenBoundCalcList, Bool (*f) (GenBoundCalc
, GenBoundCalc)); GenBoundCalc (*Find) (GenBoundCalcList, GenBoundCalc
, Bool(*eq)(GenBoundCalc,GenBoundCalc) , int *); GenBoundCalc
(*Match) (GenBoundCalcList, void *, Bool(*match)(GenBoundCalc
, void *), int *); GenBoundCalcList (*MatchAll) (GenBoundCalcList
, void *, Bool(*match)(GenBoundCalc, void *)); GenBoundCalcList
(*FreeCons) (GenBoundCalcList); void (*Free) (GenBoundCalcList
); GenBoundCalcList (*FreeTo) (GenBoundCalcList, GenBoundCalcList
); void (*FreeDeeply) (GenBoundCalcList, void (*f)(GenBoundCalc
)); GenBoundCalcList (*FreeDeeplyTo) (GenBoundCalcList, GenBoundCalcList
, void (*f) (GenBoundCalc) ); GenBoundCalcList (*FreeIfSat) (
GenBoundCalcList, void (*f)(GenBoundCalc), Bool (*s)(GenBoundCalc
)); GenBoundCalc (*Elt) (GenBoundCalcList, Length); GenBoundCalcList
(*Drop) (GenBoundCalcList, Length); GenBoundCalcList (*LastCons
) (GenBoundCalcList); Length (*_Length) (GenBoundCalcList); Bool
(*IsLength) (GenBoundCalcList, Length); Bool (*IsShorter) (GenBoundCalcList
, Length); Bool (*IsLonger) (GenBoundCalcList, Length); GenBoundCalcList
(*Copy) (GenBoundCalcList); GenBoundCalcList (*CopyTo) (GenBoundCalcList
, GenBoundCalcList); GenBoundCalcList (*CopyDeeply) (GenBoundCalcList
, GenBoundCalc (*)(GenBoundCalc)); GenBoundCalcList (*CopyDeeplyTo
) (GenBoundCalcList, GenBoundCalcList, GenBoundCalc (*)(GenBoundCalc
)); GenBoundCalcList (*Map) (GenBoundCalc (*f)(GenBoundCalc),
GenBoundCalcList); GenBoundCalcList (*NMap) (GenBoundCalc (*
f)(GenBoundCalc), GenBoundCalcList); GenBoundCalcList (*Reverse
) (GenBoundCalcList); GenBoundCalcList (*NReverse) (GenBoundCalcList
); GenBoundCalcList (*Concat) (GenBoundCalcList, GenBoundCalcList
); GenBoundCalcList (*NConcat) (GenBoundCalcList, GenBoundCalcList
); Bool (*Memq) (GenBoundCalcList, GenBoundCalc); Bool (*Member
) (GenBoundCalcList, GenBoundCalc, Bool(*eq)(GenBoundCalc,GenBoundCalc
) ); Bool (*ContainsAllq) (GenBoundCalcList, GenBoundCalcList
); Bool (*ContainsAnyq) (GenBoundCalcList, GenBoundCalcList);
Bool (*ContainsAll) (GenBoundCalcList, GenBoundCalcList, Bool
(*eq)(GenBoundCalc, GenBoundCalc)); Bool (*ContainsAny) (GenBoundCalcList
, GenBoundCalcList, Bool (*eq)(GenBoundCalc, GenBoundCalc)); int
(*Posq) (GenBoundCalcList, GenBoundCalc); int (*Position) (GenBoundCalcList
, GenBoundCalc, Bool(*eq)(GenBoundCalc,GenBoundCalc) ); GenBoundCalcList
(*NRemove) (GenBoundCalcList, GenBoundCalc, Bool(*eq)(GenBoundCalc
,GenBoundCalc) ); void (*FillVector) (GenBoundCalc *, GenBoundCalcList
); int (*Print) (FILE *, GenBoundCalcList, int (*pr)(FILE *, GenBoundCalc
) ); int (*GPrint) (FILE *, GenBoundCalcList, int (*pr)(FILE *
, GenBoundCalc), char *l,char *m,char *r); int (*Format) (OStream
, CString, GenBoundCalcList); }; extern struct GenBoundCalc_listOpsStruct
const *GenBoundCalc_listPointer
;
356typedef enum { GB_Min, GB_Mult, GB_Sum, GB_One, GB_None, GB_Ask } GenBoundTag;
357
358struct GenBoundCalc {
359 GenBoundTag tag;
360 AbSyn code;
361 GenBoundCalcList subs;
362};
363
364localstatic GenBoundCalc gen0MakeBoundCalc (AbSyn, Bool);
365localstatic GenBoundCalc gen0NewBoundCalc (GenBoundTag, AbSyn, GenBoundCalcList);
366localstatic GenBoundCalc gen0MakeYieldBound (AbSyn);
367localstatic GenBoundCalc gen0MakeRepeatBound (AbSyn, Bool);
368localstatic GenBoundCalc gen0MakeIterBound (AbSyn, Bool);
369localstatic GenBoundCalc gen0MakeForBound (AbSyn, Bool);
370localstatic GenBoundCalc gen0MakeSeqBound (AbSyn, Bool);
371localstatic Bool gen0VerifyExprBoundSafe (AbSyn, Bool);
372localstatic AbSynList gen0FindIterVars (AbSyn);
373
374#ifdef GenerBetterGuesses
375localstatic Foam gen0ComputeBoundExpr (GenBoundCalc, int);
376localstatic Foam gen0ComputeBoundGener (AbSyn, int);
377localstatic Foam gen0ComputeBCall (FoamBValTag, FoamList);
378localstatic FoamBValTag gen0CalcToBuiltin (GenBoundTag);
379localstatic Foam gen0ComputeMin (FoamList);
380#endif
381
382/* I/face to forIter from bound calc */
383
384struct GenerGenInfo {
385 AbSynList geners;
386 FoamList foamVars;
387 FoamList nestChecks;
388 AbSynList ids;
389};
390
391/* Same order as GenCalcTags */
392FoamBValTag gen0CalcOps[] = {
393 FOAM_BVal_SIntMin,
394 FOAM_BVal_SIntTimes,
395 FOAM_BVal_SIntPlus,
396 0,
397 0,
398 0,
399};
400
401CREATE_LIST(GenBoundCalc)struct GenBoundCalc_listOpsStruct const *GenBoundCalc_listPointer
= (struct GenBoundCalc_listOpsStruct const *) &ptrlistOps
;
402
403localstatic GenBoundCalc
404gen0NewBoundCalc(GenBoundTag tag, AbSyn absyn, GenBoundCalcList subs)
405{
406 GenBoundCalc new;
407 new = (GenBoundCalc) stoAlloc(OB_Other0, sizeof(*new));
408 new->tag = tag;
409 new->code = absyn;
410 new->subs = subs;
411
412 return new;
413}
414
415#ifdef GenerBetterGuesses
416localstatic GenBoundCalc
417gen0MakeBoundInit(AbSyn absyn)
418{
419 GenBoundCalc calc;
420
421 gen0GenInfo = (GenerGenInfo) stoAlloc(OB_Other0, sizeof(*gen0GenInfo));
422 gen0GenInfo->ids = listNil(AbSyn)((AbSynList) 0);
423 gen0GenInfo->geners = listNil(AbSyn)((AbSynList) 0);
424 gen0GenInfo->nestChecks = listNil(Foam)((FoamList) 0);
425 gen0GenInfo->foamVars = listNil(Foam)((FoamList) 0);
426
427 calc = gen0MakeBoundCalc(absyn, false((int) 0));
428
429 if (!calc) {
430 listFree(AbSyn)(AbSyn_listPointer->Free)(gen0GenInfo->ids);
431 listFree(AbSyn)(AbSyn_listPointer->Free)(gen0GenInfo->geners);
432 listFree(Foam)(Foam_listPointer->Free)(gen0GenInfo->nestChecks);
433 listFree(Foam)(Foam_listPointer->Free)(gen0GenInfo->foamVars);
434 gen0GenInfo->ids = listNil(AbSyn)((AbSynList) 0);
435 gen0GenInfo->geners = listNil(AbSyn)((AbSynList) 0);
436 gen0GenInfo->nestChecks = listNil(Foam)((FoamList) 0);
437 gen0GenInfo->foamVars = listNil(Foam)((FoamList) 0);
438 }
439 return calc;
440}
441
442localstatic Foam
443gen0ComputeBoundFunction(GenBoundCalc calc)
444{
445 GenFoamState saved;
446 Foam clos, foam, ret;
447 int exitLabel, retLabel;
448
449 clos = foamNewClos(foamNewEnv(-1), foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(-1)), foamNew
(FOAM_Const, 1, (AInt)(gen0NumProgs)))
;
450 foam = gen0ProgInitEmpty(boundFName()("generBound"), NULL((void*)0));
451 saved = gen0ProgSaveState(PT_Std);
452
453 exitLabel = gen0State->labelNo++;
454 retLabel = gen0State->labelNo++;
455
456 ret = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
457 gen0AddStmt(foamNewSet(ret, gen0ComputeBoundExpr(calc, exitLabel))foamNew(FOAM_Set, 2, ret, gen0ComputeBoundExpr(calc, exitLabel
))
, NULL((void*)0));
458 gen0AddStmt(foamNewGoto(retLabel)foamNew(FOAM_Goto, 1, (AInt)(retLabel)), NULL((void*)0));
459 gen0AddStmt(foamNewLabel(exitLabel)foamNew(FOAM_Label, 1, (AInt)(exitLabel)), NULL((void*)0));
460 gen0AddStmt(foamNewSet(foamCopy(ret), foamNewSInt(-1))foamNew(FOAM_Set, 2, foamCopy(ret), foamNew(FOAM_SInt, 1, (AInt
)(-1)))
, NULL((void*)0));
461 gen0AddStmt(foamNewLabel(retLabel)foamNew(FOAM_Label, 1, (AInt)(retLabel)), NULL((void*)0));
462 gen0AddStmt(foamNewReturn(foamCopy(ret))foamNew(FOAM_Return, 1, foamCopy(ret)), NULL((void*)0));
463
464 foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), true1);
465
466 foam->foamProg.infoBits = IB_SIDE(1 << 0) | IB_INLINEME(1 << 4);
467
468 gen0ProgPushFormat(emptyFormatSlot4);
469 gen0ProgPushFormat(emptyFormatSlot4);
470 gen0ProgFiniEmpty(foam, FOAM_SInt, int0((int) 0));
471 gen0AddLexLevels(foam, 2);
472
473 gen0ProgRestoreState(saved);
474 return clos;
475}
476#endif
477
478Foam
479gen0GenLiftedGener(AbSyn forIter, AbSyn gener)
480{
481#ifndef GenerBetterGuesses
482 return genImplicit(forIter, gener, FOAM_Clos);
483#else
484 Foam check, vars, call;
485 int place, i;
486
487 if (gen0GenInfo)
488 place = listPosq(AbSyn)(AbSyn_listPointer->Posq)(gen0GenInfo->geners, forIter);
489 else
490 place = -1;
491
492 if (place < 0) {
493 Foam vals = gen0TempFrDDecl(gen0MakeGenerRetFormat(), true1);
494 Foam doneFun = gen0Temp(FOAM_Clos)gen0Temp0(FOAM_Clos, 4);
495 Foam stepFun = gen0Temp(FOAM_Clos)gen0Temp0(FOAM_Clos, 4);
496 Foam valueFun = gen0Temp(FOAM_Clos)gen0Temp0(FOAM_Clos, 4);
497 Foam boundFun = gen0Temp(FOAM_Clos)gen0Temp0(FOAM_Clos, 4);
498
499 call = foamNewEmpty(FOAM_CCall, 2);
500 call->foamCCall.type = FOAM_NOp;
501 call->foamCCall.op = genImplicit(forIter, gener, FOAM_Clos);
502 call = foamNewMFmt(gen0MakeGenerRetFormat(), call)foamNew(FOAM_MFmt, 2, gen0MakeGenerRetFormat(), call);
503 gen0AddStmt(foamNewDef(foamCopy(vals), call)foamNew(FOAM_Def, 2, foamCopy(vals), call), forIter);
504 gen0AddStmt(foamNewDef(doneFun, vals->foamValues.argv[0])foamNew(FOAM_Def, 2, doneFun, vals->foamValues.argv[0]),
505 forIter);
506 gen0AddStmt(foamNewDef(stepFun, vals->foamValues.argv[1])foamNew(FOAM_Def, 2, stepFun, vals->foamValues.argv[1]),
507 forIter);
508 gen0AddStmt(foamNewDef(valueFun, vals->foamValues.argv[2])foamNew(FOAM_Def, 2, valueFun, vals->foamValues.argv[2]),
509 forIter);
510 gen0AddStmt(foamNewDef(boundFun, vals->foamValues.argv[3])foamNew(FOAM_Def, 2, boundFun, vals->foamValues.argv[3]),
511 forIter);
512 return foamNew(FOAM_Values, 4, doneFun, stepFun,
513 valueFun, boundFun);
514 }
515 check = listElt(Foam)(Foam_listPointer->Elt)(gen0GenInfo->nestChecks, place);
516 vars = listElt(Foam)(Foam_listPointer->Elt)(gen0GenInfo->foamVars, place);
517 if (check) {
518 Foam vals = gen0TempFrDDecl(gen0MakeGenerRetFormat(), true1);
519
520 call = foamNewEmpty(FOAM_CCall, 2);
521 call->foamCCall.type = FOAM_NOp;
522 call->foamCCall.op = genImplicit(forIter,
523 forIter->abFor.whole,
524 FOAM_Clos);
525 gen0AddStmt(foamNewDef(foamCopy(vals),foamNew(FOAM_Def, 2, foamCopy(vals), foamNew(FOAM_MFmt, 2, gen0MakeGenerRetFormat
(), call))
526 foamNewMFmt(gen0MakeGenerRetFormat(),foamNew(FOAM_Def, 2, foamCopy(vals), foamNew(FOAM_MFmt, 2, gen0MakeGenerRetFormat
(), call))
527 call))foamNew(FOAM_Def, 2, foamCopy(vals), foamNew(FOAM_MFmt, 2, gen0MakeGenerRetFormat
(), call))
, forIter);
528 gen0AddStmt(foamNewDef(foamCopy(check), foamNewBool(true))foamNew(FOAM_Def, 2, foamCopy(check), foamNew(FOAM_Bool, 1, (
AInt)(1)))
,
529 forIter);
530 for (i=0; i < 4; i++)
531 gen0AddStmt(foamNewDef(foamCopy(varsfoamNew(FOAM_Def, 2, foamCopy(vars ->foamValues.argv[i]), foamCopy
(vals ->foamValues.argv[i]))
532 ->foamValues.argv[i]),foamNew(FOAM_Def, 2, foamCopy(vars ->foamValues.argv[i]), foamCopy
(vals ->foamValues.argv[i]))
533 foamCopy(valsfoamNew(FOAM_Def, 2, foamCopy(vars ->foamValues.argv[i]), foamCopy
(vals ->foamValues.argv[i]))
534 ->foamValues.argv[i]))foamNew(FOAM_Def, 2, foamCopy(vars ->foamValues.argv[i]), foamCopy
(vals ->foamValues.argv[i]))
,
535 forIter);
536 return foamCopy(vars);
537 }
538 return foamCopy(vars);
539#endif
540}
541
542/* Internal bound calculation routines */
543localstatic GenBoundCalc
544gen0MakeBoundCalc(AbSyn absyn, Bool nestCheck)
545{
546 switch (abTag(absyn)((absyn)->abHdr.tag)) {
547 case AB_Yield:
548 return gen0MakeYieldBound(absyn);
549 case AB_Sequence:
550 return gen0MakeSeqBound(absyn, nestCheck);
551 case AB_Repeat:
552 return gen0MakeRepeatBound(absyn, nestCheck);
553 /* Nasty problems with side-effects if we allow apply, set, etc. */
554 default:
555 return NULL((void*)0);
556 }
557}
558
559localstatic GenBoundCalc
560gen0MakeYieldBound(AbSyn absyn)
561{
562 if (gen0VerifyExprBoundSafe(absyn->abYield.value, false((int) 0)))
563 return gen0NewBoundCalc(GB_One, NULL((void*)0), NULL((void*)0));
564 else
565 return NULL((void*)0);
566}
567
568localstatic GenBoundCalc
569gen0MakeRepeatBound(AbSyn absyn, Bool nestCheck)
570{
571 GenBoundCalc inner, loop;
572 GenBoundCalcList lst;
573
574 if (nestCheck) return NULL((void*)0);
575 /* calcs ids too.. */
576 loop = gen0MakeIterBound(absyn, nestCheck);
577 if (!loop)
578 return NULL((void*)0);
579 inner = gen0MakeBoundCalc(absyn->abRepeat.body, true1);
580 if (!inner)
581 return NULL((void*)0);
582 lst = listCons(GenBoundCalc)(GenBoundCalc_listPointer->Cons)(loop,
583 listCons(GenBoundCalc)(GenBoundCalc_listPointer->Cons)(inner, listNil(GenBoundCalc)((GenBoundCalcList) 0)));
584 return gen0NewBoundCalc(GB_Mult, NULL((void*)0), lst);
585
586}
587
588localstatic GenBoundCalc
589gen0MakeIterBound(AbSyn ab, Bool nestCheck)
590{
591 GenBoundCalcList lst = listNil(GenBoundCalc)((GenBoundCalcList) 0);
592 GenBoundCalc new;
593 AbSyn iter;
594 int i;
595 String msg;
596
597 if (abRepeatIterc(ab)(((ab)->abHdr.argc)-1) == 0) {
598 return NULL((void*)0);
599 }
600
601 if (abRepeatIterc(ab)(((ab)->abHdr.argc)-1) == 1) {
602 iter = ab->abRepeat.iterv[0];
603 switch (abTag(iter)((iter)->abHdr.tag)) {
604 case AB_While:
605 new = NULL((void*)0);
606 break;
607 case AB_For:
608 new = gen0MakeForBound(iter, nestCheck);
609 break;
610 default:
611 msg = "bad iterator passed to gen0MakeIterBound";
612 comsgFatal(ab, ALDOR_F_Bug365, msg);
613#if 0
614 bug("not an iterate");
615 new = NULL((void*)0);
616#endif
617 NotReached(new = NULL){(void)bug("Not supposed to reach line %d in file: %s\n",617,
"gf_gener.c");}
;
618 }
619 return new;
620 }
621 for (i=0; i<abRepeatIterc(ab)(((ab)->abHdr.argc)-1); i++) {
622 iter = ab->abRepeat.iterv[i];
623 switch(abTag(iter)((iter)->abHdr.tag)) {
624 case AB_For:
625 new = gen0MakeForBound(iter, nestCheck);
626 if (!new) {
627 listFree(GenBoundCalc)(GenBoundCalc_listPointer->Free)(lst);
628 return NULL((void*)0);
629 }
630 lst = listCons(GenBoundCalc)(GenBoundCalc_listPointer->Cons)(new, lst);
631 break;
632 case AB_While:
633 if (!gen0VerifyExprBoundSafe(iter->abWhile.test, false((int) 0)))
634 return NULL((void*)0);
635 break;
636 default:
637 msg = "bad iterator passed to gen0MakeIterBound";
638 comsgFatal(ab, ALDOR_F_Bug365, msg);
639#if 0
640 bug("not an iterator");
641 return NULL((void*)0);
642#endif
643 }
644 }
645 return gen0NewBoundCalc(GB_Min, NULL((void*)0), lst);
646}
647
648localstatic GenBoundCalc
649gen0MakeForBound(AbSyn absyn, Bool nestCheck)
650{
651 if (!gen0VerifyExprBoundSafe(absyn->abFor.lhs, true1) ||
652 !gen0VerifyExprBoundSafe(absyn->abFor.test, false((int) 0)))
653 return NULL((void*)0);
654
655 gen0GenInfo->ids = listNConcat(AbSyn)(AbSyn_listPointer->NConcat)(gen0FindIterVars(absyn->abFor.lhs),
656 gen0GenInfo->ids);
657 gen0GenInfo->geners = listCons(AbSyn)(AbSyn_listPointer->Cons)(absyn, gen0GenInfo->geners);
658 /* should check nestCheck if we want to un-nest gtor */
659 gen0GenInfo->nestChecks = listCons(Foam)(Foam_listPointer->Cons)(gen0TempLex(FOAM_Bool)gen0TempLex0(FOAM_Bool, 4),
660 gen0GenInfo->nestChecks);
661 return gen0NewBoundCalc(GB_Ask, absyn, NULL((void*)0));
662}
663
664localstatic AbSynList
665gen0FindIterVars(AbSyn ab)
666{
667 AbSynList lst = listNil(AbSyn)((AbSynList) 0);
668 int i;
669 String msg;
670
671 switch (abTag(ab)((ab)->abHdr.tag)) {
672 case AB_Id:
673 lst = listCons(AbSyn)(AbSyn_listPointer->Cons)(ab, listNil(AbSyn)((AbSynList) 0));
674 break;
675 case AB_Declare:
676 lst = gen0FindIterVars(ab->abDeclare.id);
677 break;
678 case AB_Free:
679 case AB_Fluid:
680 lst = listNil(AbSyn)((AbSynList) 0);
681 for (i=0; i < abArgc(ab)((ab)->abHdr.argc); i++)
682 lst = listNConcat(AbSyn)(AbSyn_listPointer->NConcat)(gen0FindIterVars(abArgv(ab)((ab)->abGen.data.argv)[i]), lst);
683 break;
684 case AB_Comma:
685 lst = listNil(AbSyn)((AbSynList) 0);
686 for (i=0; i < abArgc(ab)((ab)->abHdr.argc); i++)
687 lst = listNConcat(AbSyn)(AbSyn_listPointer->NConcat)(gen0FindIterVars(abArgv(ab)((ab)->abGen.data.argv)[i]), lst);
688 break;
689 default:
690 msg = "bad iterator passed to gen0FindIterVars";
691 comsgFatal(ab, ALDOR_F_Bug365, msg);
692#if 0
693 abPrint(dbOut, ab);
694 bug("unhandled iteration form");
695 NotReached(lst = listNil(AbSyn)){(void)bug("Not supposed to reach line %d in file: %s\n",695,
"gf_gener.c");}
;
696 break;
697#endif
698 }
699 return lst;
700}
701
702localstatic GenBoundCalc
703gen0MakeSeqBound(AbSyn absyn, Bool nestCheck)
704{
705 GenBoundCalcList lst = listNil(GenBoundCalc)((GenBoundCalcList) 0);
706 GenBoundCalc val;
707 int i;
708
709 if (abArgc(absyn)((absyn)->abHdr.argc) == 0)
710 return gen0NewBoundCalc(GB_None, NULL((void*)0), NULL((void*)0));
711 for (i=0; i < abArgc(absyn)((absyn)->abHdr.argc); i++) {
712 val = gen0MakeBoundCalc(absyn->abSequence.argv[i], nestCheck);
713 if (!val) {
714 listFree(GenBoundCalc)(GenBoundCalc_listPointer->Free)(lst);
715 return NULL((void*)0);
716 }
717
718 lst = listCons(GenBoundCalc)(GenBoundCalc_listPointer->Cons)(val, lst);
719 }
720
721 if (!lst) {
722 return NULL((void*)0);
723 }
724 return gen0NewBoundCalc(GB_Sum, NULL((void*)0), lst);
725}
726
727localstatic Bool
728gen0VerifyExprBoundSafe(AbSyn ab, Bool iterIds)
729{
730 int i;
731 switch(abTag(ab)((ab)->abHdr.tag)) {
732 case AB_Id:
733 if (iterIds && listMember(AbSyn)(AbSyn_listPointer->Member)(gen0GenInfo->ids, ab, abEqual)) {
734 return false((int) 0);
735 }
736 return true1;
737 case AB_Yield:
738 case AB_Goto:
739 case AB_Sequence:
740 return false((int) 0);
741 case AB_LitInteger:
742 case AB_LitFloat:
743 case AB_LitString:
744 return true1;
745 default:
746 for (i=0; i<abArgc(ab)((ab)->abHdr.argc); i++)
747 if (!gen0VerifyExprBoundSafe(abArgv(ab)((ab)->abGen.data.argv)[i], iterIds)) {
748 return false((int) 0);
749 }
750 return true1;
751 }
752}
753
754#ifdef GenerBetterGuesses
755
756/* Added at generator base */
757localstatic void
758gen0ComputeGeners()
759{
760 AbSynList idlst, glst;
761 FoamList foamVars, nestlst;
762 Foam tmpVar, genVals;
763
764 Foam vals = gen0TempFrDDecl(gen0MakeGenerRetFormat(), true1);
765 int i;
766
767 idlst = listNReverse(AbSyn)(AbSyn_listPointer->NReverse)(gen0GenInfo->ids);
768 glst = listNReverse(AbSyn)(AbSyn_listPointer->NReverse)(gen0GenInfo->geners);
769 nestlst = listNReverse(Foam)(Foam_listPointer->NReverse)(gen0GenInfo->nestChecks);
770 gen0GenInfo->geners = glst;
771 gen0GenInfo->ids = idlst;
772 gen0GenInfo->nestChecks = nestlst;
773
774 foamVars = listNil(Foam)((FoamList) 0);
775 while (glst) {
776 Foam doneFun = gen0TempLex(FOAM_Clos)gen0TempLex0(FOAM_Clos, 4);
777 Foam stepFun = gen0TempLex(FOAM_Clos)gen0TempLex0(FOAM_Clos, 4);
778 Foam valueFun = gen0TempLex(FOAM_Clos)gen0TempLex0(FOAM_Clos, 4);
779 Foam boundFun = gen0TempLex(FOAM_Clos)gen0TempLex0(FOAM_Clos, 4);
780 FoamTag type;
781 AInt fmt;
782
783 type = gen0Type(gen0AbType(car(idlst)((idlst)->first)), &fmt);
784 tmpVar = gen0TempLocal0(type, fmt);
785 foamVars = listCons(Foam)(Foam_listPointer->Cons)(foamNew(FOAM_Values, 4, doneFun, stepFun,
786 valueFun, boundFun), foamVars);
787 if (car(nestlst)((nestlst)->first))
788 gen0AddStmt(foamNewSet(car(nestlst), foamNewBool(false))foamNew(FOAM_Set, 2, ((nestlst)->first), foamNew(FOAM_Bool
, 1, (AInt)(((int) 0))))
, NULL((void*)0));
789 else {
790 genVals = genImplicit(car(glst)((glst)->first), car(glst)((glst)->first)->abFor.whole, FOAM_Clos);
791 gen0AddStmt(foamNewSet(tmpVar, genVals)foamNew(FOAM_Set, 2, tmpVar, genVals), NULL((void*)0));
792 genVals = foamNewMFmt(gen0MakeGenerRetFormat(),foamNew(FOAM_MFmt, 2, gen0MakeGenerRetFormat(), foamNew(FOAM_CCall
, 2, FOAM_NOp, foamCopy(tmpVar)))
793 foamNew(FOAM_CCall, 2,foamNew(FOAM_MFmt, 2, gen0MakeGenerRetFormat(), foamNew(FOAM_CCall
, 2, FOAM_NOp, foamCopy(tmpVar)))
794 FOAM_NOp, foamCopy(tmpVar)))foamNew(FOAM_MFmt, 2, gen0MakeGenerRetFormat(), foamNew(FOAM_CCall
, 2, FOAM_NOp, foamCopy(tmpVar)))
;
795 gen0AddStmt(foamNewSet(foamCopy(vals), genVals)foamNew(FOAM_Set, 2, foamCopy(vals), genVals), NULL((void*)0));
796 for (i=0; i<foamArgc(vals)((vals)->hdr.argc); i++)
797 gen0AddStmt(foamNewSet(foamCopy(car(foamVars)->foamValues.argv[i]),foamNew(FOAM_Set, 2, foamCopy(((foamVars)->first)->foamValues
.argv[i]), foamCopy(vals->foamValues.argv[i]))
798 foamCopy(vals->foamValues.argv[i]))foamNew(FOAM_Set, 2, foamCopy(((foamVars)->first)->foamValues
.argv[i]), foamCopy(vals->foamValues.argv[i]))
, NULL((void*)0));
799 }
800 idlst = cdr(idlst)((idlst)->rest);
801 glst = cdr(glst)((glst)->rest);
802 nestlst = cdr(nestlst)((nestlst)->rest);
803 }
804 foamFree(vals);
805 gen0GenInfo->foamVars = listNReverse(Foam)(Foam_listPointer->NReverse)(foamVars);
806}
807
808localstatic Foam
809gen0ComputeBoundExpr(GenBoundCalc calc, int exitLabel)
810{
811 FoamList lst;
812 Foam val;
813 GenBoundCalcList clst;
814
815 switch(calc->tag) {
816 case GB_One:
817 val = foamNewSInt(1)foamNew(FOAM_SInt, 1, (AInt)(1));
818 break;
819 case GB_None:
820 val = foamNewSInt(int0)foamNew(FOAM_SInt, 1, (AInt)(((int) 0)));
821 break;
822 case GB_Ask: /* Look in list for foam */
823 val = gen0ComputeBoundGener(calc->code, exitLabel);
824 break;
825 default:
826 lst = listNil(Foam)((FoamList) 0);
827 clst = calc->subs;
828 while (clst) {
829 lst = listCons(Foam)(Foam_listPointer->Cons)
830 (gen0ComputeBoundExpr(car(clst)((clst)->first), exitLabel),
831 lst);
832 clst = cdr(clst)((clst)->rest);
833 }
834 if (calc->tag == GB_Min)
835 val = gen0ComputeMin(lst);
836 else
837 val = gen0ComputeBCall(gen0CalcToBuiltin(calc->tag), lst);
838 }
839 return val;
840}
841
842localstatic Foam
843gen0ComputeBoundGener(AbSyn code, int exitLabel)
844{
845 Foam tmp = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
846 Foam vals, nestCheck, call;
847 int place;
848
849 place = listPosq(AbSyn)(AbSyn_listPointer->Posq)(gen0GenInfo->geners, code);
850 vals = listElt(Foam)(Foam_listPointer->Elt)(gen0GenInfo->foamVars, place);
851 nestCheck = listElt(Foam)(Foam_listPointer->Elt)(gen0GenInfo->nestChecks, place);
852
853 if (nestCheck) {
854 gen0AddStmt(foamNewIf(foamNotThis(foamCopy(nestCheck)),foamNew(FOAM_If, 2, foamNotThis(foamCopy(nestCheck)), exitLabel
)
855 exitLabel)foamNew(FOAM_If, 2, foamNotThis(foamCopy(nestCheck)), exitLabel
)
, NULL((void*)0));
856 }
857 call = foamNewEmpty(FOAM_CCall, 2);
858 call->foamCCall.type = FOAM_SInt;
859 call->foamCCall.op = foamCopy(vals->foamValues.argv[boundPlace3]);
860
861 gen0AddStmt(foamNewSet(tmp, call)foamNew(FOAM_Set, 2, tmp, call), NULL((void*)0));
862 gen0AddStmt(foamNewIf(foamNew(FOAM_BCall, 3, (AInt)FOAM_BVal_SIntLT,foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, (AInt)FOAM_BVal_SIntLT
, foamCopy(tmp), foamNew(FOAM_SInt, 1, (AInt)(((int) 0)))), exitLabel
)
863 foamCopy(tmp), foamNewSInt(int0)),foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, (AInt)FOAM_BVal_SIntLT
, foamCopy(tmp), foamNew(FOAM_SInt, 1, (AInt)(((int) 0)))), exitLabel
)
864 exitLabel)foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, (AInt)FOAM_BVal_SIntLT
, foamCopy(tmp), foamNew(FOAM_SInt, 1, (AInt)(((int) 0)))), exitLabel
)
, NULL((void*)0));
865 gen0UseStackedFormat(int0((int) 0));
866 return foamCopy(tmp);
867}
868
869localstatic Foam
870gen0ComputeMin(FoamList lst)
871{
872 Foam acc = gen0TempLocal(FOAM_SInt)gen0TempLocal0(FOAM_SInt, 4);
873
874 gen0AddStmt(foamNewSet(acc, car(lst))foamNew(FOAM_Set, 2, acc, ((lst)->first)), NULL((void*)0));
875 lst = cdr(lst)((lst)->rest);
876
877 while (lst) {
878 int label = gen0State->labelNo++;
879 gen0AddStmt(foamNewIf(foamNew(FOAM_BCall, 3, FOAM_BVal_SIntLT,foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntLT, foamCopy
(acc), ((lst)->first)), label)
880 foamCopy(acc), car(lst)), label)foamNew(FOAM_If, 2, foamNew(FOAM_BCall, 3, FOAM_BVal_SIntLT, foamCopy
(acc), ((lst)->first)), label)
,
881 NULL((void*)0));
882 gen0AddStmt(foamNewSet(foamCopy(acc), foamCopy(car(lst)))foamNew(FOAM_Set, 2, foamCopy(acc), foamCopy(((lst)->first
)))
, NULL((void*)0));
883 gen0AddStmt(foamNewLabel(label)foamNew(FOAM_Label, 1, (AInt)(label)), NULL((void*)0));
884 lst = cdr(lst)((lst)->rest);
885 }
886 return foamCopy(acc);
887}
888
889localstatic Foam
890gen0ComputeBCall(FoamBValTag fn, FoamList lst)
891{
892 Foam acc;
893 if (cdr(lst)((lst)->rest)==0) return car(lst)((lst)->first);
894 acc = foamNew(FOAM_BCall, 3, fn, car(lst)((lst)->first), gen0ComputeBCall(fn, cdr(lst)((lst)->rest)));
895 return acc;
896}
897
898localstatic FoamBValTag
899gen0CalcToBuiltin(GenBoundTag tag)
900{
901 assert(gen0CalcOps[tag])do { if (!(gen0CalcOps[tag])) _do_assert(("gen0CalcOps[tag]")
,"gf_gener.c",901); } while (0)
;
902 return gen0CalcOps[tag];
903}
904
905#endif