Bug Summary

File:src/foam.c
Warning:line 2485, column 18
Value stored to 'af' 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 foam.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 foam.c
1/*****************************************************************************
2 *
3 * foam.c: First Order Abstract Machine -- FOAM code.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ****************************************************************************/
8
9/*
10 * This is the layout of a piece of FOAM
11 *
12 * (Unit
13 * (DFmt ...)
14 * (DDef
15 * (Def (Glo 0) ...)
16 * (Def (Glo 1) ...)
17 * ...
18 * (Def (Glo ng-1) ...)
19 * (Def (Const 0) ...)
20 * ...
21 * (Def (Const nc-1) ...)
22 * (Def (Lex 0 0) ...)
23 * (Def (Lex 0 1) ...)
24 * ...
25 * (Def (Lex 0 nl-1) ...)
26 * ))
27 */
28
29#include "axlobs.h"
30#include "comsg.h"
31#include "debug.h"
32#include "fbox.h"
33#include "file.h"
34#include "fluid.h"
35#include "foamsig.h"
36#include "format.h"
37#include "int.h"
38#include "intset.h"
39#include "javasig.h"
40#include "opsys.h"
41#include "sexpr.h"
42#include "store.h"
43#include "symbol.h"
44#include "symcoinfo.h"
45#include "util.h"
46#include "xfloat.h"
47
48/* Used for foam sharing audit */
49#define FOAM_MARKED0x01 0x01
50#define FOAM_UNMARKED0x00 0x00
51
52Bool foamDebug = false((int) 0);
53Bool foamConstDebug = false((int) 0);
54Bool foamSposDebug = false((int) 0);
55
56#define foamDEBUGif (!foamDebug) { } else afprintf DEBUG_IF(foam)if (!foamDebug) { } else afprintf
57#define foamConstDEBUGif (!foamConstDebug) { } else afprintf DEBUG_IF(foamConst)if (!foamConstDebug) { } else afprintf
58#define foamSposDEBUGif (!foamSposDebug) { } else afprintf DEBUG_IF(foamSpos)if (!foamSposDebug) { } else afprintf
59
60/*****************************************************************************
61 *
62 * :: Basic operations
63 *
64 ****************************************************************************/
65
66SrcPos foamDefaultPosition;
67static Bool foamIsInit = false((int) 0);
68localstatic int foamListFormatter(OStream ostream, Pointer p);
69localstatic int foamFormatter(OStream ostream, Pointer p);
70localstatic int foamSigFormatter(OStream ostream, Pointer p);
71
72localstatic int foamTypeFormatter(OStream ostream, Pointer p);
73localstatic int foamFormatterExt(OStream ostream, Pointer p, FoamSxFlags flags);
74
75/*
76 * Note: This implementation shares the foamTagVal field of symCoInfo so foam
77 * instructions, builtins and protocols must not have overlapping names.
78 */
79void
80foamEnsureInit(void)
81{
82 if (!foamIsInit)
83 foamInit();
84}
85
86void
87foamInit(void)
88{
89 int i;
90 Symbol sym;
91
92 foamDefaultPosition = sposNone;
93
94 for (i = FOAM_START; i < FOAM_LIMIT; i++) {
95 sym = symInternConst(foamInfo(i).str)symProbe((foamInfoTable [(int)(i)-(int)FOAM_START]).str, 1);
96 if (symCoInfo(sym) == NULL((void*)0)) symCoInfoInit(sym)(((sym)->info) = &(symCoInfoNew()->align));
97
98 foamInfo(i)(foamInfoTable [(int)(i)-(int)FOAM_START]).sxsym = sxiFrSymbol(sym);
99 symCoInfo(sym)->foamTagVal = i;
100 }
101 for (i = FOAM_BVAL_START; i < FOAM_BVAL_LIMIT; i++) {
102 sym = symInternConst(foamBValInfo(i).str)symProbe((foamBValInfoTable[(int)(i)-(int)FOAM_BVAL_START]).str
, 1)
;
103 if (symCoInfo(sym) == NULL((void*)0)) symCoInfoInit(sym)(((sym)->info) = &(symCoInfoNew()->align));
104
105 foamBValInfo(i)(foamBValInfoTable[(int)(i)-(int)FOAM_BVAL_START]).sxsym = sxiFrSymbol(sym);
106 symCoInfo(sym)->foamTagVal = i;
107 }
108 for (i = FOAM_PROTO_START; i < FOAM_PROTO_LIMIT; i++) {
109 sym = symInternConst(foamProtoInfo(i).str)symProbe((foamProtoInfoTable[(int)(i)-(int)FOAM_PROTO_START])
.str, 1)
;
110 if (symCoInfo(sym) == NULL((void*)0)) symCoInfoInit(sym)(((sym)->info) = &(symCoInfoNew()->align));
111
112 foamProtoInfo(i)(foamProtoInfoTable[(int)(i)-(int)FOAM_PROTO_START]).sxsym = sxiFrSymbol(sym);
113 symCoInfo(sym)->foamTagVal = i;
114 }
115 for (i = 0; i < FOAM_DDECL_LIMIT; i++) {
116 sym = symInternConst(foamDDeclInfo(i).str)symProbe((foamDDeclInfoTable[(int)(i)]).str, 1);
117 if (symCoInfo(sym) == NULL((void*)0)) symCoInfoInit(sym)(((sym)->info) = &(symCoInfoNew()->align));
118
119 foamDDeclInfo(i)(foamDDeclInfoTable[(int)(i)]).sxsym = sxiFrSymbol(sym);
120 symCoInfo(sym)->foamTagVal = i;
121 }
122
123 fmtRegister("Foam", foamFormatter);
124 fmtRegister("FoamList", foamListFormatter);
125 fmtRegister("FoamSig", foamSigFormatter);
126 fmtRegister("FoamTypes", foamTypeFormatter);
127
128 foamIsInit = true1;
129}
130
131localstatic int
132foamFormatter(OStream ostream, Pointer p)
133{
134 return foamFormatterExt(ostream, p, FOAMSX_None);
135}
136
137localstatic int
138foamTypeFormatter(OStream ostream, Pointer p)
139{
140 return foamFormatterExt(ostream, p, FOAMSX_Syme);
141}
142
143localstatic int
144foamFormatterExt(OStream ostream, Pointer p, FoamSxFlags flags)
145{
146 Foam foam = (Foam) p;
147 int c;
148
149 SExpr sx = foamToSExprExtra(foam, flags);
150 Buffer b = bufNew();
151 sxiToBufferFormatted(b, sx, SXRW_MixedCase(1L<<0));
152 c = ostreamWrite(ostream, bufLiberate(b), -1);
153 sxiFree(sx);
154
155 return c;
156}
157
158localstatic int
159foamListFormatter(OStream ostream, Pointer p)
160{
161 AbSynList list = (AbSynList) p;
162 return listFormat(AbSyn)(AbSyn_listPointer->Format)(ostream, "Foam", list);
163}
164
165localstatic int
166foamSigFormatter(OStream ostream, Pointer p)
167{
168 FoamSig sig = (FoamSig) p;
169 int nc = 0;
170 int i;
171 nc += ostreamPrintf(ostream, "{FoamSig (%pAIntList) --> %d %d",
172 sig->inArgs, sig->nRets, sig->retType);
173 if (sig->nRets == 0) {
174 ;
175 }
176 else {
177 String sep = "";
178 ostreamWriteChar(ostream, '(');
179 nc++;
180 if (sig->rets == NULL((void*)0)) {
181 nc += ostreamPrintf(ostream, "Word * %d", sig->nRets);
182 }
183 else {
184 for (i=0; i<sig->nRets; i++) {
185 nc += ostreamPrintf(ostream, "%s%s", sep, foamStr(sig->rets[i])((foamInfoTable [(int)(sig->rets[i])-(int)FOAM_START]).str
)
);
186 sep = ", ";
187 }
188 }
189 ostreamWriteChar(ostream, ')');
190 nc++;
191 }
192
193 ostreamWriteChar(ostream, '}');
194 nc++;
195 return nc;
196}
197
198Foam
199foamNewAlloc(FoamTag tag, Length argsize)
200{
201 Foam foam;
202 Length sz;
203
204 if (!foamIsInit) foamInit();
205
206 argsize = (argsize + (sizeof(Foam) - 1)) & -sizeof(Foam);
207 sz = sizeof(struct foamGen) + argsize - NARY10 * sizeof(Foam);
208 foam = (Foam) stoAlloc((unsigned) OB_Foam(14 + 12), sz);
209
210 foam->foamGen.hdr.tag = tag;
211 foam->foamGen.hdr.argc = 0;
212 foam->foamGen.hdr.mark = FOAM_UNMARKED0x00;
213 foam->foamGen.hdr.dvMark = 0;
214 foam->foamGen.hdr.pos = sposNone;
215 foam->foamGen.hdr.syme = NULL((void*)0);
216 foam->foamGen.hdr.defnId = -1;
217 foam->foamGen.hdr.info.opt = NULL((void*)0);
218
219 return foam;
220}
221
222Foam
223foamNewDFlo(DFloat d)
224{
225 Foam foam = foamNewAlloc(FOAM_DFlo, sizeof(DFloat));
226
227 foam->foamDFlo.hdr.argc = 1;
228 foam->foamDFlo.DFloData = d;
229
230 return foam;
231}
232
233Foam
234foamNewSFlo(SFloat s)
235{
236 Foam foam = foamNewAlloc(FOAM_SFlo, sizeof(SFloat));
237
238 foam->foamSFlo.hdr.argc = 1;
239 foam->foamSFlo.SFloData = s;
240
241 return foam;
242}
243
244Foam
245foamNewSeq(Foam arg0, ...)
246{
247 FoamList l = listNil(Foam)((FoamList) 0);
248 va_list argp;
249
250 va_start(argp, arg0)__builtin_va_start(argp, arg0);
251 if (arg0 != NULL((void*)0)) {
252 l = listListv(Foam)(Foam_listPointer->Listv)(argp);
253 l = listCons(Foam)(Foam_listPointer->Cons)(arg0, l);
254 }
255 va_end(argp)__builtin_va_end(argp);
256
257 return foamNewOfList(FOAM_Seq, l);
258}
259
260Foam
261foamNewSeqOfList(FoamList ll)
262{
263 return foamNewOfList(FOAM_Seq, ll);
264}
265
266
267
268Foam
269foamNewProgEmpty()
270{
271 return foamNewProg(int0,int0,int0,int0,int0,NULL,NULL,NULL,NULL,NULL)foamNew(FOAM_Prog, 13, (AInt)(((int) 0)),(AInt)(((int) 0)),(AInt
)(((int) 0)),(AInt)(((int) 0)), (AInt)(((int) 0)), (AInt)0, (
AInt)0, (AInt)0 , ((void*)0), ((void*)0), ((void*)0), ((void*
)0), ((void*)0))
;
272}
273
274Foam
275foamNewCCall(AInt type, Foam op, ...)
276{
277 FoamList args;
278 va_list argp;
279
280 va_start(argp, op)__builtin_va_start(argp, op);
281 args = listListv(Foam)(Foam_listPointer->Listv)(argp);
282 va_end(argp)__builtin_va_end(argp);
283
284 return foamNewCCallOfList(type, op, args);
285}
286
287Foam
288foamNewCCallOfList(AInt type, Foam op, FoamList args)
289{
290 Foam foam;
291 int i;
292
293 foam = foamNewEmpty(FOAM_CCall, foamCCallSlotc(2) + listLength(Foam)(Foam_listPointer->_Length)(args));
294 foam->foamCCall.type = type;
295 foam->foamCCall.op = op;
296
297 i = 0;
298 while (args != listNil(Foam)((FoamList) 0)) {
299 foam->foamCCall.argv[i++] = car(args)((args)->first);
300 args = listFreeCons(Foam)(Foam_listPointer->FreeCons)(args);
301 }
302
303 return foam;
304}
305
306Foam
307foamNewPCall(AInt protocol, AInt type, Foam op, ...)
308{
309 FoamList args;
310 va_list argp;
311
312 va_start(argp, op)__builtin_va_start(argp, op);
313 args = listListv(Foam)(Foam_listPointer->Listv)(argp);
314 va_end(argp)__builtin_va_end(argp);
315
316 return foamNewPCallOfList(protocol, type, op, args);
317}
318
319Foam
320foamNewPCallOfList(AInt protocol, AInt type, Foam op, FoamList args)
321{
322 Foam foam;
323 int i;
324
325 foam = foamNewEmpty(FOAM_PCall, foamPCallSlotc(3) + listLength(Foam)(Foam_listPointer->_Length)(args));
326 foam->foamPCall.protocol = protocol;
327 foam->foamPCall.type = type;
328 foam->foamPCall.op = op;
329
330 i = 0;
331 while (args != listNil(Foam)((FoamList) 0)) {
332 foam->foamPCall.argv[i++] = car(args)((args)->first);
333 args = listFreeCons(Foam)(Foam_listPointer->FreeCons)(args);
334 }
335
336 return foam;
337}
338
339Foam
340foamNewBCall(AInt op, ...)
341{
342 FoamList args;
343 Foam foam;
344 va_list argp;
345 int i;
346
347 va_start(argp, op)__builtin_va_start(argp, op);
348 args = listListv(Foam)(Foam_listPointer->Listv)(argp);
349 va_end(argp)__builtin_va_end(argp);
350
351 foam = foamNewEmpty(FOAM_BCall, foamBCallSlotc(1) + listLength(Foam)(Foam_listPointer->_Length)(args));
352 foam->foamBCall.op = op;
353
354 i = 0;
355 while (args != listNil(Foam)((FoamList) 0)) {
356 foam->foamBCall.argv[i++] = car(args)((args)->first);
357 args = listFreeCons(Foam)(Foam_listPointer->FreeCons)(args);
358 }
359
360 return foam;
361}
362
363
364Foam
365foamNewDDecl(AInt usage, ...)
366{
367 FoamList foamList;
368 va_list argp;
369
370 va_start(argp, usage)__builtin_va_start(argp, usage);
371 foamList = listListv(Foam)(Foam_listPointer->Listv)(argp);
372 va_end(argp)__builtin_va_end(argp);
373
374 return foamNewDDeclOfList(usage, foamList);
375}
376
377Foam foamNewDDeclEmpty(AInt n, AInt usage)
378{
379 Foam foam = foamNewEmpty(FOAM_DDecl, 1 + n);
380 foam->foamDDecl.usage = usage;
381 return foam;
382}
383
384Foam
385foamNewDDeclOfList(AInt usage, FoamList foamList)
386{
387 Foam foam;
388 int i;
389 assert(foamDDeclSlotc == 1)do { if (!((1) == 1)) _do_assert(("foamDDeclSlotc == 1"),"foam.c"
,389); } while (0)
; /* Will blow up if a field is added */
390
391 foam = foamNewEmpty(FOAM_DDecl, foamDDeclSlotc(1) + listLength(Foam)(Foam_listPointer->_Length)(foamList));
392 foam->foamDDecl.usage = usage;
393 i=0;
394 while (foamList != listNil(Foam)((FoamList) 0)) {
395 foam->foamDDecl.argv[i++] = car(foamList)((foamList)->first);
396 foamList = listFreeCons(Foam)(Foam_listPointer->FreeCons)(foamList);
397 }
398
399 return foam;
400}
401
402Foam
403foamNewDFmt(Foam arg0, ...)
404{
405 FoamList foamList;
406 va_list argp;
407
408 va_start(argp, arg0)__builtin_va_start(argp, arg0);
409 foamList = listListv(Foam)(Foam_listPointer->Listv)(argp);
410 va_end(argp)__builtin_va_end(argp);
411 foamList = listCons(Foam)(Foam_listPointer->Cons)(arg0, foamList);
412
413 return foamNewOfList(FOAM_DFmt, foamList);
414}
415
416Foam
417foamNewDDef(Foam arg0, ...)
418{
419 FoamList foamList;
420 va_list argp;
421
422 va_start(argp, arg0)__builtin_va_start(argp, arg0);
423 foamList = listListv(Foam)(Foam_listPointer->Listv)(argp);
424 va_end(argp)__builtin_va_end(argp);
425 foamList = listCons(Foam)(Foam_listPointer->Cons)(arg0, foamList);
426
427 return foamNewOfList(FOAM_DDef, foamList);
428}
429
430Foam
431foamNewDEnvUnused(AInt len)
432{
433 Foam foam = foamNewEmpty(FOAM_DEnv, len);
434 for (AInt i=0; i<len; i++) {
435 foam->foamDEnv.argv[i] = emptyFormatSlot4;
436 }
437 return foam;
438}
439
440
441Foam
442foamNewSelect(Foam op, AInt nBranches)
443{
444 Foam foam = foamNewEmpty(FOAM_Select, 1 + nBranches);
445 foam->foamSelect.op = op;
446 return foam;
447}
448
449Foam
450foamNewSelectRange(Foam op, AInt lo, AInt count)
451{
452 Foam foam;
453 AInt idx;
454
455 foam = foamNewEmpty(FOAM_Select, 1 + count);
456 foam->foamSelect.op = op;
457
458 for (idx = 0; idx < count; idx++) {
459 foam->foamSelect.argv[idx] = lo + idx;
460 }
461
462 return foam;
463}
464
465Foam
466foamNewValuesOfList(FoamList lst)
467{
468 return foamNewOfList(FOAM_Values, lst);
469}
470
471Foam
472foamNewValues(Foam arg0, ...)
473{
474 FoamList foamList;
475 va_list argp;
476
477 va_start(argp, arg0)__builtin_va_start(argp, arg0);
478 foamList = listListv(Foam)(Foam_listPointer->Listv)(argp);
479 va_end(argp)__builtin_va_end(argp);
480 foamList = listCons(Foam)(Foam_listPointer->Cons)(arg0, foamList);
481
482 return foamNewOfList(FOAM_Values, foamList);
483}
484
485Foam
486foamNewEmpty(FoamTag tag, Length argc)
487{
488 Foam foam;
489 Length i;
490
491 foam = foamNewAlloc(tag, argc * sizeof(Foam));
492
493 foam->foamGen.hdr.argc = argc;
494 for (i = 0; i < argc; i += 1)
495 foam->foamGen.argv[i].code = 0;
496
497 return foam;
498}
499
500Foam
501foamNew(FoamTag tag, Length argc, ...)
502{
503 Foam foam;
504 va_list argp;
505 Length i;
506
507 foam = foamNewEmpty(tag, argc);
508
509 va_start(argp, argc)__builtin_va_start(argp, argc);
510 for (i = 0; i < argc; i++)
511 foam->foamGen.argv[i].code = va_arg(argp, Foam)__builtin_va_arg(argp, Foam);
512 va_end(argp)__builtin_va_end(argp);
513
514 return foam;
515}
516
517
518Foam
519foamNewOfList(FoamTag tag, FoamList lfoam)
520{
521 Foam s;
522 FoamList l;
523 int i;
524
525 s = foamNewEmpty(tag, listLength(Foam)(Foam_listPointer->_Length)(lfoam));
526 for (i = 0, l = lfoam; l; i++, l = cdr(l)((l)->rest))
527 foamArgv(s)((s)->foamGen.argv)[i].code = car(l)((l)->first);
528 return s;
529}
530
531Foam
532foamNewOfList1(FoamTag tag, AInt sub, FoamList lfoam)
533{
534 Foam s;
535 FoamList l;
536 int i;
537
538 s = foamNewEmpty(tag, 1 + listLength(Foam)(Foam_listPointer->_Length)(lfoam));
539 i = 0;
540 foamArgv(s)((s)->foamGen.argv)[i++].data = sub;
541
542 for (l = lfoam; l; i++, l = cdr(l)((l)->rest))
543 foamArgv(s)((s)->foamGen.argv)[i].code = car(l)((l)->first);
544 return s;
545}
546
547Foam
548foamCopyNode(Foam foam)
549{
550 Foam newFoam;
551 Length i, argc = foamArgc(foam)((foam)->hdr.argc);
552
553 if (foamTag(foam)((foam)->hdr.tag) == FOAM_DFlo)
554 newFoam = foamNewDFlo(foam->foamDFlo.DFloData);
555 else {
556 newFoam = foamNewEmpty(foamTag(foam)((foam)->hdr.tag), argc);
557 for (i = 0; i < argc; i++)
558 foamArgv(newFoam)((newFoam)->foamGen.argv)[i] = foamArgv(foam)((foam)->foamGen.argv)[i];
559 }
560
561 foamPos(newFoam)((newFoam)->hdr.pos) = foamPos(foam)((foam)->hdr.pos);
562 foamSyme(newFoam)((newFoam)->hdr.syme) = foamSyme(foam)((foam)->hdr.syme);
563
564 /* if (!otIsVar(foam)) */
565 if (foamTag(foam)((foam)->hdr.tag) != FOAM_Loc &&
566 foamTag(foam)((foam)->hdr.tag) != FOAM_Par &&
567 foamTag(foam)((foam)->hdr.tag) != FOAM_Lex &&
568 foamTag(foam)((foam)->hdr.tag) != FOAM_Glo)
569 foamOptInfo(newFoam)((newFoam)->hdr.info.opt) = foamOptInfo(foam)((foam)->hdr.info.opt);
570
571 return newFoam;
572}
573
574Foam
575foamCopy(Foam foam)
576{
577 Foam newFoam;
578 String argf = foamInfo(foamTag(foam))(foamInfoTable [(int)(((foam)->hdr.tag))-(int)FOAM_START]).argf;
579 Length i;
580
581 newFoam = foamCopyNode(foam);
582
583 for (i = 0; i < foamArgc(foam)((foam)->hdr.argc); i++, argf++) {
584 if (*argf == '*') argf--;
585 switch (*argf) {
586 case 'C': {
587 Foam *arg = (Foam *) foamArgv(foam)((foam)->foamGen.argv)+i;
588 foamArgv(newFoam)((newFoam)->foamGen.argv)[i].code = foamCopy(*arg);
589 break;
590 }
591 case 's':
592 foamArgv(newFoam)((newFoam)->foamGen.argv)[i].str = strCopy(foamArgv(foam)((foam)->foamGen.argv)[i].str);
593 break;
594 case 'n':
595 foamArgv(newFoam)((newFoam)->foamGen.argv)[i].bint =
596 bintCopy(foamArgv(foam)((foam)->foamGen.argv)[i].bint);
597 break;
598 }
599 }
600 return newFoam;
601}
602
603void
604foamFree(Foam foam)
605{
606 int si, fi;
607 String argf;
608
609 if (!foamIsInit) foamInit();
610 if (!foam) return;
611
612 argf = foamInfo(foamTag(foam))(foamInfoTable [(int)(((foam)->hdr.tag))-(int)FOAM_START]).argf;
613
614 for (si = fi = 0; si < foamArgc(foam)((foam)->hdr.argc); si++, fi++) {
615 if (argf[fi] == '*') fi--;
616 switch (argf[fi]) {
617 case 'C': foamFree(foamArgv(foam)((foam)->foamGen.argv)[si].code); break;
618 case 's': strFree(foamArgv(foam)((foam)->foamGen.argv)[si].str); break;
619 case 'n': bintFree(foamArgv(foam)((foam)->foamGen.argv)[si].bint); break;
620 }
621 }
622 /*!!
623 if (foamOptInfo(foam)) stoFree(foamOptInfo(foam));
624 */
625 stoFree((Pointer) foam);
626}
627
628Length
629foamNodeCount(Foam foam)
630{
631 Length n, si, fi;
632 String argf;
633
634 n = 1;
635 argf = foamInfo(foamTag(foam))(foamInfoTable [(int)(((foam)->hdr.tag))-(int)FOAM_START]).argf;
636 for (si = fi = 0; si < foamArgc(foam)((foam)->hdr.argc); si++, fi++) {
637 if (argf[fi] == '*') fi--;
638 if (argf[fi] == 'C')
639 n += foamNodeCount(foamArgv(foam)((foam)->foamGen.argv)[si].code);
640 }
641 return n;
642}
643
644int
645foamNaryStart(FoamTag tag)
646{
647 String argf;
648 int n=0;
649
650 argf = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argf;
651 while (argf[n]!='*')
652 n++;
653
654 return n-1;
655}
656
657/*
658 * :: Foam Equality
659 *
660 * This is complicated by the way SInt is dealt with in foamToBuffer.
661 * 64 bit foam SInt constants are rewritten as 32 bit expressions, but
662 * should be considered equal when we want to verify foamToBuffer and
663 * foamFrBuffer are consistent.
664 */
665localstatic Bool foamEqual1(int mods, Foam f1, Foam f2);
666
667#define FE_ModSIntReduce(1<<0) (1<<0)
668localstatic Bool foamEqual0(int mods, Foam f1, Foam f2);
669
670Bool
671foamEqualModBuffer(Foam f1, Foam f2)
672{
673 return foamEqual0(FE_ModSIntReduce(1<<0), f1, f2);
674}
675
676Bool
677foamEqual(Foam f1, Foam f2)
678{
679 return foamEqual0(0, f1, f2);
680}
681
682localstatic Bool
683foamEqual0(int mods, Foam f1, Foam f2)
684{
685 Foam of1 = f1;
686 Foam of2 = f2;
687 Bool ret;
688 if (mods & FE_ModSIntReduce(1<<0)) {
689 if (foamTag(f1)((f1)->hdr.tag) == FOAM_SInt)
690 f1 = foamSIntReduce(f1);
691 if (foamTag(f2)((f2)->hdr.tag) == FOAM_SInt)
692 f2 = foamSIntReduce(f2);
693 }
694
695 ret = foamEqual1(mods, f1, f2);
696 if (of1 != f1)
697 foamFree(f1);
698 if (of2 != f2)
699 foamFree(f2);
700 return ret;
701}
702
703localstatic Bool
704foamEqual1(int mods, Foam f1, Foam f2)
705{
706 int fi, si;
707 String argf;
708
709 if (foamTag(f1)((f1)->hdr.tag) != foamTag(f2)((f2)->hdr.tag)) return false((int) 0);
710 if (foamArgc(f1)((f1)->hdr.argc) != foamArgc(f2)((f2)->hdr.argc)) return false((int) 0);
711
712 argf = foamInfo(foamTag(f1))(foamInfoTable [(int)(((f1)->hdr.tag))-(int)FOAM_START]).argf;
713
714 for (si = fi = 0; si < foamArgc(f1)((f1)->hdr.argc); si++, fi++) {
715 if (argf[fi] == '*') fi--;
716 switch (argf[fi]) {
717 case 'C':
718 if (!foamEqual0(mods, foamArgv(f1)((f1)->foamGen.argv)[si].code,
719 foamArgv(f2)((f2)->foamGen.argv)[si].code))
720 return false((int) 0);
721 break;
722 case 't':
723 case 'o':
724 case 'p':
725 case 'D':
726 case 'b':
727 case 'h':
728 case 'w':
729 case 'i':
730 case 'L':
731 case 'X':
732 case 'F':
733 if (foamArgv(f1)((f1)->foamGen.argv)[si].data != foamArgv(f2)((f2)->foamGen.argv)[si].data)
734 return false((int) 0);
735 break;
736 case 'f':
737 if (foamArgv(f1)((f1)->foamGen.argv)[si].sfloat != foamArgv(f2)((f2)->foamGen.argv)[si].sfloat)
738 return false((int) 0);
739 break;
740 case 's':
741 if (!strEqual(foamArgv(f1)((f1)->foamGen.argv)[si].str,
742 foamArgv(f2)((f2)->foamGen.argv)[si].str))
743 return false((int) 0);
744 break;
745 case 'n':
746 if (!bintEQ(foamArgv(f1)((f1)->foamGen.argv)[si].bint,
747 foamArgv(f2)((f2)->foamGen.argv)[si].bint))
748 return false((int) 0);
749 break;
750 case 'd':
751 if (*((DFloat *) foamArgv(f1)((f1)->foamGen.argv)) !=
752 *((DFloat *) foamArgv(f2)((f2)->foamGen.argv)))
753 return false((int) 0);
754 break;
755 default:
756 bugBadCase(argf[si])bug("Bad case %d (line %d in file %s).", (int) argf[si], 756,
"foam.c")
;
757 break;
758 }
759 }
760 return true1;
761}
762
763Hash
764foamHash(Foam foam)
765{
766 Hash h;
767 Length si, fi;
768 String argf;
769
770 h = 0;
771
772 argf = foamInfo(foamTag(foam))(foamInfoTable [(int)(((foam)->hdr.tag))-(int)FOAM_START]).argf;
773
774 for (si = fi = 0; si < foamArgc(foam)((foam)->hdr.argc); si++, fi++) {
775 if (argf[fi] == '*') fi--;
776 h ^= (h << 8);
777 switch (argf[fi]) {
778 case 'C':
779 h += foamHash(foamArgv(foam)((foam)->foamGen.argv)[si].code);
780 break;
781 case 't':
782 case 'o':
783 case 'p':
784 case 'D':
785 case 'b':
786 case 'h':
787 case 'w':
788 case 'i':
789 case 'L':
790 case 'X':
791 case 'F':
792 case 'f':
793 h += foamArgv(foam)((foam)->foamGen.argv)[si].data;
794 break;
795 case 's':
796 h += strHash(foamArgv(foam)((foam)->foamGen.argv)[si].str);
797 break;
798 case 'd':
799 case 'n':
800 /*!! Hash for biginit and double */
801 break;
802 default:
803 bugBadCase(argf[si])bug("Bad case %d (line %d in file %s).", (int) argf[si], 803,
"foam.c")
;
804 break;
805 }
806 h += 200041;
807 h &= 0x3FFFFFFF;
808 }
809
810 h += foamTag(foam)((foam)->hdr.tag);
811 h &= 0x3FFFFFFF;
812 return h;
813}
814
815void
816foamFreeNode(Foam foam)
817{
818 stoFree((Pointer) foam);
819}
820
821int
822foamPrint(FILE *fout, Foam foam)
823{
824 return foamWrSExpr(fout, foam, SXRW_Default((1L<<1) | (1L<<3)));
825}
826
827int
828foamPrintDb(Foam foam)
829{
830 return foamWrSExpr(dbOut, foam, int0((int) 0));
831}
832
833void
834foamDumpToFile(Foam foam, String name)
835{
836 FILE *out = fileTryOpen(fnameParse(name), osIoWrMode);
837
838 /* Only dump if we managed to open the file */
839 if (out)
840 {
841 (void)foamWrSExpr(out, foam, SXRW_NoSrcPos(1L<<3));
842 (void)fclose(out);
843 }
844 else
845 (void)fprintf(dbOut, "Sorry: failed to create `%s'\n", name);
846}
847
848int
849foamDefPrintDb(Foam foam, int defNo)
850{
851 Foam defs;
852
853 assert(foamTag(foam) == FOAM_Unit)do { if (!(((foam)->hdr.tag) == FOAM_Unit)) _do_assert(("foamTag(foam) == FOAM_Unit"
),"foam.c",853); } while (0)
;
854
855 defs = foam->foamUnit.defs;
856
857 return foamPrintDb(defs->foamDDef.argv[defNo]);
858}
859
860Bool
861foamProgHasMultiAssign(Foam prog)
862{
863 int bodyArgc, i;
864 Foam seq;
865 assert(foamTag(prog) == FOAM_Prog)do { if (!(((prog)->hdr.tag) == FOAM_Prog)) _do_assert(("foamTag(prog) == FOAM_Prog"
),"foam.c",865); } while (0)
;
866 seq = prog->foamProg.body;
867 bodyArgc = foamArgc(seq)((seq)->hdr.argc);
868
869 for (i = 0; i < bodyArgc; i++) {
870 if (foamIsMultiAssign(seq->foamSeq.argv[i])) {
871 return true1;
872 }
873 }
874
875 return false((int) 0);
876}
877
878AInt
879foamProgFormatForLevel(Foam prog, AInt level)
880{
881 return prog->foamProg.levels->foamDEnv.argv[level];
882}
883
884
885Bool
886foamIsMultiAssign(Foam foam)
887{
888 return (foamTag(foam)((foam)->hdr.tag) == FOAM_Set || foamTag(foam)((foam)->hdr.tag) == FOAM_Def)
889 && foamTag(foam->foamSet.lhs)((foam->foamSet.lhs)->hdr.tag) == FOAM_Values;
890}
891
892Bool
893foamDeclEqual(Foam decl1, Foam decl2)
894{
895 return decl1->foamDecl.type == decl2->foamDecl.type
896 && decl1->foamDecl.format == decl2->foamDecl.format;
897}
898
899Bool
900foamUnitHasCoroutine(Foam foam)
901{
902 int i;
903 for (i=0; i<foamArgc(foam->foamUnit.defs)((foam->foamUnit.defs)->hdr.argc); i++) {
904 Foam def = foam->foamUnit.defs->foamDDef.argv[i];
905 Foam prog;
906 if (foamTag(def->foamDef.rhs)((def->foamDef.rhs)->hdr.tag) != FOAM_Prog) {
907 continue;
908 }
909 prog = def->foamDef.rhs;
910 if (foamProgIsCoroutine(prog)((prog)->foamProg.infoBits & (1 << 7))) {
911 return true1;
912 }
913 }
914 return false((int) 0);
915}
916
917/** Return the next statement in seq which is reachable */
918int
919foamSeqNextReachable(Foam seq, int index)
920{
921 Foam lastStmt;
922
923 if (index == foamArgc(seq)((seq)->hdr.argc) - 1)
924 return -1;
925 if (index == -1)
926 return 0;
927
928 lastStmt = seq->foamSeq.argv[index];
929 if (foamTag(lastStmt)((lastStmt)->hdr.tag) == FOAM_Goto
930 || foamInfo(foamTag(lastStmt))(foamInfoTable [(int)(((lastStmt)->hdr.tag))-(int)FOAM_START
])
.properties & FOAMP_SeqExit(1<<0)) {
931 index++;
932 while (index < foamArgc(seq)((seq)->hdr.argc)) {
933 Foam nextStmt = seq->foamSeq.argv[index];
934 if (foamTag(nextStmt)((nextStmt)->hdr.tag) == FOAM_Label)
935 return index;
936 index++;
937 }
938 return -1;
939 }
940 return index + 1;
941}
942
943
944/* Foam Auditing */
945
946localstatic Bool foamAuditExpr (Foam foam);
947localstatic void foamAuditBadRef (Foam foam);
948localstatic void foamAuditBadSharing (Foam foam);
949localstatic void foamAuditBadRuntime (Foam foam);
950localstatic void foamAuditBadCast (Foam foam);
951localstatic void foamAuditBadDecl (Foam foam);
952localstatic void foamAuditBadType (Foam foam);
953localstatic void foamAuditBadEnv (Foam foam);
954
955Foam faUnit;
956Foam faProg;
957Foam faFormats;
958Foam * faFormatsv;
959Foam * faGlobalsv;
960Foam * faFluidsv;
961int faNumFormats;
962int faNumConsts;
963int faNumGlobals;
964int faNumFluids;
965AInt * faDEnv;
966int faNumLevels;
967int faConstNum;
968int faNumLocals;
969int faNumParams;
970
971#define faNumLexes(level)((faFormatsv[faDEnv[level]])->hdr.argc) foamArgc(faFormatsv[faDEnv[level]])((faFormatsv[faDEnv[level]])->hdr.argc)
972
973#define FOAM_AUDIT_Records0x0001 0x0001
974#define FOAM_AUDIT_Envs0x0002 0x0002
975#define FOAM_AUDIT_BCall0x0004 0x0004
976#define FOAM_AUDIT_Values0x0008 0x0008
977#define FOAM_AUDIT_If0x0010 0x0010
978#define FOAM_AUDIT_Return0x0020 0x0020
979#define FOAM_AUDIT_Cast0x0040 0x0040
980
981
982#define FOAM_AUDIT_All0xffff 0xffff
983
984localstatic Bool faAll = false((int) 0);
985static Bool foamAuditTypeChecking = false((int) 0); /* fluid variable */
986
987localstatic Bool foamAuditRecords = false((int) 0);
988localstatic Bool foamAuditBCall = false((int) 0);
989localstatic Bool foamAuditEnvs = false((int) 0);
990localstatic Bool foamAuditValues = false((int) 0);
991localstatic Bool foamAuditIf = false((int) 0);
992localstatic Bool foamAuditReturn = false((int) 0);
993localstatic Bool foamAuditCast = false((int) 0);
994
995
996localstatic Bool foamAudit0 (Foam);
997localstatic Bool foamAuditTypeCheck (Foam);
998localstatic void foamAuditCastExpr (Foam foam);
999localstatic void foamAuditDEnv (Foam foam);
1000localstatic void foamAuditPCall (Foam foam);
1001localstatic void foamAuditPCallJava (Foam foam);
1002
1003localstatic Bool faTypeCheckingValues (Foam, Foam, AInt);
1004localstatic Bool faTypeCheckingFmtIsEnv (Foam, AInt);
1005localstatic Bool faTypeCheckingFmtIsRec (Foam, AInt);
1006localstatic Bool faTypeCheckingBCall (Foam);
1007localstatic FoamTag faFoamExprType (Foam, AInt *);
1008
1009localstatic void faTypeCheckingFailure (Foam, String, ...) chk_fmt (2, 3)__attribute__((format(printf, 2, 3)));
1010
1011localstatic void foamAuditUnmark (Foam);
1012
1013void
1014foamAuditSetAll()
1015{
1016 faAll = true1;
1017}
1018
1019Bool
1020foamAuditAll(Foam foam, UShort tests)
1021{
1022 Scope("foamAuditAll")String scopeName = ("foamAuditAll"); int fluidLevel0 = (scopeLevel
++, fluidLevel)
;
1023 Bool fluid(foamAuditTypeChecking)fluidSave_foamAuditTypeChecking = ( fluidStack = (fluidLevel==
fluidLimit) ? fluidGrow() : fluidStack, fluidStack[fluidLevel
].scopeName = scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel
, fluidStack[fluidLevel].pglobal = (Pointer) &(foamAuditTypeChecking
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_foamAuditTypeChecking
, fluidStack[fluidLevel].size = sizeof(foamAuditTypeChecking)
, fluidLevel++, (foamAuditTypeChecking) )
;
1024 Bool result;
1025
1026 /* Type checking disabled - there's a very large number
1027 * of edge cases that need to be cleared up before it
1028 * can work */
1029 foamAuditTypeChecking = false((int) 0);
1030
1031 foamAuditRecords = (tests & FOAM_AUDIT_Records0x0001);
1032 foamAuditEnvs = (tests & FOAM_AUDIT_Envs0x0002);
1033 foamAuditBCall = (tests & FOAM_AUDIT_BCall0x0004);
1034 foamAuditValues = (tests & FOAM_AUDIT_Values0x0008);
1035 foamAuditIf = (tests & FOAM_AUDIT_If0x0010);
1036 foamAuditReturn = (tests & FOAM_AUDIT_Return0x0020);
1037 foamAuditCast = (tests & FOAM_AUDIT_Cast0x0040);
1038
1039 result = foamAudit0(foam);
1040
1041 Return(result){ fluidUnwind(fluidLevel0, ((int) 0)); return result;; };
1042}
1043
1044Bool
1045foamAudit(Foam foam)
1046{
1047 return foamAuditAll(foam, 0xFFFF);
1048}
1049
1050/* Check variable references and formats for consistency. */
1051localstatic Bool
1052foamAudit0(Foam foam)
1053{
1054 Bool ok;
1055 assert(foamTag(foam) == FOAM_Unit)do { if (!(((foam)->hdr.tag) == FOAM_Unit)) _do_assert(("foamTag(foam) == FOAM_Unit"
),"foam.c",1055); } while (0)
;
1056 faUnit = foam;
1057 faFormats = foamUnitFormats(foam)((foam)->foamUnit.formats); /* used for type checking */
1058 faFormatsv = foamUnitFormats(foam)((foam)->foamUnit.formats)->foamDFmt.argv;
1059 faGlobalsv = foamUnitGlobals(foam)((((foam)->foamUnit.formats)->foamGen.argv)[0].code)->foamDDecl.argv;
1060 faFluidsv = foamUnitGlobals(foam)((((foam)->foamUnit.formats)->foamGen.argv)[0].code)->foamDDecl.argv;
1061 faNumFormats = foamArgc(foamUnitFormats(foam))((((foam)->foamUnit.formats))->hdr.argc);
1062 faNumConsts = foamDDeclArgc(foamUnitConstants(foam))(((((((foam)->foamUnit.formats)->foamGen.argv)[1].code)
)->hdr.argc) - (1))
;
1063 faNumGlobals = foamDDeclArgc(foamUnitGlobals(foam))(((((((foam)->foamUnit.formats)->foamGen.argv)[0].code)
)->hdr.argc) - (1))
;
1064 faNumFluids = foamDDeclArgc(foamUnitFluids(foam))(((((((foam)->foamUnit.formats)->foamGen.argv)[3].code)
)->hdr.argc) - (1))
;
1065 ok = foamAuditExpr(foam->foamUnit.defs);
1066 if (ok) {
1067 phaseDEBUGif (!phaseDebug) { } else afprintf(dbOut, "Foam OK\n");
1068 }
1069 foamAuditUnmark(foam);
1070 return ok;
1071}
1072
1073localstatic Bool
1074foamAuditExpr(Foam foam)
1075{
1076 Bool result = true1;
1077 Bool checkTypes = false((int) 0);
1078 assert(foam)do { if (!(foam)) _do_assert(("foam"),"foam.c",1078); } while
(0)
;
1079 assert(foamTag(foam) <= FOAM_LIMIT)do { if (!(((foam)->hdr.tag) <= FOAM_LIMIT)) _do_assert
(("foamTag(foam) <= FOAM_LIMIT"),"foam.c",1079); } while (
0)
;
1080 if (foamMark(foam)((foam)->hdr.mark) == FOAM_MARKED0x01)
1081 foamAuditBadSharing(foam);
1082 foamMark(foam)((foam)->hdr.mark) = FOAM_MARKED0x01;
1083
1084 switch (foamTag(foam)((foam)->hdr.tag)) {
1085 case FOAM_Prog:
1086 faProg = foam;
1087 faDEnv = foam->foamProg.levels->foamDEnv.argv;
1088 faNumLevels = foamArgc(foam->foamProg.levels)((foam->foamProg.levels)->hdr.argc);
1089 faNumLocals = foamDDeclArgc(foam->foamProg.locals)(((foam->foamProg.locals)->hdr.argc) - (1));
1090 faNumParams = foamDDeclArgc(foam->foamProg.params)(((foam->foamProg.params)->hdr.argc) - (1));
1091 break;
1092 case FOAM_Def:
1093 if (foamTag(foam->foamDef.lhs)((foam->foamDef.lhs)->hdr.tag) == FOAM_Const)
1094 faConstNum = foam->foamDef.lhs->foamConst.index;
1095 break;
1096 default:
1097 break;
1098 }
1099
1100 foamIter(foam, arg, foamAuditExpr(*arg)){ { 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; { foamAuditExpr(*arg); }; } } }; }
;
1101
1102 switch (foamTag(foam)((foam)->hdr.tag)) {
1103 case FOAM_Set:
1104 case FOAM_Def:
1105 if (foamTag(foam->foamSet.lhs)((foam->foamSet.lhs)->hdr.tag) == FOAM_Values
1106 && foamArgc(foam->foamSet.lhs)((foam->foamSet.lhs)->hdr.argc) == 0)
1107 foamAuditBadRef(foam);
1108 break;
1109 case FOAM_If:
1110 checkTypes = true1;
1111 break;
1112 case FOAM_Loc:
1113 if (foam->foamLoc.index >= faNumLocals)
1114 foamAuditBadRef(foam);
1115 break;
1116 case FOAM_Par:
1117 if (foam->foamPar.index >= faNumParams)
1118 foamAuditBadRef(foam);
1119 break;
1120 case FOAM_Lex:
1121 if (foam->foamLex.level >= faNumLevels ||
1122 faDEnv[foam->foamLex.level] >= faNumFormats ||
1123 foam->foamLex.index >= faNumLexes(foam->foamLex.level)((faFormatsv[faDEnv[foam->foamLex.level]])->hdr.argc))
1124 foamAuditBadRef(foam);
1125 if (foam->foamLex.level < 0)
1126 foamAuditBadRef(foam);
1127 break;
1128 case FOAM_Const:
1129 if (foam->foamConst.index >= faNumConsts)
1130 foamAuditBadRef(foam);
1131 break;
1132 case FOAM_Glo:
1133 if (foam->foamGlo.index >= faNumGlobals)
1134 foamAuditBadRef(foam);
1135 break;
1136 case FOAM_Fluid:
1137 if (foam->foamFluid.index >= faNumFluids)
1138 foamAuditBadRef(foam);
1139 break;
1140 case FOAM_EElt:
1141 if (foam->foamEElt.env >= faNumFormats ||
1142 foam->foamEElt.lex >=
1143 foamArgc(faFormatsv[foam->foamEElt.env])((faFormatsv[foam->foamEElt.env])->hdr.argc))
1144 foamAuditBadRef(foam);
1145 if (foam->foamEElt.level < 0)
1146 foamAuditBadRef(foam);
1147 break;
1148 case FOAM_Env:
1149 if (foam->foamEnv.level < 0)
1150 foamAuditBadRef(foam);
1151 if (foam->foamEnv.level >= faNumLevels)
1152 foamAuditBadRef(foam);
1153 break;
1154 case FOAM_RElt:
1155 if (foam->foamRElt.format >= faNumFormats)
1156 foamAuditBadRef(foam);
1157 break;
1158 case FOAM_RRElt:
1159 if (foam->foamRRElt.field < 0)
1160 foamAuditBadRef(foam);
1161 break;
1162 case FOAM_RRNew:
1163 break;
1164 case FOAM_RRFmt:
1165 if (foamTag(foam->foamRRFmt.fmt)((foam->foamRRFmt.fmt)->hdr.tag) != FOAM_Values)
1166 foamAuditBadRef(foam);
1167 break;
1168 case FOAM_RNew:
1169 if (foam->foamRNew.format >= faNumFormats)
1170 foamAuditBadRef(foam);
1171 break;
1172 case FOAM_PushEnv:
1173 if (foam->foamPushEnv.format >= faNumFormats)
1174 foamAuditBadRef(foam);
1175 break;
1176 case FOAM_Cast:
1177 if (foamTag(foam->foamCast.expr)((foam->foamCast.expr)->hdr.tag) == FOAM_Values)
1178 foamAuditBadCast(foam);
1179 foamAuditCastExpr(foam);
1180 break;
1181 case FOAM_CCall:
1182 /* There was a check for runtime constraint breakage
1183 * here - removed as a layering violation... */
1184 break;
1185 case FOAM_Decl:
1186 foamAuditDecl(foam);
1187 break;
1188 case FOAM_DEnv:
1189 foamAuditDEnv(foam);
1190 break;
1191 case FOAM_PCall:
1192 foamAuditPCall(foam);
1193 break;
1194 default:
1195 break;
1196 }
1197
1198 if (foamAuditTypeChecking)
1199 result = foamAuditTypeCheck(foam);
1200
1201 return result;
1202}
1203
1204void
1205foamAuditDecl(Foam decl)
1206{
1207 FoamTag type = decl->foamDecl.type;
1208 AInt fmt = decl->foamDecl.format;
1209 switch (type) {
1210 case FOAM_Arr:
1211 if (fmt >= FOAM_DATA_LIMIT && fmt != FOAM_BInt)
1212 foamAuditBadDecl(decl);
1213 break;
1214 case FOAM_JavaObj:
1215 if (fmt >= faNumFormats)
1216 foamAuditBadDecl(decl);
1217 break;
1218 case FOAM_CObj:
1219 if (fmt >= faNumFormats)
1220 foamAuditBadDecl(decl);
1221 break;
1222 case FOAM_Rec:
1223 /*
1224 TODO: Fix implicit exports so that they don't
1225 have argument types of FOAM_Rec.
1226 if (fmt == emptyFormatSlot)
1227 foamAuditBadDecl(decl);
1228 */
1229 break;
1230 case FOAM_Env:
1231 // There's an argument for tracking types of env properly
1232 default:
1233 if (fmt != emptyFormatSlot4 && fmt != 0)
1234 foamAuditBadDecl(decl);
1235 break;
1236 }
1237}
1238
1239void
1240foamAuditCastExpr(Foam foam)
1241{
1242 FoamTag type = foam->foamCast.type;
1243 FoamTag exprType = faFoamExprType(foam->foamCast.expr, NULL((void*)0));
1244
1245 if (type == FOAM_Ptr && exprType == FOAM_SInt) {
1246 foamAuditBadType(foam);
1247 }
1248
1249 if (type == FOAM_BInt && foamTag(foam->foamCast.expr)((foam->foamCast.expr)->hdr.tag) == FOAM_Arr) {
1250 foamAuditBadType(foam);
1251 }
1252}
1253
1254localstatic void
1255foamAuditDEnv(Foam foam)
1256{
1257 IntSet is;
1258 int i;
1259
1260 is = intSetNew(foamArgc(faFormats)((faFormats)->hdr.argc));
1261 for (i=0; i<foamDEnvArgc(foam)((foam)->hdr.argc); i++) {
1262 AInt fmt = foam->foamDEnv.argv[i];
1263 if (fmt < 0 || fmt > foamArgc(faFormats)((faFormats)->hdr.argc))
1264 foamAuditBadEnv(foam);
1265 if (fmt != emptyFormatSlot4 && fmt != 0 && intSetMember(is, fmt)) {
1266 foamAuditBadEnv(foam);
1267 }
1268 intSetAdd(is, fmt);
1269 }
1270 intSetFree(is);
1271}
1272
1273localstatic void
1274foamAuditPCall(Foam foam)
1275{
1276 AInt proto = foam->foamPCall.protocol;
1277 switch (proto) {
1278 case FOAM_Proto_Java:
1279 case FOAM_Proto_JavaMethod:
1280 case FOAM_Proto_JavaConstructor:
1281 foamAuditPCallJava(foam);
1282 break;
1283 default:
1284 break;
1285 }
1286
1287}
1288
1289localstatic void
1290foamAuditPCallJava(Foam foam)
1291{
1292 Foam op, glo, ddecl;
1293 int extra;
1294
1295 op = foam->foamPCall.op;
1296 if (foamTag(op)((op)->hdr.tag) == FOAM_Arr) {
1297 if (op->foamArr.baseType != FOAM_Char)
1298 bug("incorrect type for java pcall");
1299 return;
1300 }
1301 if (foamTag(op)((op)->hdr.tag) != FOAM_Glo)
1302 foamAuditBadType(foam);
1303 glo = faGlobalsv[op->foamGlo.index];
1304 ddecl = faFormats->foamDFmt.argv[glo->foamGDecl.format];
1305
1306 if (ddecl->foamDDecl.usage != FOAM_DDecl_JavaSig)
1307 foamAuditBadType(foam);
1308
1309 if (javaSigArgc(ddecl) != foamPCallArgc(foam)(((foam)->hdr.argc) - (3)))
1310 foamAuditBadType(foam);
1311}
1312
1313/**************************************************************************
1314 * NOTE: This procedure doesn't perform type checking on subtrees,
1315 * except in the case of (Values ...).
1316 *
1317 * PLEASE, update this documentation if other controls are added.
1318 *
1319 * WHAT is checked?
1320 *
1321 * - (Set typeA typeB) typeA == typeB ?
1322 * - (Set (Values X1..Xn) (MFmt F ..)) -> has F n slots ?
1323 * -> type Xi correspond to type slot?
1324 * - (If (test is Boolean) ..)
1325 * - (Return expr) -> does expr match type of Prog ?
1326 * - (Return (Values ...)) -> as (Set (Values ...
1327 * - (Cast T (expr)) -> expr already of type T ?
1328 * - (PushEnv FMT ...) -> Is FMT an env format ?
1329 * - (EElt FMT ...) -> " " "
1330 * - (BCall ...) -> arguments type checking
1331 * - ( FMT ), appearing in a record context -> is a record format ?
1332 *
1333 **************************************************************************/
1334localstatic Bool
1335foamAuditTypeCheck(Foam foam)
1336{
1337 AInt type, fmt;
1338
1339 switch (foamTag(foam)((foam)->hdr.tag)) {
1340 case FOAM_Set:
1341 case FOAM_Def: {
1342 Foam lhs, rhs;
1343 AInt typeLhs, typeRhs, fmtLhs, fmtRhs;
1344
1345 lhs = foam->foamSet.lhs;
1346 rhs = foam->foamSet.rhs;
1347
1348 if (!foamIsRef(lhs) && (foamTag(lhs)((lhs)->hdr.tag) != FOAM_Values)) {
1349 faTypeCheckingFailure(foam, "lhs is not an l-value");
1350 return false((int) 0);
1351 }
1352
1353 if (foamTag(lhs)((lhs)->hdr.tag) == FOAM_Values) {
1354
1355 if (foamTag(rhs)((rhs)->hdr.tag) != FOAM_MFmt) {
1356 faTypeCheckingFailure(foam,
1357 "lhs is Values, but no MFmt on the rhs");
1358 return false((int) 0);
1359 }
1360
1361 return faTypeCheckingValues(foam, lhs,
1362 rhs->foamMFmt.format);
1363 }
1364 else {
1365 typeLhs = faFoamExprType(lhs, &fmtLhs);
1366 typeRhs = faFoamExprType(rhs, &fmtRhs);
1367 if (typeLhs == FOAM_Nil && typeRhs == FOAM_Ptr)
1368 return true1;
1369 if (typeRhs == FOAM_Nil && typeLhs == FOAM_Ptr)
1370 return true1;
1371 if (typeRhs == FOAM_Nil && typeLhs == FOAM_Word)
1372 return true1;
1373
1374 if (typeLhs != typeRhs) {
1375 faTypeCheckingFailure(foam,
1376 "The type of lhs (%s) doesn't match type of rhs (%s).", foamInfo(typeLhs)(foamInfoTable [(int)(typeLhs)-(int)FOAM_START]).str, foamInfo(typeRhs)(foamInfoTable [(int)(typeRhs)-(int)FOAM_START]).str);
1377 return false((int) 0);
1378 }
1379
1380 if (typeLhs == FOAM_Rec && fmtLhs != fmtRhs
1381 && fmtLhs != emptyFormatSlot4 && fmtRhs != emptyFormatSlot4) {
1382 faTypeCheckingFailure(foam,
1383 "assignment between records with different formats");
1384 return false((int) 0);
1385 }
1386 if (typeLhs == FOAM_Arr && fmtLhs != fmtRhs
1387 && fmtLhs != 0 && fmtRhs != 0
1388 /* FIXME: The emptyFormatSlot clauses are wrong */
1389 && fmtLhs != emptyFormatSlot4 && fmtRhs != emptyFormatSlot4) {
1390 faTypeCheckingFailure(foam,
1391 "assignment between array with different base type (%s - %s)", foamInfo(fmtLhs)(foamInfoTable [(int)(fmtLhs)-(int)FOAM_START]).str, foamInfo(fmtRhs)(foamInfoTable [(int)(fmtRhs)-(int)FOAM_START]).str);
1392 return false((int) 0);
1393 }
1394 }
1395
1396 return true1;
1397 }
1398 case FOAM_If:
1399
1400 if (!foamAuditIf) return true1;
1401
1402 type = faFoamExprType(foam->foamIf.test, NULL((void*)0));
1403
1404 if (type != FOAM_Bool) {
1405 faTypeCheckingFailure(foam,
1406 "test of 'If' is not FOAM_Bool");
1407 return false((int) 0);
1408 }
1409 return true1;
1410
1411 case FOAM_Return:
1412
1413 if (!foamAuditReturn) return true1;
1414
1415 if (faProg->foamProg.retType == FOAM_NOp) {
1416
1417 if (foamTag(foam->foamReturn.value)((foam->foamReturn.value)->hdr.tag) != FOAM_Values) {
1418 faTypeCheckingFailure(foam,
1419 "Prog should return Values expr and a return without Values has been found");
1420 return false((int) 0);
1421 }
1422
1423 return faTypeCheckingValues(foam,
1424 foam->foamReturn.value,
1425 faProg->foamProg.format);
1426 }
1427
1428 type = faFoamExprType(foam->foamReturn.value, &fmt);
1429
1430 if (type != faProg->foamProg.retType) {
1431 AInt typeLhs = faProg->foamProg.retType;
1432 AInt typeRhs = type;
1433 if (typeLhs == FOAM_Nil && typeRhs == FOAM_Ptr)
1434 return true1;
1435 if (typeRhs == FOAM_Nil && typeLhs == FOAM_Ptr)
1436 return true1;
1437 if (typeRhs == FOAM_Nil && typeLhs == FOAM_Word)
1438 return true1;
1439 faTypeCheckingFailure(foam,
1440 "Return value type doesn't match Prog return type");
1441 return false((int) 0);
1442 }
1443
1444 return true1;
1445
1446 case FOAM_Cast:
1447
1448 if (!foamAuditCast) return true1;
1449
1450 type = faFoamExprType(foam->foamCast.expr, NULL((void*)0));
1451
1452 return true1;
1453
1454 /* ---------------- Envs ------------------------------- */
1455
1456 case FOAM_PushEnv:
1457 fmt = foam->foamPushEnv.format;
1458 return faTypeCheckingFmtIsEnv(foam, fmt);
1459
1460 case FOAM_EElt:
1461 fmt = foam->foamEElt.env;
1462 return faTypeCheckingFmtIsEnv(foam, fmt);
1463
1464 case FOAM_BCall:
1465 return faTypeCheckingBCall(foam);
1466
1467 default:
1468 return true1;
1469 }
1470}
1471
1472/* Given (Values X1..Xn) and a format, verify arity and type
1473 * FOAM is used to print the error msg
1474 */
1475localstatic Bool
1476faTypeCheckingValues(Foam foam, Foam values, AInt formatNo)
1477{
1478 int numFmtSlots, i;
1479 Foam decl;
1480 AInt type, fmt;
1481 Bool result = true1;
1482
1483 assert(foamTag(values) == FOAM_Values)do { if (!(((values)->hdr.tag) == FOAM_Values)) _do_assert
(("foamTag(values) == FOAM_Values"),"foam.c",1483); } while (
0)
;
1484
1485 if (!foamAuditValues) return true1;
1486
1487 /* Progs with formatNo = 0 are nullary */
1488 numFmtSlots = (formatNo ? foamDDeclArgc(faFormatsv[formatNo])(((faFormatsv[formatNo])->hdr.argc) - (1)) : 0);
1489
1490 if (formatNo == 0 && foamArgc(values)((values)->hdr.argc) == 0)
1491 return true1;
1492
1493 if (foamArgc(values)((values)->hdr.argc) != numFmtSlots) {
1494 faTypeCheckingFailure(foam,
1495 "Values arity and fmt slots different");
1496 return false((int) 0);
1497 }
1498
1499 for (i = 0; i < numFmtSlots; i++) {
1500 type = faFoamExprType(values->foamValues.argv[i], &fmt);
1501 decl = faFormatsv[formatNo]->foamDDecl.argv[i];
1502
1503 if (type != decl->foamDecl.type) {
1504 faTypeCheckingFailure(foam,
1505 "type of arg %d (%s) of Values doesn't match the type of corresponding slot (%s)",
1506 i, foamInfo(type)(foamInfoTable [(int)(type)-(int)FOAM_START]).str,
1507 foamInfo(decl->foamDecl.type)(foamInfoTable [(int)(decl->foamDecl.type)-(int)FOAM_START
])
.str);
1508 result = false((int) 0);
1509 }
1510
1511 if ((type == FOAM_Rec || type == FOAM_Arr) &&
1512 fmt != decl->foamDecl.format) {
1513 faTypeCheckingFailure(foam,
1514 "format of arg %d of Values doesn't match the format of corresponding slot", i);
1515 result = false((int) 0);
1516 }
1517
1518 if (type == FOAM_Rec &&
1519 !faTypeCheckingFmtIsRec(foam, fmt))
1520 result = false((int) 0);
1521 }
1522
1523 return result;
1524}
1525
1526localstatic Bool
1527faTypeCheckingFmtIsEnv(Foam foam, AInt format)
1528{
1529 if (!foamAuditEnvs)
1530 return true1;
1531
1532 if (faFormatsv[format]->foamDDecl.usage != FOAM_DDecl_LocalEnv &&
1533 faFormatsv[format]->foamDDecl.usage != FOAM_DDecl_NonLocalEnv &&
1534 format != envUsedSlot0) {
1535 faTypeCheckingFailure(foam,
1536 "NOT environment format used in environment context");
1537 return false((int) 0);
1538 }
1539
1540 return true1;
1541}
1542
1543localstatic Bool
1544faTypeCheckingFmtIsRec(Foam foam, AInt format)
1545{
1546 if (!foamAuditRecords)
1547 return true1;
1548
1549 if (faFormatsv[format]->foamDDecl.usage != FOAM_DDecl_Record) {
1550 faTypeCheckingFailure(foam,
1551 "NOT record format (" AINT_FMT"%ld" ") used in record context",
1552 format);
1553 return false((int) 0);
1554 }
1555
1556 return true1;
1557}
1558
1559localstatic Bool
1560faTypeCheckingBCall(Foam foam)
1561{
1562 int i, nargs;
1563 FoamBValTag op;
1564 AInt argType, parType, fmt;
1565 Bool result = true1;
1566
1567 assert(foamTag(foam) == FOAM_BCall)do { if (!(((foam)->hdr.tag) == FOAM_BCall)) _do_assert(("foamTag(foam) == FOAM_BCall"
),"foam.c",1567); } while (0)
;
1568
1569 if (!foamAuditBCall) return true1;
1570
1571 op = foam->foamBCall.op;
1572 nargs = foamBValInfo(op)(foamBValInfoTable[(int)(op)-(int)FOAM_BVAL_START]).argCount;
1573
1574 for (i = 0; i < nargs; i++) {
1575
1576 argType = faFoamExprType(foam->foamBCall.argv[i], &fmt);
1577
1578 parType = foamBValInfo(op)(foamBValInfoTable[(int)(op)-(int)FOAM_BVAL_START]).argTypes[i];
1579
1580 if (argType != parType) {
1581 faTypeCheckingFailure(foam,
1582 "Bad arg type (%s) to BCall: expected %s.",
1583 foamInfo(argType)(foamInfoTable [(int)(argType)-(int)FOAM_START]).str,
1584 foamInfo(parType)(foamInfoTable [(int)(parType)-(int)FOAM_START]).str);
1585 result = false((int) 0);
1586 }
1587
1588 if (argType == FOAM_Rec &&
1589 !faTypeCheckingFmtIsRec(foam, fmt))
1590 result = false((int) 0);
1591 }
1592
1593 return result;
1594}
1595
1596localstatic void
1597faTypeCheckingFailure(Foam foam, String msg, ...)
1598{
1599 va_list argp;
1600 va_start(argp, msg)__builtin_va_start(argp, msg);
1601
1602 fprintf(dbOut, "\n------ FoamAudit Type Checking failure in const %d: ------\n>> ",
1603 faConstNum);
1604 vfprintf(dbOut, msg, argp);
1605 fprintf(dbOut, "\nThe foam expression that caused the failure is:\n");
1606
1607 foamWrSExpr(dbOut, foam, SXRW_AsIs(0L));
1608 va_end(argp)__builtin_va_end(argp);
1609}
1610
1611localstatic FoamTag
1612faFoamExprType(Foam foam, AInt *fmt)
1613{
1614 FoamTag type = foamExprType0(foam,
1615 faProg, faFormats, NULL((void*)0), NULL((void*)0), fmt);
1616
1617 return type;
1618}
1619
1620/* Reset the foam sharing mark. */
1621localstatic void
1622foamAuditUnmark(Foam foam)
1623{
1624 foamIter(foam, arg, foamAuditUnmark(*arg)){ { 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; { foamAuditUnmark(*arg); }; } } }; }
;
1625
1626 foamMark(foam)((foam)->hdr.mark) = FOAM_UNMARKED0x00;
1627}
1628
1629localstatic void
1630foamAuditBadRef(Foam foam)
1631{
1632 foamPrint(stderrstderr, foam);
1633 if (DEBUG(foam)foamDebug){foamPrint(dbOut, faUnit);}
1634 bug("\nBad foam reference in const %d:\n", faConstNum);
1635}
1636
1637localstatic void
1638foamAuditBadSharing(Foam foam)
1639{
1640 foamPrint(stderrstderr, foam);
1641 if (DEBUG(foam)foamDebug){foamPrint(dbOut, faUnit);}
1642 bug("\nBad foam sharing in const %d:\n", faConstNum);
1643}
1644
1645localstatic void
1646foamAuditBadCast(Foam foam)
1647{
1648 foamPrint(stderrstderr, foam);
1649 if (DEBUG(foam)foamDebug){foamPrint(dbOut, faUnit);}
1650 bug("\nBad foam cast %d:\n", faConstNum);
1651}
1652
1653localstatic void
1654foamAuditBadDecl(Foam foam)
1655{
1656 foamPrint(stderrstderr, foam);
1657 if (DEBUG(foam)foamDebug){foamPrint(dbOut, faUnit);}
1658 bug("\nBad foam decl %d:\n", faConstNum);
1659}
1660
1661localstatic void
1662foamAuditBadType(Foam foam)
1663{
1664 foamPrint(stderrstderr, foam);
1665 bug("\nBad type %d:\n", faConstNum);
1666}
1667
1668localstatic void
1669foamAuditBadEnv(Foam foam)
1670{
1671 foamPrint(stderrstderr, foam);
1672 bug("\nBad env %d:\n", faConstNum);
1673}
1674
1675localstatic void
1676foamAuditBadRuntime(Foam foam)
1677{
1678 foamPrint(stderrstderr, foam);
1679 if (DEBUG(foam)foamDebug){foamPrint(dbOut, faUnit);}
1680 fprintf(dbOut, "\nBad runtime call to domainGetExport in const %d:\n",
1681 faConstNum);
1682}
1683
1684int
1685foamStdPrint(Foam foam)
1686{
1687 return foamPrint(dbOut, foam);
1688}
1689
1690/* Return true if foam is a lhs - except Values */
1691Bool
1692foamIsRef(Foam foam)
1693{
1694 switch(foamTag(foam)((foam)->hdr.tag)) {
1695
1696 case FOAM_Loc:
1697 case FOAM_Par:
1698 case FOAM_Lex:
1699 case FOAM_Glo:
1700 case FOAM_Const:
1701 case FOAM_RElt:
1702 case FOAM_RRElt:
1703 case FOAM_IRElt:
1704 case FOAM_TRElt:
1705 case FOAM_EElt:
1706 case FOAM_EInfo:
1707 case FOAM_PRef:
1708 case FOAM_CEnv:
1709 case FOAM_CProg:
1710 case FOAM_AElt:
1711 return true1;
1712 default:
1713 return false((int) 0);
1714 }
1715}
1716
1717/*
1718 * Determine when a foam expression is immediate data.
1719 */
1720Bool
1721foamIsData(Foam foam)
1722{
1723 switch(foamTag(foam)((foam)->hdr.tag)) {
1724 case FOAM_Nil:
1725 case FOAM_Char:
1726 case FOAM_Bool:
1727 case FOAM_Byte:
1728 case FOAM_HInt:
1729 case FOAM_SInt:
1730 case FOAM_BInt:
1731 case FOAM_SFlo:
1732 case FOAM_DFlo:
1733 case FOAM_Word:
1734 case FOAM_Arb:
1735 case FOAM_Arr:
1736 return true1;
1737 case FOAM_Cast:
1738 return foamIsData(foam->foamCast.expr);
1739 default:
1740 return false((int) 0);
1741 }
1742}
1743
1744/*
1745 * Returns a list of symes refered to in the foam.
1746 */
1747SymeList
1748foamSymeList(Foam foam)
1749{
1750 Foam *fmtv, *declv, dfmt, decl;
1751 Length fmtc, declc, i, j;
1752 Syme syme;
1753 SymeList l = listNil(Syme)((SymeList) 0);
1754
1755 assert(foamTag(foam) == FOAM_Unit)do { if (!(((foam)->hdr.tag) == FOAM_Unit)) _do_assert(("foamTag(foam) == FOAM_Unit"
),"foam.c",1755); } while (0)
;
1756 dfmt = foam->foamUnit.formats;
1757
1758 assert(foamTag(dfmt) == FOAM_DFmt)do { if (!(((dfmt)->hdr.tag) == FOAM_DFmt)) _do_assert(("foamTag(dfmt) == FOAM_DFmt"
),"foam.c",1758); } while (0)
;
1759 fmtv = dfmt->foamDFmt.argv;
1760 fmtc = foamArgc(dfmt)((dfmt)->hdr.argc);
1761
1762 for (i = 1; i < fmtc; i += 1) {
1763 assert(foamTag(fmtv[i]) == FOAM_DDecl)do { if (!(((fmtv[i])->hdr.tag) == FOAM_DDecl)) _do_assert
(("foamTag(fmtv[i]) == FOAM_DDecl"),"foam.c",1763); } while (
0)
;
1764 declv = fmtv[i]->foamDDecl.argv;
1765 declc = foamDDeclArgc(fmtv[i])(((fmtv[i])->hdr.argc) - (1));
1766 for (j = 0; j < declc; j += 1) {
1767 decl = declv[j];
1768 assert(foamIsDecl(decl))do { if (!((((decl)->hdr.tag) == FOAM_Decl))) _do_assert((
"foamIsDecl(decl)"),"foam.c",1768); } while (0)
;
1769 syme = foamSyme(decl)((decl)->hdr.syme);
1770 if (syme) l = listCons(Syme)(Syme_listPointer->Cons)(syme, l);
1771 }
1772 }
1773
1774 return listNReverse(Syme)(Syme_listPointer->NReverse)(l);
1775}
1776
1777/*****************************************************************************
1778 *
1779 * :: General Utilities
1780 *
1781 ****************************************************************************/
1782
1783/*
1784 * This can modify its argument, or even free parts of it.
1785 */
1786Foam
1787foamNotThis(Foam foam)
1788{
1789 return foamNew(FOAM_BCall, 2, FOAM_BVal_BoolNot, foam);
1790}
1791
1792int
1793foamCountSubtreesOfKind(Foam foam, FoamTag kind)
1794{
1795 int i, count;
1796
1797 assert(foam && foamTag(foam) == FOAM_Seq)do { if (!(foam && ((foam)->hdr.tag) == FOAM_Seq))
_do_assert(("foam && foamTag(foam) == FOAM_Seq"),"foam.c"
,1797); } while (0)
;
1798
1799 for (count = 0, i = 0; i < foamArgc(foam)((foam)->hdr.argc); i++)
1800 if (foamTag(foam->foamSeq.argv[i])((foam->foamSeq.argv[i])->hdr.tag) == kind) count++;
1801
1802 return count;
1803}
1804
1805/*****************************************************************************
1806 *
1807 * :: FOAM_Arr
1808 *
1809 ****************************************************************************/
1810
1811String
1812foamArrToString(Foam foam)
1813{
1814 int i, arrSize;
1815 String str;
1816 assert(foam->foamArr.baseType == FOAM_Char)do { if (!(foam->foamArr.baseType == FOAM_Char)) _do_assert
(("foam->foamArr.baseType == FOAM_Char"),"foam.c",1816); }
while (0)
;
1817
1818 arrSize = foamArgc(foam)((foam)->hdr.argc);
1819 str = strAlloc(arrSize);
1820 for (i = 0; i < arrSize - 1; i++)
1821 str[i] = foam->foamArr.eltv[i];
1822 str[i] = '\0';
1823
1824 return str;
1825}
1826
1827
1828/*****************************************************************************
1829 *
1830 * :: FOAM_GDecl
1831 *
1832 ****************************************************************************/
1833
1834Bool
1835foamGDeclIsExport(Foam foam)
1836{
1837 return foam->foamGDecl.dir == FOAM_GDecl_Export;
1838}
1839
1840Bool
1841foamGDeclIsImport(Foam foam)
1842{
1843 return foam->foamGDecl.dir == FOAM_GDecl_Import;
1844}
1845
1846Bool
1847foamGDeclIsExportOf(AInt tag, Foam foam)
1848{
1849 return foamGDeclIsExport(foam) && foam->foamGDecl.protocol == tag;
1850}
1851
1852
1853/*****************************************************************************
1854 *
1855 * :: Byte code conversion to/from Buffer
1856 *
1857 *****************************************************************************/
1858
1859#define STD_FORMS2 2 /* Number of standard formats.
1860 * I.e. all 4 or 2 or 1 bytes.
1861 * Cannot be changed */
1862#define IMMED_FORMS3 3 /* Number of immediate, implicit formats.
1863 * I.e. byte = 0, 1,...
1864 * Can be changed. */
1865#define NUM_FORMS(2 + 3) (STD_FORMS2 + IMMED_FORMS3)
1866
1867
1868#define FFO_ORIGIN(FOAM_VECTOR_START) (FOAM_VECTOR_START)
1869#define FFO_SPAN(FOAM_LIMIT - (FOAM_VECTOR_START)) (FOAM_LIMIT - FFO_ORIGIN(FOAM_VECTOR_START))
1870
1871#define FOAM_FORMAT_GET(tag)((tag)<(FOAM_VECTOR_START)? 0:(((tag)-(FOAM_VECTOR_START))
/(FOAM_LIMIT - (FOAM_VECTOR_START))))
((tag)<FFO_ORIGIN(FOAM_VECTOR_START)? 0:FOAM_FORMAT_GET_X(tag)(((tag)-(FOAM_VECTOR_START))/(FOAM_LIMIT - (FOAM_VECTOR_START
)))
)
1872#define FOAM_FORMAT_GET_X(tag)(((tag)-(FOAM_VECTOR_START))/(FOAM_LIMIT - (FOAM_VECTOR_START
)))
(((tag)-FFO_ORIGIN(FOAM_VECTOR_START))/FFO_SPAN(FOAM_LIMIT - (FOAM_VECTOR_START)))
1873#define FOAM_FORMAT_PUT(tag, fmt)((tag) + (fmt)*(FOAM_LIMIT - (FOAM_VECTOR_START))) ((tag) + (fmt)*FFO_SPAN(FOAM_LIMIT - (FOAM_VECTOR_START)))
1874#define FOAM_FORMAT_REMOVE(tag,fmt)((tag) - (fmt)*(FOAM_LIMIT - (FOAM_VECTOR_START))) ((tag) - (fmt)*FFO_SPAN(FOAM_LIMIT - (FOAM_VECTOR_START)))
1875
1876#define FOAM_FORMAT_FOR(n)((long)(n) <= ((1<<(1*8))-1) ? 1 : 0) \
1877 ((long)(n) <= MAX_BYTE((1<<(1*8))-1) ? 1 : 0)
1878
1879#define FOAM_PUT_INT(format, buf, i){ switch (format) { case 0: bufPutSInt(buf, i); break; case 1
: {if (i > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, i); break; default: break; } }
{ \
1880 switch (format) { \
1881 case 0: bufPutSInt(buf, i); break; \
1882 case 1: FOAM_CHK_INT(i){if (i > ((1<<(1*8))-1)) bug("oops - int too large")
;}
; bufPutByte(buf, i); break; \
1883 default: break; /* Included in tag. */ \
1884 } \
1885}
1886
1887#define FOAM_CHK_INT(i){if (i > ((1<<(1*8))-1)) bug("oops - int too large")
;}
{if (i > MAX_BYTE((1<<(1*8))-1)) bug("oops - int too large");}
1888
1889#define FOAM_GET_INT(format, buf, i){ switch (format) { case 0: (i) = bufGetSInt(buf); break; case
1: (i) = bufGetByte(buf); break; default: (i) = (format) - 2
; break; } }
{ \
1890 switch (format) { \
1891 case 0: (i) = bufGetSInt(buf); break; \
1892 case 1: (i) = bufGetByte(buf); break; \
1893 default: (i) = (format) - STD_FORMS2; break; \
1894 } \
1895}
1896
1897int
1898foamTagLimit(void)
1899{
1900 return 1 * FFO_ORIGIN(FOAM_VECTOR_START) + NUM_FORMS(2 + 3) * (FFO_SPAN(FOAM_LIMIT - (FOAM_VECTOR_START)));
1901}
1902
1903
1904/* For debugging */
1905int
1906foamTagSpanLength(void)
1907{
1908 return FFO_SPAN(FOAM_LIMIT - (FOAM_VECTOR_START));
1909}
1910
1911
1912localstatic int foamTagFormat (Foam);
1913localstatic int labelFmt;
1914
1915/*
1916 * Check that a buffer filled by foamToBuffer will
1917 * unpack to the original foam
1918 */
1919Bool
1920foamVerifyBuffer(Buffer buf, Foam foam)
1921{
1922 Foam readFoam;
1923 Bool ret;
1924 Length pos;
1925
1926 pos = bufPosition(buf);
1927 bufSetPosition(buf, 0);
1928 readFoam = foamFrBuffer(buf);
1929 ret = foamEqualModBuffer(foam, readFoam);
1930 bufSetPosition(buf, pos);
1931 foamFree(readFoam);
1932
1933 return ret;
1934}
1935
1936/*
1937 * External entry point for reading foam byte codes from a buffer.
1938 */
1939Foam
1940foamFrBuffer(Buffer buf)
1941{
1942 Foam foam;
1943 int fi, si, tag, argc, format, bi;
1944 Bool isArr, isNary;
1945 String argf;
1946 Bool neg;
1947
1948 tag = bufGetByte(buf);
1949 format = FOAM_FORMAT_GET(tag)((tag)<(FOAM_VECTOR_START)? 0:(((tag)-(FOAM_VECTOR_START))
/(FOAM_LIMIT - (FOAM_VECTOR_START))))
;
1950 tag = FOAM_FORMAT_REMOVE(tag, format)((tag) - (format)*(FOAM_LIMIT - (FOAM_VECTOR_START)));
1951
1952 isArr = (tag == FOAM_Arr);
1953 isNary = (foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc == FOAM_NARY(-1));
1954
1955 if (!isNary)
1956 argc = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc;
1957 else
1958 FOAM_GET_INT(format, buf, argc){ switch (format) { case 0: (argc) = bufGetSInt(buf); break; case
1: (argc) = bufGetByte(buf); break; default: (argc) = (format
) - 2; break; } }
;
1959
1960 argf = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argf;
1961 if (tag == FOAM_DFlo)
1962 foam = foamNewDFlo(0.0);
1963 else
1964 foam = foamNewEmpty(tag, argc);
1965
1966 for (fi = si = 0; si < argc; fi++, si++) {
1967 int af = argf[fi], n, slen;
1968 if (af == '*') af = argf[--fi];
1969 switch (argf[fi]) {
1970 case 't':
1971 n = bufGetByte(buf);
1972 foamArgv(foam)((foam)->foamGen.argv)[si].data = FOAM_START + n;
1973 break;
1974 case 'o':
1975#if SMALL_BVAL_TAGS
1976 n = bufGetByte(buf);
1977#else
1978 n = bufGetHInt(buf);
1979#endif
1980 foamArgv(foam)((foam)->foamGen.argv)[si].data = FOAM_BVAL_START + n;
1981 break;
1982 case 'p':
1983 n = bufGetByte(buf);
1984 foamArgv(foam)((foam)->foamGen.argv)[si].data = FOAM_PROTO_START + n;
1985 break;
1986 case 'D':
1987 n = bufGetByte(buf);
1988 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
1989 break;
1990 case 'b':
1991 n = bufGetByte(buf);
1992 foamArgv(foam)((foam)->foamGen.argv)[si].data = (char)n;
1993 break;
1994 case 'h':
1995 n = bufGetHInt(buf);
1996 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
1997 break;
1998 case 'w':
1999 n = bufGetSInt(buf);
2000 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2001 break;
2002 case 'X':
2003 /* Throw away length/offset information in tree form. */
2004 /* This makes .fm the same whether from .as or .ao. */
2005 FOAM_GET_INT(int0, buf, n){ switch (((int) 0)) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (((int) 0)) -
2; break; } }
;
2006 foamArgv(foam)((foam)->foamGen.argv)[si].data = 0;
2007 break;
2008 case 'F':
2009 FOAM_GET_INT(int0, buf, n){ switch (((int) 0)) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (((int) 0)) -
2; break; } }
;
2010 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2011 labelFmt = FOAM_FORMAT_FOR(n)((long)(n) <= ((1<<(1*8))-1) ? 1 : 0);
2012 break;
2013 case 'L':
2014 FOAM_GET_INT(labelFmt, buf, n){ switch (labelFmt) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (labelFmt) -
2; break; } }
;
2015 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2016 break;
2017 case 'i':
2018 FOAM_GET_INT(format, buf, n){ switch (format) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (format) - 2
; break; } }
;
2019 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2020 break;
2021 case 's':
2022 FOAM_GET_INT(format, buf, slen){ switch (format) { case 0: (slen) = bufGetSInt(buf); break; case
1: (slen) = bufGetByte(buf); break; default: (slen) = (format
) - 2; break; } }
;
2023 foamArgv(foam)((foam)->foamGen.argv)[si].str = bufRdChars(buf, slen);
2024 break;
2025 case 'f':
2026 foamToSFlo(foam)((foam)->foamSFlo.SFloData) = bufRdSFloat(buf);
2027 si = argc;
2028 break;
2029 case 'd':
2030 foamToDFlo(foam)((foam)->foamDFlo.DFloData) = bufRdDFloat(buf);
2031 si = argc;
2032 break;
2033 case 'n': {
2034 BInt b;
2035 U16 *data;
2036 neg = bufGetByte(buf);
2037 FOAM_GET_INT(format, buf, slen){ switch (format) { case 0: (slen) = bufGetSInt(buf); break; case
1: (slen) = bufGetByte(buf); break; default: (slen) = (format
) - 2; break; } }
;
2038 data = (U16*) stoAlloc(OB_Other0, slen*sizeof(U16));
2039 for (bi = 0; bi < slen; bi++) {
2040 n = bufGetHInt(buf);
2041 data[bi] = n;
2042 }
2043 b = bintFrPlacevS(neg, slen, data);
2044 stoFree(data);
2045 foamArgv(foam)((foam)->foamGen.argv)[si].bint = b;
2046 break;
2047 }
2048
2049 case 'C':
2050 foamArgv(foam)((foam)->foamGen.argv)[si].code = foamFrBuffer(buf);
2051 break;
2052 default:
2053 bugBadCase(argf[fi])bug("Bad case %d (line %d in file %s).", (int) argf[fi], 2053
, "foam.c")
;
2054 }
2055 }
2056 return foam;
2057}
2058
2059/* Get the header of a Prog skipping the body. It stops when find the first
2060 * piece of foam, so parameters, locals, dfluis/denv and body are not
2061 * returned.
2062 * Return NULL if the constant does not refer to a Prog.
2063 * NOTE: this procedure could be more general, but less efficient. This
2064 * implementations rely on the fact that if a foam subtree is found, then
2065 * all the remaining subtrees are foam (as in Prog).
2066 * This implementation needs to be fast because is used by the inliner.
2067 */
2068
2069localstatic Foam
2070foamProgHdrFrBuffer(Buffer buf)
2071{
2072 Foam foam;
2073 int fi, si, tag, argc, format, bi;
2074 Bool isArr, isNary;
2075 String argf;
2076 Bool neg;
2077
2078 tag = bufGetByte(buf);
2079 format = FOAM_FORMAT_GET(tag)((tag)<(FOAM_VECTOR_START)? 0:(((tag)-(FOAM_VECTOR_START))
/(FOAM_LIMIT - (FOAM_VECTOR_START))))
;
2080 tag = FOAM_FORMAT_REMOVE(tag, format)((tag) - (format)*(FOAM_LIMIT - (FOAM_VECTOR_START)));
2081
2082 isArr = (tag == FOAM_Arr);
2083 isNary = (foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc == FOAM_NARY(-1));
2084
2085 if (!isNary)
2086 argc = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc;
2087 else
2088 FOAM_GET_INT(format, buf, argc){ switch (format) { case 0: (argc) = bufGetSInt(buf); break; case
1: (argc) = bufGetByte(buf); break; default: (argc) = (format
) - 2; break; } }
;
2089
2090 if (tag != FOAM_Prog) return NULL((void*)0);
2091
2092 argf = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argf;
2093
2094 foam = foamNewEmpty(tag, argc);
2095
2096 for (fi = si = 0; si < argc; fi++, si++) {
2097 int af = argf[fi], n, slen;
2098 if (af == '*') af = argf[--fi];
2099 switch (argf[fi]) {
2100 case 't':
2101 n = bufGetByte(buf);
2102 foamArgv(foam)((foam)->foamGen.argv)[si].data = FOAM_START + n;
2103 break;
2104 case 'o':
2105#if SMALL_BVAL_TAGS
2106 n = bufGetByte(buf);
2107#else
2108 n = bufGetHInt(buf);
2109#endif
2110 foamArgv(foam)((foam)->foamGen.argv)[si].data = FOAM_BVAL_START + n;
2111 break;
2112 case 'p':
2113 n = bufGetByte(buf);
2114 foamArgv(foam)((foam)->foamGen.argv)[si].data = FOAM_PROTO_START + n;
2115 break;
2116 case 'b':
2117 n = bufGetByte(buf);
2118 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2119 break;
2120 case 'h':
2121 n = bufGetHInt(buf);
2122 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2123 break;
2124 case 'w':
2125 n = bufGetSInt(buf);
2126 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2127 break;
2128 case 'X':
2129 /* Throw away length/offset information in tree form. */
2130 /* This makes .fm the same whether from .as or .ao. */
2131 FOAM_GET_INT(int0, buf, n){ switch (((int) 0)) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (((int) 0)) -
2; break; } }
;
2132 foamArgv(foam)((foam)->foamGen.argv)[si].data = 0;
2133 break;
2134 case 'F':
2135 FOAM_GET_INT(int0, buf, n){ switch (((int) 0)) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (((int) 0)) -
2; break; } }
;
2136 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2137 labelFmt = FOAM_FORMAT_FOR(n)((long)(n) <= ((1<<(1*8))-1) ? 1 : 0);
2138 break;
2139 case 'L':
2140 FOAM_GET_INT(labelFmt, buf, n){ switch (labelFmt) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (labelFmt) -
2; break; } }
;
2141 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2142 break;
2143 case 'i':
2144 FOAM_GET_INT(format, buf, n){ switch (format) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (format) - 2
; break; } }
;
2145 foamArgv(foam)((foam)->foamGen.argv)[si].data = n;
2146 break;
2147 case 's':
2148 FOAM_GET_INT(format, buf, slen){ switch (format) { case 0: (slen) = bufGetSInt(buf); break; case
1: (slen) = bufGetByte(buf); break; default: (slen) = (format
) - 2; break; } }
;
2149 foamArgv(foam)((foam)->foamGen.argv)[si].str = bufRdChars(buf, slen);
2150 break;
2151 case 'f':
2152 foamToSFlo(foam)((foam)->foamSFlo.SFloData) = bufRdSFloat(buf);
2153 si = argc;
2154 break;
2155 case 'd':
2156 foamToDFlo(foam)((foam)->foamDFlo.DFloData) = bufRdDFloat(buf);
2157 si = argc;
2158 break;
2159 case 'n': {
2160 BInt b;
2161 U16 *data;
2162 neg = bufGetByte(buf);
2163 FOAM_GET_INT(format, buf, slen){ switch (format) { case 0: (slen) = bufGetSInt(buf); break; case
1: (slen) = bufGetByte(buf); break; default: (slen) = (format
) - 2; break; } }
;
2164 data = (U16*) stoAlloc(OB_Other0, slen*sizeof(U16));
2165 for (bi = 0; bi < slen; bi++) {
2166 n = bufGetHInt(buf);
2167 data[bi] = n;
2168 }
2169 b = bintFrPlacevS(neg, slen, data);
2170 stoFree(data);
2171 foamArgv(foam)((foam)->foamGen.argv)[si].bint = b;
2172 break;
2173 }
2174 case 'C':
2175 break;
2176 default:
2177 bugBadCase(argf[fi])bug("Bad case %d (line %d in file %s).", (int) argf[fi], 2177
, "foam.c")
;
2178 }
2179 }
2180 return foam;
2181}
2182
2183
2184void
2185foamPosFrBuffer(Buffer buf, Foam foam)
2186{
2187 int fi, si, tag, argc;
2188 String argf;
2189
2190 tag = foamTag(foam)((foam)->hdr.tag);
2191 argc = foamArgc(foam)((foam)->hdr.argc);
2192 argf = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argf;
2193
2194 if (tag == FOAM_Seq) {
2195 for (si = 0; si < argc; si++)
2196 foamPos(foamArgv(foam)[si].code)((((foam)->foamGen.argv)[si].code)->hdr.pos) = bufRdULong(buf);
2197 }
2198 else {
2199 if (tag == FOAM_Prog)
2200 foamPos(foam)((foam)->hdr.pos) = bufRdULong(buf);
2201 for (fi = si = 0; si < argc; fi++, si++) {
2202 int af = argf[fi];
2203 if (af == '*') af = argf[--fi];
2204
2205 switch (af) {
2206 case 'C':
2207 foamPosFrBuffer(buf, foamArgv(foam)((foam)->foamGen.argv)[si].code);
2208 break;
2209 default:
2210 break;
2211 }
2212 }
2213 }
2214}
2215
2216Foam
2217foamSIntReduce(Foam foam)
2218{
2219 int negative;
2220 long bignum;
2221
2222 if (sizeof(foam->foamSInt.SIntData) <= SINT_BYTES4)
2223 return foam;
2224 /*
2225 * Convert arbitrarily large integer literals into an equivalent
2226 * expression involving only unsigned 31 bit arithmetic. This is
2227 * to allow >32-bit constants on 64-bit platforms to be stored in
2228 * flat FOAM buffers/files and be retrieved correctly.
2229 */
2230 negative = (foam->foamSInt.SIntData < 0);
2231 bignum = !longIsInt32(foam->foamSInt.SIntData);
2232 assert(foamTag(foam) == FOAM_SInt)do { if (!(((foam)->hdr.tag) == FOAM_SInt)) _do_assert(("foamTag(foam) == FOAM_SInt"
),"foam.c",2232); } while (0)
;
2233 if (bignum) {
2234 /* Must split into unsigned 31-bit chunks */
2235 int i, bits = sizeof(foam->foamSInt.SIntData)*8;
2236 int hunks = bits/31 + ((bits%31) ? 1 : 0);
2237 long *parts = (long *)stoAlloc(OB_Other0, hunks*sizeof(long));
2238
2239 /* Kill the sign */
2240 long number = negative ? -foam->foamSInt.SIntData : foam->foamSInt.SIntData;
2241
2242 /* Split ... */
2243 for (i = 0; i < hunks; i++)
2244 parts[i] = number & 0x7fffffff, number >>= 31;
2245
2246 /* Find most significant chunk */
2247 for (i = hunks - 1; i >= 0 && !parts[i]; i--) {}
2248
2249 /* Reconstruct ... */
2250 foam = foamNewSInt(parts[i--])foamNew(FOAM_SInt, 1, (AInt)(parts[i--])); /* Don't foamFree(foam) ! */
2251 while (i >= 0) {
2252 foam = foamNew(FOAM_BCall, 3, FOAM_BVal_SIntShiftUp,
2253 foam, foamNewSInt(31)foamNew(FOAM_SInt, 1, (AInt)(31)));
2254 foam = foamNew(FOAM_BCall, 3, FOAM_BVal_SIntOr,
2255 foam, foamNewSInt(parts[i--])foamNew(FOAM_SInt, 1, (AInt)(parts[i--])));
2256 }
2257
2258 /* Deal with the sign */
2259 if (negative)
2260 foam = foamNew(FOAM_BCall,2,FOAM_BVal_SIntNegate,foam);
2261 stoFree(parts);
2262 }
2263 return foam;
2264}
2265
2266/*
2267 * External entry point for writing foam byte codes to a buffer.
2268 */
2269
2270int
2271foamToBuffer(Buffer buf, Foam foam)
2272{
2273 int fi, si, tag, argc, format, bi;
2274 Bool isArr, isNary;
2275 BInt bint;
2276 String argf;
2277 Offset tmpPos, offPos = 0;
2278 Offset start = bufPosition(buf);
2279
2280 if (foamTag(foam)((foam)->hdr.tag) == FOAM_SInt) foam = foamSIntReduce(foam);
2281
2282 tag = foamTag(foam)((foam)->hdr.tag);
2283
2284 isArr = (tag == FOAM_Arr);
2285 isNary = (foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc == FOAM_NARY(-1));
2286
2287 argc = foamArgc(foam)((foam)->hdr.argc);
2288 argf = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argf;
2289 format = foamTagFormat(foam);
2290 tag = FOAM_FORMAT_PUT(tag, format)((tag) + (format)*(FOAM_LIMIT - (FOAM_VECTOR_START)));
2291
2292 bufPutByte(buf, tag);
2293 if (isNary) FOAM_PUT_INT(format, buf, argc){ switch (format) { case 0: bufPutSInt(buf, argc); break; case
1: {if (argc > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, argc); break; default: break; } }
;
2294 for (fi = si = 0; si < argc; fi++, si++) {
2295 int n, af = argf[fi];
2296 if (af == '*') af = argf[--fi];
2297
2298 switch (af) {
2299 case 't':
2300 n = foamArgv(foam)((foam)->foamGen.argv)[si].data - FOAM_START;
2301 bufPutByte(buf, n);
2302 break;
2303 case 'o':
2304 n = foamArgv(foam)((foam)->foamGen.argv)[si].data - FOAM_BVAL_START;
2305#if SMALL_BVAL_TAGS
2306 bufPutByte(buf, n);
2307#else
2308 bufPutHInt(buf, n);
2309#endif
2310 break;
2311 case 'p':
2312 n = foamArgv(foam)((foam)->foamGen.argv)[si].data - FOAM_PROTO_START;
2313 bufPutByte(buf, n);
2314 break;
2315 case 'D':
2316 n = foamArgv(foam)((foam)->foamGen.argv)[si].data;
2317 bufPutByte(buf, n);
2318 break;
2319 case 'b':
2320 bufPutByte(buf, foamArgv(foam)((foam)->foamGen.argv)[si].data);
2321 break;
2322 case 'h':
2323 bufPutHInt(buf, foamArgv(foam)((foam)->foamGen.argv)[si].data);
2324 break;
2325 case 'w':
2326 assert(bufIsSInt(foamArgv(foam)[si].data))do { if (!(bufIsSInt(((foam)->foamGen.argv)[si].data))) _do_assert
(("bufIsSInt(foamArgv(foam)[si].data)"),"foam.c",2326); } while
(0)
;
2327 n = foamArgv(foam)((foam)->foamGen.argv)[si].data;
2328 bufPutSInt(buf, n);
2329 break;
2330 case 'X':
2331 offPos = bufPosition(buf);
2332 FOAM_PUT_INT(int0, buf, offPos){ switch (((int) 0)) { case 0: bufPutSInt(buf, offPos); break
; case 1: {if (offPos > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, offPos); break; default: break; } }
;
2333 break;
2334 case 'F':
2335 n = foamArgv(foam)((foam)->foamGen.argv)[si].data;
2336 FOAM_PUT_INT(int0, buf, n){ switch (((int) 0)) { case 0: bufPutSInt(buf, n); break; case
1: {if (n > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, n); break; default: break; } }
;
2337 labelFmt = FOAM_FORMAT_FOR(n)((long)(n) <= ((1<<(1*8))-1) ? 1 : 0);
2338 break;
2339 case 'L':
2340 FOAM_PUT_INT(labelFmt, buf, foamArgv(foam)[si].data){ switch (labelFmt) { case 0: bufPutSInt(buf, ((foam)->foamGen
.argv)[si].data); break; case 1: {if (((foam)->foamGen.argv
)[si].data > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, ((foam)->foamGen.argv)[si].data); break
; default: break; } }
;
2341 break;
2342 case 'i':
2343 FOAM_PUT_INT(format, buf, foamArgv(foam)[si].data){ switch (format) { case 0: bufPutSInt(buf, ((foam)->foamGen
.argv)[si].data); break; case 1: {if (((foam)->foamGen.argv
)[si].data > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, ((foam)->foamGen.argv)[si].data); break
; default: break; } }
;
2344 break;
2345 case 's': {
2346 String s = foamArgv(foam)((foam)->foamGen.argv)[si].str;
2347 int slen = strlen(s);
2348 FOAM_PUT_INT(format,buf,slen){ switch (format) { case 0: bufPutSInt(buf, slen); break; case
1: {if (slen > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, slen); break; default: break; } }
;
2349 bufWrChars(buf, slen, s);
2350 break;
2351 }
2352 case 'f':
2353 bufWrSFloat(buf, foamToSFlo(foam)((foam)->foamSFlo.SFloData));
2354 si = argc;
2355 break;
2356 case 'd':
2357 bufWrDFloat(buf, foamToDFlo(foam)((foam)->foamDFlo.DFloData));
2358 si = argc;
2359 break;
2360 case 'n': {
2361 int slen;
2362 U16 *data;
2363 /*!! Should not store here. */
2364 bint=xintStore(bintCopy(foamArgv(foam)((foam)->foamGen.argv)[si].bint));
2365 bufPutByte(buf,bint->isNeg);
2366 bintToPlacevS(bint, &slen, &data);
2367 FOAM_PUT_INT(format,buf,slen){ switch (format) { case 0: bufPutSInt(buf, slen); break; case
1: {if (slen > ((1<<(1*8))-1)) bug("oops - int too large"
);}; bufPutByte(buf, slen); break; default: break; } }
;
2368 for (bi = 0; bi < slen; bi++)
2369 bufPutHInt(buf,data[bi]);
2370 bintFree(bint);
2371 bintReleasePlacevS(data);
2372 break;
2373 }
2374 case 'C':
2375 foamToBuffer(buf, foamArgv(foam)((foam)->foamGen.argv)[si].code);
2376 break;
2377 default:
2378 bugBadCase(af)bug("Bad case %d (line %d in file %s).", (int) af, 2378, "foam.c"
)
;
2379 }
2380 }
2381
2382 if (foamTag(foam)((foam)->hdr.tag) == FOAM_Prog) {
2383 tmpPos = bufPosition(buf);
2384 bufSetPosition(buf, offPos);
2385 FOAM_PUT_INT(int0, buf, tmpPos - offPos){ switch (((int) 0)) { case 0: bufPutSInt(buf, tmpPos - offPos
); break; case 1: {if (tmpPos - offPos > ((1<<(1*8))
-1)) bug("oops - int too large");}; bufPutByte(buf, tmpPos - offPos
); break; default: break; } }
;
2386 if (tmpPos != 0)
2387 bufSetPosition(buf, tmpPos);
2388 }
2389
2390 return bufPosition(buf) - start;
2391}
2392
2393void
2394foamPosToBuffer(Buffer buf, Foam foam)
2395{
2396 int fi, si, tag, argc;
2397 String argf;
2398
2399 tag = foamTag(foam)((foam)->hdr.tag);
2400 argc = foamArgc(foam)((foam)->hdr.argc);
2401 argf = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argf;
2402
2403 if (tag == FOAM_Seq) {
2404 for (fi = si = 0; si < argc; fi++, si++)
2405 bufWrULong(buf, foamPos(foamArgv(foam)[si].code)((((foam)->foamGen.argv)[si].code)->hdr.pos));
2406 }
2407 else {
2408 if (tag == FOAM_Prog)
2409 bufWrULong(buf, foamPos(foam)((foam)->hdr.pos));
2410 for (fi = si = 0; si < argc; fi++, si++) {
2411 int af = argf[fi];
2412 if (af == '*') af = argf[--fi];
2413
2414 switch (af) {
2415 case 'C':
2416 foamPosToBuffer(buf, foamArgv(foam)((foam)->foamGen.argv)[si].code);
2417 break;
2418 default:
2419 break;
2420 }
2421 }
2422 }
2423}
2424
2425void
2426foamPosBufPrint(FILE *file, Buffer buf)
2427{
2428 int i, size, step;
2429 int sposFlag = 0;
2430 SrcPos sp;
2431
2432 size = sizeof(SrcPos);
2433 step = bufSize(buf) / size;
2434
2435 fprintf(file, "Buffer length: %d, SrcPos size: %d\n", (int) bufSize(buf), size);
2436 fprintf(file, "Number of steps: %d\n", step);
2437 for (i = 0, bufStart(buf); bufPosition(buf) < bufSize(buf); i++) {
2438 sp = bufRdULong(buf);
2439 if (sposLine(sp) != 0) {
2440 fprintf(file, "[%d]. ", i);
2441 if (sposFlag)
2442 sposPrint(file, sp);
2443 else
2444 fprintf(file, "%lu", (ULong)sposLine(sp));
2445 fprintf(file, "\n");
2446 }
2447 }
2448}
2449
2450/*
2451 * Skip over the foam tag in a buffer.
2452 */
2453localstatic int
2454foamTagFrBuffer0(Buffer buf)
2455{
2456 FoamTag tag;
2457 tag = bufGetByte(buf);
2458 return FOAM_FORMAT_GET(tag)((tag)<(FOAM_VECTOR_START)? 0:(((tag)-(FOAM_VECTOR_START))
/(FOAM_LIMIT - (FOAM_VECTOR_START))))
;
2459}
2460
2461/*
2462 * Skip over a piece of foam in a buffer.
2463 */
2464localstatic void
2465foamFrBuffer0(Buffer buf)
2466{
2467 int fi, si, tag, argc, format;
2468 Bool isNary;
2469 String argf;
2470
2471 tag = bufGetByte(buf);
2472 format = FOAM_FORMAT_GET(tag)((tag)<(FOAM_VECTOR_START)? 0:(((tag)-(FOAM_VECTOR_START))
/(FOAM_LIMIT - (FOAM_VECTOR_START))))
;
2473 tag = FOAM_FORMAT_REMOVE(tag, format)((tag) - (format)*(FOAM_LIMIT - (FOAM_VECTOR_START)));
2474
2475 isNary = (foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc == FOAM_NARY(-1));
2476 if (!isNary)
2477 argc = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc;
2478 else
2479 FOAM_GET_INT(format, buf, argc){ switch (format) { case 0: (argc) = bufGetSInt(buf); break; case
1: (argc) = bufGetByte(buf); break; default: (argc) = (format
) - 2; break; } }
;
2480
2481 argf = foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argf;
2482
2483 for (fi = si = 0; si < argc; fi++, si++) {
2484 int af = argf[fi], n;
2485 if (af == '*') af = argf[--fi];
Value stored to 'af' is never read
2486 switch (argf[fi]) {
2487 case 't':
2488#ifdef SMALL_BVAL_TAGS
2489 case 'o':
2490#endif
2491 case 'p':
2492 case 'D':
2493 case 'b':
2494 bufGetn(buf, BYTE_BYTES1);
2495 break;
2496#ifndef SMALL_BVAL_TAGS
2497 case 'o':
2498#endif
2499 case 'h':
2500 bufGetn(buf, HINT_BYTES2);
2501 break;
2502 case 'w':
2503 bufGetn(buf, SINT_BYTES4);
2504 break;
2505 case 'X':
2506 FOAM_GET_INT(int0, buf, n){ switch (((int) 0)) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (((int) 0)) -
2; break; } }
;
2507 break;
2508 case 'F':
2509 FOAM_GET_INT(int0, buf, n){ switch (((int) 0)) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (((int) 0)) -
2; break; } }
;
2510 labelFmt = FOAM_FORMAT_FOR(n)((long)(n) <= ((1<<(1*8))-1) ? 1 : 0);
2511 break;
2512 case 'L':
2513 FOAM_GET_INT(labelFmt, buf, n){ switch (labelFmt) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (labelFmt) -
2; break; } }
;
2514 break;
2515 case 'i':
2516 FOAM_GET_INT(format, buf, n){ switch (format) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (format) - 2
; break; } }
;
2517 break;
2518 case 's':
2519 FOAM_GET_INT(format, buf, n){ switch (format) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (format) - 2
; break; } }
;
2520 bufGetn(buf, n);
2521 break;
2522 case 'f':
2523 bufGetn(buf, XSFLOAT_BYTES6);
2524 return;
2525 case 'd':
2526 bufGetn(buf, XDFLOAT_BYTES10);
2527 return;
2528 case 'n':
2529 bufGetn(buf, BYTE_BYTES1);
2530 FOAM_GET_INT(format, buf, n){ switch (format) { case 0: (n) = bufGetSInt(buf); break; case
1: (n) = bufGetByte(buf); break; default: (n) = (format) - 2
; break; } }
;
2531 bufGetn(buf, n * HINT_BYTES2);
2532 break;
2533 case 'C':
2534 foamFrBuffer0(buf);
2535 break;
2536 default:
2537 bugBadCase(argf[fi])bug("Bad case %d (line %d in file %s).", (int) argf[fi], 2537
, "foam.c")
;
2538 }
2539 }
2540 return;
2541}
2542
2543/*
2544 * Read the foam formats from a foam unit in a buffer.
2545 */
2546Foam
2547foamFormatsFrBuffer(Buffer buf)
2548{
2549 bufStart(buf);
2550
2551 /* Read the foam unit tag. */
2552 foamTagFrBuffer0(buf);
2553
2554 /* Read the formats. */
2555 return foamFrBuffer(buf);
2556}
2557
2558/*
2559 * Read the constant number at position pos from a foam unit in a buffer.
2560 */
2561Foam
2562foamConstFrBuffer(Buffer buf, int pos)
2563{
2564 bufSetPosition(buf, pos);
2565 return foamFrBuffer(buf);
2566}
2567
2568/*
2569 * Read the number of constants from a foam unit in a buffer.
2570 */
2571Length
2572foamConstcFrBuffer(Buffer buf)
2573{
2574 Length i, argc, format;
2575
2576 bufStart(buf);
2577
2578 /* Read the foam unit tag. */
2579 foamTagFrBuffer0(buf);
2580
2581 /* Read the foam dfmt tag. */
2582 format = foamTagFrBuffer0(buf);
2583
2584 /* Read the number of ddecls. */
2585 FOAM_GET_INT(format, buf, argc){ switch (format) { case 0: (argc) = bufGetSInt(buf); break; case
1: (argc) = bufGetByte(buf); break; default: (argc) = (format
) - 2; break; } }
;
2586
2587 /* Skip to the predefined constsSlot. */
2588 for (i = 0; i < constsSlot1; i += 1)
2589 foamFrBuffer0(buf);
2590
2591 /* Read the foam ddecl tag. */
2592 format = foamTagFrBuffer0(buf);
2593
2594 /* Read the type field */
2595
2596 /* Read the number of foam constants. */
2597 FOAM_GET_INT(format, buf, argc){ switch (format) { case 0: (argc) = bufGetSInt(buf); break; case
1: (argc) = bufGetByte(buf); break; default: (argc) = (format
) - 2; break; } }
;
2598
2599 return argc-foamNaryStart(FOAM_DDecl);
2600}
2601
2602/*
2603 * Compute the positions of the constants from a foam unit in a buffer.
2604 */
2605void
2606foamConstvFrBuffer(Buffer buf, Length posc, int *posv)
2607{
2608 Length i, j, c, argc, format;
2609
2610 for (i = 0; i < posc; i += 1)
2611 posv[i] = 0;
2612
2613 bufStart(buf);
2614
2615 /* Read the foam unit tag. */
2616 foamTagFrBuffer0(buf);
2617
2618 /* Skip over the formats. */
2619 foamFrBuffer0(buf);
2620
2621 /* Read the foam ddef tag. */
2622 format = foamTagFrBuffer0(buf);
2623
2624 /* Read the number of foam definitions. */
2625 FOAM_GET_INT(format, buf, argc){ switch (format) { case 0: (argc) = bufGetSInt(buf); break; case
1: (argc) = bufGetByte(buf); break; default: (argc) = (format
) - 2; break; } }
;
2626
2627 /* Compute the positions of the foam constants. */
2628 for (i = 0, c = 0; i < argc; i += 1) {
2629 FoamTag tag;
2630
2631 /* Read the foam def tag. */
2632 foamTagFrBuffer0(buf);
2633
2634 /* Read the foam const/global tag. */
2635 tag = bufGetByte(buf);
2636 format = FOAM_FORMAT_GET(tag)((tag)<(FOAM_VECTOR_START)? 0:(((tag)-(FOAM_VECTOR_START))
/(FOAM_LIMIT - (FOAM_VECTOR_START))))
;
2637 tag = FOAM_FORMAT_REMOVE(tag, format)((tag) - (format)*(FOAM_LIMIT - (FOAM_VECTOR_START)));
2638
2639 /* Read the constant/global number. */
2640 FOAM_GET_INT(format, buf, j){ switch (format) { case 0: (j) = bufGetSInt(buf); break; case
1: (j) = bufGetByte(buf); break; default: (j) = (format) - 2
; break; } }
;
2641
2642 /* If we have a constant, store its position. */
2643 if (tag == FOAM_Const) {
2644 assert(posv[j] == 0)do { if (!(posv[j] == 0)) _do_assert(("posv[j] == 0"),"foam.c"
,2644); } while (0)
;
2645 posv[j] = bufPosition(buf);
2646 c += 1;
2647 }
2648
2649 /* Skip over the rest of the foam definition. */
2650 foamFrBuffer0(buf);
2651 }
2652 assert(c == posc)do { if (!(c == posc)) _do_assert(("c == posc"),"foam.c",2652
); } while (0)
;
2653
2654 return;
2655}
2656
2657/*
2658 * Fill the vector with the constants from the foam unit.
2659 */
2660void
2661foamConstvFrFoam(Foam unit, Length argc, Foam *argv)
2662{
2663 Length defc = foamArgc(unit->foamUnit.defs)((unit->foamUnit.defs)->hdr.argc);
2664 Length i, j, c;
2665
2666 for (i = 0; i < argc; i += 1)
2667 argv[i] = 0;
2668
2669 for (i = 0, c = 0; i < defc; i += 1) {
2670 Foam def = foamArgv(unit->foamUnit.defs)((unit->foamUnit.defs)->foamGen.argv)[i].code;
2671 Foam lhs = def->foamDef.lhs;
2672 if (foamTag(lhs)((lhs)->hdr.tag) == FOAM_Const) {
2673 j = lhs->foamConst.index;
2674 assert(argv[j] == 0)do { if (!(argv[j] == 0)) _do_assert(("argv[j] == 0"),"foam.c"
,2674); } while (0)
;
2675 argv[j] = def->foamDef.rhs;
2676 c += 1;
2677 }
2678 }
2679 assert(c == argc)do { if (!(c == argc)) _do_assert(("c == argc"),"foam.c",2679
); } while (0)
;
2680}
2681
2682
2683/* Return NULL if is not a Prog */
2684Foam
2685foamGetProgHdrFrBuffer(Buffer buf, int pos)
2686{
2687 Foam prog;
2688 bufSetPosition(buf, pos);
2689 prog = foamProgHdrFrBuffer(buf);
2690
2691 if (prog) {
2692 prog->foamProg.locals = NULL((void*)0);
2693 prog->foamProg.params = NULL((void*)0);
2694 prog->foamProg.fluids = NULL((void*)0);
2695 prog->foamProg.levels = NULL((void*)0);
2696 prog->foamProg.body = NULL((void*)0);
2697 }
2698
2699 return prog;
2700}
2701
2702/*
2703 * Determine the tag format for compact linear output.
2704 */
2705localstatic int
2706foamTagFormat(Foam foam)
2707{
2708 int tag = foamTag(foam)((foam)->hdr.tag), format, isNary, argc;
2709 int ix[3], x1, x2, i, si, di, ng1, ng2;
2710
2711 isNary = (foamInfo(tag)(foamInfoTable [(int)(tag)-(int)FOAM_START]).argc == FOAM_NARY(-1));
2712 argc = foamArgc(foam)((foam)->hdr.argc);
2713 if (tag < FOAM_INDEX_START) {
2714 if (tag < FFO_ORIGIN(FOAM_VECTOR_START))
2715 format = 0;
2716 else {
2717 if (tag == FOAM_Unimp)
2718 si = strlen(foamArgv(foam)((foam)->foamGen.argv)[0].str);
2719 else if (tag == FOAM_Decl || tag == FOAM_GDecl)
2720 {
2721 /*
2722 * We are storing a compressible integer
2723 * and a string in this chunk so we need
2724 * to be careful about our format number.
2725 */
2726 si = strlen(foamArgv(foam)((foam)->foamGen.argv)[1].str);
2727 di = foamArgv(foam)((foam)->foamGen.argv)[3].data;
2728 if (di > si) si = di;
2729 }
2730 else if (tag == FOAM_BInt) {
2731 /* !! Should not store here. */
2732 BInt bint;
2733 bint= xintStore(bintCopy(foamArgv(foam)((foam)->foamGen.argv)[0].bint));
2734 si = bint->placec;
2735 bintFree(bint);
2736 }
2737 else {
2738 NotReached(si = 0){(void)bug("Not supposed to reach line %d in file: %s\n",2738
, "foam.c");}
;
2739 }
2740 format = FOAM_FORMAT_FOR(si)((long)(si) <= ((1<<(1*8))-1) ? 1 : 0);
2741 }
2742 }
2743 else if (tag == FOAM_Rec ||
2744 tag == FOAM_DEnv ||
2745 tag == FOAM_DFluid) {
2746 si = argc;
2747 format = FOAM_FORMAT_FOR(si)((long)(si) <= ((1<<(1*8))-1) ? 1 : 0);
2748 for (i = 0; i<argc ; i++) {
2749 int fi;
2750 si = foamArgv(foam)((foam)->foamGen.argv)[i].data;
2751 fi = FOAM_FORMAT_FOR(si)((long)(si) <= ((1<<(1*8))-1) ? 1 : 0);
2752 if (fi < format) format = fi;
2753 if (format == 0) break;
2754 }
2755 }
2756 else if (tag < FOAM_INDEX_LIMIT || isNary) {
2757 si = isNary ? argc : foamArgv(foam)((foam)->foamGen.argv)[0].data;
2758
2759 /*
2760 * !! HACK. The first test is here due to a bug discovered
2761 * after the freeze of v. 0.37 (EInfo is in the wrong position
2762 * in foamTag enumeration). Without this hack we should change
2763 * the format of .ao files.
2764 *
2765 * During development of 1.1.13, new instructions were added
2766 * and EInfo put in the correct place. This check is only
2767 * here temporarily until we are sure that the problem has
2768 * gone away.
2769 */
2770 if (tag == FOAM_EInfo)
2771 {
2772 bug("Arrgghh! The EInfo bug is back!");
2773 format = 0;
2774 }
2775 else if (si < IMMED_FORMS3)
2776 format = STD_FORMS2 + si;
2777 else
2778 format = FOAM_FORMAT_FOR(si)((long)(si) <= ((1<<(1*8))-1) ? 1 : 0);
2779 }
2780 else {
2781 switch (tag) {
2782 case FOAM_Lex: x1 = 1; x2 = -1; break;
2783 case FOAM_RElt: x1 = 2; x2 = -1; break;
2784 case FOAM_RRElt: x1 = 0; x2 = -1; break;
2785 case FOAM_EElt: x1 = 2; x2 = 3; break;
2786 case FOAM_IRElt: x1 = 2; x2 = -1; break;
2787 case FOAM_TRElt: x1 = 3; x2 = -1; break;
2788 default:
2789 bugBadCase(tag)bug("Bad case %d (line %d in file %s).", (int) tag, 2789, "foam.c"
)
;
2790 NotReached(x1 = x2 = 0){(void)bug("Not supposed to reach line %d in file: %s\n",2790
, "foam.c");}
;
2791 }
2792 ix[0] = foamArgv(foam)((foam)->foamGen.argv)[0].data;
2793 ix[1] = foamArgv(foam)((foam)->foamGen.argv)[x1].data;
2794 ix[2] = (x2 == -1) ? 0 : foamArgv(foam)((foam)->foamGen.argv)[x2].data;
2795
2796 for (ng1 = ng2 = 0, i = 0; i < 3; i++) {
2797 if ((long) ix[i] > MAX_HINT((((ULong) ((1<<(1*8))-1))&((1<<8)-1)) | ((((
ULong) ((1<<(1*8))-1))&((1<<8)-1))<<8))
) { ng2++; }
2798 if ((long) ix[i] > MAX_BYTE((1<<(1*8))-1)) { ng1++; }
2799 }
2800 /* We only care if any are > MAX_BYTE ... */
2801 if (ng1 > 0) format = 0;
2802 else format = 1;
2803 }
2804 return format;
2805}
2806
2807localstatic Foam
2808foamGetDecl(int index, Foam ddecl, FoamBox fbox)
2809{
2810 assert(ddecl == NULL || foamTag(ddecl) == FOAM_DDecl)do { if (!(ddecl == ((void*)0) || ((ddecl)->hdr.tag) == FOAM_DDecl
)) _do_assert(("ddecl == NULL || foamTag(ddecl) == FOAM_DDecl"
),"foam.c",2810); } while (0)
;
2811 if (ddecl && index < foamDDeclArgc(ddecl)(((ddecl)->hdr.argc) - (1)))
2812 return ddecl->foamDDecl.argv[index];
2813 else {
2814 assert (fbox)do { if (!(fbox)) _do_assert(("fbox"),"foam.c",2814); } while
(0)
;
2815 return fboxNth(fbox, index);
2816 }
2817}
2818
2819localstatic Foam
2820foamGetDDecl(int index, Foam fmts, FoamBox fbox)
2821{
2822 assert(fmts == NULL || foamTag(fmts) == FOAM_DFmt)do { if (!(fmts == ((void*)0) || ((fmts)->hdr.tag) == FOAM_DFmt
)) _do_assert(("fmts == NULL || foamTag(fmts) == FOAM_DFmt"),
"foam.c",2822); } while (0)
;
2823 if (fmts && index < foamArgc(fmts)((fmts)->hdr.argc))
2824 return fmts->foamDFmt.argv[index];
2825 else {
2826 assert (fbox)do { if (!(fbox)) _do_assert(("fbox"),"foam.c",2826); } while
(0)
;
2827 return fboxNth(fbox, index);
2828 }
2829}
2830
2831/*
2832 * Given an expression occuring in a foam prog and given the DFmt section for
2833 * the unit where it is defined, return the foam type of the expression
2834 *
2835 * If the EXTRA parameter is not NULL, then extra type information is
2836 * eventually stored in it. In example, if the type is FOAM_Rec, in EXTRA is
2837 * returned format number.
2838 * Extra type information:
2839 * Record -> format number
2840 * Array -> type of elements
2841 */
2842
2843FoamTag
2844foamExprTypeCB(Foam expr, AInt *extra, FoamExprTypeCallback callback, void *arg)
2845{
2846 FoamTag type;
2847 Foam decl;
2848
2849 if (extra) *extra = emptyFormatSlot4;
2850 switch (foamTag(expr)((expr)->hdr.tag)) {
2851 case FOAM_Nil:
2852 case FOAM_Char:
2853 case FOAM_Bool:
2854 case FOAM_Byte:
2855 case FOAM_HInt:
2856 case FOAM_SInt:
2857 case FOAM_SFlo:
2858 case FOAM_DFlo:
2859 case FOAM_Word:
2860 case FOAM_Arb:
2861 case FOAM_Ptr:
2862 case FOAM_Clos:
2863 case FOAM_Gener:
2864 case FOAM_GenIter:
2865 case FOAM_BInt:
2866 case FOAM_Env:
2867 case FOAM_RRec:
2868 case FOAM_Prog:
2869 return foamTag(expr)((expr)->hdr.tag);
2870
2871 case FOAM_Rec:
2872 if (extra) *extra = expr->foamRec.format;
2873 return foamTag(expr)((expr)->hdr.tag);
2874
2875 case FOAM_Arr:
2876 if (extra) *extra = expr->foamArr.baseType;
2877 return foamTag(expr)((expr)->hdr.tag);
2878
2879 case FOAM_BVal:
2880 return foamBValInfo(expr->foamBVal.builtinTag)(foamBValInfoTable[(int)(expr->foamBVal.builtinTag)-(int)FOAM_BVAL_START
])
.retType;
2881 case FOAM_CProg:
2882 return FOAM_Prog;
2883 case FOAM_CEnv:
2884 return FOAM_Env;
2885 case FOAM_Cast:
2886 if (expr->foamCast.type == FOAM_Arr && extra)
2887 *extra = 0;
2888 return expr->foamCast.type;
2889 case FOAM_ANew:
2890 if (extra) *extra = expr->foamANew.eltType;
2891 return FOAM_Arr;
2892
2893 case FOAM_Set:
2894 return foamExprTypeCB(expr->foamSet.rhs, extra, callback, arg);
2895 case FOAM_Def:
2896 return foamExprTypeCB(expr->foamDef.rhs, extra, callback, arg);
2897 case FOAM_AElt:
2898 return expr->foamAElt.baseType;
2899 case FOAM_Par:
2900 decl = callback(arg, expr);
2901 type = decl->foamDecl.type;
2902
2903 if (extra &&
2904 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2905 *extra = decl->foamDecl.format;
2906 return type;
2907 case FOAM_Loc: {
2908 decl = callback(arg, expr);
2909 type = (decl->foamDecl.type) & 0xFF;
2910
2911 if (extra &&
2912 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2913 *extra = decl->foamDecl.format;
2914
2915 return type;
2916 }
2917 case FOAM_Glo:
2918 decl = callback(arg, expr);
2919 type = decl->foamGDecl.type;
2920
2921 if (extra &&
2922 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2923 *extra = decl->foamGDecl.format;
2924
2925 return type;
2926
2927 case FOAM_Fluid:
2928 decl = callback(arg, expr);
2929 type = decl->foamDecl.type;
2930
2931 if (extra &&
2932 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2933 *extra = decl->foamDecl.format;
2934
2935 return type;
2936
2937 case FOAM_Const:
2938 decl = callback(arg, expr);
2939 return decl->foamDecl.type;
2940
2941 case FOAM_RNew:
2942 if (extra) *extra = expr->foamRNew.format;
2943 return FOAM_Rec;
2944
2945 case FOAM_RRNew:
2946 return FOAM_RRec;
2947
2948 case FOAM_RRFmt:
2949 return FOAM_Word;
2950
2951 case FOAM_TRNew:
2952 if (extra) *extra = expr->foamTRNew.format;
2953 return FOAM_TR;
2954
2955 case FOAM_RRElt:
2956 return FOAM_Word;
2957
2958 case FOAM_GenerValue:
2959 return FOAM_Word;
2960
2961 case FOAM_Lex: {
2962 decl = callback(arg, expr);
2963 type = decl->foamDecl.type;
2964
2965 if (extra &&
2966 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2967 *extra = decl->foamDecl.format;
2968
2969 return type;
2970 }
2971 case FOAM_RElt: {
2972 decl = callback(arg, expr);
2973 type = decl->foamDecl.type;
2974
2975 if (extra &&
2976 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2977 *extra = decl->foamDecl.format;
2978
2979 return type;
2980 }
2981 case FOAM_IRElt: {
2982 decl = callback(arg, expr);
2983 type = decl->foamDecl.type;
2984
2985 if (extra &&
2986 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2987 *extra = decl->foamDecl.format;
2988
2989 return type;
2990 }
2991
2992 case FOAM_TRElt: {
2993 decl = callback(arg, expr);
2994 type = decl->foamDecl.type;
2995
2996 if (extra &&
2997 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
2998 *extra = decl->foamDecl.format;
2999
3000 return type;
3001 }
3002 case FOAM_EElt: {
3003 decl = callback(arg, expr);
3004 type = decl->foamDecl.type;
3005
3006 if (extra &&
3007 (type == FOAM_Rec || type == FOAM_Arr || type == FOAM_TR))
3008 *extra = decl->foamDecl.format;
3009
3010 return type;
3011 }
3012 case FOAM_PCall:
3013 return expr->foamPCall.type;
3014 case FOAM_BCall:
3015 return foamBValInfo(expr->foamBCall.op)(foamBValInfoTable[(int)(expr->foamBCall.op)-(int)FOAM_BVAL_START
])
.retType;
3016 case FOAM_CCall:
3017 return expr->foamCCall.type;
3018 case FOAM_OCall:
3019 return expr->foamOCall.type;
3020 case FOAM_PRef:
3021 return FOAM_SInt;
3022 case FOAM_MFmt:
3023 if (extra) *extra = expr->foamMFmt.format;
3024 return FOAM_Rec;
3025 case FOAM_EInfo:
3026 return FOAM_Word;
3027 case FOAM_PushEnv:
3028 return FOAM_Env;
3029 case FOAM_Values:
3030 return FOAM_NOp;
3031 case FOAM_EEnv:
3032 return FOAM_Env;
3033 default:
3034 bugWarning("foamExprType0: type %s unhandled. Returning 0", foamInfo(foamTag(expr))(foamInfoTable [(int)(((expr)->hdr.tag))-(int)FOAM_START]).str);
3035 }
3036
3037 bug("foamExprType0: reached end of code.");
3038
3039 return 0; /* quit warnings */
3040}
3041
3042
3043
3044struct foamExprTypeStd {
3045 Foam prog;
3046 Foam formats;
3047 FoamBox locals;
3048 FoamBox formatBox;
3049 FoamBox globals;
3050};
3051
3052localstatic Foam foamExprTypeCallbackStd(void *ptr, Foam expr);
3053
3054FoamTag
3055foamExprTypeG0(Foam expr, Foam prog, Foam formats, FoamBox locals,
3056 FoamBox formatBox, FoamBox globals, AInt * extra)
3057{
3058 struct foamExprTypeStd stdArgs;
3059
3060 stdArgs.prog = prog;
3061 stdArgs.formats = formats;
3062 stdArgs.locals = locals;
3063 stdArgs.formatBox = formatBox;
3064 stdArgs.globals = globals;
3065 return foamExprTypeCB(expr, extra, foamExprTypeCallbackStd, &stdArgs);
3066}
3067
3068FoamTag
3069foamExprType0(Foam expr, Foam prog, Foam formats, FoamBox locals,
3070 FoamBox formatBox, AInt *extra)
3071{
3072 struct foamExprTypeStd stdArgs;
3073
3074 stdArgs.prog = prog;
3075 stdArgs.formats = formats;
3076 stdArgs.locals = locals;
3077 stdArgs.formatBox = formatBox;
3078 stdArgs.globals = 0;
3079
3080 return foamExprTypeCB(expr, extra, foamExprTypeCallbackStd, &stdArgs);
3081}
3082
3083localstatic Foam
3084foamExprTypeCallbackStd(void *ptr, Foam expr)
3085{
3086 struct foamExprTypeStd *stdArgs = ptr;
3087 Foam prog = stdArgs->prog;
3088 Foam formats = stdArgs->formats;
3089 FoamBox locals = stdArgs->locals;
3090 FoamBox formatBox = stdArgs->formatBox;
3091 FoamBox globals = stdArgs->globals;
3092 Foam decl = NULL((void*)0);
3093
3094 switch (foamTag(expr)((expr)->hdr.tag)) {
3095 case FOAM_Loc: {
3096 AInt index = expr->foamLoc.index;
3097 decl = foamGetDecl(index, prog->foamProg.locals, locals);
3098 break;
3099 }
3100 case FOAM_Par:
3101 decl = prog->foamProg.params->foamDDecl.argv[expr->foamPar.index];
3102 break;
3103 case FOAM_Glo:
3104 decl = foamGetDecl(expr->foamGlo.index, formats->foamDFmt.argv[globalsSlot0], globals);
3105 break;
3106 case FOAM_Fluid:
3107 decl = formats->foamDFmt.argv[fluidsSlot3]->
3108 foamDDecl.argv[expr->foamFluid.index];
3109 break;
3110 case FOAM_Const:
3111 decl = formats->foamDFmt.argv[constsSlot1]->
3112 foamDDecl.argv[expr->foamConst.index];
3113 break;
3114 case FOAM_Lex: {
3115 Foam ddecl;
3116 int index;
3117
3118 index = prog->foamProg.levels->foamDEnv.argv[expr->foamLex.level];
3119 ddecl = foamGetDDecl(index, formats, formatBox);
3120 decl = ddecl->foamDDecl.argv[expr->foamLex.index];
3121 break;
3122 }
3123 case FOAM_RElt: {
3124 int index = expr->foamRElt.format;
3125 Foam ddecl = foamGetDDecl(index, formats, formatBox);
3126 decl = ddecl->foamDDecl.argv[expr->foamRElt.field];
3127 break;
3128 }
3129 case FOAM_IRElt: {
3130 int index = expr->foamIRElt.format;
3131 Foam ddecl = foamGetDDecl(index, formats, formatBox);
3132 decl = foamTRDDeclIDecl(ddecl, expr->foamIRElt.field)((ddecl)->foamDDecl.argv[1+(expr->foamIRElt.field)]); /* use foamIRDeclIdx() */
3133 break;
3134 }
3135 case FOAM_TRElt: {
3136 int index = expr->foamIRElt.format;
3137 Foam ddecl = foamGetDDecl(index, formats, formatBox);
3138 decl = foamTRDDeclTDecl(ddecl, expr->foamTRElt.field)((ddecl)->foamDDecl.argv [1+ ((ddecl)->foamDDecl.argv[0
]->foamDecl.format) + (expr->foamTRElt.field)])
; /* use foamTRDeclIdx() */
3139 break;
3140 }
3141 case FOAM_EElt: {
3142 int index = expr->foamEElt.env;
3143 Foam ddecl = foamGetDDecl(index, formats, formatBox);
3144 decl = ddecl->foamDDecl.argv[expr->foamEElt.lex];
3145 break;
3146 }
3147 }
3148
3149 return decl;
3150}
3151
3152FoamTag
3153foamExprType(Foam expr, Foam prog, Foam formats, FoamBox locals,
3154 FoamBox formatBox, AInt * extra)
3155{
3156 FoamTag tag;
3157 AInt foo;
3158 tag = foamExprType0(expr, prog, formats, locals, formatBox, &foo);
3159
3160#if 0 /* Need to check against FOAM_CCall as well as FOAM_Cast, plus others */
3161 assert( foamTag(expr) == FOAM_Cast || tag != FOAM_Rec || foo != emptyFormatSlot)do { if (!(((expr)->hdr.tag) == FOAM_Cast || tag != FOAM_Rec
|| foo != 4)) _do_assert(("foamTag(expr) == FOAM_Cast || tag != FOAM_Rec || foo != emptyFormatSlot"
),"foam.c",3161); } while (0)
;
3162#endif
3163 if (extra) *extra = foo;
3164 return tag;
3165}
3166
3167Bool
3168foamTypeIsVoid(Foam fmts, FoamTag type, AInt fmt)
3169{
3170 Foam decl;
3171 if (type != FOAM_NOp)
3172 return false((int) 0);
3173 if (fmt == 0)
3174 return true1;
3175 decl = fmts->foamDFmt.argv[fmt];
3176 return foamDDeclArgc(decl)(((decl)->hdr.argc) - (1)) == 0;
3177}
3178
3179Bool
3180foamTypeIsMulti(Foam fmts, FoamTag type, AInt fmt)
3181{
3182 Foam decl;
3183 if (type != FOAM_NOp)
3184 return false((int) 0);
3185 if (fmt == 0)
3186 return false((int) 0);
3187 decl = fmts->foamDFmt.argv[fmt];
3188 return foamDDeclArgc(decl)(((decl)->hdr.argc) - (1)) > 0;
3189}
3190
3191Bool
3192foamTypeIsValue(Foam fmts, FoamTag type, AInt fmt)
3193{
3194 return type != FOAM_NOp;
3195}
3196
3197Bool
3198foamHasSideEffect(Foam foam)
3199{
3200 Bool t;
3201
3202 switch(foamTag(foam)((foam)->hdr.tag)) {
3203 case FOAM_Set:
3204 case FOAM_Def:
3205 case FOAM_PCall:
3206 case FOAM_OCall:
3207 case FOAM_CCall:
3208 if (!foamPure(foam)((foam)->hdr.info.pure))
3209 return true1;
3210 break;
3211 case FOAM_BCall:
3212 if (foamBValInfo(foam->foamBCall.op)(foamBValInfoTable[(int)(foam->foamBCall.op)-(int)FOAM_BVAL_START
])
.hasSideFx)
3213 return true1;
3214 break;
3215 case FOAM_Catch:
3216 return true1;
3217 case FOAM_Prog:
3218 return false((int) 0);
3219 case FOAM_EEnsure:
3220 return true1;
3221 case FOAM_Yield:
3222 return true1;
3223 default:
3224 break;
3225 }
3226 if (foamTag(foam)((foam)->hdr.tag) == FOAM_Prog) return false((int) 0);
3227
3228 foamIter(foam, arg, {t = foamHasSideEffect(*arg);{ { 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; { {t = foamHasSideEffect(*arg); if (t) return 1;}; }; }
} }; }
3229 if (t) return true;}){ { 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; { {t = foamHasSideEffect(*arg); if (t) return 1;}; }; }
} }; }
;
3230 return false((int) 0);
3231}
3232
3233Bool
3234foamIsControlFlow(Foam foam)
3235{
3236 switch(foamTag(foam)((foam)->hdr.tag)) {
3237 case FOAM_Return:
3238 case FOAM_Label:
3239 case FOAM_Goto:
3240 case FOAM_If:
3241 case FOAM_Select:
3242 case FOAM_Loose:
3243 case FOAM_Kill:
3244 case FOAM_Free:
3245 case FOAM_Throw:
3246 case FOAM_Catch:
3247 case FOAM_Seq:
3248 case FOAM_GenerStep:
3249 return true1;
3250 default:
3251 return false((int) 0);
3252 }
3253}
3254
3255Foam
3256foamFindFirst(FoamTestFn testFn, Foam foam)
3257{
3258 if (testFn(foam))
3259 return foam;
3260
3261 foamIter(foam, arg, {{ { 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; { { Foam f = foamFindFirst(testFn, *arg); if (f != 0) return
f; }; }; } } }; }
3262 Foam f = foamFindFirst(testFn, *arg);{ { 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; { { Foam f = foamFindFirst(testFn, *arg); if (f != 0) return
f; }; }; } } }; }
3263 if (f != 0){ { 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; { { Foam f = foamFindFirst(testFn, *arg); if (f != 0) return
f; }; }; } } }; }
3264 return f;{ { 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; { { Foam f = foamFindFirst(testFn, *arg); if (f != 0) return
f; }; }; } } }; }
3265 }){ { 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; { { Foam f = foamFindFirst(testFn, *arg); if (f != 0) return
f; }; }; } } }; }
;
3266 return 0;
3267}
3268
3269Foam
3270foamFindFirstEnv(FoamTestEnvFn testFn, Foam foam, AInt env)
3271{
3272 if (testFn(foam, env))
3273 return foam;
3274
3275 foamIter(foam, arg, {{ { 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; { { Foam f = foamFindFirstEnv(testFn, *arg, env); if (f
!= 0) return f; }; }; } } }; }
3276 Foam f = foamFindFirstEnv(testFn, *arg, env);{ { 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; { { Foam f = foamFindFirstEnv(testFn, *arg, env); if (f
!= 0) return f; }; }; } } }; }
3277 if (f != 0){ { 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; { { Foam f = foamFindFirstEnv(testFn, *arg, env); if (f
!= 0) return f; }; }; } } }; }
3278 return f;{ { 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; { { Foam f = foamFindFirstEnv(testFn, *arg, env); if (f
!= 0) return f; }; }; } } }; }
3279 }){ { 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; { { Foam f = foamFindFirstEnv(testFn, *arg, env); if (f
!= 0) return f; }; }; } } }; }
;
3280 return 0;
3281}
3282
3283Foam
3284foamFindFirstTag(FoamTag tag, Foam foam)
3285{
3286 if (foamTag(foam)((foam)->hdr.tag) == tag)
3287 return foam;
3288
3289 foamIter(foam, arg, {{ { 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; { { Foam f = foamFindFirstTag(tag, *arg); if (f != 0) return
f; }; }; } } }; }
3290 Foam f = foamFindFirstTag(tag, *arg);{ { 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; { { Foam f = foamFindFirstTag(tag, *arg); if (f != 0) return
f; }; }; } } }; }
3291 if (f != 0){ { 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; { { Foam f = foamFindFirstTag(tag, *arg); if (f != 0) return
f; }; }; } } }; }
3292 return f;{ { 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; { { Foam f = foamFindFirstTag(tag, *arg); if (f != 0) return
f; }; }; } } }; }
3293 }){ { 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; { { Foam f = foamFindFirstTag(tag, *arg); if (f != 0) return
f; }; }; } } }; }
;
3294 return 0;
3295}
3296
3297Foam
3298foamCastIfNeeded(FoamTag wanted, FoamTag actual, Foam foam)
3299{
3300 if (wanted == actual)
3301 return foam;
3302
3303 return foamNewCast(wanted, foam)foamNew(FOAM_Cast, 2, wanted, foam);
3304}
3305
3306Foam
3307foamNeutralValue(FoamTag type)
3308{
3309 switch (type) {
3310 case FOAM_SInt:
3311 return foamNewSInt(0)foamNew(FOAM_SInt, 1, (AInt)(0));
3312 default:
3313 return foamNewCast(type, foamNewNil())foamNew(FOAM_Cast, 2, type, foamNew(FOAM_Nil, (int) 0));
3314 }
3315}
3316
3317/*****************************************************************************
3318 *
3319 * :: Table of FOAM instruction codes
3320 *
3321 ****************************************************************************/
3322
3323/*
3324 * Meanings of the bytes in the argf field:
3325 *
3326 * t = AInt as a foam type tag.
3327 * o = AInt as a foam builtin tag.
3328 * p = AInt as a foam protocol tag.
3329 * D = AInt as a foam DDecl tag.
3330 * b = AInt as a byte.
3331 * h = AInt as a half-int.
3332 * w = AInt as a single-int.
3333 * i = AInt as a usually small index (to be compressed).
3334 * L = AInt as a usually small label (to be compressed).
3335 * X = AInt length of byte-coded tree rooted at this node (to be compressed).
3336 * F = AInt as a byte, indicating format of all labels in prog.
3337 * s = String.
3338 * f = Single float.
3339 * d = Double float.
3340 * n = Big integer.
3341 * C = foam code.
3342 * ! = Arbitrary value (cannot be written to a file).
3343 */
3344
3345struct foam_info foamInfoTable[] = {
3346/* tag sxsym str argc argf, flags */
3347 {FOAM_Nil, 0,"Nil", 0, "", 0},
3348 {FOAM_Char, 0,"Char", 1, "b", 0},
3349 {FOAM_Bool, 0,"Bool", 1, "b", 0},
3350 {FOAM_Byte, 0,"Byte", 1, "b", 0},
3351 {FOAM_HInt, 0,"HInt", 1, "h", 0},
3352 {FOAM_SInt, 0,"SInt", 1, "w", 0},
3353 {FOAM_SFlo, 0,"SFlo", 1, "f", 0},
3354 {FOAM_DFlo, 0,"DFlo", 1, "d", 0},
3355 {FOAM_Word, 0,"Word", 1, "w", 0},
3356 {FOAM_Arb, 0,"Arb", 1, "!", 0},
3357
3358 {FOAM_Int8, 0,"Int8", 1, "b", 0},
3359 {FOAM_Int16, 0,"Int16", 1, "bb", 0},
3360 {FOAM_Int32, 0,"Int32", 1, "bbbb", 0},
3361 {FOAM_Int64, 0,"Int64", 1, "bbbbbbbb", 0},
3362 {FOAM_Int128, 0,"Int128", 1, "bbbbbbbbbbbbbbbb", 0},
3363
3364 {FOAM_NOp, 0,"NOp", 0, "", 0},
3365 {FOAM_BVal, 0,"BVal", 1, "o", 0},
3366 {FOAM_Ptr, 0,"Ptr", 1, "C", 0},
3367 {FOAM_CProg, 0,"CProg", 1, "C", 0},
3368 {FOAM_CEnv, 0,"CEnv", 1, "C", 0},
3369 {FOAM_Loose, 0,"Loose", 1, "C", 0},
3370 {FOAM_EEnsure, 0,"EEnsure", 1, "C", 0},
3371 {FOAM_EInfo, 0,"EInfo", 1, "C", 0},
3372 {FOAM_Kill, 0,"Kill", 1, "C", 0},
3373 {FOAM_Free, 0,"Free", 1, "C", 0},
3374 {FOAM_Return, 0,"Return", 1, "C", FOAMP_SeqExit(1<<0)},
3375 {FOAM_Cast, 0,"Cast", 2, "tC", 0},
3376 {FOAM_ANew, 0,"ANew", 2, "tC", 0},
3377 {FOAM_RRNew, 0,"RRNew", 2, "iC", 0},
3378 {FOAM_RRec, 0,"RRec", 2, "CC", 0},
3379 {FOAM_Clos, 0,"Clos", 2, "CC", 0},
3380 {FOAM_Set, 0,"Set", 2, "CC", 0},
3381 {FOAM_Def, 0,"Def", 2, "CC", 0},
3382 {FOAM_AElt, 0,"AElt", 3, "tCC", 0},
3383 {FOAM_If, 0,"If", 2, "CL", 0},
3384 {FOAM_Goto, 0,"Goto", 1, "L", 0},
3385 {FOAM_Throw, 0,"Throw", 2, "CC", FOAMP_SeqExit(1<<0)},
3386 {FOAM_Catch, 0,"Catch", 2, "CC", 0},
3387 {FOAM_Protect, 0,"Protect", 2, "CCC", 0},
3388 {FOAM_Unit, 0,"Unit", 2, "CC", 0},
3389 {FOAM_PushEnv, 0,"PushEnv", 2, "iC", 0},
3390 {FOAM_PopEnv, 0,"PopEnv", 0, "", 0},
3391 {FOAM_MFmt, 0,"MFmt", 2, "iC", 0},
3392 {FOAM_RRFmt, 0,"RRFmt", 1, "C", 0},
3393 {FOAM_JavaObj, 0,"JavaObj", 0, "", 0},
3394 {FOAM_CObj, 0,"CObj", 0, "", 0},
3395 {FOAM_Gener, 0,"Gener", 3, "iCC", 0},
3396 {FOAM_Yield, 0,"Yield", 1, "C", 0},
3397 {FOAM_GenIter, 0,"GenIter", 1, "C", 0},
3398 {FOAM_GenerValue, 0,"GenerValue", 1, "C", 0},
3399 {FOAM_GenerStep, 0,"GenerStep", 2, "LC", 0},
3400
3401/* ========> FFO_ORIGIN (start of multi-format instructions) <======== */
3402
3403 {FOAM_Unimp, 0,"Unimp", 1, "s", 0},
3404 {FOAM_GDecl, 0,"GDecl", 6, "tswibp", 0},
3405 {FOAM_Decl, 0,"Decl", 4, "tswi", 0},
3406 {FOAM_BInt, 0,"BInt", 1, "n", 0},
3407
3408 {FOAM_Par, 0,"Par", 1, "i", 0},
3409 {FOAM_Loc, 0,"Loc", 1, "i", 0},
3410 {FOAM_Glo, 0,"Glo", 1, "i", 0},
3411 {FOAM_Fluid, 0,"Fluid", 1, "i", 0},
3412 {FOAM_Const, 0,"Const", 1, "i", 0},
3413 {FOAM_Env, 0,"Env", 1, "i", 0},
3414 {FOAM_EEnv, 0,"EEnv", 2, "iC", 0},
3415 {FOAM_RNew, 0,"RNew", 1, "i", 0},
3416 {FOAM_PRef, 0,"PRef", 2, "iC", 0},
3417 {FOAM_TRNew, 0,"TRNew", 2, "iC", 0},
3418 {FOAM_RRElt, 0,"RRElt", 3, "iCC", 0},
3419 {FOAM_Label, 0,"Label", 1, "i", 0},
3420
3421 {FOAM_Lex, 0,"Lex", 2, "ii", 0},
3422 {FOAM_RElt, 0,"RElt", 3, "iCi", 0},
3423 {FOAM_IRElt, 0,"IRElt", 3, "iCi", 0},
3424 {FOAM_TRElt, 0,"TRElt", 4, "iCCi", 0},
3425 {FOAM_EElt, 0,"EElt", 4, "iCii", 0},
3426 {FOAM_CFCall, 0,"CFCall", 4, "iiCC", 0},
3427 {FOAM_OFCall, 0,"OFCall", 4, "iiCCC", 0},
3428
3429 {FOAM_DDecl, 0,"DDecl", FOAM_NARY(-1), "DC*", 0},
3430 {FOAM_DFluid, 0,"DFluid", FOAM_NARY(-1), "i*", 0},
3431 {FOAM_DEnv, 0,"DEnv", FOAM_NARY(-1), "i*", 0},
3432 {FOAM_DDef, 0,"DDef", FOAM_NARY(-1), "C*", 0},
3433 {FOAM_DFmt, 0,"DFmt", FOAM_NARY(-1), "C*", 0},
3434 {FOAM_Rec, 0,"Rec", FOAM_NARY(-1), "iC*", 0},
3435 {FOAM_Arr, 0,"Arr", FOAM_NARY(-1), "tw*", 0},
3436 {FOAM_TR, 0,"TR", FOAM_NARY(-1), "iC*", 0},
3437 {FOAM_Select, 0,"Select", FOAM_NARY(-1), "CL*", 0},
3438 {FOAM_PCall, 0,"PCall", FOAM_NARY(-1), "ptC*", 0},
3439 {FOAM_BCall, 0,"BCall", FOAM_NARY(-1), "oC*", 0},
3440 {FOAM_CCall, 0,"CCall", FOAM_NARY(-1), "tCC*", 0},
3441 {FOAM_OCall, 0,"OCall", FOAM_NARY(-1), "tCCC*", 0},
3442 {FOAM_Seq, 0,"Seq", FOAM_NARY(-1), "C*", 0},
3443 {FOAM_Values, 0,"Values", FOAM_NARY(-1), "C*", 0},
3444 {FOAM_Prog, 0,"Prog", FOAM_NARY(-1), "XFtwwwwwC*", 0}
3445};
3446
3447/*****************************************************************************
3448 *
3449 * :: Table of FOAM protcols
3450 *
3451 ****************************************************************************/
3452
3453struct foamProto_info foamProtoInfoTable[] = {
3454 {FOAM_Proto_Foam, 0,"Foam", FOAM_Proto_Foam},
3455 {FOAM_Proto_Fortran, 0,"Fortran", FOAM_Proto_Fortran},
3456 {FOAM_Proto_C, 0,"C", FOAM_Proto_C},
3457 {FOAM_Proto_Java, 0,"Java", FOAM_Proto_Java},
3458 {FOAM_Proto_JavaConstructor, 0,"JavaConstructor", FOAM_Proto_Java},
3459 {FOAM_Proto_JavaMethod, 0,"JavaMethod", FOAM_Proto_Java},
3460 {FOAM_Proto_Lisp, 0,"Lisp", FOAM_Proto_Lisp},
3461 {FOAM_Proto_Init, 0,"Init", FOAM_Proto_Init},
3462 {FOAM_Proto_Include, 0,"Include", FOAM_Proto_Include},
3463 {FOAM_Proto_Other, 0,"Other", FOAM_Proto_Other}
3464};
3465
3466/*****************************************************************************
3467 *
3468 * :: Table of FOAM decl information
3469 *
3470 ****************************************************************************/
3471
3472struct foamDDecl_info foamDDeclInfoTable[] = {
3473 { FOAM_DDecl_LocalEnv, 0, "LocalEnv" },
3474 { FOAM_DDecl_NonLocalEnv, 0, "NonLocalEnv" },
3475 { FOAM_DDecl_Param, 0, "Params" },
3476 { FOAM_DDecl_Local, 0, "Locals" },
3477 { FOAM_DDecl_Fluid, 0, "Fluids" },
3478 { FOAM_DDecl_Multi, 0, "Multis" },
3479 { FOAM_DDecl_Union, 0, "Unions" },
3480 { FOAM_DDecl_Record, 0, "Records" },
3481 { FOAM_DDecl_TrailingArray, 0, "TrailingArray" },
3482 { FOAM_DDecl_Consts, 0, "Consts" },
3483 { FOAM_DDecl_Global, 0, "Globals" },
3484 { FOAM_DDecl_FortranSig, 0, "FortranSig" },
3485 { FOAM_DDecl_CSig, 0, "CSig" },
3486 { FOAM_DDecl_CType, 0, "CType" },
3487 { FOAM_DDecl_JavaSig, 0, "JavaSig" },
3488 { FOAM_DDecl_JavaClass, 0, "JavaClass" },
3489};
3490
3491/*****************************************************************************
3492 *
3493 * :: Table of FOAM builtin operations
3494 *
3495 ****************************************************************************/
3496
3497struct foamBVal_info foamBValInfoTable[] = {
3498 {FOAM_BVal_BoolFalse, 0,"BoolFalse",
3499 0,0,{0}, FOAM_Bool, 1, {0}},
3500 {FOAM_BVal_BoolTrue, 0,"BoolTrue",
3501 0,0,{0}, FOAM_Bool, 1, {0}},
3502 {FOAM_BVal_BoolNot, 0,"BoolNot",
3503 0,1,{FOAM_Bool}, FOAM_Bool, 1, {0}},
3504 {FOAM_BVal_BoolAnd, 0,"BoolAnd",
3505 0,2,{FOAM_Bool, FOAM_Bool}, FOAM_Bool, 1, {0}},
3506 {FOAM_BVal_BoolOr, 0,"BoolOr",
3507 0,2,{FOAM_Bool, FOAM_Bool}, FOAM_Bool, 1, {0}},
3508 {FOAM_BVal_BoolEQ, 0,"BoolEQ",
3509 0,2,{FOAM_Bool, FOAM_Bool}, FOAM_Bool, 1, {0}},
3510 {FOAM_BVal_BoolNE, 0,"BoolNE",
3511 0,2,{FOAM_Bool, FOAM_Bool}, FOAM_Bool, 1, {0}},
3512
3513 {FOAM_BVal_CharSpace, 0,"CharSpace",
3514 0,0,{0}, FOAM_Char, 1, {0}},
3515 {FOAM_BVal_CharNewline, 0,"CharNewline",
3516 0,0,{0}, FOAM_Char, 1, {0}},
3517 {FOAM_BVal_CharTab, 0,"CharTab",
3518 0,0,{0}, FOAM_Char, 1, {0}},
3519 {FOAM_BVal_CharMin, 0,"CharMin",
3520 0,0,{0}, FOAM_Char, 1, {0}},
3521 {FOAM_BVal_CharMax, 0,"CharMax",
3522 0,0,{0}, FOAM_Char, 1, {0}},
3523 {FOAM_BVal_CharIsDigit, 0,"CharIsDigit",
3524 0,1,{FOAM_Char}, FOAM_Bool, 1, {0}},
3525 {FOAM_BVal_CharIsLetter,0,"CharIsLetter",
3526 0,1,{FOAM_Char}, FOAM_Bool, 1, {0}},
3527 {FOAM_BVal_CharEQ, 0,"CharEQ",
3528 0,2,{FOAM_Char,FOAM_Char}, FOAM_Bool, 1, {0}},
3529 {FOAM_BVal_CharNE, 0,"CharNE",
3530 0,2,{FOAM_Char,FOAM_Char}, FOAM_Bool, 1, {0}},
3531 {FOAM_BVal_CharLT, 0,"CharLT",
3532 0,2,{FOAM_Char,FOAM_Char}, FOAM_Bool, 1, {0}},
3533 {FOAM_BVal_CharLE, 0,"CharLE",
3534 0,2,{FOAM_Char,FOAM_Char}, FOAM_Bool, 1, {0}},
3535 {FOAM_BVal_CharLower, 0,"CharLower",
3536 0,1,{FOAM_Char}, FOAM_Char, 1, {0}},
3537 {FOAM_BVal_CharUpper, 0,"CharUpper",
3538 0,1,{FOAM_Char}, FOAM_Char, 1, {0}},
3539 {FOAM_BVal_CharOrd, 0,"CharOrd",
3540 0,1,{FOAM_Char}, FOAM_SInt, 1, {0}},
3541 {FOAM_BVal_CharNum, 0,"CharNum",
3542 0,1,{FOAM_SInt}, FOAM_Char, 1, {0}},
3543
3544 /* Floating point system properties are omitted, but need to be returned. */
3545
3546 {FOAM_BVal_SFlo0, 0,"SFlo0",
3547 0,0,{0}, FOAM_SFlo, 1, {0}},
3548 {FOAM_BVal_SFlo1, 0,"SFlo1",
3549 0,0,{0}, FOAM_SFlo, 1, {0}},
3550 {FOAM_BVal_SFloMin, 0,"SFloMin",
3551 0,0,{0}, FOAM_SFlo, 1, {0}},
3552 {FOAM_BVal_SFloMax, 0,"SFloMax",
3553 0,0,{0}, FOAM_SFlo, 1, {0}},
3554 {FOAM_BVal_SFloEpsilon, 0,"SFloEpsilon",
3555 0,0,{0}, FOAM_SFlo, 1, {0}},
3556 {FOAM_BVal_SFloIsZero, 0,"SFloIsZero",
3557 0,1,{FOAM_SFlo}, FOAM_Bool, 1, {0}},
3558 {FOAM_BVal_SFloIsNeg, 0,"SFloIsNeg",
3559 0,1,{FOAM_SFlo}, FOAM_Bool, 1, {0}},
3560 {FOAM_BVal_SFloIsPos, 0,"SFloIsPos",
3561 0,1,{FOAM_SFlo}, FOAM_Bool, 1, {0}},
3562 {FOAM_BVal_SFloEQ, 0,"SFloEQ",
3563 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_Bool, 1, {0}},
3564 {FOAM_BVal_SFloNE, 0,"SFloNE",
3565 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_Bool, 1, {0}},
3566 {FOAM_BVal_SFloLT, 0,"SFloLT",
3567 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_Bool, 1, {0}},
3568 {FOAM_BVal_SFloLE, 0,"SFloLE",
3569 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_Bool, 1, {0}},
3570 {FOAM_BVal_SFloNegate, 0,"SFloNegate",
3571 0,1,{FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3572 {FOAM_BVal_SFloPrev, 0,"SFloPrev",
3573 0,1,{FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3574 {FOAM_BVal_SFloNext, 0,"SFloNext",
3575 0,1,{FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3576 {FOAM_BVal_SFloPlus, 0,"SFloPlus",
3577 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3578 {FOAM_BVal_SFloMinus, 0,"SFloMinus",
3579 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3580 {FOAM_BVal_SFloTimes, 0,"SFloTimes",
3581 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3582 {FOAM_BVal_SFloTimesPlus, 0,"SFloTimesPlus",
3583 0,3,{FOAM_SFlo,FOAM_SFlo,FOAM_SFlo},FOAM_SFlo, 1, {0}},
3584 {FOAM_BVal_SFloDivide, 0,"SFloDivide",
3585 0,2,{FOAM_SFlo,FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3586 {FOAM_BVal_SFloRPlus, 0,"SFloRPlus",
3587 0,3,{FOAM_SFlo,FOAM_SFlo,FOAM_SInt}, FOAM_SFlo, 1, {0}},
3588 {FOAM_BVal_SFloRMinus, 0,"SFloRMinus",
3589 0,3,{FOAM_SFlo,FOAM_SFlo,FOAM_SInt}, FOAM_SFlo, 1, {0}},
3590 {FOAM_BVal_SFloRTimes, 0,"SFloRTimes",
3591 0,3,{FOAM_SFlo,FOAM_SFlo,FOAM_SInt}, FOAM_SFlo, 1, {0}},
3592 {FOAM_BVal_SFloRTimesPlus, 0,"SFloRTimesPlus",
3593 0,4,{FOAM_SFlo,FOAM_SFlo,FOAM_SFlo,FOAM_SInt},
3594 FOAM_SFlo, 1, {0}},
3595 {FOAM_BVal_SFloRDivide, 0,"SFloRDivide",
3596 0,3,{FOAM_SFlo,FOAM_SFlo,FOAM_SInt}, FOAM_SFlo, 1, {0}},
3597 {FOAM_BVal_SFloDissemble,0,"SFloDissemble",
3598 0,1,{FOAM_SFlo}, FOAM_NOp, 3,
3599 {FOAM_Bool,FOAM_SInt,FOAM_Word}},
3600 {FOAM_BVal_SFloAssemble,0,"SFloAssemble",
3601 0,3, {FOAM_Bool,FOAM_SInt,FOAM_Word},FOAM_SFlo, 1, {0}},
3602
3603
3604 {FOAM_BVal_DFlo0, 0,"DFlo0",
3605 0,0,{0}, FOAM_DFlo, 1, {0}},
3606 {FOAM_BVal_DFlo1, 0,"DFlo1",
3607 0,0,{0}, FOAM_DFlo, 1, {0}},
3608 {FOAM_BVal_DFloMin, 0,"DFloMin",
3609 0,0,{0}, FOAM_DFlo, 1, {0}},
3610 {FOAM_BVal_DFloMax, 0,"DFloMax",
3611 0,0,{0}, FOAM_DFlo, 1, {0}},
3612 {FOAM_BVal_DFloEpsilon, 0,"DFloEpsilon",
3613 0,0,{0}, FOAM_DFlo, 1, {0}},
3614 {FOAM_BVal_DFloIsZero, 0,"DFloIsZero",
3615 0,1,{FOAM_DFlo}, FOAM_Bool, 1, {0}},
3616 {FOAM_BVal_DFloIsNeg, 0,"DFloIsNeg",
3617 0,1,{FOAM_DFlo}, FOAM_Bool, 1, {0}},
3618 {FOAM_BVal_DFloIsPos, 0,"DFloIsPos",
3619 0,1,{FOAM_DFlo}, FOAM_Bool, 1, {0}},
3620 {FOAM_BVal_DFloEQ, 0,"DFloEQ",
3621 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_Bool, 1, {0}},
3622 {FOAM_BVal_DFloNE, 0,"DFloNE",
3623 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_Bool, 1, {0}},
3624 {FOAM_BVal_DFloLT, 0,"DFloLT",
3625 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_Bool, 1, {0}},
3626 {FOAM_BVal_DFloLE, 0,"DFloLE",
3627 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_Bool, 1, {0}},
3628 {FOAM_BVal_DFloNegate, 0,"DFloNegate",
3629 0,1,{FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3630 {FOAM_BVal_DFloPrev, 0,"DFloPrev",
3631 0,1,{FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3632 {FOAM_BVal_DFloNext, 0,"DFloNext",
3633 0,1,{FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3634 {FOAM_BVal_DFloPlus, 0,"DFloPlus",
3635 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3636 {FOAM_BVal_DFloMinus, 0,"DFloMinus",
3637 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3638 {FOAM_BVal_DFloTimes, 0,"DFloTimes",
3639 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3640 {FOAM_BVal_DFloTimesPlus, 0,"DFloTimesPlus",
3641 0,3,{FOAM_DFlo,FOAM_DFlo,FOAM_DFlo},FOAM_DFlo, 1, {0}},
3642 {FOAM_BVal_DFloDivide, 0,"DFloDivide",
3643 0,2,{FOAM_DFlo,FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3644 {FOAM_BVal_DFloRPlus, 0,"DFloRPlus",
3645 0,3,{FOAM_DFlo,FOAM_DFlo,FOAM_SInt},FOAM_DFlo, 1, {0}},
3646 {FOAM_BVal_DFloRMinus, 0,"DFloRMinus",
3647 0,3,{FOAM_DFlo,FOAM_DFlo,FOAM_SInt},FOAM_DFlo, 1, {0}},
3648 {FOAM_BVal_DFloRTimes, 0,"DFloRTimes",
3649 0,3,{FOAM_DFlo,FOAM_DFlo,FOAM_SInt},FOAM_DFlo, 1, {0}},
3650 {FOAM_BVal_DFloRTimesPlus, 0,"DFloRTimesPlus",
3651 0,4,{FOAM_DFlo,FOAM_DFlo,FOAM_DFlo,FOAM_SInt},
3652 FOAM_DFlo, 1, {0}},
3653 {FOAM_BVal_DFloRDivide, 0,"DFloRDivide",
3654 0,3,{FOAM_DFlo,FOAM_DFlo,FOAM_SInt}, FOAM_DFlo, 1, {0}},
3655 {FOAM_BVal_DFloDissemble,0,"DFloDissemble",
3656 0,1,{FOAM_DFlo}, FOAM_NOp, 4,
3657 {FOAM_Bool,FOAM_SInt,FOAM_Word,FOAM_Word}},
3658 {FOAM_BVal_DFloAssemble,0,"DFloAssemble",
3659 0,4,{FOAM_Bool,FOAM_SInt,FOAM_Word,FOAM_Word},
3660 FOAM_DFlo, 1, {0}},
3661
3662
3663 {FOAM_BVal_Byte0, 0,"Byte0",
3664 0,0,{0}, FOAM_Byte, 1, {0}},
3665 {FOAM_BVal_Byte1, 0,"Byte1",
3666 0,0,{0}, FOAM_Byte, 1, {0}},
3667 {FOAM_BVal_ByteMin, 0,"ByteMin",
3668 0,0,{0}, FOAM_Byte, 1, {0}},
3669 {FOAM_BVal_ByteMax, 0,"ByteMax",
3670 0,0,{0}, FOAM_Byte, 1, {0}},
3671
3672 {FOAM_BVal_HInt0, 0,"HInt0",
3673 0,0,{0}, FOAM_HInt, 1, {0}},
3674 {FOAM_BVal_HInt1, 0,"HInt1",
3675 0,0,{0}, FOAM_HInt, 1, {0}},
3676 {FOAM_BVal_HIntMin, 0,"HIntMin",
3677 0,0,{0}, FOAM_HInt, 1, {0}},
3678 {FOAM_BVal_HIntMax, 0,"HIntMax",
3679 0,0,{0}, FOAM_HInt, 1, {0}},
3680
3681 {FOAM_BVal_SInt0, 0,"SInt0",
3682 0,0,{0}, FOAM_SInt, 1, {0}},
3683 {FOAM_BVal_SInt1, 0,"SInt1",
3684 0,0,{0}, FOAM_SInt, 1, {0}},
3685 {FOAM_BVal_SIntMin, 0,"SIntMin",
3686 0,0,{0}, FOAM_SInt, 1, {0}},
3687 {FOAM_BVal_SIntMax, 0,"SIntMax",
3688 0,0,{0}, FOAM_SInt, 1, {0}},
3689 {FOAM_BVal_SIntIsZero, 0,"SIntIsZero",
3690 0,1,{FOAM_SInt}, FOAM_Bool, 1, {0}},
3691 {FOAM_BVal_SIntIsNeg, 0,"SIntIsNeg",
3692 0,1,{FOAM_SInt}, FOAM_Bool, 1, {0}},
3693 {FOAM_BVal_SIntIsPos, 0,"SIntIsPos",
3694 0,1,{FOAM_SInt}, FOAM_Bool, 1, {0}},
3695 {FOAM_BVal_SIntIsEven, 0,"SIntIsEven",
3696 0,1,{FOAM_SInt}, FOAM_Bool, 1, {0}},
3697 {FOAM_BVal_SIntIsOdd, 0,"SIntIsOdd",
3698 0,1,{FOAM_SInt}, FOAM_Bool, 1, {0}},
3699 {FOAM_BVal_SIntEQ, 0,"SIntEQ",
3700 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_Bool, 1, {0}},
3701 {FOAM_BVal_SIntNE, 0,"SIntNE",
3702 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_Bool, 1, {0}},
3703 {FOAM_BVal_SIntLT, 0,"SIntLT",
3704 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_Bool, 1, {0}},
3705 {FOAM_BVal_SIntLE, 0,"SIntLE",
3706 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_Bool, 1, {0}},
3707 {FOAM_BVal_SIntNegate, 0,"SIntNegate",
3708 0,1,{FOAM_SInt}, FOAM_SInt, 1, {0}},
3709 {FOAM_BVal_SIntPrev, 0,"SIntPrev",
3710 0,1,{FOAM_SInt}, FOAM_SInt, 1, {0}},
3711 {FOAM_BVal_SIntNext, 0,"SIntNext",
3712 0,1,{FOAM_SInt}, FOAM_SInt, 1, {0}},
3713 {FOAM_BVal_SIntPlus, 0,"SIntPlus",
3714 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3715 {FOAM_BVal_SIntMinus, 0,"SIntMinus",
3716 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3717 {FOAM_BVal_SIntTimes, 0,"SIntTimes",
3718 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3719 {FOAM_BVal_SIntTimesPlus, 0,"SIntTimesPlus",
3720 0,3,{FOAM_SInt,FOAM_SInt,FOAM_SInt},FOAM_SInt, 1, {0}},
3721 {FOAM_BVal_SIntMod, 0,"SIntMod",
3722 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3723 {FOAM_BVal_SIntQuo, 0,"SIntQuo",
3724 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3725 {FOAM_BVal_SIntRem, 0,"SIntRem",
3726 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3727 {FOAM_BVal_SIntDivide, 0,"SIntDivide",
3728 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_NOp,
3729 2, {FOAM_SInt, FOAM_SInt}},
3730 {FOAM_BVal_SIntGcd, 0,"SIntGcd",
3731 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3732 {FOAM_BVal_SIntPlusMod, 0,"SIntPlusMod",
3733 0,3,{FOAM_SInt,FOAM_SInt,FOAM_SInt},FOAM_SInt, 1, {0}},
3734 {FOAM_BVal_SIntMinusMod,0,"SIntMinusMod",
3735 0,3,{FOAM_SInt,FOAM_SInt,FOAM_SInt},FOAM_SInt, 1, {0}},
3736 {FOAM_BVal_SIntTimesMod,0,"SIntTimesMod",
3737 0,3,{FOAM_SInt,FOAM_SInt,FOAM_SInt},FOAM_SInt, 1, {0}},
3738 {FOAM_BVal_SIntTimesModInv,0,"SIntTimesModInv",
3739 0,4,{FOAM_SInt,FOAM_SInt,FOAM_SInt,FOAM_DFlo},
3740 FOAM_SInt, 1, {0}},
3741 {FOAM_BVal_SIntLength, 0,"SIntLength",
3742 0,1,{FOAM_SInt}, FOAM_SInt, 1, {0}},
3743 {FOAM_BVal_SIntShiftUp, 0,"SIntShiftUp",
3744 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3745 {FOAM_BVal_SIntShiftDn, 0,"SIntShiftDn",
3746 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3747 {FOAM_BVal_SIntBit, 0,"SIntBit",
3748 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_Bool, 1, {0}},
3749 {FOAM_BVal_SIntNot, 0,"SIntNot",
3750 0,1,{FOAM_SInt}, FOAM_SInt, 1, {0}},
3751 {FOAM_BVal_SIntAnd, 0,"SIntAnd",
3752 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3753 {FOAM_BVal_SIntOr, 0,"SIntOr",
3754 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3755 {FOAM_BVal_SIntXOr, 0,"SIntXOr",
3756 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3757 {FOAM_BVal_SIntHashCombine,
3758 0,"SIntHashCombine",
3759 0,2,{FOAM_SInt,FOAM_SInt}, FOAM_SInt, 1, {0}},
3760
3761 {FOAM_BVal_WordTimesDouble,0,"WordTimesDouble",
3762 0,2,{FOAM_Word,FOAM_Word}, FOAM_NOp, 2,
3763 {FOAM_Word,FOAM_Word}},
3764 {FOAM_BVal_WordDivideDouble,0,"WordDivideDouble",
3765 0,3,{FOAM_Word,FOAM_Word,FOAM_Word},FOAM_NOp, 3,
3766 {FOAM_Word,FOAM_Word,FOAM_Word}},
3767 {FOAM_BVal_WordPlusStep,0,"WordPlusStep",
3768 0,3,{FOAM_Word,FOAM_Word,FOAM_Word},FOAM_NOp, 2,
3769 {FOAM_Word,FOAM_Word}},
3770 {FOAM_BVal_WordTimesStep,0,"WordTimesStep",
3771 0,4,{FOAM_Word,FOAM_Word,FOAM_Word,FOAM_Word},
3772 FOAM_NOp, 2,
3773 {FOAM_Word,FOAM_Word}},
3774
3775 {FOAM_BVal_BInt0, 0,"BInt0",
3776 0,0,{0}, FOAM_BInt, 1, {0}},
3777 {FOAM_BVal_BInt1, 0,"BInt1",
3778 0,0,{0}, FOAM_BInt, 1, {0}},
3779 {FOAM_BVal_BIntIsZero, 0,"BIntIsZero",
3780 0,1,{FOAM_BInt}, FOAM_Bool, 1, {0}},
3781 {FOAM_BVal_BIntIsNeg, 0,"BIntIsNeg",
3782 0,1,{FOAM_BInt}, FOAM_Bool, 1, {0}},
3783 {FOAM_BVal_BIntIsPos, 0,"BIntIsPos",
3784 0,1,{FOAM_BInt}, FOAM_Bool, 1, {0}},
3785 {FOAM_BVal_BIntIsEven, 0,"BIntIsEven",
3786 0,1,{FOAM_BInt}, FOAM_Bool, 1, {0}},
3787 {FOAM_BVal_BIntIsOdd, 0,"BIntIsOdd",
3788 0,1,{FOAM_BInt}, FOAM_Bool, 1, {0}},
3789 {FOAM_BVal_BIntIsSingle,0,"BIntIsSingle",
3790 0,1,{FOAM_BInt}, FOAM_Bool, 1, {0}},
3791 {FOAM_BVal_BIntEQ, 0,"BIntEQ",
3792 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_Bool, 1, {0}},
3793 {FOAM_BVal_BIntNE, 0,"BIntNE",
3794 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_Bool, 1, {0}},
3795 {FOAM_BVal_BIntLT, 0,"BIntLT",
3796 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_Bool, 1, {0}},
3797 {FOAM_BVal_BIntLE, 0,"BIntLE",
3798 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_Bool, 1, {0}},
3799 {FOAM_BVal_BIntNegate, 0,"BIntNegate",
3800 0,1,{FOAM_BInt}, FOAM_BInt, 1, {0}},
3801 {FOAM_BVal_BIntPrev, 0,"BIntPrev",
3802 0,1,{FOAM_BInt}, FOAM_BInt, 1, {0}},
3803 {FOAM_BVal_BIntNext, 0,"BIntNext",
3804 0,1,{FOAM_BInt}, FOAM_BInt, 1, {0}},
3805 {FOAM_BVal_BIntPlus, 0,"BIntPlus",
3806 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3807 {FOAM_BVal_BIntMinus, 0,"BIntMinus",
3808 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3809 {FOAM_BVal_BIntTimes, 0,"BIntTimes",
3810 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3811 {FOAM_BVal_BIntTimesPlus, 0,"BIntTimesPlus",
3812 0,3,{FOAM_BInt,FOAM_BInt,FOAM_BInt},FOAM_BInt, 1, {0}},
3813 {FOAM_BVal_BIntMod, 0,"BIntMod",
3814 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3815 {FOAM_BVal_BIntQuo, 0,"BIntQuo",
3816 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3817 {FOAM_BVal_BIntRem, 0,"BIntRem",
3818 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3819 {FOAM_BVal_BIntDivide, 0,"BIntDivide",
3820 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_NOp,
3821 2, {FOAM_BInt, FOAM_BInt}},
3822 {FOAM_BVal_BIntGcd, 0,"BIntGcd",
3823 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3824 {FOAM_BVal_BIntSIPower, 0,"BIntSIPower",
3825 0,2,{FOAM_BInt, FOAM_SInt}, FOAM_BInt, 1, {0}},
3826 {FOAM_BVal_BIntBIPower, 0,"BIntBIPower",
3827 0,2,{FOAM_BInt, FOAM_BInt}, FOAM_BInt, 1, {0}},
3828 {FOAM_BVal_BIntPowerMod,0,"BIntPowerMod",
3829 0,3,{FOAM_BInt, FOAM_BInt, FOAM_BInt},FOAM_BInt, 1, {0}},
3830 {FOAM_BVal_BIntLength, 0,"BIntLength",
3831 0,1,{FOAM_BInt}, FOAM_SInt, 1, {0}},
3832 {FOAM_BVal_BIntShiftUp, 0,"BIntShiftUp",
3833 0,2,{FOAM_BInt, FOAM_SInt}, FOAM_BInt, 1, {0}},
3834 {FOAM_BVal_BIntShiftDn, 0,"BIntShiftDn",
3835 0,2,{FOAM_BInt, FOAM_SInt}, FOAM_BInt, 1, {0}},
3836 {FOAM_BVal_BIntShiftRem, 0,"BIntShiftRem",
3837 0,2,{FOAM_BInt, FOAM_SInt}, FOAM_BInt, 1, {0}},
3838 {FOAM_BVal_BIntBit, 0,"BIntBit",
3839 0,2,{FOAM_BInt, FOAM_SInt}, FOAM_Bool, 1, {0}},
3840
3841 {FOAM_BVal_PtrNil, 0,"PtrNil",
3842 0,0,{0}, FOAM_Ptr, 1, {0}},
3843 {FOAM_BVal_PtrIsNil, 0,"PtrIsNil",
3844 0,1,{FOAM_Ptr}, FOAM_Bool, 1, {0}},
3845 {FOAM_BVal_PtrMagicEQ, 0,"PtrMagicEQ",
3846 0,2,{FOAM_Ptr, FOAM_Ptr}, FOAM_Bool, 1, {0}},
3847 {FOAM_BVal_PtrEQ, 0,"PtrEQ",
3848 0,2,{FOAM_Ptr, FOAM_Ptr}, FOAM_Bool, 1, {0}},
3849 {FOAM_BVal_PtrNE, 0,"PtrNE",
3850 0,2,{FOAM_Ptr, FOAM_Ptr}, FOAM_Bool, 1, {0}},
3851
3852 {FOAM_BVal_FormatSFlo, 0,"FormatSFlo",
3853 1,3,{FOAM_SFlo,FOAM_Arr,FOAM_SInt}, FOAM_SInt, 1, {0}},
3854 {FOAM_BVal_FormatDFlo, 0,"FormatDFlo",
3855 1,3,{FOAM_DFlo,FOAM_Arr,FOAM_SInt}, FOAM_SInt, 1, {0}},
3856 {FOAM_BVal_FormatSInt, 0,"FormatSInt",
3857 1,3,{FOAM_SInt,FOAM_Arr,FOAM_SInt}, FOAM_SInt, 1, {0}},
3858 {FOAM_BVal_FormatBInt, 0,"FormatBInt",
3859 1,3,{FOAM_BInt, FOAM_Arr,FOAM_SInt},FOAM_SInt, 1, {0}},
3860
3861 {FOAM_BVal_ScanSFlo, 0,"ScanSFlo",
3862 0,2,{FOAM_Arr, FOAM_SInt}, FOAM_NOp,
3863 2, {FOAM_SFlo, FOAM_SInt}},
3864 {FOAM_BVal_ScanDFlo, 0,"ScanDFlo",
3865 0,2,{FOAM_Arr, FOAM_SInt}, FOAM_NOp,
3866 2, {FOAM_DFlo, FOAM_SInt}},
3867 {FOAM_BVal_ScanSInt, 0,"ScanSInt",
3868 0,2,{FOAM_Arr, FOAM_SInt}, FOAM_NOp,
3869 2, {FOAM_SInt, FOAM_SInt}},
3870 {FOAM_BVal_ScanBInt, 0,"ScanBInt",
3871 0,2,{FOAM_Arr, FOAM_SInt}, FOAM_NOp,
3872 2, {FOAM_BInt, FOAM_SInt}},
3873
3874 {FOAM_BVal_SFloToDFlo, 0,"SFloToDFlo",
3875 0,1,{FOAM_SFlo}, FOAM_DFlo, 1, {0}},
3876 {FOAM_BVal_DFloToSFlo, 0,"DFloToSFlo",
3877 0,1,{FOAM_DFlo}, FOAM_SFlo, 1, {0}},
3878 {FOAM_BVal_ByteToSInt, 0,"ByteToSInt",
3879 0,1,{FOAM_Byte}, FOAM_SInt, 1, {0}},
3880 {FOAM_BVal_SIntToByte, 0,"SIntToByte",
3881 0,1,{FOAM_SInt}, FOAM_Byte, 1, {0}},
3882 {FOAM_BVal_HIntToSInt, 0,"HIntToSInt",
3883 0,1,{FOAM_HInt}, FOAM_SInt, 1, {0}},
3884 {FOAM_BVal_SIntToHInt, 0,"SIntToHInt",
3885 0,1,{FOAM_SInt}, FOAM_HInt, 1, {0}},
3886 {FOAM_BVal_SIntToBInt, 0,"SIntToBInt",
3887 0,1,{FOAM_SInt}, FOAM_BInt, 1, {0}},
3888 {FOAM_BVal_BIntToSInt, 0,"BIntToSInt",
3889 0,1,{FOAM_BInt}, FOAM_SInt, 1, {0}},
3890 {FOAM_BVal_SIntToSFlo, 0,"SIntToSFlo",
3891 0,1,{FOAM_SInt}, FOAM_SFlo, 1, {0}},
3892 {FOAM_BVal_SIntToDFlo, 0,"SIntToDFlo",
3893 0,1,{FOAM_SInt}, FOAM_DFlo, 1, {0}},
3894 {FOAM_BVal_BIntToSFlo, 0,"BIntToSFlo",
3895 0,1,{FOAM_BInt}, FOAM_SFlo, 1, {0}},
3896 {FOAM_BVal_BIntToDFlo, 0,"BIntToDFlo",
3897 0,1,{FOAM_BInt}, FOAM_DFlo, 1, {0}},
3898 {FOAM_BVal_PtrToSInt, 0,"PtrToSInt",
3899 0,1,{FOAM_Ptr}, FOAM_SInt, 1, {0}},
3900 {FOAM_BVal_SIntToPtr, 0,"SIntToPtr",
3901 0,1,{FOAM_SInt}, FOAM_Ptr, 1, {0}},
3902
3903 {FOAM_BVal_ArrToSFlo, 0,"ArrToSFlo",
3904 0,1,{FOAM_Arr}, FOAM_SFlo, 1, {0}},
3905 {FOAM_BVal_ArrToDFlo, 0,"ArrToDFlo",
3906 0,1,{FOAM_Arr}, FOAM_DFlo, 1, {0}},
3907 {FOAM_BVal_ArrToSInt, 0,"ArrToSInt",
3908 0,1,{FOAM_Arr}, FOAM_SInt, 1, {0}},
3909 {FOAM_BVal_ArrToBInt, 0,"ArrToBInt",
3910 0,1,{FOAM_Arr}, FOAM_BInt, 1, {0}},
3911
3912 {FOAM_BVal_PlatformRTE, 0,"PlatformRTE",
3913 0,0,{0}, FOAM_SInt, 1, {0}},
3914
3915 {FOAM_BVal_PlatformOS, 0,"PlatformOS",
3916 0,0,{0}, FOAM_SInt, 1, {0}},
3917
3918 {FOAM_BVal_Halt, 0,"Halt",
3919 1,1,{FOAM_SInt}, FOAM_Word, 1, {0}},
3920
3921 {FOAM_BVal_RoundZero, 0,"RoundZero",
3922 0, 0, {0}, FOAM_SInt, 1, {0}},
3923 {FOAM_BVal_RoundNearest, 0,"RoundNearest",
3924 0, 0, {0}, FOAM_SInt, 1, {0}},
3925 {FOAM_BVal_RoundUp, 0,"RoundUp",
3926 0, 0, {0}, FOAM_SInt, 1, {0}},
3927 {FOAM_BVal_RoundDown, 0,"RoundDown",
3928 0, 0, {0}, FOAM_SInt, 1, {0}},
3929 {FOAM_BVal_RoundDontCare, 0,"RoundDontCare",
3930 0, 0, {0}, FOAM_SInt, 1, {0}},
3931
3932 {FOAM_BVal_SFloTruncate, 0, "SFloTruncate",
3933 0,1,{FOAM_SFlo}, FOAM_BInt, 1, {0}},
3934 {FOAM_BVal_SFloFraction, 0, "SFloFraction",
3935 0,1,{FOAM_SFlo}, FOAM_SFlo, 1, {0}},
3936 {FOAM_BVal_SFloRound, 0, "SFloRound",
3937 0,2,{FOAM_SFlo, FOAM_SInt}, FOAM_BInt, 1, {0}},
3938
3939 {FOAM_BVal_DFloTruncate, 0, "DFloTruncate",
3940 0,1,{FOAM_DFlo}, FOAM_BInt, 1, {0}},
3941 {FOAM_BVal_DFloFraction, 0, "DFloFraction",
3942 0,1,{FOAM_DFlo}, FOAM_DFlo, 1, {0}},
3943 {FOAM_BVal_DFloRound, 0, "DFloRound",
3944 0,2,{FOAM_DFlo, FOAM_SInt}, FOAM_BInt, 1, {0}},
3945
3946 {FOAM_BVal_StoForceGC, 0, "StoForceGC",
3947 1, 0, {0}, FOAM_NOp, 0, {0}},
3948 {FOAM_BVal_StoInHeap, 0, "StoInHeap",
3949 1, 1, {FOAM_Ptr}, FOAM_Bool, 1, {0}},
3950 {FOAM_BVal_StoIsWritable, 0, "StoIsWritable",
3951 1, 1, {FOAM_Ptr}, FOAM_SInt, 1, {0}},
3952 {FOAM_BVal_StoMarkObject, 0, "StoMarkObject",
3953 1, 1, {FOAM_Ptr}, FOAM_SInt, 1, {0}},
3954 {FOAM_BVal_StoRecode, 0, "StoRecode",
3955 1, 2, {FOAM_Ptr, FOAM_SInt}, FOAM_Word, 1, {0}},
3956 {FOAM_BVal_StoNewObject, 0, "StoNewObject",
3957 1, 2, {FOAM_SInt, FOAM_Bool}, FOAM_NOp, 0, {0}},
3958 {FOAM_BVal_StoATracer, 0, "StoATracer",
3959 1, 2, {FOAM_SInt, FOAM_Clos}, FOAM_NOp, 0, {0}},
3960 {FOAM_BVal_StoCTracer, 0, "StoCTracer",
3961 1, 2, {FOAM_SInt, FOAM_Word}, FOAM_NOp, 0, {0}},
3962 {FOAM_BVal_StoShow, 0, "StoShow",
3963 1, 1, {FOAM_SInt}, FOAM_NOp, 0, {0}},
3964 {FOAM_BVal_StoShowArgs, 0, "StoShowArgs",
3965 1, 1, {FOAM_Ptr}, FOAM_SInt, 1, {0}},
3966
3967 {FOAM_BVal_TypeInt8, 0, "TypeInt8", 0, 0, {0}, FOAM_SInt, 1, {0}},
3968 {FOAM_BVal_TypeInt16, 0, "TypeInt16", 0, 0, {0}, FOAM_SInt, 1, {0}},
3969 {FOAM_BVal_TypeInt32, 0, "TypeInt32", 0, 0, {0}, FOAM_SInt, 1, {0}},
3970 {FOAM_BVal_TypeInt64, 0, "TypeInt64", 0, 0, {0}, FOAM_SInt, 1, {0}},
3971 {FOAM_BVal_TypeInt128, 0, "TypeInt128", 0, 0, {0}, FOAM_SInt, 1, {0}},
3972
3973 {FOAM_BVal_TypeNil, 0, "TypeNil", 0, 0, {0}, FOAM_SInt, 1, {0}},
3974 {FOAM_BVal_TypeChar, 0, "TypeChar", 0, 0, {0}, FOAM_SInt, 1, {0}},
3975 {FOAM_BVal_TypeBool, 0, "TypeBool", 0, 0, {0}, FOAM_SInt, 1, {0}},
3976 {FOAM_BVal_TypeByte, 0, "TypeByte", 0, 0, {0}, FOAM_SInt, 1, {0}},
3977 {FOAM_BVal_TypeHInt, 0, "TypeHInt", 0, 0, {0}, FOAM_SInt, 1, {0}},
3978 {FOAM_BVal_TypeSInt, 0, "TypeSInt", 0, 0, {0}, FOAM_SInt, 1, {0}}, {FOAM_BVal_TypeBInt, 0, "TypeBInt", 0, 0, {0}, FOAM_SInt, 1, {0}},
3979 {FOAM_BVal_TypeSFlo, 0, "TypeSFlo", 0, 0, {0}, FOAM_SInt, 1, {0}},
3980 {FOAM_BVal_TypeDFlo, 0, "TypeDFlo", 0, 0, {0}, FOAM_SInt, 1, {0}},
3981 {FOAM_BVal_TypeWord, 0, "TypeWord", 0, 0, {0}, FOAM_SInt, 1, {0}},
3982 {FOAM_BVal_TypeClos, 0, "TypeClos", 0, 0, {0}, FOAM_SInt, 1, {0}},
3983 {FOAM_BVal_TypePtr, 0, "TypePtr", 0, 0, {0}, FOAM_SInt, 1, {0}},
3984 {FOAM_BVal_TypeRec, 0, "TypeRec", 0, 0, {0}, FOAM_SInt, 1, {0}},
3985 {FOAM_BVal_TypeArr, 0, "TypeArr", 0, 0, {0}, FOAM_SInt, 1, {0}},
3986 {FOAM_BVal_TypeTR, 0, "TypeTR", 0, 0, {0}, FOAM_SInt, 1, {0}},
3987
3988 {FOAM_BVal_RawRepSize, 0, "RawRepSize", 0, 1, {FOAM_SInt},
3989 FOAM_SInt, 1, {0}},
3990
3991 {FOAM_BVal_SizeOfInt8, 0, "SizeOfInt8", 0, 0, {0}, FOAM_SInt, 1, {0}},
3992 {FOAM_BVal_SizeOfInt16,0, "SizeOfInt16", 0, 0, {0}, FOAM_SInt, 1, {0}},
3993 {FOAM_BVal_SizeOfInt32,0, "SizeOfInt32", 0, 0, {0}, FOAM_SInt, 1, {0}},
3994 {FOAM_BVal_SizeOfInt64,0, "SizeOfInt64", 0, 0, {0}, FOAM_SInt, 1, {0}},
3995 {FOAM_BVal_SizeOfInt128,0, "SizeOfInt128", 0, 0, {0}, FOAM_SInt, 1, {0}},
3996
3997 {FOAM_BVal_SizeOfNil, 0, "SizeOfNil", 0, 0, {0}, FOAM_SInt, 1, {0}},
3998 {FOAM_BVal_SizeOfChar, 0, "SizeOfChar", 0, 0, {0}, FOAM_SInt, 1, {0}},
3999 {FOAM_BVal_SizeOfBool, 0, "SizeOfBool", 0, 0, {0}, FOAM_SInt, 1, {0}},
4000 {FOAM_BVal_SizeOfByte, 0, "SizeOfByte", 0, 0, {0}, FOAM_SInt, 1, {0}},
4001 {FOAM_BVal_SizeOfHInt, 0, "SizeOfHInt", 0, 0, {0}, FOAM_SInt, 1, {0}},
4002 {FOAM_BVal_SizeOfSInt, 0, "SizeOfSInt", 0, 0, {0}, FOAM_SInt, 1, {0}},
4003 {FOAM_BVal_SizeOfBInt, 0, "SizeOfBInt", 0, 0, {0}, FOAM_SInt, 1, {0}},
4004 {FOAM_BVal_SizeOfSFlo, 0, "SizeOfSFlo", 0, 0, {0}, FOAM_SInt, 1, {0}},
4005 {FOAM_BVal_SizeOfDFlo, 0, "SizeOfDFlo", 0, 0, {0}, FOAM_SInt, 1, {0}},
4006 {FOAM_BVal_SizeOfWord, 0, "SizeOfWord", 0, 0, {0}, FOAM_SInt, 1, {0}},
4007 {FOAM_BVal_SizeOfClos, 0, "SizeOfClos", 0, 0, {0}, FOAM_SInt, 1, {0}},
4008 {FOAM_BVal_SizeOfPtr, 0, "SizeOfPtr", 0, 0, {0}, FOAM_SInt, 1, {0}},
4009 {FOAM_BVal_SizeOfRec, 0, "SizeOfRec", 0, 0, {0}, FOAM_SInt, 1, {0}},
4010 {FOAM_BVal_SizeOfArr, 0, "SizeOfArr", 0, 0, {0}, FOAM_SInt, 1, {0}},
4011 {FOAM_BVal_SizeOfTR, 0, "SizeOfTR", 0, 0, {0}, FOAM_SInt, 1, {0}},
4012
4013 {FOAM_BVal_ListNil, 0, "ListNil",
4014 0, 0, {0}, FOAM_Ptr, 1, {0}},
4015 {FOAM_BVal_ListEmptyP, 0, "ListEmptyP",
4016 0, 1, {FOAM_Ptr}, FOAM_Bool, 1, {0}},
4017 {FOAM_BVal_ListHead, 0, "ListHead",
4018 0, 1, {FOAM_Ptr}, FOAM_Word, 1, {0}},
4019 {FOAM_BVal_ListTail, 0, "ListTail",
4020 0, 1, {FOAM_Ptr}, FOAM_Ptr, 1, {0}},
4021 {FOAM_BVal_ListCons, 0, "ListCons",
4022 0, 2, {FOAM_Word, FOAM_Ptr}, FOAM_Ptr, 1, {0}},
4023
4024 {FOAM_BVal_NewExportTable, 0, "NewExportTable",
4025 0, 2, {FOAM_Word, FOAM_SInt}, FOAM_Word, 1, {0}},
4026 {FOAM_BVal_AddToExportTable, 0, "AddToExportTable",
4027 1, 5, {FOAM_Word, FOAM_SInt, FOAM_SInt, FOAM_Arr,
4028 FOAM_Arr}, FOAM_Values, 0, {0}},
4029 {FOAM_BVal_FreeExportTable, 0, "FreeExportTable",
4030 1, 1, {FOAM_Word}, FOAM_Values, 0, {0}},
4031#if EDIT_1_0_n1_AB1
4032 /*
4033 * Note that ssaPhi actually takes variable number of arguments
4034 * but since it must never reach genc this doesn't matter.
4035 */
4036 {FOAM_BVal_ssaPhi, 0, "ssaPhi", 0, 0, {0}, FOAM_Values, 0, {0}},
4037#endif
4038
4039};