Bug Summary

File:src/tinfer.c
Warning:line 1620, column 41
Access to field 'first' results in a dereference of a null pointer (loaded from variable 'nstab')

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 tinfer.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 tinfer.c
1/****************************************************************************
2 *
3 * tinfer.c: Type inference.
4 *
5 * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org).
6 *
7 ***************************************************************************/
8
9#include "ablogic.h"
10#include "abpretty.h"
11#include "comsg.h"
12#include "debug.h"
13#include "fluid.h"
14#include "format.h"
15#include "lib.h"
16
17#include "opsys.h"
18#include "sefo.h"
19#include "spesym.h"
20#include "stab.h"
21#include "store.h"
22#include "strops.h"
23#include "syme.h"
24#include "table.h"
25#include "tconst.h"
26#include "terror.h"
27#include "tfcond.h"
28#include "tfsat.h"
29#include "ti_bup.h"
30#include "ti_sef.h"
31#include "ti_tdn.h"
32#include "ti_top.h"
33#include "tinfer.h"
34#include "tposs.h"
35#include "tqual.h"
36
37
38/*****************************************************************************
39 *
40 * :: Selective debug stuff
41 *
42 ****************************************************************************/
43
44Bool tipAddDebug = false((int) 0);
45Bool tipApplyDebug = false((int) 0);
46Bool tipAssignDebug = false((int) 0);
47Bool tipDeclareDebug = false((int) 0);
48Bool tipDefineDebug = false((int) 0);
49Bool tipFarDebug = false((int) 0);
50Bool tipIdDebug = false((int) 0);
51Bool tipLitDebug = false((int) 0);
52Bool tipEmbedDebug = false((int) 0);
53Bool tipExtendDebug = false((int) 0);
54
55Bool titfDebug = false((int) 0);
56Bool titfOneDebug = false((int) 0);
57Bool titfStabDebug = false((int) 0);
58Bool abExpandDebug = false((int) 0);
59
60extern Bool symeRefreshDebug;
61
62#define titfDEBUGif (!titfDebug) { } else afprintf DEBUG_IF(titf)if (!titfDebug) { } else afprintf
63#define titfOneDEBUGif (!titfOneDebug) { } else afprintf DEBUG_IF(titfOne)if (!titfOneDebug) { } else afprintf
64#define titfStabDEBUGif (!titfStabDebug) { } else afprintf DEBUG_IF(titfStab)if (!titfStabDebug) { } else afprintf
65#define abExpandDEBUGif (!abExpandDebug) { } else afprintf DEBUG_IF(abExpand)if (!abExpandDebug) { } else afprintf
66#define symeRefreshDEBUGif (!symeRefreshDebug) { } else afprintf DEBUG_IF(symeRefresh)if (!symeRefreshDebug) { } else afprintf
67
68extern Bool tipExtendDebug;
69#define tipExtendDEBUGif (!tipExtendDebug) { } else afprintf DEBUG_IF(tipExtend)if (!tipExtendDebug) { } else afprintf
70
71void
72tiReportStore(String s)
73{
74 static ULong obytes = 0;
75 ULong nbytes = stoBytesAlloc;
76
77 if (nbytes > obytes) {
78 if (s) fprintf(osStdout, "%s", s);
79 fprintf(osStdout, "Store %8ld B delta %8ld\n",
80 nbytes, nbytes - obytes);
81 obytes = nbytes;
82 }
83}
84
85/*****************************************************************************
86 *
87 * :: Local Declarations
88 *
89 ****************************************************************************/
90
91/*
92 * DefaultState
93 */
94
95enum def_state {
96 DEF_State_No, /* No special action for defaults. */
97 DEF_State_NotYet, /* Skip defaults when walking an absyn. */
98 DEF_State_Yes, /* Walk defaults when walking an absyn. */
99 DEF_State_LIMIT
100};
101
102typedef Enum(def_state)enum def_state DefaultState;
103
104/* typeInferTForms helper functions. */
105
106localstatic SymbolList tiTfDeclarees = 0;
107localstatic SymbolList tiTfDefinees = 0;
108localstatic DefaultState tiTfDoingDefault = DEF_State_No;
109
110localstatic SymbolList tiTfGetDeclarees (TFormUses);
111localstatic SymbolList tiTfPushDeclarees (SymbolList);
112localstatic void tiTfPopDeclarees (SymbolList);
113
114localstatic Symbol tiTfUsesSymbol (TFormUses);
115localstatic void tiTfPushDefinee0 (Symbol);
116
117localstatic Bool tiTfIsBoundary (TFormUses);
118
119/* typeInferTForms cases. */
120
121localstatic void tiTfOne (Stab, TFormUses, TForm);
122localstatic void tiTfSort (Stab, TFormUsesList);
123localstatic void tiTfCycle (Stab, TFormUsesList);
124localstatic void tiTfDefault (Stab, TFormUsesList);
125localstatic Bool tiTfDefaultSyntax (Stab, TForm);
126localstatic void tiTfDefaultSyntaxMap (Stab, TForm);
127localstatic Bool tiTfDefaultSyntaxDefine (Stab, TForm);
128
129extern void tiTfPrint (FILE *, Stab, String,
130 TFormUsesList);
131extern void tiTfEnter (FILE *, String,
132 TFormUses, TForm);
133extern void tiTfExit (FILE *, String,
134 TFormUses, TForm);
135
136#define tiTfPrintDb(v)if (vDebug) tiTfPrint if (DEBUG(v)vDebug) tiTfPrint
137#define tiTfEnterDb(v)if (vDebug) tiTfEnter if (DEBUG(v)vDebug) tiTfEnter
138#define tiTfExitDb(v)if (vDebug) tiTfExit if (DEBUG(v)vDebug) tiTfExit
139
140/* typeInferTForms phases. */
141
142localstatic TFormUsesList tiTfPartition (Stab, TFormUsesList);
143localstatic TFormUsesList tiTfSyntax (Stab, TFormUsesList);
144localstatic TFormUsesList tiTfSelect (Stab, TFormUsesList);
145
146localstatic Bool tiTfSyntax1 (Stab, TFormUses, TForm,
147 AbSynList);
148localstatic Bool tiTfFloat1 (Stab, TForm);
149localstatic void tiTfMap1 (Stab, TFormUses, TForm,
150 AbSynList);
151localstatic Bool tiTfDefine1 (Stab, TFormUses, TForm,
152 AbSynList);
153localstatic void tiTfThird1 (Stab, TFormUses, TForm,
154 AbSynList);
155localstatic void tiTfCategory1 (Stab, TFormUses, TForm,
156 AbSynList);
157localstatic void tiTfUnknown1 (Stab, TFormUses, TForm,
158 AbSynList);
159localstatic void tiTfPending1 (Stab, TForm);
160localstatic void tiTfBottomUp1 (Stab, TFormUses, TForm);
161localstatic void tiTfAudit1 (Stab, TForm);
162localstatic void tiTfTopDown1 (Stab, TForm);
163localstatic void tiTfMeaning1 (Stab, TForm);
164localstatic void tiTfExtend1 (Stab, TFormUses);
165localstatic void tiTfImport1 (Stab, TFormUses);
166localstatic void tiTfDefault1 (Stab, Sefo);
167localstatic void tiTfCascades1 (Stab stab, TFormUses tfu);
168/* typeInferTForms topological sorting. */
169
170localstatic Table tiTfGetDeclareeTable (TFormUsesList);
171localstatic void tiTfFreeDeclareeTable (Table);
172localstatic void tiTfCollectHasDependees (TFormUsesList, TFormUses);
173localstatic void tiTfCollectDependees (Table, TFormUses, TForm);
174localstatic void tiTfCollectSefoDependees(Table, TFormUses, Sefo);
175localstatic void tiTfCollectSymDependees (Table, TFormUses, Symbol);
176localstatic void tiTfAddDependee (TFormUses, TFormUses);
177localstatic void tiTfFreeDependees (TFormUsesList);
178localstatic void tiTfFreeCDependees (TFormUsesList);
179
180localstatic TFormUsesList tiTopForward (TFormUsesList);
181localstatic TFormUsesList tiTopReverse (TFormUsesList);
182localstatic TFormUsesList tiTopCForward (TFormUsesList);
183localstatic TFormUsesList tiTopCReverse (TFormUsesList);
184localstatic TFormUsesList tiTopSort (TFormUsesList);
185localstatic TFormUsesList tiTopCycle (TFormUsesList);
186
187/* tiTopClique helper functions. */
188
189localstatic TFormUsesList tiTopClique (TFormUsesList);
190localstatic TFormUses tiTopCliqueUnion (TFormUsesList);
191localstatic TFormUses tiTopCliqueRep (TFormUses);
192localstatic void tiTopCliqueMark (TFormUsesList, Bool);
193localstatic void tiTopCliqueAddVertex (TFormUses);
194localstatic void tiTopCliqueAddCVertex (TFormUses);
195localstatic void tiTopCliqueDelCVertex (TFormUses);
196localstatic void tiTopCliqueAddEdge (TFormUses, TFormUses);
197localstatic void tiTopCliqueDelEdge (TFormUses, TFormUses);
198localstatic Bool tiTopEqual (TFormUses, TFormUses);
199
200/*****************************************************************************
201 *
202 * :: Main entry points for type inference
203 *
204 ****************************************************************************/
205
206localstatic Bool tqShouldImport (TQual);
207localstatic TForm tiGetTopLevelTForm(AbLogic context, AbSyn type);
208localstatic Bool tiCheckSymeConditionalImplementation(Stab stab, Syme syme, Syme implSyme);
209
210void
211tinferInit()
212{
213 TiTopLevel topLevel = (TiTopLevel) stoAlloc(OB_Other0, sizeof(*topLevel));
214
215 topLevel->terrorTypeConstFailed = terrorTypeConstFailed;
216 topLevel->tiBottomUp = tiBottomUp;
217 topLevel->tiTopDown = tiTopDown;
218 topLevel->tiCanSefo = tiCanSefo;
219 topLevel->tiGetTopLevelTForm = tiGetTopLevelTForm;
220
221 topLevel->tiUnaryToRaw = tiUnaryToRaw;
222 topLevel->tiRawToUnary = tiRawToUnary;
223 topLevel->tiSefo = tiSefo;
224 topLevel->tiTfSefo = tiTfSefo;
225 topLevel->typeInferTForms = typeInferTForms;
226
227 topLevel->tqShouldImport = tqShouldImport;
228 topLevel->typeInferTForm = typeInferTForm;
229
230 tiTopLevelInit(topLevel);
231
232}
233
234/*
235 * Type inference consists of two passes:
236
237
238 * 1) a bottom up pass which constructs a set of possible types for each node
239 * 2) a top down pass which restricts each node to a unique type.
240 */
241
242TForm
243typeInferAs(Stab stab, AbSyn absyn, TForm type)
244{
245 if (abState(absyn)((absyn)->abHdr.state) != AB_State_HasUnique) {
246 tiBottomUp (stab, absyn, type);
247 typeInferAudit(stab, absyn);
248 tiTopDown (stab, absyn, type);
249 }
250 return abTUnique(absyn)((absyn)->abHdr.type.unique);
251}
252
253TForm
254typeInfer(Stab stab, AbSyn absyn)
255{
256 TForm tf;
257
258 tcInit();
259 typeInferTForms(stab);
260 tf = typeInferAs(stab, absyn, tfUnknown);
261 tcFini();
262
263 return tf;
264}
265
266Bool
267typeInferAudit(Stab stab, AbSyn absyn)
268{
269 return terrorAuditPoss(true1, absyn);
270}
271
272void
273typeInferCheck(Stab stab, AbSyn absyn, TForm type)
274{
275 Syme syme = abSyme(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->syme :
0)
;
276 TForm tf;
277
278 if (abIsNothing(absyn)((absyn)->abHdr.tag == (AB_Nothing)))
279 return;
280
281 if (type == tfDomain && syme &&
282 (symeIsLibrary(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Library)
|| symeIsArchive(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->kind) == SYME_Archive)
))
283 return;
284
285 if (abState(absyn)((absyn)->abHdr.state) != AB_State_HasUnique)
286 return;
287
288 tf = abTUnique(absyn)((absyn)->abHdr.type.unique);
289 if (!tfIsUnknown(tf)(((tf)->tag) == TF_Unknown) && !tfSatValues(tf, type)) {
290 abState(absyn)((absyn)->abHdr.state) = AB_State_Error;
291 abTPoss(absyn)((absyn)->abHdr.type.poss) = tpossSingleton(tf);
292 tiTopDown(stab, absyn, type);
293 }
294}
295
296void
297tiTfSefo(Stab stab, TForm tf)
298{
299 Length i;
300
301 if (!tfNeedsSefo(tf)((tf)->state == TF_State_NeedsSefo))
302 return;
303 tfClrNeedsSefo(tf)((tf)->state = ((tf)->state == TF_State_NeedsSefo) ? TF_State_Meaning
: (tf)->state)
;
304
305 if (tfIsAbSyn(tf)( TF_ABSYN_START <= (((tf)->tag)) && (((tf)->
tag)) < TF_ABSYN_LIMIT)
&& tiCanSefo(tfGetExpr(tf)((tf)->__absyn)))
306 tiSefo(stab, tfGetExpr(tf)((tf)->__absyn));
307
308 if (tfIsNode(tf)( TF_NODE_START <= (((tf)->tag)) && (((tf)->
tag)) < TF_NODE_LIMIT)
)
309 for (i = 0; i < tfArgc(tf)((tf)->argc); i += 1)
310 tiTfSefo(stab, tfArgv(tf)((tf)->argv)[i]);
311
312 if (tfTagHasSymes(tfTag(tf)((tf)->tag)) && tfSymes(tf)((tf)->symes) == listNil(Syme)((SymeList) 0)) {
313 tfGetSymes(stab, tf, tfExpr(tf)tfToAbSyn(tf));
314 }
315}
316
317/*
318 * Make sure that the category exports of context are visible in stab.
319 */
320void
321tiWithSymes(Stab stab, TForm context)
322{
323 SymeList mods;
324 SymeList symes;
325 SymeList csymes = listNil(Syme)((SymeList) 0);
326 SymeList esymes = listNil(Syme)((SymeList) 0);
327 Stab wstab = stab;
328 while (wstab && stabGetSelf(wstab) == NULL((void*)0)) wstab = cdr(wstab)((wstab)->rest);
329 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, ">>tiWithSymes:\n");
330
331 mods = listNConcat(Syme)(Syme_listPointer->NConcat)(tfGetSelfFrStab(wstab),
332 listCopy(Syme)(Syme_listPointer->Copy)(tfGetCatSelf(context)));
333
334 symes = tfGetCatExports(context);
335
336 for (; symes; symes = cdr(symes)((symes)->rest)) {
337 Syme syme = car(symes)((symes)->first), xsyme = NULL((void*)0);
338 Symbol sym = symeId(syme)((syme)->id);
339 TForm tf = symeType(syme);
340
341 if (DEBUG(tipAdd)tipAddDebug) {
342 afprintf(dbOut, " looking for: %pSyme\n", syme);
343 }
344
345 /* Look for syme in the capsule. */
346 if ((xsyme = stabGetExportMod(wstab, mods, sym, tf))) {
347 if (tiCheckSymeConditionalImplementation(wstab, syme, xsyme))
348 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [export]\n");
349 else {
350 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [conditional override]\n");
351 esymes = listCons(Syme)(Syme_listPointer->Cons)(syme, esymes);
352 }
353 }
354
355 else {
356 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [category]\n");
357 csymes = listCons(Syme)(Syme_listPointer->Cons)(syme, csymes);
358 }
359 }
360
361 for (; esymes != listNil(Syme)((SymeList) 0); esymes = cdr(esymes)((esymes)->rest)) {
362 Syme esyme = car(esymes)((esymes)->first);
363 Symbol sym = symeId(esyme)((esyme)->id);
364 TForm tf = symeType(esyme);
365 Syme xsyme = stabGetExportMod(wstab, mods, sym, tf);
366 if (symeCondition(esyme) == listNil(Sefo)((SefoList) 0)) {
367 symeSetDefinitionConditions(xsyme, listNil(AbSyn))(symeSetFieldVal = ((AInt) (((AbSynList) 0))), (((((xsyme)->
kind == SYME_Trigger ? libGetAllSymes((xsyme)->lib) : ((void
*)0)), (xsyme))->locmask) & (1 << (SYFI_DefinitionConditions
))) ? (((xsyme)->fieldv)[symeIndex(xsyme,SYFI_DefinitionConditions
)] = (symeSetFieldVal)) : !((xsyme)->full) && symeSetFieldVal
== (symeFieldInfo[SYFI_DefinitionConditions].def) ? symeSetFieldVal
: symeSetFieldFn(xsyme,SYFI_DefinitionConditions,symeSetFieldVal
))
;
368 }
369 else {
370 symeSetDefinitionConditions(xsyme,(symeSetFieldVal = ((AInt) ((AbSyn_listPointer->Cons)(abNewAndAll
(sposNone, (AbSynList) symeCondition(esyme)), ((AbSynList) (SYFI_DefinitionConditions
< (8 * sizeof(int)) && !(((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
hasmask) & (1 << (SYFI_DefinitionConditions))) ? (symeFieldInfo
[SYFI_DefinitionConditions].def) : (((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
locmask) & (1 << (SYFI_DefinitionConditions))) ? ((
((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme)->
lib) : ((void*)0)), (xsyme))->locmask) & (1 << (
SYFI_DefinitionConditions))) ? ((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] : (symeFieldInfo[SYFI_DefinitionConditions
].def)) : symeGetFieldFn(xsyme,SYFI_DefinitionConditions)))))
), (((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme
)->lib) : ((void*)0)), (xsyme))->locmask) & (1 <<
(SYFI_DefinitionConditions))) ? (((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] = (symeSetFieldVal)) : !((
xsyme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefinitionConditions].def) ? symeSetFieldVal : symeSetFieldFn
(xsyme,SYFI_DefinitionConditions,symeSetFieldVal))
371 listCons(AbSyn)(abNewAndAll(sposNone,(symeSetFieldVal = ((AInt) ((AbSyn_listPointer->Cons)(abNewAndAll
(sposNone, (AbSynList) symeCondition(esyme)), ((AbSynList) (SYFI_DefinitionConditions
< (8 * sizeof(int)) && !(((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
hasmask) & (1 << (SYFI_DefinitionConditions))) ? (symeFieldInfo
[SYFI_DefinitionConditions].def) : (((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
locmask) & (1 << (SYFI_DefinitionConditions))) ? ((
((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme)->
lib) : ((void*)0)), (xsyme))->locmask) & (1 << (
SYFI_DefinitionConditions))) ? ((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] : (symeFieldInfo[SYFI_DefinitionConditions
].def)) : symeGetFieldFn(xsyme,SYFI_DefinitionConditions)))))
), (((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme
)->lib) : ((void*)0)), (xsyme))->locmask) & (1 <<
(SYFI_DefinitionConditions))) ? (((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] = (symeSetFieldVal)) : !((
xsyme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefinitionConditions].def) ? symeSetFieldVal : symeSetFieldFn
(xsyme,SYFI_DefinitionConditions,symeSetFieldVal))
372 (AbSynList) symeCondition(esyme)),(symeSetFieldVal = ((AInt) ((AbSyn_listPointer->Cons)(abNewAndAll
(sposNone, (AbSynList) symeCondition(esyme)), ((AbSynList) (SYFI_DefinitionConditions
< (8 * sizeof(int)) && !(((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
hasmask) & (1 << (SYFI_DefinitionConditions))) ? (symeFieldInfo
[SYFI_DefinitionConditions].def) : (((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
locmask) & (1 << (SYFI_DefinitionConditions))) ? ((
((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme)->
lib) : ((void*)0)), (xsyme))->locmask) & (1 << (
SYFI_DefinitionConditions))) ? ((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] : (symeFieldInfo[SYFI_DefinitionConditions
].def)) : symeGetFieldFn(xsyme,SYFI_DefinitionConditions)))))
), (((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme
)->lib) : ((void*)0)), (xsyme))->locmask) & (1 <<
(SYFI_DefinitionConditions))) ? (((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] = (symeSetFieldVal)) : !((
xsyme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefinitionConditions].def) ? symeSetFieldVal : symeSetFieldFn
(xsyme,SYFI_DefinitionConditions,symeSetFieldVal))
373 symeDefinitionConditions(xsyme)))(symeSetFieldVal = ((AInt) ((AbSyn_listPointer->Cons)(abNewAndAll
(sposNone, (AbSynList) symeCondition(esyme)), ((AbSynList) (SYFI_DefinitionConditions
< (8 * sizeof(int)) && !(((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
hasmask) & (1 << (SYFI_DefinitionConditions))) ? (symeFieldInfo
[SYFI_DefinitionConditions].def) : (((((xsyme)->kind == SYME_Trigger
? libGetAllSymes((xsyme)->lib) : ((void*)0)), (xsyme))->
locmask) & (1 << (SYFI_DefinitionConditions))) ? ((
((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme)->
lib) : ((void*)0)), (xsyme))->locmask) & (1 << (
SYFI_DefinitionConditions))) ? ((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] : (symeFieldInfo[SYFI_DefinitionConditions
].def)) : symeGetFieldFn(xsyme,SYFI_DefinitionConditions)))))
), (((((xsyme)->kind == SYME_Trigger ? libGetAllSymes((xsyme
)->lib) : ((void*)0)), (xsyme))->locmask) & (1 <<
(SYFI_DefinitionConditions))) ? (((xsyme)->fieldv)[symeIndex
(xsyme,SYFI_DefinitionConditions)] = (symeSetFieldVal)) : !((
xsyme)->full) && symeSetFieldVal == (symeFieldInfo
[SYFI_DefinitionConditions].def) ? symeSetFieldVal : symeSetFieldFn
(xsyme,SYFI_DefinitionConditions,symeSetFieldVal))
;
374 }
375 }
376
377
378 symes = symeListSubstCat(wstab, mods, context, csymes);
379
380 symes = symeListCheckWithCondition(symes);
381 symes = symeListMakeLazyConditions(symes);
382
383 stabPutMeanings(stab, symes);
384
385 /*!! listFree(Syme)(mods); */
386 listFree(Syme)(Syme_listPointer->Free)(symes);
387 listFree(Syme)(Syme_listPointer->Free)(csymes);
388
389 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, "<<tiWithSymes:\n");
390}
391
392localstatic SymeList
393symeListSetImplicit(Stab stab, SymeList symes)
394{
395 SymeList result = listNil(Syme)((SymeList) 0);
396
397 for (;symes;symes = cdr(symes)((symes)->rest))
398 {
399 Syme syme = car(symes)((symes)->first);
400 Symbol id = symeId(syme)((syme)->id);
401 TForm tf = symeType(syme);
402
403
404 /* Look for this syme in the stab */
405 syme = stabDefExport(stab, id, tf, (Doc)0);
406
407
408 /* Syme must not have a const lib: it's local */
409 if (symeConstLib(syme)) symeSetConstLib(syme, (Lib)0);
410
411
412 /* Mark as implicit */
413 symeSetImplicit(syme)(symeSetFieldVal = ((AInt) (((AInt) (SYFI_ExtraBits < (8 *
sizeof(int)) && !(((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
hasmask) & (1 << (SYFI_ExtraBits))) ? (symeFieldInfo
[SYFI_ExtraBits].def) : (((((syme)->kind == SYME_Trigger ?
libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->locmask
) & (1 << (SYFI_ExtraBits))) ? ((((((syme)->kind
== SYME_Trigger ? libGetAllSymes((syme)->lib) : ((void*)0
)), (syme))->locmask) & (1 << (SYFI_ExtraBits)))
? ((syme)->fieldv)[symeIndex(syme,SYFI_ExtraBits)] : (symeFieldInfo
[SYFI_ExtraBits].def)) : symeGetFieldFn(syme,SYFI_ExtraBits))
) | (0x0001))), (((((syme)->kind == SYME_Trigger ? libGetAllSymes
((syme)->lib) : ((void*)0)), (syme))->locmask) & (1
<< (SYFI_ExtraBits))) ? (((syme)->fieldv)[symeIndex
(syme,SYFI_ExtraBits)] = (symeSetFieldVal)) : !((syme)->full
) && symeSetFieldVal == (symeFieldInfo[SYFI_ExtraBits
].def) ? symeSetFieldVal : symeSetFieldFn(syme,SYFI_ExtraBits
,symeSetFieldVal));
;
414
415
416 /* Add to the list of results */
417 result = listCons(Syme)(Syme_listPointer->Cons)(syme, result);
418 }
419
420 return result;
421}
422
423localstatic Bool
424tiCheckSymeConditionalImplementation(Stab stab, Syme syme, Syme implSyme)
425{
426 SefoList condition = symeCondition(syme);
427 AbSynList implCondition = symeDefinitionConditions(implSyme)((AbSynList) (SYFI_DefinitionConditions < (8 * sizeof(int)
) && !(((((implSyme)->kind == SYME_Trigger ? libGetAllSymes
((implSyme)->lib) : ((void*)0)), (implSyme))->hasmask) &
(1 << (SYFI_DefinitionConditions))) ? (symeFieldInfo[SYFI_DefinitionConditions
].def) : (((((implSyme)->kind == SYME_Trigger ? libGetAllSymes
((implSyme)->lib) : ((void*)0)), (implSyme))->locmask) &
(1 << (SYFI_DefinitionConditions))) ? ((((((implSyme)->
kind == SYME_Trigger ? libGetAllSymes((implSyme)->lib) : (
(void*)0)), (implSyme))->locmask) & (1 << (SYFI_DefinitionConditions
))) ? ((implSyme)->fieldv)[symeIndex(implSyme,SYFI_DefinitionConditions
)] : (symeFieldInfo[SYFI_DefinitionConditions].def)) : symeGetFieldFn
(implSyme,SYFI_DefinitionConditions)))
;
428 AbSynList tmp;
429 SefoList tmpSefo;
430 AbLogic implAbLog, conditionAbLog;
431 Bool result;
432
433 if (implCondition == listNil(AbSyn)((AbSynList) 0))
434 return true1;
435 /* Need to check that implCondition implies condition */
436 /* First, unconditional implies it does */
437 for (tmp = implCondition; tmp != listNil(AbSyn)((AbSynList) 0); tmp = cdr(tmp)((tmp)->rest)) {
438 if (car(tmp)((tmp)->first) == NULL((void*)0))
439 return true1;
440 }
441
442 for (tmp = implCondition; tmp != listNil(AbSyn)((AbSynList) 0); tmp = cdr(tmp)((tmp)->rest)) {
443 tiBottomUp(stab, car(tmp)((tmp)->first), tfUnknown);
444 tiTopDown(stab, car(tmp)((tmp)->first), tfUnknown);
445 }
446
447 implAbLog = ablogFalse();
448 for (tmp = implCondition; tmp != listNil(AbSyn)((AbSynList) 0); tmp = cdr(tmp)((tmp)->rest)) {
449 implAbLog = ablogOr(ablogFrSefo(car(tmp)((tmp)->first)), implAbLog);
450 }
451 conditionAbLog = ablogTrue();
452 for (tmpSefo = condition; tmpSefo != listNil(Sefo)((SefoList) 0); tmpSefo = cdr(tmpSefo)((tmpSefo)->rest)) {
453 conditionAbLog = ablogAnd(ablogFrSefo(car(tmpSefo)((tmpSefo)->first)), conditionAbLog);
454 }
455
456 result = ablogImplies(conditionAbLog,
457 ablogAnd(abCondKnown != NULL((void*)0)
458 ? abCondKnown
459 : ablogTrue(),
460 implAbLog));
461
462 return result;
463}
464
465/*
466 * Make sure that the category exports of context are visible in capsule.
467 * Return the symes which could not be found in the add. Tell the caller
468 * about symes we've added to the stab.
469 */
470SymeList
471tiAddSymes(Stab astab, AbSyn capsule, TForm base, TForm context, SymeList *p)
472{
473 Bool hasImplicit;
474 SymeList mods;
475 SymeList symes;
476 SymeList isymes = listNil(Syme)((SymeList) 0);
477 SymeList asymes = listNil(Syme)((SymeList) 0);
478 SymeList csymes = listNil(Syme)((SymeList) 0);
479 SymeList dsymes = listNil(Syme)((SymeList) 0);
480 SymeList usymes = listNil(Syme)((SymeList) 0);
481 SymeList aself = tfGetSelfFrStab(astab);
482 Syme asyme = (aself ? car(aself)((aself)->first) : NULL((void*)0));
483
484 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, "(tiAddSymes:\n");
485
486
487 /*
488 * If the caller wants to know which symes we have added to
489 * the stab then we MUST initialise our workspace now.
490 */
491 if (p) *p = listNil(Syme)((SymeList) 0);
492
493
494 /* We can't do anything with unknown contexts */
495 tfFollow(context)((context) = tfFollowFn(context));
496 if (tfIsUnknown(context)(((context)->tag) == TF_Unknown))
497 return dsymes;
498
499 /* Does the context satisfy DenseStorageCategory? */
500 hasImplicit = tfCatHasImplicit(context);
501
502
503 mods = listNConcat(Syme)(Syme_listPointer->NConcat)(listCopy(Syme)(Syme_listPointer->Copy)(tfGetDomSelf(base)),
504 listCopy(Syme)(Syme_listPointer->Copy)(tfGetCatSelf(context)));
505 mods = listNConcat(Syme)(Syme_listPointer->NConcat)(aself, mods);
506
507 symes = tfGetCatExports(context);
508 for ( ; symes; symes = cdr(symes)((symes)->rest)) {
509 Syme syme = car(symes)((symes)->first), xsyme = NULL((void*)0);
510 Symbol sym = symeId(syme)((syme)->id);
511 TForm tf = symeType(syme);
512
513 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " looking for: %pSyme %pAbSynList ", syme, symeCondition(syme));
514
515 /* Look for syme in the capsule. */
516 if ((xsyme = stabGetDomainExportMod(astab, mods, sym, tf)) != NULL((void*)0)
517 && tiCheckSymeConditionalImplementation(astab, syme, xsyme)) {
518 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [export]\n");
519 symeImplAddInherit(xsyme, base, syme);
520 }
521
522 /* Look for syme in the base. */
523 else if ((xsyme = tfHasDomExportMod(base, mods, sym, tf))
524 != NULL((void*)0)) {
525 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [add chain]\n");
526 /*!! if (!symeIsSelfSelf(xsyme)) */
527 asymes = listCons(Syme)(Syme_listPointer->Cons)(xsyme, asymes);
528 }
529
530 /* Look for syme in the defaults. */
531 else if (symeHasDefault(syme)(((((syme)->kind == SYME_Trigger ? libGetAllSymes((syme)->
lib) : ((void*)0)), (syme))->bits) & (0x0080))
) {
532 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [default]\n");
533 /*!! if (!symeIsSelfSelf(syme)) */
534 csymes = listCons(Syme)(Syme_listPointer->Cons)(syme, csymes);
535 }
536
537 /* Look for the syme in the implicits */
538 else if (hasImplicit &&
539 ((xsyme = tfImplicitExport(astab,mods,syme))!=NULL((void*)0))) {
540 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [implicit]\n");
541 isymes = listCons(Syme)(Syme_listPointer->Cons)(xsyme, isymes);
542 }
543
544 /* Look for syme in the conditional symes. */
545 else if (symeCondition(syme)) {
546 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [conditional]\n");
547 /*!! if (!symeIsSelfSelf(syme)) */
548 usymes = listCons(Syme)(Syme_listPointer->Cons)(syme, usymes);
549 }
550
551 /* The add doesn't satisfy its context. */
552 else {
553 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, " [missing]\n");
554 dsymes = listCons(Syme)(Syme_listPointer->Cons)(syme, dsymes);
555 }
556 }
557
558 if (asymes != listNil(Syme)((SymeList) 0)) {
559 symes = symeListSubstCat(astab, mods, tfUnknown, asymes);
560 stabPutMeanings(astab, symes);
561 if (p) *p = listNConcat(Syme)(Syme_listPointer->NConcat)(*p, listCopy(Syme)(Syme_listPointer->Copy)(symes));
562 listFree(Syme)(Syme_listPointer->Free)(symes);
563 }
564
565 if (isymes != listNil(Syme)((SymeList) 0)) { /* IMPLICIT */
566 SymeList symes;
567 symes = symeListSubstCat(astab, mods, tfUnknown, isymes);
568 symes = symeListSetImplicit(astab, symes);
569 /* ******************** CHECK THIS ******************** */
570 /* No need to stabPutMeanings as they ought to be there */
571 /* ******************** CHECK THIS ******************** */
572 if (p) *p = listNConcat(Syme)(Syme_listPointer->NConcat)(*p, listCopy(Syme)(Syme_listPointer->Copy)(symes));
573 listFree(Syme)(Syme_listPointer->Free)(symes);
574 }
575
576 if (csymes != listNil(Syme)((SymeList) 0)) {
577 SymeList symes;
578 csymes = symeListSubstCat(astab, mods, context, csymes);
579 symes = symeListCheckAddConditions(csymes);
580 stabPutMeanings(astab, symes);
581 if (p) *p = listNConcat(Syme)(Syme_listPointer->NConcat)(*p, listCopy(Syme)(Syme_listPointer->Copy)(symes));
582 listFree(Syme)(Syme_listPointer->Free)(symes);
583 }
584
585 if (usymes != listNil(Syme)((SymeList) 0)) {
586 SymeList symes;
587 symes = symeListSubstCat(astab, mods, context, usymes);
588 symes = symeListCheckAddConditions(symes);
589 dsymes = listNConcat(Syme)(Syme_listPointer->NConcat)(symes, dsymes);
590 }
591 if (asyme && (asymes || csymes || dsymes || isymes)
592 && !symeIsExtend(asyme)(((((asyme)->kind == SYME_Trigger ? libGetAllSymes((asyme)
->lib) : ((void*)0)), (asyme))->kind) == SYME_Extend)
)
593 {
594 Syme xself = stabDefExtend(astab, ssymSelf, context);
595 symeAddExtendee(xself, asyme);
596 symeSetExtension(asyme, xself)symeXSetExtension(asyme, (AInt) xself);
597 stabExtendMeanings(astab, xself);
598 }
599
600 /*!! listFree(Syme)(mods); */
601 listFree(Syme)(Syme_listPointer->Free)(asymes);
602 /*!! listFree(Syme)(isymes); */
603
604 tipAddDEBUGif (!tipAddDebug) { } else afprintf(dbOut, "tiAddSymes %pSymeList)\n", dsymes);
605
606 dsymes = listNReverse(Syme)(Syme_listPointer->NReverse)(dsymes);
607 return dsymes;
608}
609
610localstatic TForm
611tiGetTopLevelTForm(AbLogic context, AbSyn type)
612{
613 TForm tf;
614
615 tf = tiGetTFormContext(stabFile(), context, type);
1
Calling 'tiGetTFormContext'
616
617 return tf;
618}
619
620/*
621 * Get a cached or create and cache a new type form for the expression.
622 * It is most likely placed there by scobind.
623 */
624TForm
625tiGetTForm(Stab stab, AbSyn type)
626{
627 return tiGetTFormContext(stab, ablogTrue(), type);
628}
629
630TForm
631tiGetTFormContext(Stab stab, AbLogic context, AbSyn type)
632{
633 TForm tf, ntf;
634
635 if (abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0
)
) {
2
Assuming field 'seman' is null
3
'?' condition is false
636 /* This is a little hacky... we just want to ensure
637 * that if 'type' has an attached tform, then that
638 * tform in turn should have a decent looking sefo
639 * attached */
640 abSetTForm(type, tfFollowFn(abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0
)
));
641 if (!tfHasExpr(abTForm(type))((((type)->abHdr.seman ? (type)->abHdr.seman->tform :
0))->__absyn != 0)
)
642 tfToAbSyn(abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0
)
);
643 }
644 tf = abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0
)
? (abTForm(type)((type)->abHdr.seman ? (type)->abHdr.seman->tform : 0
)
) : tfSyntaxFrAbSyn(stab, type);
4
Taking false branch
5
'?' condition is false
6
'?' condition is false
645
646 /* Transfer semantics from type to tf. */
647 if (abIsSefo(type)(((type)->abHdr.state) == AB_State_HasUnique) && tfHasExpr(tf)((tf)->__absyn != 0) && !abIsSefo(tfGetExpr(tf))(((((tf)->__absyn))->abHdr.state) == AB_State_HasUnique
)
) {
7
Assuming field 'state' is not equal to AB_State_HasUnique
648 abTransferSemantics(type, tfGetExpr(tf)((tf)->__absyn));
649 }
650
651 if (!tfIsMeaning(tf)(((tf)->state)>=TF_State_Meaning)) {
8
Assuming field 'state' is >= TF_State_Meaning
9
Taking false branch
652 tfMergeConditions(tf, stab, tfCondEltNewKnown(stab, context));
653 }
654
655 ntf = typeInferTForm(stab, tf);
10
Calling 'typeInferTForm'
656 tfTransferSemantics(ntf, tf);
657
658 /* Transfer semantics from tf to type. */
659 if (type != tfGetExpr(tf)((tf)->__absyn))
660 if (!abIsSefo(type)(((type)->abHdr.state) == AB_State_HasUnique) &&
661 abIsSefo(tfGetExpr(ntf))(((((ntf)->__absyn))->abHdr.state) == AB_State_HasUnique
)
&& !tfIsUnknown(tfTUnique(ntf))(((((((ntf)->__absyn))->abHdr.type.unique))->tag) ==
TF_Unknown)
)
662 abTransferSemantics(tfGetExpr(ntf)((ntf)->__absyn), type);
663
664 if (!abIsSefo(type)(((type)->abHdr.state) == AB_State_HasUnique)) {
665 abState(type)((type)->abHdr.state) = AB_State_HasUnique;
666 abTUnique(type)((type)->abHdr.type.unique) = tfUnknown;
667 }
668
669 tfFollow(tf)((tf) = tfFollowFn(tf));
670 return abSetTForm(type, tf);
671}
672
673Bool
674tiMergeSyme(Syme syme, SymeList symes)
675{
676 SymeList sl = symes;
677
678 while (sl != listNil(Syme)((SymeList) 0)) {
679 if (symeEqualModConditions(listNil(Syme)((SymeList) 0), syme, car(sl)((sl)->first)))
680 return false((int) 0);
681 sl = cdr(sl)((sl)->rest);
682 }
683 return true1;
684}
685
686Syme
687tiGetMeaning(Stab stab, AbSyn absyn, TForm type)
688{
689 SatMask mask = tfSatBupMask();
690 Length nsymec, psymec;
691 Syme nsyme, psyme, syme;
692 SymeList symes, nsymes, sl;
693
694 symes = stabGetMeanings(stab, abCondKnown, abIdSym(absyn)((absyn)->abId.sym));
695 nsymes = listNil(Syme)((SymeList) 0); /* Possible (non-pending) meanings */
696 nsymec = 0; /* Number of non-pending matches */
697 psymec = 0; /* Number of all possible matches */
698 nsyme = NULL((void*)0);
699 psyme = NULL((void*)0);
700
701 for (sl = symes; sl; sl = cdr(sl)((sl)->rest)) {
702 Syme syme = car(sl)((sl)->first);
703 TForm mtype = symeType(syme);
704 SatMask result;
705
706 result = tfSat1(mask, absyn, mtype, type);
707 if (tfSatSucceed(result)) {
708 if (!tfSatPending(result)
709 && symeUseIdentifier(absyn, syme)
710 && tiMergeSyme(syme, nsymes)) {
711 nsymec += 1;
712 nsyme = syme;
713 nsymes = listCons(Syme)(Syme_listPointer->Cons)(syme, nsymes);
714 }
715 psymec += 1;
716 psyme = syme;
717 }
718
719 }
720
721 syme = NULL((void*)0);
722 if (psymec == 1 && !tfIsUnknown(symeType(psyme))(((symeType(psyme))->tag) == TF_Unknown))
723 syme = psyme;
724
725 else if (nsymec == 1 && !tfIsUnknown(symeType(nsyme))(((symeType(nsyme))->tag) == TF_Unknown))
726 syme = nsyme;
727
728 else if (nsymec == 0 && psymec > 0)
729 terrorApplyNotAnalyzed(absyn, absyn, type);
730
731 else
732 terrorNotUniqueMeaning(ALDOR_E_TinNMeanings165, absyn, nsymes,
733 symes, symString(abIdSym(absyn))((((absyn)->abId.sym))->str), type);
734
735 listFree(Syme)(Syme_listPointer->Free)(nsymes);
736
737 return syme;
738}
739
740Syme
741tiGetExtendee(Stab stab, AbSyn absyn, TForm type)
742{
743 Symbol sym = absyn->abId.sym;
744 int n;
745 SymeList ml0, ml, okSymes = listNil(Syme)((SymeList) 0);
746 Syme syme = NULL((void*)0);
747
748 ml0 = stabGetMeanings(stab, abCondKnown, sym);
749
750 for (n = 0, ml = ml0; ml; ml = cdr(ml)((ml)->rest)) {
751 Syme msyme = car(ml)((ml)->first);
752 TForm mtype = symeType(msyme);
753 if (tfCanExtend(mtype, type)) {
754 if (n > 0) okSymes = listCons(Syme)(Syme_listPointer->Cons)(syme, okSymes);
755 syme = msyme;
756 n += 1;
757 }
758 }
759
760 if (n != 1 || tfIsUnknown(symeType(syme))(((symeType(syme))->tag) == TF_Unknown)) {
761 if (n > 0) okSymes = listCons(Syme)(Syme_listPointer->Cons)(syme, okSymes);
762 terrorNotUniqueMeaning(ALDOR_E_TinNMeanings165, absyn, okSymes, ml0,
763 symString(sym)((sym)->str), type);
764
765 syme = NULL((void*)0);
766 }
767
768 listFree(Syme)(Syme_listPointer->Free)(okSymes);
769
770 return syme;
771}
772
773localstatic Bool tiCheckLambda0(TForm tf);
774
775Bool
776tiCheckLambdaType(TForm tf)
777{
778 if (tfIsDomainMap(tf) || tfIsCategoryMap(tf))
779 return false((int) 0);
780
781 return tiCheckLambda0(tf);
782}
783
784localstatic Bool
785tiCheckLambda0(TForm tf)
786{
787 if (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
)
788 tiCheckLambda0(tfMapRet(tf)tfFollowArg(tf, 1));
789
790 return !(tfSatDom(tf) || tfSatCat(tf));
791}
792
793
794/*****************************************************************************
795 *
796 * :: Packed map embeddings
797 *
798 ****************************************************************************/
799
800localstatic AbSyn
801abNewRawOf(AbSyn arg)
802{
803 AbSyn op = abNewId(abPos(arg), symIntern("raw"))abNew(AB_Id, (spstackFirst((arg)->abHdr.pos)),1, symProbe(
"raw", 1 | 2))
;
804 AbSyn ab = abNewApply1(abPos(arg), op, arg)abNew(AB_Apply, (spstackFirst((arg)->abHdr.pos)),2, op,arg
)
;
805
806 return ab;
807}
808
809localstatic AbSyn
810abNewBoxOf(AbSyn arg)
811{
812 AbSyn op = abNewId(abPos(arg), symIntern("box"))abNew(AB_Id, (spstackFirst((arg)->abHdr.pos)),1, symProbe(
"box", 1 | 2))
;
813 AbSyn ab = abNewApply1(abPos(arg), op, arg)abNew(AB_Apply, (spstackFirst((arg)->abHdr.pos)),2, op,arg
)
;
814
815 return ab;
816}
817
818Bool
819tiUnaryToRaw(Stab stab, AbSyn ab, TForm tf)
820{
821 AbSyn imp = abImplicit(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->implicit : 0
)
;
822
823 if (!imp) {
824 imp = sefoCopy(ab);
825 if (abState(imp)((imp)->abHdr.state) != AB_State_HasUnique) {
826 abState(imp)((imp)->abHdr.state) = AB_State_HasUnique;
827 abTUnique(imp)((imp)->abHdr.type.unique) = tf;
828 }
829 imp = abNewRawOf(imp);
830 abSetImplicit(ab, imp);
831 }
832
833 tiBottomUp(stab, imp, tfUnknown);
834 tiTopDown (stab, imp, tfUnknown);
835 if (abState(imp)((imp)->abHdr.state) == AB_State_HasUnique) {
836 abAddTContext(ab, AB_Embed_UnaryToRaw(((AbEmbed) 1) << 10));
837 return true1;
838 }
839 else
840 return false((int) 0);
841}
842
843Bool
844tiRawToUnary(Stab stab, AbSyn ab, TForm tf)
845{
846 AbSyn imp = abImplicit(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->implicit : 0
)
;
847
848 if (!imp) {
849 imp = sefoCopy(ab);
850 if (abState(imp)((imp)->abHdr.state) != AB_State_HasUnique) {
851 abState(imp)((imp)->abHdr.state) = AB_State_HasUnique;
852 abTUnique(imp)((imp)->abHdr.type.unique) = tf;
853 }
854 imp = abNewBoxOf(abNewRawOf(imp));
855 abSetImplicit(ab, imp);
856 }
857
858 tiBottomUp(stab, imp, tf);
859 tiTopDown (stab, imp, tf);
860 if (abState(imp)((imp)->abHdr.state) == AB_State_HasUnique) {
861 abAddTContext(ab, AB_Embed_RawToUnary(((AbEmbed) 1) << 11));
862 return true1;
863 }
864 else
865 return false((int) 0);
866}
867
868/*****************************************************************************
869 *
870 * :: tiDefine
871 *
872 ****************************************************************************/
873
874TForm
875tiDefineFilter(AbSyn absyn, TForm type)
876{
877 AbSyn lhs = absyn->abDefine.lhs;
878 if (abHasTag(lhs, AB_Declare)((lhs)->abHdr.tag == (AB_Declare)))
879 return abTForm(lhs->abDeclare.type)((lhs->abDeclare.type)->abHdr.seman ? (lhs->abDeclare
.type)->abHdr.seman->tform : 0)
;
880 else
881 return type;
882}
883
884TPoss
885tiDefineTPoss(AbSyn absyn)
886{
887 AbSyn lhs = absyn->abDefine.lhs;
888 if (abHasTag(lhs, AB_Declare)((lhs)->abHdr.tag == (AB_Declare)))
889 return abReferTPoss(lhs);
890 else
891 return abReferTPoss(absyn);
892}
893
894/*****************************************************************************
895 *
896 * :: typeInferTForms
897 *
898 ****************************************************************************/
899
900TForm
901typeInferTForm(Stab stab, TForm tf)
902{
903 DefaultState wasDoingDefaults = tiTfDoingDefault;
904 tfFollow(tf)((tf) = tfFollowFn(tf));
905
906 tiTfDoingDefault = DEF_State_Yes;
907 tiTfOne(stab, NULL((void*)0), tf);
11
Calling 'tiTfOne'
908 tiTfDoingDefault = wasDoingDefaults;
909
910 return tf;
911}
912
913void
914typeInferTForms(Stab stab)
915{
916 TFormUsesList tful0, tful1, tful2, tful;
917 static ULong serialNo = 0, depthNo = 0, serialMax = 0;
918 ULong serialThis;
919
920 /* Maybe should check cdr(stab), and use extreme caution */
921
922
923 if (car(stab)((stab)->first)->isChecked) return;
924 car(stab)((stab)->first)->isChecked = true1;
925
926 tful0 = listReverse(TFormUses)(TFormUses_listPointer->Reverse)(car(stab)((stab)->first)->tformsUsed.list);
927
928 serialNo += 1;
929 depthNo += 1;
930 serialThis = serialNo;
931 if (serialMax == 0) serialMax = stabMaxSerialNo();
932 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, stab, ">>typeInferTForms:", tful0);
933 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "->Titf: %*s%ld/%ld\n", (int)depthNo, "",
934 serialThis, serialMax);
935
936 for (tful = tful0; tful; tful = tful1) {
937 DefaultState wasDoingDefaults = tiTfDoingDefault;
938
939 if (false((int) 0)) {
940 tiTfDoingDefault = DEF_State_NotYet;
941 tiTfOne(stab, car(tful)((tful)->first), car(tful)((tful)->first)->tf);
942 tiTfDoingDefault = DEF_State_Yes;
943 tiTfDefault(stab, tful);
944 }
945 else if (cdr(tful)((tful)->rest) == NULL((void*)0) || tiTfIsBoundary(car(tful)((tful)->first))) {
946 tiTfDoingDefault = DEF_State_Yes;
947 tful1 = cdr(tful)((tful)->rest);
948 tiTfOne(stab, car(tful)((tful)->first), car(tful)((tful)->first)->tf);
949 }
950 else {
951 tful1 = tiTfPartition(stab, tful);
952 tful2 = listCopyTo(TFormUses)(TFormUses_listPointer->CopyTo)(tful, tful1);
953
954 tiTfDoingDefault = DEF_State_NotYet;
955 tiTfSort(stab, tful2);
956 tiTfDoingDefault = DEF_State_Yes;
957 tiTfDefault(stab, tful2);
958 listFree(TFormUses)(TFormUses_listPointer->Free)(tful2);
959 }
960 tiTfDoingDefault = wasDoingDefaults;
961 }
962
963 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "<-Titf: %*s%ld/%ld\n", (int)depthNo, "",
964 serialThis, serialMax);
965 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, stab, "<<typeInferTForms:", tful0);
966 depthNo -=1;
967
968 listFree(TFormUses)(TFormUses_listPointer->Free)(tful0);
969}
970
971localstatic void
972tiTfSort(Stab stab, TFormUsesList tful0)
973{
974 Table tbl;
975 TFormUsesList tful, before, cycle, after;
976 Bool allBefore = false((int) 0);
977 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[sorting %d tfus]\n",
978 (int) listLength(TFormUses)(TFormUses_listPointer->_Length)(tful0));
979
980 /* Collect the type forms used to declare each symbol. */
981 tbl = tiTfGetDeclareeTable(tful0);
982
983 /* Collect the type forms used to declare symbols in each type form. */
984 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest))
985 tiTfCollectDependees(tbl, car(tful)((tful)->first), car(tful)((tful)->first)->tf);
986
987 /* Collect the dependencies which arise from has questions. */
988 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest))
989 tiTfCollectHasDependees(tful0, car(tful)((tful)->first));
990
991 /* Free the table of type forms used to declare each symbol. */
992 tiTfFreeDeclareeTable(tbl);
993
994 /* Perform a topological sort on the type forms. */
995 before = tiTopForward (tful0);
996 after = tiTopReverse (tful0);
997 cycle = tiTopCycle (tful0);
998
999 if (DEBUG(titf)titfDebug) {
1000 tiTfPrint(dbOut, stab, ">>tiTfSort[before]:", before);
1001 tiTfPrint(dbOut, stab, ">>tiTfSort[after ]:", after);
1002 tiTfPrint(dbOut, stab, ">>tiTfSort[cycle ]:", cycle);
1003 }
1004 if (DEBUG(titfStab)titfStabDebug) {
1005 allBefore = (!cycle && !after);
1006 if (allBefore) fprintf(dbOut, "[all before]\n");
1007 }
1008
1009 /* Process the type forms in before. */
1010 if (DEBUG(titfStab)titfStabDebug) {
1011 if (!allBefore)
1012 fprintf(dbOut, "[%d before]",
1013 (int) listLength(TFormUses)(TFormUses_listPointer->_Length)(before));
1014 }
1015 for (tful = before; tful; tful = cdr(tful)((tful)->rest)) {
1016 if (DEBUG(titfStab)titfStabDebug) {
1017 if (!allBefore)
1018 fprintf(dbOut, ".");
1019 }
1020 tiTfOne(stab, car(tful)((tful)->first), car(tful)((tful)->first)->tf);
1021 }
1022 if (DEBUG(titfStab)titfStabDebug) {if (!allBefore) fnewline(dbOut);}
1023
1024 /* Process the type forms in cycle. */
1025 if (cycle) {
1026 TFormUsesList clique = tiTopClique(cycle);
1027 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[%d cliques]\n",
1028 (int) listLength(TFormUses)(TFormUses_listPointer->_Length)(clique));
1029 for (tful = clique; tful; tful = cdr(tful)((tful)->rest)) {
1030 TFormUsesList clq = car(tful)((tful)->first)->cdependents;
1031 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[clique]\n");
1032 tiTfCycle(stab, clq);
1033 }
1034 tiTfFreeCDependees(clique);
1035 listFree(TFormUses)(TFormUses_listPointer->Free)(clique);
1036 }
1037
1038 /* Process the type forms in after. */
1039 if (DEBUG(titfStab)titfStabDebug) {
1040 if (!allBefore)
1041 fprintf(dbOut, "[%d after]",
1042 (int) listLength(TFormUses)(TFormUses_listPointer->_Length)(after));
1043 }
1044 for (tful = after; tful; tful = cdr(tful)((tful)->rest)) {
1045 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, ".");
1046 tiTfOne(stab, car(tful)((tful)->first), car(tful)((tful)->first)->tf);
1047 }
1048 if (DEBUG(titfStab)titfStabDebug) {if (!allBefore) fnewline(dbOut);}
1049
1050 /* Free the lists of dependencies between type forms. */
1051 tiTfFreeDependees(tful0);
1052
1053 listFree(TFormUses)(TFormUses_listPointer->Free)(before);
1054 listFree(TFormUses)(TFormUses_listPointer->Free)(after);
1055 listFree(TFormUses)(TFormUses_listPointer->Free)(cycle);
1056}
1057
1058localstatic void
1059tiTfOne(Stab stab, TFormUses tfu, TForm tf)
1060{
1061 tiTfEnterDb(titf)if (titfDebug) tiTfEnter(dbOut, "tiTfOne", tfu, tf);
12
Assuming 'titfDebug' is 0
13
Taking false branch
1062
1063 /* tfu == NULL just means that typeInferTForm doesn't have a tfu. */
1064
1065 if (tiTfSyntax1(stab, tfu, tf, listNil(AbSyn)((AbSynList) 0))) {
14
Calling 'tiTfSyntax1'
1066 if (tfu == NULL((void*)0)) return;
1067 }
1068
1069 if (tfIsSyntax(tf)(((tf)->tag) == TF_Syntax) || tfIsPending(tf)(((tf)->state)==TF_State_Pending) || tfu == NULL((void*)0)) {
1070 tiTfPending1 (stab, tf);
1071 tiTfBottomUp1 (stab, tfu, tf);
1072 tiTfAudit1 (stab, tf);
1073 tiTfTopDown1 (stab, tf);
1074 tiTfMeaning1 (stab, tf);
1075 }
1076
1077 if (tfu) {
1078 tiTfExtend1(stab, tfu);
1079 tiTfImport1(stab, tfu);
1080 tiTfCascades1(stab, tfu);
1081 }
1082
1083 tiTfExitDb(titf)if (titfDebug) tiTfExit(dbOut, "tiTfOne", tfu, tf);
1084}
1085
1086localstatic void
1087tiTfCycle(Stab stab, TFormUsesList tful)
1088{
1089 TFormUsesList tful0, tfl;
1090
1091 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, stab, ">>tiTfCycle:", tful);
1092
1093 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[syntax]\n");
1094 tful = tiTfSyntax (stab, tful);
1095
1096 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[select]\n");
1097 tful0 = tiTfSelect (stab, tful);
1098
1099 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[pending]\n");
1100 for (tfl=tful0; tfl; tfl=cdr(tfl)((tfl)->rest))
1101 tiTfPending1(stab, car(tfl)((tfl)->first)->tf);
1102
1103 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[bottom up]\n");
1104 for (tfl=tful0; tfl; tfl=cdr(tfl)((tfl)->rest))
1105 tiTfBottomUp1(stab, car(tfl)((tfl)->first), car(tfl)((tfl)->first)->tf);
1106
1107 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[audit]\n");
1108 for (tfl=tful0; tfl; tfl=cdr(tfl)((tfl)->rest))
1109 tiTfAudit1(stab, car(tfl)((tfl)->first)->tf);
1110
1111 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[top down]\n");
1112 for (tfl=tful0; tfl; tfl=cdr(tfl)((tfl)->rest))
1113 tiTfTopDown1(stab, car(tfl)((tfl)->first)->tf);
1114
1115 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[meaning]\n");
1116 for (tfl=tful0; tfl; tfl=cdr(tfl)((tfl)->rest))
1117 tiTfMeaning1(stab, car(tfl)((tfl)->first)->tf);
1118
1119 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[extend]\n");
1120 for (tfl=tful; tfl; tfl=cdr(tfl)((tfl)->rest))
1121 tiTfExtend1(stab, car(tfl)((tfl)->first));
1122
1123 titfStabDEBUGif (!titfStabDebug) { } else afprintf(dbOut, "[import]\n");
1124 for (tfl=tful; tfl; tfl=cdr(tfl)((tfl)->rest))
1125 tiTfImport1(stab, car(tfl)((tfl)->first));
1126
1127 for (tfl=tful; tfl; tfl=cdr(tfl)((tfl)->rest))
1128 tiTfCascades1(stab, car(tfl)((tfl)->first));
1129
1130 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, stab, "<<titfCycle:", tful);
1131
1132 listFree(TFormUses)(TFormUses_listPointer->Free)(tful0);
1133}
1134
1135localstatic void
1136tiTfDefault(Stab stab, TFormUsesList tful0)
1137{
1138 TFormUsesList tful;
1139
1140 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
1141 TForm tf = car(tful)((tful)->first)->tf;
1142
1143 if (!tiTfDefaultSyntax(stab, tf))
1144 tiTfDefault1(stab, tfGetExpr(tf)((tf)->__absyn));
1145 }
1146
1147 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest))
1148 tiTfImport1(stab, car(tful)((tful)->first));
1149 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest))
1150 tiTfCascades1(stab, car(tful)((tful)->first));
1151}
1152
1153localstatic Bool
1154tiTfDefaultSyntax(Stab stab, TForm tf)
1155{
1156 Bool result = true1;
1157
1158 if (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
)
1159 tiTfDefaultSyntaxMap(stab, tf);
1160
1161 else if (tfIsDefine(tf)(((tf)->tag) == TF_Define))
1162 result = tiTfDefaultSyntaxDefine(stab, tf);
1163
1164 else
1165 result = false((int) 0);
1166
1167 return result;
1168}
1169
1170localstatic void
1171tiTfDefaultSyntaxMap(Stab stab, TForm tf)
1172{
1173 AbSyn ab = tfGetExpr(tf)((tf)->__absyn);
1174 Stab nstab = (abStab(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->stab : 0) ? abStab(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->stab : 0) : stab);
1175 TForm tfarg = tfMapArg(tf)tfFollowArg(tf, 0);
1176 TForm tfret = tfMapRet(tf)tfFollowArg(tf, 1);
1177
1178 tiTfDefault1(nstab, tfGetExpr(tfarg)((tfarg)->__absyn));
1179 if (!tiTfDefaultSyntax(nstab, tfret))
1180 tiTfDefault1(nstab, tfGetExpr(tfret)((tfret)->__absyn));
1181}
1182
1183localstatic Bool
1184tiTfDefaultSyntaxDefine(Stab stab, TForm tf)
1185{
1186 TForm tfd = tfDefineDecl(tf)tfFollowArg(tf, 0);
1187 AbSyn abd = tfGetExpr(tfd)((tfd)->__absyn);
1188 Bool result = true1;
1189
1190 if (abd && abHasTag(abd, AB_Declare)((abd)->abHdr.tag == (AB_Declare)))
1191 abd = abd->abDeclare.type;
1192 else
1193 return false((int) 0);
1194
1195 if (!abd)
1196 result = false((int) 0);
1197
1198 else if (abIsTheId(abd, ssymCategory)(((abd)->abHdr.tag == (AB_Id)) && ((abd)->abId.
sym)==(ssymCategory))
) {
1199 tiTfDefault1(stab, abd);
1200 tiTfDefault1(stab, tfGetExpr(tfDefineVal(tf))((tfFollowArg(tf, 1))->__absyn));
1201 }
1202
1203 else if (abHasTag(abd, AB_With)((abd)->abHdr.tag == (AB_With))) {
1204 tiTfDefault1(stab, abd);
1205 /* default inside an add means something else */
1206 }
1207
1208 else
1209 result = false((int) 0);
1210
1211 return result;
1212}
1213
1214void
1215tiTfPrint(FILE *fout, Stab stab, String str, TFormUsesList tful0)
1216{
1217 TFormUsesList tful;
1218 Length i;
1219
1220 fprintf(dbOut, "%s\n", str);
1221 if (stab) {
1222 fprintf(dbOut, "Symbol Table Level %ld.",
1223 car(stab)((stab)->first)->lexicalLevel);
1224 findent += 2;
1225 fnewline(dbOut);
1226 fprintf(dbOut, "Declaree stack is: ");
1227 listPrint(Symbol)(Symbol_listPointer->Print)(dbOut, tiTfDeclarees, symPrint);
1228 fnewline(dbOut);
1229 fprintf(dbOut, "Definee stack is: ");
1230 listPrint(Symbol)(Symbol_listPointer->Print)(dbOut, tiTfDefinees, symPrint);
1231 fnewline(dbOut);
1232 fprintf(dbOut, "Pending type forms:");
1233 if (tful0) fnewline(dbOut);
1234 }
1235
1236 for (i = 0, tful = tful0; tful; i += 1, tful = cdr(tful)((tful)->rest)) {
1237 fnewline(dbOut);
1238 fprintf(dbOut, "%d. ", (int) i);
1239 tfuPrint(dbOut, car(tful)((tful)->first));
1240 }
1241
1242 findent -= 2;
1243 fnewline(dbOut);
1244}
1245
1246void
1247tiTfEnter(FILE *fout, String str, TFormUses tfu, TForm tf)
1248{
1249 fprintf(fout, ">>%s:\n", str);
1250 findent += 2;
1251 fnewline(fout);
1252 if (tfu) tfuPrint(fout, tfu); else tfPrint(fout, tf);
1253 findent -= 2;
1254 fnewline(fout);
1255}
1256
1257void
1258tiTfExit(FILE *fout, String str, TFormUses tfu, TForm tf)
1259{
1260 fprintf(fout, "<<%s:\n", str);
1261 findent += 2;
1262 fnewline(fout);
1263 if (tfu) tfuPrint(fout, tfu); else tfPrint(fout, tf);
1264 findent -= 2;
1265 fnewline(fout);
1266}
1267
1268/*****************************************************************************
1269 *
1270 * :: typeInferTForms helper functions
1271 *
1272 ****************************************************************************/
1273
1274localstatic SymbolList
1275tiTfGetDeclarees(TFormUses tfu)
1276{
1277 TForm tf;
1278
1279 if (tfu == 0) return listNil(Symbol)((SymbolList) 0);
1280
1281 tf = tfu->tf;
1282 tfFollow(tf)((tf) = tfFollowFn(tf));
1283
1284 if (tfIsWith(tf)(((tf)->tag) == TF_With) || (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
&& tfIsWith(tfMapRet(tf))(((tfFollowArg(tf, 1))->tag) == TF_With)))
1285 return tfu->declarees;
1286 else
1287 return listNil(Symbol)((SymbolList) 0);
1288}
1289
1290localstatic SymbolList
1291tiTfPushDeclarees(SymbolList sl)
1292{
1293 SymbolList ol = tiTfDeclarees;
1294 tiTfDeclarees = listNConcat(Symbol)(Symbol_listPointer->NConcat)(listCopy(Symbol)(Symbol_listPointer->Copy)(sl),
1295 tiTfDeclarees);
1296 return ol;
1297}
1298
1299localstatic void
1300tiTfPopDeclarees(SymbolList ol)
1301{
1302 tiTfDeclarees = listFreeTo(Symbol)(Symbol_listPointer->FreeTo)(tiTfDeclarees, ol);
1303}
1304
1305localstatic Symbol
1306tiTfUsesSymbol(TFormUses tfu)
1307{
1308 Symbol sym = NULL((void*)0);
1309
1310 if (tfu && tfu->declarees && cdr(tfu->declarees)((tfu->declarees)->rest) == listNil(Symbol)((SymbolList) 0))
1311 sym = car(tfu->declarees)((tfu->declarees)->first);
1312 return sym;
1313}
1314
1315localstatic void
1316tiTfPushDefinee0(Symbol sym)
1317{
1318 tiTfDefinees = listCons(Symbol)(Symbol_listPointer->Cons)(sym, tiTfDefinees);
1319}
1320
1321void
1322tiTfPushDefinee(AbSyn lhs)
1323{
1324 Symbol sym;
1325
1326 if (abTag(lhs)((lhs)->abHdr.tag) == AB_Comma) {
1327 int i;
1328 for (i=0; i<abArgc(lhs)((lhs)->abHdr.argc); i++) {
1329 tiTfPushDefinee(lhs->abComma.argv[i]);
1330 }
1331 }
1332 else {
1333 lhs = abDefineeIdOrElse(lhs, NULL((void*)0));
1334 sym = lhs ? lhs->abId.sym : NULL((void*)0);
1335 tiTfPushDefinee0(sym);
1336 }
1337}
1338
1339void
1340tiTfPopDefinee(AbSyn lhs)
1341{
1342 if (abTag(lhs)((lhs)->abHdr.tag) == AB_Comma) {
1343 int i;
1344 for (i=0; i<abArgc(lhs)((lhs)->abHdr.argc); i++) {
1345 tiTfPopDefinee(lhs->abComma.argv[i]);
1346 }
1347 }
1348 else {
1349 tiTfDefinees = listFreeCons(Symbol)(Symbol_listPointer->FreeCons)(tiTfDefinees);
1350 }
1351
1352}
1353
1354void
1355tiTfPopDefinee0(Symbol sym)
1356{
1357 tiTfDefinees = listFreeCons(Symbol)(Symbol_listPointer->FreeCons)(tiTfDefinees);
1358}
1359
1360Bool
1361tiTfDoDefault(Sefo sefo)
1362{
1363 /* Skip AB_Default trees if we will traverse them later. */
1364 if (abTag(sefo)((sefo)->abHdr.tag) != AB_Default)
1365 return true1;
1366 if (tiTfDoingDefault == DEF_State_NotYet)
1367 return false((int) 0);
1368 return true1;
1369}
1370
1371localstatic Bool
1372tiTfIsBoundary(TFormUses tfu)
1373{
1374 return tfu->isExplicitImport || tfu->isParamImport;
1375}
1376
1377localstatic Bool
1378tqShouldImport(TQual tq)
1379{
1380 TForm tf;
1381 Symbol sym = NULL((void*)0);
1382
1383 if (tq == NULL((void*)0))
1384 return false((int) 0);
1385
1386 tf = tqBase(tq)((tq)->base);
1387
1388 tfFollow(tf)((tf) = tfFollowFn(tf));
1389 if (tfIsNotDomain(tf)((((tf)->tag) == TF_Type) || (((tf)->tag) == TF_With) ||
((((tf)->tag) == TF_Syntax) && ((((tf)->__absyn
))->abHdr.tag == (AB_With))) || (((tf)->tag) == TF_Join
) || (((tf)->tag) == TF_If) || (((tf)->tag) == TF_Third
))
|| tfSatDom(tf) || tfSatCat(tf))
1390 return false((int) 0);
1391
1392 if (tfIsVariable(tf)(((tf)->tag) == TF_Variable) || tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
|| tfIsMulti(tf)(((tf)->tag) == TF_Multiple))
1393 return false((int) 0);
1394
1395 if (tfIsId(tf)((((tf)->tag) == TF_General) && ((((tf)->__absyn
))->abHdr.tag) == AB_Id)
)
1396 sym = tfIdSym(tf)(((tf)->__absyn)->abId.sym);
1397 else if (tfIsApply(tf)((((tf)->tag) == TF_General) && ((((tf)->__absyn
))->abHdr.tag) == AB_Apply)
&& abTag(tfApplyOp(tf))(((((tf)->__absyn)->abApply.op))->abHdr.tag) == AB_Id)
1398 sym = tfApplyOp(tf)(((tf)->__absyn)->abApply.op)->abId.sym;
1399 else
1400 return true1;
1401
1402 if (sym == ssymSelf)
1403 return false((int) 0);
1404
1405 if (listMemq(Symbol)(Symbol_listPointer->Memq)(tiTfDeclarees, sym) ||
1406 listMemq(Symbol)(Symbol_listPointer->Memq)(tiTfDefinees, sym))
1407 return false((int) 0);
1408
1409 return true1;
1410}
1411
1412/*****************************************************************************
1413 *
1414 * :: typeInferTForms phases
1415 *
1416 ****************************************************************************/
1417
1418/* Return the first group of tforms from tful which s/b inferred as a group. */
1419localstatic TFormUsesList
1420tiTfPartition(Stab stab, TFormUsesList tful0)
1421{
1422 TFormUsesList tful;
1423
1424 for (tful = cdr(tful0)((tful0)->rest); tful; tful = cdr(tful)((tful)->rest))
1425 if (tiTfIsBoundary(car(tful)((tful)->first)))
1426 break;
1427
1428 return tful;
1429}
1430
1431/* Fill in syntax type forms which appear as type form components. */
1432localstatic TFormUsesList
1433tiTfSyntax(Stab stab, TFormUsesList tful0)
1434{
1435 TFormUsesList tful;
1436
1437 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest))
1438 tiTfSyntax1(stab, car(tful)((tful)->first), car(tful)((tful)->first)->tf, listNil(AbSyn)((AbSynList) 0));
1439
1440 return tful0;
1441}
1442
1443/* Select the syntax type forms. */
1444localstatic TFormUsesList
1445tiTfSelect(Stab stab, TFormUsesList tful)
1446{
1447 TFormUsesList tful0 = listNil(TFormUses)((TFormUsesList) 0);
1448
1449 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, stab, ">>tiTfSelect:", tful);
1450
1451 for (; tful; tful = cdr(tful)((tful)->rest)) {
1452 TFormUses tfu = car(tful)((tful)->first);
1453
1454 if (tfIsSyntax(tfu->tf)(((tfu->tf)->tag) == TF_Syntax))
1455 tful0 = listCons(TFormUses)(TFormUses_listPointer->Cons)(tfu, tful0);
1456 }
1457
1458 tful0 = listNReverse(TFormUses)(TFormUses_listPointer->NReverse)(tful0);
1459
1460 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, stab, "<<tiTfSelect:", tful0);
1461
1462 return tful0;
1463}
1464
1465localstatic Bool
1466tiTfSyntax1(Stab stab, TFormUses tfu, TForm tf, AbSynList params)
1467{
1468 Bool result = true1;
1469
1470 if (!tfIsPending(tf)(((tf)->state)==TF_State_Pending))
15
Assuming field 'state' is equal to TF_State_Pending
16
Taking false branch
1471 result = false((int) 0);
1472
1473 else if (tfIsSyntax(tf)(((tf)->tag) == TF_Syntax))
17
Assuming field 'tag' is not equal to TF_Syntax
1474 result = tiTfFloat1(stab, tf);
1475
1476 else if (tfIsAnyMap(tf)((((tf)->tag) == TF_Map) || (((tf)->tag) == TF_PackedMap
))
)
18
Taking false branch
19
Assuming field 'tag' is not equal to TF_Map
20
Assuming field 'tag' is not equal to TF_PackedMap
21
Taking false branch
1477 tiTfMap1(stab, tfu, tf, params);
1478
1479 else if (tfIsDefine(tf)(((tf)->tag) == TF_Define))
22
Assuming field 'tag' is equal to TF_Define
23
Taking true branch
1480 result = tiTfDefine1(stab, tfu, tf, params);
24
Calling 'tiTfDefine1'
1481
1482 else
1483 result = false((int) 0);
1484
1485 return result;
1486}
1487
1488localstatic Bool
1489tiTfFloat1(Stab stab, TForm tf)
1490{
1491 TForm ntf;
1492 Stab nstab;
1493
1494 nstab = tfFloat(stab, tf);
1495 if (nstab == NULL((void*)0))
1496 return false((int) 0);
1497
1498 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfFloat1", NULL((void*)0), tf);
1499
1500 ntf = typeInferTForm(nstab, tf);
1501 tfTransferSemantics(ntf, tf);
1502
1503 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfFloat1", NULL((void*)0), tf);
1504
1505 return true1;
1506}
1507
1508localstatic void
1509tiTfMap1(Stab stab, TFormUses tfu, TForm tf, AbSynList params)
1510{
1511 AbSyn ab = tfGetExpr(tf)((tf)->__absyn);
1512 Stab nstab = (abStab(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->stab : 0) ? abStab(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->stab : 0) : stab);
1513 TForm tfarg = tfMapArg(tf)tfFollowArg(tf, 0);
1514 TForm tfret = tfMapRet(tf)tfFollowArg(tf, 1);
1515 Length i;
1516
1517 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfMap1", NULL((void*)0), tf);
1518
1519 if (nstab != stab) {
1520 stabSeeOuterImports(nstab);
1521 stabGetSubstable(nstab);
1522 typeInferTForms(nstab);
1523 }
1524
1525 if (tfIsMulti(tfarg)(((tfarg)->tag) == TF_Multiple))
1526 for (i = 0; i < tfArgc(tfarg)((tfarg)->argc); i += 1)
1527 typeInferTForm(nstab, tfFollowArg(tfarg, i));
1528 typeInferTForm(nstab, tfarg);
1529
1530 params = listCons(AbSyn)(AbSyn_listPointer->Cons)(abMapArg(ab)((ab)->abApply.argv[0]), params);
1531 if (!tiTfSyntax1(nstab, tfu, tfret, params))
1532 typeInferTForm(nstab, tfret);
1533 listFreeCons(AbSyn)(AbSyn_listPointer->FreeCons)(params);
1534
1535 tiTfBottomUp1 (stab, tfu, tf);
1536 tiTfAudit1 (stab, tf);
1537 tiTfTopDown1 (stab, tf);
1538 tiTfMeaning1 (stab, tf);
1539
1540 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfMap1", NULL((void*)0), tf);
1541}
1542
1543localstatic Bool
1544tiTfDefine1(Stab stab, TFormUses tfu, TForm tf, AbSynList params)
1545{
1546 TForm tfd = tfDefineDecl(tf)tfFollowArg(tf, 0);
1547 AbSyn abd = tfGetExpr(tfd)((tfd)->__absyn);
1548 Bool result = true1;
1549
1550 if (abd && abHasTag(abd, AB_Declare)((abd)->abHdr.tag == (AB_Declare)))
25
Assuming 'abd' is non-null
26
Assuming field 'tag' is equal to AB_Declare
27
Taking true branch
1551 abd = abd->abDeclare.type;
1552 else
1553 return false((int) 0);
1554
1555 if (!abd)
28
Assuming 'abd' is non-null
29
Taking false branch
1556 result = false((int) 0);
1557
1558 else if (abIsUnknown(abd)((abd)->abHdr.tag == (AB_Blank)))
30
Assuming field 'tag' is not equal to AB_Blank
1559 tiTfUnknown1(stab, tfu, tf, params);
1560
1561 else if (abIsTheId(abd, ssymCategory)(((abd)->abHdr.tag == (AB_Id)) && ((abd)->abId.
sym)==(ssymCategory))
)
31
Taking false branch
32
Assuming field 'tag' is equal to AB_Id
33
Assuming 'ssymCategory' is equal to field 'sym'
34
Taking true branch
1562 tiTfThird1(stab, tfu, tf, params);
35
Calling 'tiTfThird1'
1563
1564 else /* if (abHasTag(abd, AB_With)) */
1565 tiTfCategory1(stab, tfu, tf, params);
1566
1567 return result;
1568}
1569
1570localstatic void
1571tiTfThird1(Stab stab, TFormUses tfu, TForm tf, AbSynList params)
1572{
1573 TForm tfc = tfDeclareType(tfDefineDecl(tf))tfFollowArg(tfFollowArg(tf, 0), 0);
1574 TForm tfw = tfDefineVal(tf)tfFollowArg(tf, 1);
1575 Symbol sym = tiTfUsesSymbol(tfu);
1576 AbSyn ab, abc, abw;
1577
1578 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfThird1", tfu, tf);
36
Assuming 'titfOneDebug' is 0
37
Taking false branch
1579
1580 tiTfPushDefinee0(sym);
1581
1582 abw = tfExpr(tfw)tfToAbSyn(tfw);
1583
1584 typeInferAs(stab, abw, tfCategory);
1585
1586 tiTfOne(stab, NULL((void*)0), tfw);
1587 /* typeInferTForm(stab, tfw); */
1588 if (tfIsSyntax(tfc)(((tfc)->tag) == TF_Syntax))
38
Assuming field 'tag' is not equal to TF_Syntax
39
Taking false branch
1589 tfForwardFrSyntax(tfc, tfThirdFrTForm(tfw));
1590 tiTfPopDefinee0(sym);
1591
1592 ab = tfExpr(tf)tfToAbSyn(tf);
1593 abc = abDefineDecl(ab)((ab)->abDefine.lhs)->abDeclare.type;
1594 abw = abDefineVal(ab)((ab)->abDefine.rhs);
1595
1596 abTransferSemantics(tfGetExpr(tfc)((tfc)->__absyn), abc);
1597 abTransferSemantics(tfGetExpr(tfw)((tfw)->__absyn), abw);
1598
1599 abSetPos(abc, abPos(tfGetExpr(tfc)))((abc)->abHdr.pos=spstackSetFirst ((abc)->abHdr.pos,((spstackFirst
((((tfc)->__absyn))->abHdr.pos)))))
;
1600 abSetPos(abw, abPos(tfGetExpr(tfw)))((abw)->abHdr.pos=spstackSetFirst ((abw)->abHdr.pos,((spstackFirst
((((tfw)->__absyn))->abHdr.pos)))))
;
1601
1602 if (abState(ab)((ab)->abHdr.state) != AB_State_HasUnique) {
40
Assuming field 'state' is equal to AB_State_HasUnique
41
Taking false branch
1603 abTUnique(ab)((ab)->abHdr.type.unique) = tfType;
1604 abState(ab)((ab)->abHdr.state) = AB_State_HasUnique;
1605 }
1606
1607 tfFollow(tfc)((tfc) = tfFollowFn(tfc));
1608 tfSetPending(tfc)(((tfc)->state)=TF_State_Pending);
1609 tfSetPending(tf)(((tf)->state)=TF_State_Pending);
1610
1611 if (sym && sym != ssymJoin) {
42
Assuming 'sym' is non-null
43
Assuming 'sym' is not equal to 'ssymJoin'
44
Taking true branch
1612 AbSyn abd;
1613 TForm tfd;
1614 Syme pp;
1615 AbSynList pl;
1616 Stab nstab = (abStab(abw)((abw)->abHdr.seman ? (abw)->abHdr.seman->stab : 0) ? abStab(abw)((abw)->abHdr.seman ? (abw)->abHdr.seman->stab : 0) : stab);
45
Assuming field 'seman' is non-null
46
'?' condition is true
47
Assuming the condition is true
48
'?' condition is true
49
Assuming field 'seman' is null
50
'?' condition is false
51
'nstab' initialized to a null pointer value
1617
1618 abd = abNewDefineLhs(sym, params);
1619 tfd = tiGetTForm(stab, abd);
1620 pp = symeNewExport(ssymSelfSelf, tfd, car(nstab)((nstab)->first));
52
Access to field 'first' results in a dereference of a null pointer (loaded from variable 'nstab')
1621 symeSetDefault(pp)(((((pp)->kind == SYME_Trigger ? libGetAllSymes((pp)->lib
) : ((void*)0)), (pp))->bits) |= (0x0080))
;
1622 tfSetSymes(tfc, listCons(Syme)(pp, listNil(Syme)))((tfc)->symes = ((Syme_listPointer->Cons)(pp, ((SymeList
) 0))))
;
1623 }
1624
1625 tfSetMeaning(tfc)(((tfc)->state)=TF_State_Meaning);
1626 tfCheckConsts(tfc);
1627
1628 tfSetMeaning(tf)(((tf)->state)=TF_State_Meaning);
1629 tfCheckConsts(tf);
1630 tiTfMeaning1(stab, tf);
1631
1632 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfThird1", tfu, tf);
1633}
1634
1635/*
1636 * This function adds as many symes from the specified list to
1637 * the symes of tf as possible. We leave out %% symes because
1638 * they cause too many problems and probably ought not to be
1639 * seen in tfSymes() for add bodies. Hopefully this function
1640 * won't be invoked too many times (just once for each add in
1641 * a program) so its O(N^2) cost won't hurt too much.
1642 */
1643localstatic void
1644tiAppendSymes(TForm tf, SymeList symes)
1645{
1646 SymeList originals = tfSymes(tf)((tf)->symes);
1647 SymeList additions = listNil(Syme)((SymeList) 0);
1648
1649
1650 /* Check each syme in symes */
1651 for (;symes;symes = cdr(symes)((symes)->rest))
1652 {
1653 Syme syme = car(symes)((symes)->first);
1654
1655
1656 /* Skip %% */
1657 if (symeIsSelfSelf(syme)(((syme)->id) == ssymSelfSelf)) continue;
1658
1659
1660 /* Skip symes already in tfSymes(tf) */
1661 if (symeListMember(syme, originals, symeEqual)) continue;
1662
1663
1664 /* Remember this additional syme */
1665 additions = listCons(Syme)(Syme_listPointer->Cons)(syme, additions);
1666 }
1667
1668
1669 /* Do nothing if nothing to add */
1670 if (!additions) return;
1671
1672
1673 /* Reverse the new list */
1674 additions = listNReverse(Syme)(Syme_listPointer->NReverse)(additions);
1675
1676
1677 /* Debugging */
1678 if (DEBUG(symeRefresh)symeRefreshDebug) {
1679 (void)fprintf(dbOut, "-----------> (extra)\n");
1680 symeListPrintDb(additions);
1681 (void)fprintf(dbOut, "\n\n");
1682 }
1683
1684
1685 /* Append onto tfSymes(tf) */
1686 originals = listNConcat(Syme)(Syme_listPointer->NConcat)(originals, additions);
1687
1688
1689 /* Unnecessary, but makes things obvious */
1690 tfSetSymes(tf, originals)((tf)->symes = (originals));
1691}
1692
1693
1694localstatic void
1695tiTfCategory1(Stab stab, TFormUses tfu, TForm tf, AbSynList params)
1696{
1697 TForm tfw = tfDeclareType(tfDefineDecl(tf))tfFollowArg(tfFollowArg(tf, 0), 0);
1698 TForm tfa = tfDefineVal(tf)tfFollowArg(tf, 1);
1699 Symbol sym = tiTfUsesSymbol(tfu);
1700 AbSyn ab, abw, aba, abt = NULL((void*)0);
1701 Stab nstab;
1702
1703 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfCategory1", NULL((void*)0), tf);
1704
1705 tiTfPushDefinee0(sym);
1706
1707 typeInferTForm(stab, tfw);
1708
1709 /* Process the add tform (tfa) to get the add symes, but
1710 * without analyzing the add body, to avoid unnecessary
1711 * dependencies between type forms.
1712 * The add body will be analyzed in its normal sequence.
1713 */
1714 aba = tfGetExpr(tfa)((tfa)->__absyn);
1715 if (tfIsSyntax(tfa)(((tfa)->tag) == TF_Syntax))
1716 tfForwardFrSyntax(tfa, tfPending(stab, aba));
1717 tfFollow(tfa)((tfa) = tfFollowFn(tfa));
1718
1719 /* Identify % in the add body (aba) with the definee. */
1720 if (abTag(aba)((aba)->abHdr.tag) == AB_Sequence && abArgc(aba)((aba)->abHdr.argc) > 0)
1721 aba = abArgv(aba)((aba)->abGen.data.argv)[abArgc(aba)((aba)->abHdr.argc) - 1];
1722 nstab = abStab(aba)((aba)->abHdr.seman ? (aba)->abHdr.seman->stab : 0);
1723 if (nstab == NULL((void*)0)) nstab = stab;
1724
1725 if (sym) {
1726 SymeList aself = tfGetSelfFrStab(nstab);
1727 Syme asyme = (aself ? car(aself)((aself)->first) : NULL((void*)0));
1728 Syme xsyme;
1729 AbSyn abd;
1730 AbSynList pl;
1731 TForm tfd, val;
1732
1733 if (asyme) {
1734 Stab istab = (params ? stab : nstab);
1735 abd = abNewDefineLhs(sym, params);
1736 tfd = tfSyntaxFrAbSyn(istab, abd);
1737 tfd = tfDefineOfType(tfd);
1738 xsyme = stabDefExtend(nstab, ssymSelf, tfd);
1739 symeAddExtendee(xsyme, asyme);
1740 symeSetExtension(asyme, xsyme)symeXSetExtension(asyme, (AInt) xsyme);
1741 stabExtendMeanings(nstab, xsyme);
1742
1743 if (nstab != stab) {
1744 stabSeeOuterImports(nstab);
1745 stabGetSubstable(nstab);
1746 }
1747
1748 typeInferAs(istab, abd, tfType);
1749 val = tfDefineVal(tfd)tfFollowArg(tfd, 1);
1750 if (tfIsSyntax(val)(((val)->tag) == TF_Syntax)) {
1751 tfMeaningFrSyntax(istab, abd, val);
1752 tfSetMeaningArgs(tfd);
1753 }
1754 abt = abd;
1755 }
1756 }
1757
1758 if (nstab != stab) {
1759 stabSeeOuterImports(nstab);
1760 stabGetSubstable(nstab);
1761 }
1762
1763 if (nstab != stab) {
1764 /*!! Try to fill the types for parameterized add symes. */
1765 if (params) typeInferTForms(nstab);
1766 tfSetSymes(tfa, stabGetExportedSymes(nstab))((tfa)->symes = (stabGetExportedSymes(nstab)));
1767 tfGetSelf(nstab, tfa);
1768 }
1769 tfSetMeaning(tfa)(((tfa)->state)=TF_State_Meaning);
1770 tfCheckConsts(tfa);
1771
1772 tfSetMeaning(tf)(((tf)->state)=TF_State_Meaning);
1773 tfCheckConsts(tf);
1774
1775 if (abTag(aba)((aba)->abHdr.tag) == AB_Add) {
1776 AbSyn base = aba->abAdd.base;
1777 AbSyn capsule = aba->abAdd.capsule;
1778 AbSynList extl = tfu ? tfu->extension : NULL((void*)0);
1779 SymeList extras;
1780
1781 tiGetTForm(nstab, base);
1782 for (; extl; extl = cdr(extl)((extl)->rest)) {
1783 AbSyn ab0 = car(extl)((extl)->first);
1784 Syme syme = abSyme(ab0)((ab0)->abHdr.seman ? (ab0)->abHdr.seman->syme : 0);
1785 Syme extension = symeExtension(syme);
1786 TForm tf = symeType(extension);
1787 Syme osyme;
1788
1789 assert(ab0 && abHasTag(ab0, AB_Id))do { if (!(ab0 && ((ab0)->abHdr.tag == (AB_Id)))) _do_assert
(("ab0 && abHasTag(ab0, AB_Id)"),"tinfer.c",1789); } while
(0)
;
1790 assert(syme && symeIsExport(syme))do { if (!(syme && (((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
kind) == SYME_Export))) _do_assert(("syme && symeIsExport(syme)"
),"tinfer.c",1790); } while (0)
;
1791 assert(extension && symeIsExtend(extension))do { if (!(extension && (((((extension)->kind == SYME_Trigger
? libGetAllSymes((extension)->lib) : ((void*)0)), (extension
))->kind) == SYME_Extend))) _do_assert(("extension && symeIsExtend(extension)"
),"tinfer.c",1791); } while (0)
;
1792 assert(listMemq(Syme)(symeExtendee(extension), syme))do { if (!((Syme_listPointer->Memq)(symeExtendee(extension
), syme))) _do_assert(("listMemq(Syme)(symeExtendee(extension), syme)"
),"tinfer.c",1792); } while (0)
;
1793
1794 osyme = tiGetExtendee(stab, ab0, tf);
1795 if (osyme) {
1796 TForm otf = symeType(osyme);
1797 if (tfIsAnyMap(otf)((((otf)->tag) == TF_Map) || (((otf)->tag) == TF_PackedMap
))
)
1798 otf = tfExtendeeSubst(nstab, otf, tf);
1799 tiWithSymes(nstab, otf);
1800 }
1801 }
1802 tiAddSymes(nstab, capsule, abTForm(base)((base)->abHdr.seman ? (base)->abHdr.seman->tform : 0
)
, tfw, &extras);
1803
1804 /* When is tfu allowed to be NULL? */
1805 if (tfu) {
1806 listFree(AbSyn)(AbSyn_listPointer->Free)(tfu->extension);
1807 tfu->extension = NULL((void*)0);
1808 }
1809
1810 /* Add the new symes to tfSymes for the add */
1811 tiAppendSymes(tfa, extras);
1812 }
1813 if (abt && tfu)
1814 tfu->extension = listCons(AbSyn)(AbSyn_listPointer->Cons)(abt, listNil(AbSyn)((AbSynList) 0));
1815
1816 tiTfPopDefinee0(sym);
1817
1818 ab = tfExpr(tf)tfToAbSyn(tf);
1819 abw = abDefineDecl(ab)((ab)->abDefine.lhs)->abDeclare.type;
1820 aba = abDefineVal(ab)((ab)->abDefine.rhs);
1821
1822 abTransferSemantics(tfGetExpr(tfw)((tfw)->__absyn), abw);
1823 abTransferSemantics(tfGetExpr(tfa)((tfa)->__absyn), aba);
1824
1825 abSetPos(abw, abPos(tfGetExpr(tfw)))((abw)->abHdr.pos=spstackSetFirst ((abw)->abHdr.pos,((spstackFirst
((((tfw)->__absyn))->abHdr.pos)))))
;
1826 abSetPos(aba, abPos(tfGetExpr(tfa)))((aba)->abHdr.pos=spstackSetFirst ((aba)->abHdr.pos,((spstackFirst
((((tfa)->__absyn))->abHdr.pos)))))
;
1827
1828 if (abState(ab)((ab)->abHdr.state) != AB_State_HasUnique) {
1829 abTUnique(ab)((ab)->abHdr.type.unique) = tfType;
1830 abState(ab)((ab)->abHdr.state) = AB_State_HasUnique;
1831 }
1832 tiTfMeaning1(stab, tfDefineDecl(tf)tfFollowArg(tf, 0));
1833 tiTfMeaning1(stab, tf);
1834
1835 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfCategory1", NULL((void*)0), tf);
1836}
1837
1838localstatic void
1839tiTfUnknown1(Stab stab, TFormUses tfu, TForm tf, AbSynList params)
1840{
1841 TForm tfl = tfDeclareType(tfDefineDecl(tf))tfFollowArg(tfFollowArg(tf, 0), 0);
1842 TForm tfr = tfDefineVal(tf)tfFollowArg(tf, 1);
1843 Symbol sym = tiTfUsesSymbol(tfu);
1844 AbSyn ab, abl, abr;
1845
1846 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfUnknown1", NULL((void*)0), tf);
1847
1848 tiTfPushDefinee0(sym);
1849
1850 typeInferAs(stab, tfExpr(tfr)tfToAbSyn(tfr), tfUnknown);
1851 if (tfIsSyntax(tfr)(((tfr)->tag) == TF_Syntax))
1852 tfMeaningFrSyntax(stab, tfGetExpr(tfr)((tfr)->__absyn), tfr);
1853 tfFollow(tfr)((tfr) = tfFollowFn(tfr));
1854
1855 typeInferTForm(stab, tfl);
1856
1857 tfSetMeaning(tf)(((tf)->state)=TF_State_Meaning);
1858 tfCheckConsts(tf);
1859
1860 tiTfPopDefinee0(sym);
1861
1862 ab = tfExpr(tf)tfToAbSyn(tf);
1863 abl = abDefineDecl(ab)((ab)->abDefine.lhs)->abDeclare.type;
1864 abr = abDefineVal(ab)((ab)->abDefine.rhs);
1865
1866 abTransferSemantics(tfGetExpr(tfl)((tfl)->__absyn), abl);
1867 abTransferSemantics(tfGetExpr(tfr)((tfr)->__absyn), abr);
1868
1869 abSetPos(abl, abPos(tfGetExpr(tfl)))((abl)->abHdr.pos=spstackSetFirst ((abl)->abHdr.pos,((spstackFirst
((((tfl)->__absyn))->abHdr.pos)))))
;
1870 abSetPos(abr, abPos(tfGetExpr(tfr)))((abr)->abHdr.pos=spstackSetFirst ((abr)->abHdr.pos,((spstackFirst
((((tfr)->__absyn))->abHdr.pos)))))
;
1871
1872 if (abState(ab)((ab)->abHdr.state) != AB_State_HasUnique) {
1873 abTUnique(ab)((ab)->abHdr.type.unique) = tfType;
1874 abState(ab)((ab)->abHdr.state) = AB_State_HasUnique;
1875 }
1876 tiTfMeaning1(stab, tf);
1877
1878 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfUnknown1", NULL((void*)0), tf);
1879}
1880
1881/* Convert syntax tforms to pending tforms. */
1882localstatic void
1883tiTfPending1(Stab stab, TForm tf)
1884{
1885 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfPending1", NULL((void*)0), tf);
1886 tfPendingFrSyntax(stab, tfGetExpr(tf)((tf)->__absyn), tf);
1887 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfPending1", NULL((void*)0), tf);
1888}
1889
1890localstatic AbLogic tiTfCondition(Stab stab, TForm tf);
1891/* Perform bottom-up analysis to generate tposs sets. */
1892localstatic void
1893tiTfBottomUp1(Stab stab, TFormUses tfu, TForm tf)
1894{
1895 Scope("tiTfBottomUp1")String scopeName = ("tiTfBottomUp1"); int fluidLevel0 = (scopeLevel
++, fluidLevel)
;
1896 SymbolList ol = listNil(Symbol)((SymbolList) 0);
1897 AbSyn absyn = tfGetExpr(tf)((tf)->__absyn);
1898 TForm type = tfTypeTuple;
1899 AbLogic fluid(abCondKnown)fluidSave_abCondKnown = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(abCondKnown
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_abCondKnown
, fluidStack[fluidLevel].size = sizeof(abCondKnown), fluidLevel
++, (abCondKnown) )
;
1900
1901 abCondKnown = tiTfCondition(stab, tf);
1902
1903 if (abUse(absyn)((absyn)->abHdr.use) == AB_Use_Define || abUse(absyn)((absyn)->abHdr.use) == AB_Use_Assign)
1904 type = tfUnknown;
1905 else if (abUse(absyn)((absyn)->abHdr.use) == AB_Use_Except)
1906 type = tfTuple(tfCategory);
1907
1908 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfBottomUp1", tfu, tf);
1909 ol = tiTfPushDeclarees(tiTfGetDeclarees(tfu));
1910 tiBottomUp(stab, absyn, type);
1911 tiTfPopDeclarees(ol);
1912 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfBottomUp1", tfu, tf);
1913
1914 Return(Nothing){ fluidUnwind(fluidLevel0, ((int) 0)); return ;; };
1915}
1916
1917localstatic AbLogic
1918tiTfCondition(Stab stab, TForm tf)
1919{
1920 Scope("tiTfCondition")String scopeName = ("tiTfCondition"); int fluidLevel0 = (scopeLevel
++, fluidLevel)
;
1921 AbSynList condition = tfConditionalAbSyn(tf);
1922 AbSyn absyn = tfGetExpr(tf)((tf)->__absyn);
1923 AbLogic rule = ablogTrue();
1924 AbLogic fluid(abCondKnown)fluidSave_abCondKnown = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(abCondKnown
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_abCondKnown
, fluidStack[fluidLevel].size = sizeof(abCondKnown), fluidLevel
++, (abCondKnown) )
;
1925
1926 while (condition != listNil(AbSyn)((AbSynList) 0)) {
1927 Stab cstab = stab;/*tfConditionalStab(tf);*/
1928 AbSyn ab = car(condition)((condition)->first);
1929
1930 assert(cstab != NULL)do { if (!(cstab != ((void*)0))) _do_assert(("cstab != NULL")
,"tinfer.c",1930); } while (0)
;
1931 if (DEBUG(titf)titfDebug) {
1932 afprintf(dbOut, "Condition: ");
1933 abPrintDb(car(condition)((condition)->first));
1934 }
1935 if (abContains(ab, absyn)) {
1936 condition = cdr(condition)((condition)->rest);
1937 continue;
1938 }
1939 abCondKnown = rule;
1940 tiBottomUp(cstab, ab, tfUnknown);
1941 tiTopDown (cstab, ab, tfUnknown);
1942 rule = ablogAnd(rule, ablogFrSefo(ab));
1943 condition = cdr(condition)((condition)->rest);
1944 }
1945 TfCond conds = tfConditions(tf);
1946
1947 Return(rule){ fluidUnwind(fluidLevel0, ((int) 0)); return rule;; };
1948}
1949
1950/* Audit the bottom-up type analysis phase. */
1951localstatic void
1952tiTfAudit1(Stab stab, TForm tf)
1953{
1954 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfAudit1", NULL((void*)0), tf);
1955 typeInferAudit(stab, tfGetExpr(tf)((tf)->__absyn));
1956 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfAudit1", NULL((void*)0), tf);
1957}
1958
1959/* Perform top-down analysis to generate semantics for each AbSyn. */
1960localstatic void
1961tiTfTopDown1(Stab stab, TForm tf)
1962{
1963 Scope("tiTfTopDown1")String scopeName = ("tiTfTopDown1"); int fluidLevel0 = (scopeLevel
++, fluidLevel)
;
1964 AbSyn absyn = tfGetExpr(tf)((tf)->__absyn);
1965 TForm type = tfTypeTuple;
1966 AbLogic fluid(abCondKnown)fluidSave_abCondKnown = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(abCondKnown
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_abCondKnown
, fluidStack[fluidLevel].size = sizeof(abCondKnown), fluidLevel
++, (abCondKnown) )
;
1967
1968 abCondKnown = tiTfCondition(stab, tf);
1969
1970 if (abUse(absyn)((absyn)->abHdr.use) == AB_Use_Define || abUse(absyn)((absyn)->abHdr.use) == AB_Use_Assign)
1971 type = tfUnknown;
1972 else if (abUse(absyn)((absyn)->abHdr.use) == AB_Use_Except)
1973 type = tfTuple(tfCategory);
1974
1975 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfTopDown1", NULL((void*)0), tf);
1976 tiTopDown(stab, absyn, type);
1977 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfTopDown1", NULL((void*)0), tf);
1978
1979 Return(Nothing){ fluidUnwind(fluidLevel0, ((int) 0)); return ;; };
1980}
1981
1982/* Convert the pending type forms to full type forms. */
1983localstatic void
1984tiTfMeaning1(Stab stab, TForm tf)
1985{
1986 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfMeaning1", NULL((void*)0), tf);
1987 tfMeaning(stab, tfGetExpr(tf)((tf)->__absyn), tf);
1988 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfMeaning1", NULL((void*)0), tf);
1989}
1990
1991/* Fill the extension type using the type form as the type of an extendee. */
1992localstatic void
1993tiTfExtend1(Stab stab, TFormUses tfu)
1994{
1995 AbSynList alist;
1996
1997 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfExtend1", tfu, tfu->tf);
1998
1999 for (alist = tfu->extendees; alist; alist = cdr(alist)((alist)->rest)) {
2000 AbSyn ab = car(alist)((alist)->first), abt;
2001 Syme syme = abSyme(ab)((ab)->abHdr.seman ? (ab)->abHdr.seman->syme : 0), osyme = NULL((void*)0);
2002 Syme extension = symeExtension(syme);
2003 TForm tf = symeType(extension);
2004 TFormUses tu0;
2005
2006 titfOneDEBUGif (!titfOneDebug) { } else afprintf(dbOut, "Syme: %pSyme TForm: %pTForm\n", syme, tf);
2007
2008 assert(ab && abHasTag(ab, AB_Id))do { if (!(ab && ((ab)->abHdr.tag == (AB_Id)))) _do_assert
(("ab && abHasTag(ab, AB_Id)"),"tinfer.c",2008); } while
(0)
;
2009 assert(syme && symeIsExport(syme))do { if (!(syme && (((((syme)->kind == SYME_Trigger
? libGetAllSymes((syme)->lib) : ((void*)0)), (syme))->
kind) == SYME_Export))) _do_assert(("syme && symeIsExport(syme)"
),"tinfer.c",2009); } while (0)
;
2010 assert(extension && symeIsExtend(extension))do { if (!(extension && (((((extension)->kind == SYME_Trigger
? libGetAllSymes((extension)->lib) : ((void*)0)), (extension
))->kind) == SYME_Extend))) _do_assert(("extension && symeIsExtend(extension)"
),"tinfer.c",2010); } while (0)
;
2011 assert(listMemq(Syme)(symeExtendee(extension), syme))do { if (!((Syme_listPointer->Memq)(symeExtendee(extension
), syme))) _do_assert(("listMemq(Syme)(symeExtendee(extension), syme)"
),"tinfer.c",2011); } while (0)
;
2012
2013 if (tfIsExtendTemplate(tf)) {
2014 SymeList extendee = symeExtendee(extension);
2015 Length argc = listLength(Syme)(Syme_listPointer->_Length)(extendee);
2016
2017 osyme = tiGetExtendee(stab, ab, tf);
2018 if (osyme == NULL((void*)0)) continue;
2019
2020 tf = tfExtendEmpty(tf, argc + 1);
2021 symeSetType(extension, tf);
2022
2023 tfExtendFill(tf, tfExtendNext(tf), symeType(osyme));
2024 symeAddExtendee(extension, osyme);
2025 symeSetExtension(osyme, extension)symeXSetExtension(osyme, (AInt) extension);
2026 }
2027
2028 symeSetExtension(syme, NULL)symeXSetExtension(syme, (AInt) ((void*)0));
2029
2030 tfExtendFill(tf, tfExtendNext(tf), symeType(syme));
2031
2032 abt = tfGetExpr(symeType(syme))((symeType(syme))->__absyn);
2033 tu0 = stabFindTFormUses(stab, abt);
2034 abt = tu0 && tu0->extension ? car(tu0->extension)((tu0->extension)->first) : NULL((void*)0);
2035 if (abt && osyme && abIsId(abt)((abt)->abHdr.tag == (AB_Id)) && abSyme(abt)((abt)->abHdr.seman ? (abt)->abHdr.seman->syme : 0) == osyme) {
2036 abState(abt)((abt)->abHdr.state) = AB_State_AbSyn;
2037 typeInferAs(stab, abt, tfType);
2038 }
2039
2040 symeSetExtension(syme, extension)symeXSetExtension(syme, (AInt) extension);
2041
2042 if (tfExtendDone(tf)(tfExtendNext(tf) == (((((tf)->tag) == TF_Map) || (((tf)->
tag) == TF_PackedMap)) ? ((tfFollowArg(tf, 1))->argc) : ((
tf)->argc)))
) {
2043 if (DEBUG(tipExtend)tipExtendDebug) {
2044 fprintf(dbOut, "titfExtend1:\n");
2045 symePrint(dbOut, extension);
2046 fnewline(dbOut);
2047 }
2048 tfExtendSubst(stab, tf);
2049 tfExtendFinish(tf);
2050 stabExtendMeanings(stab, extension);
2051 }
2052 }
2053
2054 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfExtend1", tfu, tfu->tf);
2055}
2056
2057localstatic void
2058typeInferTFormList(Stab stab, TFormList tfl)
2059{
2060 for (; tfl; tfl = cdr(tfl)((tfl)->rest)) {
2061 TForm tf = car(tfl)((tfl)->first);
2062 if (tfIsJoin(tf)(((tf)->tag) == TF_Join)) {
2063 Length i;
2064 for (i = 0; i < tfJoinArgc(tf)((tf)->argc); i += 1)
2065 typeInferTForm(stab, tfJoinArgN(tf, i)tfFollowArg(tf, i));
2066 tfSetMeaningArgs(tf);
2067 assert(tfIsMeaning(tf))do { if (!((((tf)->state)>=TF_State_Meaning))) _do_assert
(("tfIsMeaning(tf)"),"tinfer.c",2067); } while (0)
;
2068 }
2069 else
2070 typeInferTForm(stab, tf);
2071 }
2072}
2073
2074/* Import the exports from each type form. */
2075localstatic void
2076tiTfImport1(Stab stab, TFormUses tfu)
2077{
2078 Scope("tiTfImport1")String scopeName = ("tiTfImport1"); int fluidLevel0 = (scopeLevel
++, fluidLevel)
;
2079 AbLogic fluid(abCondKnown)fluidSave_abCondKnown = ( fluidStack = (fluidLevel==fluidLimit
) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName
= scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel,
fluidStack[fluidLevel].pglobal = (Pointer) &(abCondKnown
), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_abCondKnown
, fluidStack[fluidLevel].size = sizeof(abCondKnown), fluidLevel
++, (abCondKnown) )
;
2080
2081 TForm tf = tfFollow(tfu->tf)((tfu->tf) = tfFollowFn(tfu->tf));
2082 abCondKnown = tiTfCondition(stab, tf);
2083
2084 tiTfEnterDb(titfOne)if (titfOneDebug) tiTfEnter(dbOut, "tiTfImport1", tfu, tf);
2085
2086 if (tiTfDoingDefault == DEF_State_NotYet )
2087 Return(Nothing){ fluidUnwind(fluidLevel0, ((int) 0)); return ;; };
2088
2089 if (tfu->exports)
2090 typeInferTFormList(stab, tqQual(tfu->exports)((tfu->exports)->qual));
2091
2092 if (tqShouldImport(tfu->imports)) {
2093 TQualList cascades;
2094 typeInferTFormList(stab, tqQual(tfu->imports)((tfu->imports)->qual));
2095
2096 if (tfQueries(tf)((tf)->queries))
2097 typeInferTFormList(stab, tfQueries(tf)((tf)->queries));
2098
2099 cascades = stabImportFrom(stab, tfu->imports);
2100
2101 if (tfu != NULL((void*)0))
2102 tfu->cascades = cascades;
2103 else
2104 tiTfImportCascades(stab, cascades);
2105 }
2106 else if (tfu->isCategoryImport)
2107 tiWithSymes(stab, tf);
2108 else if (tfu->isCatConditionImport) {
2109 Syme self;
2110 Stab sstab = stab;
2111 TForm cond;
2112 assert(sstab)do { if (!(sstab)) _do_assert(("sstab"),"tinfer.c",2112); } while
(0)
; /* -- MND -- */
2113 self = NULL((void*)0); /* Avoid uninitialized msg */
2114 while ( sstab && (self = stabGetSelf(sstab)) == NULL((void*)0))
2115 sstab = cdr(sstab)((sstab)->rest);
2116 cond = tfIf(tfHas(self, tf), tf, tfNone()tfMulti(0));
2117 tfSetMeaning(cond)(((cond)->state)=TF_State_Meaning);
2118 tiWithSymes(stab, cond);
2119 }
2120 else if (tfu->isExplicitImport) {
2121 String s = tfPretty(tf);
2122 comsgWarning(abNewNothing(car(stab)->spos)abNew(AB_Nothing, ((stab)->first)->spos,0 ), ALDOR_W_StabNotImporting142, s);
2123 strFree(s);
2124 }
2125
2126 tiTfExitDb(titfOne)if (titfOneDebug) tiTfExit(dbOut, "tiTfImport1", tfu, tf);
2127 Return(Nothing){ fluidUnwind(fluidLevel0, ((int) 0)); return ;; };
2128}
2129
2130void
2131tiTfCascades1(Stab stab, TFormUses tfu)
2132{
2133 tiTfImportCascades(stab, tfu->cascades);
2134}
2135
2136void
2137tiTfImportCascades(Stab stab, TQualList list)
2138{
2139 TQualList ql;
2140
2141 for (ql = list; ql; ql = cdr(ql)((ql)->rest)) {
2142 TQual innerTq = car(ql)((ql)->first);
2143 if (!tqShouldImport(innerTq))
2144 continue;
2145 if (tqIsQualified(innerTq)((innerTq)->isQual == 1)) {
2146 stabImportFrom(stab, innerTq);
2147 }
2148 else {
2149 TQualList moreImports;
2150 TForm innerTf = tqBase(innerTq)((innerTq)->base);
2151 TForm tf = stabFindOuterTForm(stab, tfExpr(innerTf)tfToAbSyn(innerTf));
2152 if (tf != NULL((void*)0)) {
2153 tf = typeInferTForm(stab, tf);
2154 if (tfQueries(tf)((tf)->queries))
2155 typeInferTFormList(stab, tfQueries(tf)((tf)->queries));
2156
2157 innerTf = tf;
2158 }
2159 innerTq = tqNewUnqualified(innerTf);
2160 moreImports = stabImportFrom(stab, innerTq);
2161 ql = listNConcat(TQual)(TQual_listPointer->NConcat)(ql, listCopy(TQual)(TQual_listPointer->Copy)(moreImports));
2162 tqFree(innerTq);
2163 }
2164 }
2165}
2166
2167
2168/* Type infer the default clauses for each type form. */
2169localstatic void
2170tiTfDefault1(Stab stab, Sefo sefo)
2171{
2172 if (abStab(sefo)((sefo)->abHdr.seman ? (sefo)->abHdr.seman->stab : 0
)
)
2173 stab = abStab(sefo)((sefo)->abHdr.seman ? (sefo)->abHdr.seman->stab : 0
)
;
2174
2175 if (abTag(sefo)((sefo)->abHdr.tag) == AB_Default) {
2176 abState(sefo)((sefo)->abHdr.state) = AB_State_AbSyn;
2177 typeInferAs(stab, sefo, tfUnknown);
2178 }
2179 else if (!abIsLeaf(sefo)(((sefo)->abHdr.tag) < AB_NODE_START)) {
2180 Length i;
2181 for (i = 0; i < abArgc(sefo)((sefo)->abHdr.argc); i += 1)
2182 tiTfDefault1(stab, abArgv(sefo)((sefo)->abGen.data.argv)[i]);
2183 }
2184}
2185
2186/*****************************************************************************
2187 *
2188 * :: typeInferTForms topological sorting
2189 *
2190 ****************************************************************************/
2191
2192localstatic Table
2193tiTfGetDeclareeTable(TFormUsesList tful0)
2194{
2195 Table tbl = tblNew((TblHashFun) 0, (TblEqFun) 0);
2196 TFormUsesList tful, tfl;
2197
2198 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2199 TFormUses tfu = car(tful)((tful)->first);
2200 SymbolList dl = tfu->declarees;
2201
2202 for (; dl; dl = cdr(dl)((dl)->rest)) {
2203 tfl = (TFormUsesList) tblElt(tbl, car(dl)((dl)->first),
2204 listNil(TFormUses)((TFormUsesList) 0));
2205 tblSetElt(tbl, car(dl)((dl)->first), listCons(TFormUses)(TFormUses_listPointer->Cons)(tfu, tfl));
2206 }
2207 }
2208
2209 if (DEBUG(titf)titfDebug) {
2210 fprintf(dbOut, ">>tiTfGetDeclareeTable:\n");
2211 tblPrint(dbOut, tbl, (TblPrKeyFun) symPrint,
2212 (TblPrEltFun) tfulPrint);
2213 fnewline(dbOut);
2214 }
2215
2216 return tbl;
2217}
2218
2219localstatic void
2220tiTfFreeDeclareeTable(Table tbl)
2221{
2222 tblFreeDeeply(tbl,
2223 (TblFreeKeyFun) 0, (TblFreeEltFun) listFree(TFormUses)(TFormUses_listPointer->Free));
2224}
2225
2226localstatic void
2227tiTfCollectHasDependees(TFormUsesList tful, TFormUses S)
2228{
2229 TFormList hl;
2230
2231 for (hl = tfQueries(S->tf)((S->tf)->queries); hl; hl = cdr(hl)((hl)->rest)) {
2232 TForm cat = car(hl)((hl)->first);
2233 TFormUsesList tfl;
2234 for (tfl = tful; tfl; tfl = cdr(tfl)((tfl)->rest))
2235 if (cat == car(tfl)((tfl)->first)->tf)
2236 tiTfAddDependee(S, car(tfl)((tfl)->first));
2237 }
2238}
2239
2240localstatic void
2241tiTfCollectDependees(Table tbl, TFormUses S, TForm tf)
2242{
2243 Symbol sym = tiTfUsesSymbol(S);
2244 AbSynList al, l;
2245
2246 if (sym && tfIsCategoryMap(tf))
2247 tiTfCollectSymDependees(tbl, S, sym);
2248 for (al = S->extendees; al; al = cdr(al)((al)->rest))
2249 tiTfCollectSefoDependees(tbl, S, car(al)((al)->first));
2250 tiTfCollectSefoDependees(tbl, S, tfGetExpr(tf)((tf)->__absyn));
2251 l = tfConditionalAbSyn(tf);
2252 while (l != listNil(AbSyn)((AbSynList) 0)) {
2253 tiTfCollectSefoDependees(tbl, S, car(l)((l)->first));
2254 l = cdr(l)((l)->rest);
2255 }
2256}
2257
2258localstatic void
2259tiTfCollectSefoDependees(Table tbl, TFormUses S, Sefo sefo)
2260{
2261 if (abIsStrTag(abTag(sefo))( AB_STR_START <= (((sefo)->abHdr.tag)) && (((sefo
)->abHdr.tag)) < AB_STR_LIMIT)
) {
2262 Symbol sym = NULL((void*)0);
2263
2264 if (abTag(sefo)((sefo)->abHdr.tag) == AB_LitInteger)
2265 sym = ssymTheInteger;
2266 else if (abTag(sefo)((sefo)->abHdr.tag) == AB_LitString)
2267 sym = ssymTheString;
2268 else if (abTag(sefo)((sefo)->abHdr.tag) == AB_LitFloat)
2269 sym = ssymTheFloat;
2270
2271 assert(sym)do { if (!(sym)) _do_assert(("sym"),"tinfer.c",2271); } while
(0)
;
2272 tiTfCollectSymDependees(tbl, S, sym);
2273 }
2274
2275 else if (abIsSymTag(abTag(sefo))( (((sefo)->abHdr.tag)) < AB_SYM_LIMIT))
2276 tiTfCollectSymDependees(tbl, S, abLeafSym(sefo)((sefo)->abGen.data.sym));
2277
2278 else if (tiTfDoDefault(sefo)) {
2279 Length i;
2280 for (i = 0; i < abArgc(sefo)((sefo)->abHdr.argc); i += 1)
2281 tiTfCollectSefoDependees(tbl, S, abArgv(sefo)((sefo)->abGen.data.argv)[i]);
2282 }
2283}
2284
2285localstatic void
2286tiTfCollectSymDependees(Table tbl, TFormUses S, Symbol sym)
2287{
2288 TFormUsesList tfl;
2289
2290 tfl = (TFormUsesList) tblElt(tbl, sym, listNil(TFormUses)((TFormUsesList) 0));
2291 for (; tfl; tfl = cdr(tfl)((tfl)->rest))
2292 tiTfAddDependee(S, car(tfl)((tfl)->first));
2293}
2294
2295localstatic void
2296tiTfAddDependee(TFormUses S, TFormUses T)
2297{
2298 /* T must be type analyzed before S. */
2299 if (S != T && !listMemq(TFormUses)(TFormUses_listPointer->Memq)(S->dependees, T)) {
2300 listPush(TFormUses, T, S->dependees)(S->dependees = (TFormUses_listPointer->Cons)(T, S->
dependees))
;
2301 listPush(TFormUses, S, T->dependents)(T->dependents = (TFormUses_listPointer->Cons)(S, T->
dependents))
;
2302 T->nafter += 1;
2303 S->nbefore += 1;
2304 }
2305}
2306
2307localstatic void
2308tiTfFreeDependees(TFormUsesList tful0)
2309{
2310 TFormUsesList tful;
2311
2312 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2313 TFormUses tfu = car(tful)((tful)->first);
2314
2315 listFree(TFormUses)(TFormUses_listPointer->Free)(tfu->dependents);
2316 listFree(TFormUses)(TFormUses_listPointer->Free)(tfu->dependees);
2317
2318 tfu->nbefore = 0;
2319 tfu->nafter = 0;
2320 tfu->dependents = listNil(TFormUses)((TFormUsesList) 0);
2321 tfu->dependees = listNil(TFormUses)((TFormUsesList) 0);
2322 }
2323}
2324
2325localstatic void
2326tiTfFreeCDependees(TFormUsesList tful0)
2327{
2328 TFormUsesList tful;
2329
2330 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2331 TFormUses tfu = car(tful)((tful)->first);
2332
2333 listFree(TFormUses)(TFormUses_listPointer->Free)(tfu->cdependents);
2334 listFree(TFormUses)(TFormUses_listPointer->Free)(tfu->cdependees);
2335
2336 tfu->ncbefore = 0;
2337 tfu->ncafter = 0;
2338 tfu->cdependents= listNil(TFormUses)((TFormUsesList) 0);
2339 tfu->cdependees = listNil(TFormUses)((TFormUsesList) 0);
2340 }
2341}
2342
2343localstatic TFormUsesList
2344tiTopForward(TFormUsesList tful0)
2345{
2346 TFormUsesList tful;
2347
2348 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2349 TFormUses tfu = car(tful)((tful)->first);
2350 tfu->inDegree = tfu->nbefore;
2351 tfu->outEdges = tfu->dependents;
2352 assert(tfu->nbefore == listLength(TFormUses)(tfu->dependees))do { if (!(tfu->nbefore == (TFormUses_listPointer->_Length
)(tfu->dependees))) _do_assert(("tfu->nbefore == listLength(TFormUses)(tfu->dependees)"
),"tinfer.c",2352); } while (0)
;
2353 assert(tfu->nafter == listLength(TFormUses)(tfu->dependents))do { if (!(tfu->nafter == (TFormUses_listPointer->_Length
)(tfu->dependents))) _do_assert(("tfu->nafter == listLength(TFormUses)(tfu->dependents)"
),"tinfer.c",2353); } while (0)
;
2354 }
2355
2356 return tiTopSort(tful0);
2357}
2358
2359localstatic TFormUsesList
2360tiTopReverse(TFormUsesList tful0)
2361{
2362 TFormUsesList tful;
2363
2364 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2365 TFormUses tfu = car(tful)((tful)->first);
2366 tfu->inDegree = tfu->nafter;
2367 tfu->outEdges = tfu->dependees;
2368 assert(tfu->nbefore == listLength(TFormUses)(tfu->dependees))do { if (!(tfu->nbefore == (TFormUses_listPointer->_Length
)(tfu->dependees))) _do_assert(("tfu->nbefore == listLength(TFormUses)(tfu->dependees)"
),"tinfer.c",2368); } while (0)
;
2369 assert(tfu->nafter == listLength(TFormUses)(tfu->dependents))do { if (!(tfu->nafter == (TFormUses_listPointer->_Length
)(tfu->dependents))) _do_assert(("tfu->nafter == listLength(TFormUses)(tfu->dependents)"
),"tinfer.c",2369); } while (0)
;
2370 }
2371
2372 return listNReverse(TFormUses)(TFormUses_listPointer->NReverse)(tiTopSort(tful0));
2373}
2374
2375localstatic TFormUsesList
2376tiTopCForward(TFormUsesList tful0)
2377{
2378 TFormUsesList tful;
2379
2380 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2381 TFormUses tfu = car(tful)((tful)->first);
2382 tfu->inDegree = tfu->ncbefore;
2383 tfu->outEdges = tfu->cdependents;
2384 assert(tfu->ncbefore==listLength(TFormUses)(tfu->cdependees))do { if (!(tfu->ncbefore==(TFormUses_listPointer->_Length
)(tfu->cdependees))) _do_assert(("tfu->ncbefore==listLength(TFormUses)(tfu->cdependees)"
),"tinfer.c",2384); } while (0)
;
2385 assert(tfu->ncafter==listLength(TFormUses)(tfu->cdependents))do { if (!(tfu->ncafter==(TFormUses_listPointer->_Length
)(tfu->cdependents))) _do_assert(("tfu->ncafter==listLength(TFormUses)(tfu->cdependents)"
),"tinfer.c",2385); } while (0)
;
2386 }
2387
2388 return tiTopSort(tful0);
2389}
2390
2391localstatic TFormUsesList
2392tiTopCReverse(TFormUsesList tful0)
2393{
2394 TFormUsesList tful;
2395
2396 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2397 TFormUses tfu = car(tful)((tful)->first);
2398 tfu->inDegree = tfu->ncafter;
2399 tfu->outEdges = tfu->cdependees;
2400 assert(tfu->ncbefore==listLength(TFormUses)(tfu->cdependees))do { if (!(tfu->ncbefore==(TFormUses_listPointer->_Length
)(tfu->cdependees))) _do_assert(("tfu->ncbefore==listLength(TFormUses)(tfu->cdependees)"
),"tinfer.c",2400); } while (0)
;
2401 assert(tfu->ncafter==listLength(TFormUses)(tfu->cdependents))do { if (!(tfu->ncafter==(TFormUses_listPointer->_Length
)(tfu->cdependents))) _do_assert(("tfu->ncafter==listLength(TFormUses)(tfu->cdependents)"
),"tinfer.c",2401); } while (0)
;
2402 }
2403
2404 return tiTopSort(tful0);
2405}
2406
2407/* Use tfu->inDegree and tfu->outEdges to perform a topological sort. */
2408localstatic TFormUsesList
2409tiTopSort(TFormUsesList tful0)
2410{
2411 TFormUsesList tful, stack, result;
2412
2413 /* tful collects the type forms which can now be first. */
2414 stack = listNil(TFormUses)((TFormUsesList) 0);
2415 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest))
2416 if (car(tful)((tful)->first)->inDegree == 0)
2417 stack = listCons(TFormUses)(TFormUses_listPointer->Cons)(car(tful)((tful)->first), stack);
2418
2419 result = listNil(TFormUses)((TFormUsesList) 0);
2420 while (stack) {
2421 /* Pop the next type form to be processed. */
2422 TFormUses next = car(stack)((stack)->first);
2423 stack = listFreeCons(TFormUses)(TFormUses_listPointer->FreeCons)(stack);
2424
2425 assert(next->inDegree == 0)do { if (!(next->inDegree == 0)) _do_assert(("next->inDegree == 0"
),"tinfer.c",2425); } while (0)
;
2426 if (next->sortMark == false((int) 0)) {
2427 result = listCons(TFormUses)(TFormUses_listPointer->Cons)(next, result);
2428 next->sortMark = true1;
2429 }
2430
2431 /* Unmark the type forms which depend on next. */
2432 for (tful = next->outEdges; tful; tful = cdr(tful)((tful)->rest)) {
2433 TFormUses tfu = car(tful)((tful)->first);
2434
2435 /* Assert that tfu is not yet on the list. */
2436 assert (tfu->inDegree > 0)do { if (!(tfu->inDegree > 0)) _do_assert(("tfu->inDegree > 0"
),"tinfer.c",2436); } while (0)
;
2437
2438 /* If all of the type forms on which tfu depends
2439 * have been processed, then tfu can be next.
2440 */
2441 if ((tfu->inDegree -= 1) == 0)
2442 stack = listCons(TFormUses)(TFormUses_listPointer->Cons)(tfu, stack);
2443 }
2444 }
2445
2446 result = listNReverse(TFormUses)(TFormUses_listPointer->NReverse)(result);
2447 return result;
2448}
2449
2450localstatic TFormUsesList
2451tiTopCycle(TFormUsesList tful0)
2452{
2453 TFormUsesList tful, cycle;
2454
2455 /* Collect any type forms which participate in a cycle. */
2456 cycle = listNil(TFormUses)((TFormUsesList) 0);
2457 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2458 TFormUses tfu = car(tful)((tful)->first);
2459 if (tfu->sortMark == false((int) 0))
2460 cycle = listCons(TFormUses)(TFormUses_listPointer->Cons)(tfu, cycle);
2461
2462 tfu->sortMark = false((int) 0);
2463 tfu->inDegree = 0;
2464 tfu->outEdges = listNil(TFormUses)((TFormUsesList) 0);
2465 }
2466
2467 cycle = listNReverse(TFormUses)(TFormUses_listPointer->NReverse)(cycle);
2468 return cycle;
2469}
2470
2471/*****************************************************************************
2472 *
2473 * :: tiTopClique
2474 *
2475 ****************************************************************************/
2476
2477/* Topologically sort the cliques in the graph. */
2478localstatic TFormUsesList
2479tiTopClique(TFormUsesList tful0)
2480{
2481 TFormUsesList tful, tfl, graph, result;
2482
2483 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, NULL((void*)0), ">>tiTopClique:", tful0);
2484
2485 /* Mark the nodes in the clique graph without adding their edges. */
2486 tiTopCliqueMark(tful0, true1);
2487
2488 /* For each vertex, add the edges and sort to find the cliques. */
2489 graph = listCopy(TFormUses)(TFormUses_listPointer->Copy)(tful0);
2490 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2491 TFormUses tfu = car(tful)((tful)->first), crep;
2492 TFormUsesList before, after, cycle;
2493
2494 /* Add the edges of V to the clique graph. */
2495 tiTopCliqueAddVertex(tfu);
2496
2497 /* Perform a topological sort on the graph. */
2498 before = tiTopCForward (graph);
2499 after = tiTopCReverse (graph);
2500 cycle = tiTopCycle (graph);
2501
2502 if (cycle) {
2503 /* Remove the cycle from the graph. */
2504 for (tfl = cycle; tfl; tfl = cdr(tfl)((tfl)->rest))
2505 listPop(TFormUses,car(tfl),graph,tiTopEqual)(graph = (TFormUses_listPointer->NRemove)(graph, ((tfl)->
first), tiTopEqual))
;
2506
2507 /* Mark the cycle as part of the same clique. */
2508 crep = tiTopCliqueUnion(cycle);
2509 listPush(TFormUses, crep, graph)(graph = (TFormUses_listPointer->Cons)(crep, graph));
2510 }
2511
2512 listFree(TFormUses)(TFormUses_listPointer->Free)(before);
2513 listFree(TFormUses)(TFormUses_listPointer->Free)(after);
2514 listFree(TFormUses)(TFormUses_listPointer->Free)(cycle);
2515 }
2516
2517 /* Topologically sort the final clique graph. */
2518 result = tiTopCForward(graph);
2519
2520 /* Free the clique graph. */
2521 tiTfFreeCDependees(tful0);
2522
2523 /* Collect the cliques on their canonical representative. */
2524 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2525 TFormUses tfu = car(tful)((tful)->first);
2526 TFormUses crep = tiTopCliqueRep(tfu);
2527 listPush(TFormUses, tfu, crep->cdependents)(crep->cdependents = (TFormUses_listPointer->Cons)(tfu,
crep->cdependents))
;
2528 }
2529 for (tful = result; tful; tful = cdr(tful)((tful)->rest)) {
2530 TFormUses tfu = car(tful)((tful)->first);
2531 tfu->cdependents = listNReverse(TFormUses)(TFormUses_listPointer->NReverse)(tfu->cdependents);
2532 }
2533 tiTopCliqueMark(tful0, false((int) 0));
2534
2535 tiTfPrintDb(titf)if (titfDebug) tiTfPrint(dbOut, NULL((void*)0), "<<tiTopClique:", result);
2536
2537 return result;
2538}
2539
2540localstatic TFormUses
2541tiTopCliqueUnion(TFormUsesList cycle)
2542{
2543 TFormUsesList tful;
2544 TFormUses nrep = car(cycle)((cycle)->first);
2545
2546 /* Mark the nodes in the cycle with a new canonical representative. */
2547 for (tful = cdr(cycle)((cycle)->rest); tful; tful = cdr(tful)((tful)->rest)) {
2548 TFormUses tfu = car(tful)((tful)->first);
2549 assert(tfu->crep == NULL)do { if (!(tfu->crep == ((void*)0))) _do_assert(("tfu->crep == NULL"
),"tinfer.c",2549); } while (0)
;
2550 tfu->crep = nrep;
2551 }
2552
2553 /* Move edges to the new canonical representative. */
2554 for (tful = cdr(cycle)((cycle)->rest); tful; tful = cdr(tful)((tful)->rest))
2555 tiTopCliqueAddCVertex(car(tful)((tful)->first));
2556
2557 /* Delete edges to non-canonical nodes. */
2558 for (tful = cycle; tful; tful = cdr(tful)((tful)->rest))
2559 tiTopCliqueDelCVertex(car(tful)((tful)->first));
2560
2561 return nrep;
2562}
2563
2564localstatic TFormUses
2565tiTopCliqueRep(TFormUses S)
2566{
2567 if (S->crep) {
2568 S->crep = tiTopCliqueRep(S->crep);
2569 return S->crep;
2570 }
2571 else
2572 return S;
2573}
2574
2575localstatic void
2576tiTopCliqueMark(TFormUsesList tful0, Bool mark)
2577{
2578 TFormUsesList tful;
2579
2580 for (tful = tful0; tful; tful = cdr(tful)((tful)->rest)) {
2581 TFormUses tfu = car(tful)((tful)->first);
2582 tfu->sortMark = false((int) 0);
2583 tfu->cmarked = true1;
2584 tfu->crep = NULL((void*)0);
2585 }
2586}
2587
2588localstatic void
2589tiTopCliqueAddVertex(TFormUses S)
2590{
2591 TFormUsesList tful;
2592
2593 for (tful = S->dependees; tful; tful = cdr(tful)((tful)->rest))
2594 tiTopCliqueAddEdge(car(tful)((tful)->first), S);
2595
2596 for (tful = S->dependents; tful; tful = cdr(tful)((tful)->rest))
2597 tiTopCliqueAddEdge(S, car(tful)((tful)->first));
2598}
2599
2600localstatic void
2601tiTopCliqueAddCVertex(TFormUses S)
2602{
2603 TFormUsesList tful;
2604
2605 for (tful = S->cdependees; tful; tful = cdr(tful)((tful)->rest))
2606 tiTopCliqueAddEdge(car(tful)((tful)->first), S);
2607
2608 for (tful = S->cdependents; tful; tful = cdr(tful)((tful)->rest))
2609 tiTopCliqueAddEdge(S, car(tful)((tful)->first));
2610}
2611
2612localstatic void
2613tiTopCliqueDelCVertex(TFormUses S)
2614{
2615 TFormUsesList tful;
2616
2617 for (tful = S->cdependees; tful; ) {
2618 TFormUses tfu = car(tful)((tful)->first);
2619 tful = cdr(tful)((tful)->rest); /* cdr before delete */
2620 tiTopCliqueDelEdge(tfu, S);
2621 }
2622
2623 for (tful = S->cdependents; tful; ) {
2624 TFormUses tfu = car(tful)((tful)->first);
2625 tful = cdr(tful)((tful)->rest); /* cdr before delete */
2626 tiTopCliqueDelEdge(S, tfu);
2627 }
2628}
2629
2630/* Add an edge from S to T to the clique graph. */
2631localstatic void
2632tiTopCliqueAddEdge(TFormUses S, TFormUses T)
2633{
2634 S = tiTopCliqueRep(S);
2635 T = tiTopCliqueRep(T);
2636
2637 if (S == T) return;
2638 if (S->cmarked == false((int) 0) || T->cmarked == false((int) 0)) return;
2639 if (listMemq(TFormUses)(TFormUses_listPointer->Memq)(S->cdependents, T)) return;
2640 assert(!listMemq(TFormUses)(T->cdependees, S))do { if (!(!(TFormUses_listPointer->Memq)(T->cdependees
, S))) _do_assert(("!listMemq(TFormUses)(T->cdependees, S)"
),"tinfer.c",2640); } while (0)
;
2641
2642 listPush(TFormUses, T, S->cdependents)(S->cdependents = (TFormUses_listPointer->Cons)(T, S->
cdependents))
;
2643 listPush(TFormUses, S, T->cdependees)(T->cdependees = (TFormUses_listPointer->Cons)(S, T->
cdependees))
;
2644 T->ncbefore += 1;
2645 S->ncafter += 1;
2646
2647 assert(T->ncbefore == listLength(TFormUses)(T->cdependees))do { if (!(T->ncbefore == (TFormUses_listPointer->_Length
)(T->cdependees))) _do_assert(("T->ncbefore == listLength(TFormUses)(T->cdependees)"
),"tinfer.c",2647); } while (0)
;
2648 assert(S->ncafter == listLength(TFormUses)(S->cdependents))do { if (!(S->ncafter == (TFormUses_listPointer->_Length
)(S->cdependents))) _do_assert(("S->ncafter == listLength(TFormUses)(S->cdependents)"
),"tinfer.c",2648); } while (0)
;
2649}
2650
2651localstatic void
2652tiTopCliqueDelEdge(TFormUses S, TFormUses T)
2653{
2654 if (S == tiTopCliqueRep(S) && T == tiTopCliqueRep(T)) return;
2655 assert(listMemq(TFormUses)(S->cdependents, T))do { if (!((TFormUses_listPointer->Memq)(S->cdependents
, T))) _do_assert(("listMemq(TFormUses)(S->cdependents, T)"
),"tinfer.c",2655); } while (0)
;
2656 assert(listMemq(TFormUses)(T->cdependees, S))do { if (!((TFormUses_listPointer->Memq)(T->cdependees,
S))) _do_assert(("listMemq(TFormUses)(T->cdependees, S)")
,"tinfer.c",2656); } while (0)
;
2657
2658 listPop(TFormUses, T, S->cdependents, tiTopEqual)(S->cdependents = (TFormUses_listPointer->NRemove)(S->
cdependents, T, tiTopEqual))
;
2659 listPop(TFormUses, S, T->cdependees, tiTopEqual)(T->cdependees = (TFormUses_listPointer->NRemove)(T->
cdependees, S, tiTopEqual))
;
2660 T->ncbefore -= 1;
2661 S->ncafter -= 1;
2662
2663 assert(!listMemq(TFormUses)(S->cdependents, T))do { if (!(!(TFormUses_listPointer->Memq)(S->cdependents
, T))) _do_assert(("!listMemq(TFormUses)(S->cdependents, T)"
),"tinfer.c",2663); } while (0)
;
2664 assert(!listMemq(TFormUses)(T->cdependees, S))do { if (!(!(TFormUses_listPointer->Memq)(T->cdependees
, S))) _do_assert(("!listMemq(TFormUses)(T->cdependees, S)"
),"tinfer.c",2664); } while (0)
;
2665
2666 assert(T->ncbefore == listLength(TFormUses)(T->cdependees))do { if (!(T->ncbefore == (TFormUses_listPointer->_Length
)(T->cdependees))) _do_assert(("T->ncbefore == listLength(TFormUses)(T->cdependees)"
),"tinfer.c",2666); } while (0)
;
2667 assert(S->ncafter == listLength(TFormUses)(S->cdependents))do { if (!(S->ncafter == (TFormUses_listPointer->_Length
)(S->cdependents))) _do_assert(("S->ncafter == listLength(TFormUses)(S->cdependents)"
),"tinfer.c",2667); } while (0)
;
2668}
2669
2670localstatic Bool
2671tiTopEqual(TFormUses tfu0, TFormUses tfu1)
2672{
2673 return tfu0 == tfu1;
2674}
2675
2676/******************************************************************************
2677 *
2678 * :: SetSoftMissing, GetSoftMissing
2679 *
2680 *****************************************************************************/
2681
2682/* When tiSoftMissing is `on', then the compiler will give a warning msg
2683 * (instead of an error msg) when a domain implementation is missing some
2684 * exports.
2685 */
2686static Bool tiSoftMissing = false((int) 0);
2687
2688void
2689tiSetSoftMissing(Bool state)
2690{
2691 tiSoftMissing = state;
2692}
2693
2694Bool
2695tiIsSoftMissing() { return tiSoftMissing; }
2696
2697/******************************************************************************
2698 *
2699 * :: abExpandDefs (normalise a piece of absyn)
2700 *
2701 *****************************************************************************/
2702
2703AbSyn
2704abExpandDefs(Stab stab, AbSyn ab)
2705{
2706 TForm tf = (TForm)NULL((void*)0);
2707 int i;
2708 AbSyn newAb, tmpAb, def;
2709 TPoss tp;
2710
2711 /* Safety check */
2712 assert(ab != 0)do { if (!(ab != 0)) _do_assert(("ab != 0"),"tinfer.c",2712);
} while (0)
;
2713
2714
2715 /* Deal with the simple cases. */
2716 if (abIsNothing(ab)((ab)->abHdr.tag == (AB_Nothing))) return ab;
2717
2718
2719 /* Bad absyn gets thrown back immediately */
2720 if (abState(ab)((ab)->abHdr.state) == AB_State_Error) return ab;
2721
2722
2723 /* Local copy of the abstract syntax node. */
2724 newAb = (AbSyn)sefoCopy((Sefo)ab);
2725
2726
2727 /*
2728 * We MUST have a unique type for this to work. Type
2729 * inferring at this level is dangerous and may blow
2730 * up in our face (eg if still in tibupSelect).
2731 */
2732 if (abState(newAb)((newAb)->abHdr.state) == AB_State_HasPoss)
2733 {
2734 TPoss tp = abTPoss(newAb)((newAb)->abHdr.type.poss);
2735
2736 /* Ensure that type inference is complete */
2737 if (!tpossIsUnique(tp))
2738 typeInferAs(stab, newAb, tfUnknown);
2739 }
2740 else if (abState(newAb)((newAb)->abHdr.state) == AB_State_AbSyn)
2741 typeInferAs(stab, newAb, tfUnknown);
2742
2743
2744 /* Hopefully we have a unique type or singleton tposs */
2745 switch (abState(newAb)((newAb)->abHdr.state))
2746 {
2747 case AB_State_HasUnique:
2748 tf = abTUnique(newAb)((newAb)->abHdr.type.unique);
2749 break;
2750 case AB_State_HasPoss:
2751 tp = abTPoss(newAb)((newAb)->abHdr.type.poss);
2752 if (tpossIsUnique(tp))
2753 tf = tpossUnique(tp);
2754 break;
2755 default:
2756 break;
2757 }
2758
2759
2760 /* If we still don't have a unique type then give up */
2761 if (!tf) return ab;
2762
2763
2764 /* Recursively expand the definition */
2765 switch (abTag(newAb)((newAb)->abHdr.tag)) {
2766 case AB_Not:
2767 tmpAb = newAb->abNot.expr;
2768 tmpAb = abExpandDefs(stab, tmpAb);
2769 newAb->abNot.expr = tmpAb;
2770 break;
2771 case AB_And:
2772 if (abArgc(newAb)((newAb)->abHdr.argc) != 0) {
2773 for (i = 0; i < abArgc(newAb)((newAb)->abHdr.argc); i++) {
2774 tmpAb = newAb->abAnd.argv[i];
2775 tmpAb = abExpandDefs(stab, tmpAb);
2776 newAb->abAnd.argv[i] = tmpAb;
2777 }
2778 }
2779 break;
2780 case AB_Or:
2781 if (abArgc(newAb)((newAb)->abHdr.argc) != 0) {
2782 for (i = 0; i < abArgc(newAb)((newAb)->abHdr.argc); i++) {
2783 tmpAb = newAb->abOr.argv[i];
2784 tmpAb = abExpandDefs(stab, tmpAb);
2785 newAb->abOr.argv[i] = tmpAb;
2786 }
2787 }
2788 break;
2789 case AB_Id:
2790 /*
2791 * If this symbol is a constant definition then we want
2792 * to replace it with the definition body. This assumes
2793 * that the correct RHS of a definition can always be obtained
2794 * and therefore requires that the definition has lexical
2795 * scoping. Dynamically scoped constants (fluids) are
2796 * hopefully impossible.
2797 *
2798 * Only perform substitutions on definitions
2799 */
2800 if (!((tfTag(tf)((tf)->tag) == TF_Define) && tfHasExpr(tf)((tf)->__absyn != 0)))
2801 break;
2802
2803
2804 /* Get the absyn for the definition */
2805 def = tfGetExpr(tf)((tf)->__absyn);
2806
2807
2808 /* Safety check: I'm paranoid */
2809 if (abTag(def)((def)->abHdr.tag) != AB_Define)
2810 break;
2811
2812
2813 /* Use the expanded RHS of the definition */
2814 def = def->abDefine.rhs;
2815
2816
2817 /* A little bit of debugging info */
2818 if (DEBUG(abExpand)abExpandDebug) {
2819 (void)fprintf(dbOut,
2820 "abExpand: %s --> %s",
2821 abPretty(newAb),
2822 abPretty(def));
2823 fnewline(dbOut);
2824 }
2825
2826
2827 /* I really hope this can't loop */
2828 newAb = abExpandDefs(stab, def);
2829 break;
2830 case AB_Test:
2831 tmpAb = newAb->abTest.cond;
2832 tmpAb = abExpandDefs(stab, tmpAb);
2833 newAb->abTest.cond = tmpAb;
2834 break;
2835 default:
2836 ab = newAb;
2837 break;
2838 }
2839
2840 return newAb;
2841}
2842
2843