| File: | src/ti_decl.c |
| Warning: | line 152, column 2 Value stored to 'serialThis' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /**************************************************************************** |
| 2 | * |
| 3 | * ti_decl.c: Type inference -- declaration pass. |
| 4 | * |
| 5 | * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org). |
| 6 | * |
| 7 | ***************************************************************************/ |
| 8 | |
| 9 | #include "debug.h" |
| 10 | #include "fluid.h" |
| 11 | #include "format.h" |
| 12 | #include "stab.h" |
| 13 | #include "store.h" |
| 14 | #include "terror.h" |
| 15 | #include "ti_bup.h" |
| 16 | #include "ti_decl.h" |
| 17 | #include "ti_tdn.h" |
| 18 | #include "tinfer.h" |
| 19 | #include "abpretty.h" |
| 20 | |
| 21 | |
| 22 | struct _pendingDecl |
| 23 | { |
| 24 | AbSyn absyn; /* AB_Declare node to be tibup'd */ |
| 25 | Stab stab; /* Symbol table in which to tibup(absyn) */ |
| 26 | TForm type; /* Type constraint on absyn */ |
| 27 | }; |
| 28 | typedef struct _pendingDecl *PendingDecl; |
| 29 | |
| 30 | DECLARE_LIST(PendingDecl)typedef struct PendingDeclListCons { PendingDecl first; struct PendingDeclListCons *rest; } *PendingDeclList; struct PendingDecl_listOpsStruct { PendingDeclList (*Cons) (PendingDecl, PendingDeclList); PendingDeclList (*Singleton) (PendingDecl); PendingDeclList (*List) (int n, ... ); PendingDeclList (*Listv) (va_list argp); PendingDeclList ( *ListNull) (PendingDecl, ...); Bool (*Equal) (PendingDeclList , PendingDeclList, Bool (*f) (PendingDecl, PendingDecl)); PendingDecl (*Find) (PendingDeclList, PendingDecl, Bool(*eq)(PendingDecl ,PendingDecl) , int *); PendingDecl (*Match) (PendingDeclList , void *, Bool(*match)(PendingDecl, void *), int *); PendingDeclList (*MatchAll) (PendingDeclList, void *, Bool(*match)(PendingDecl , void *)); PendingDeclList (*FreeCons) (PendingDeclList); void (*Free) (PendingDeclList); PendingDeclList (*FreeTo) (PendingDeclList , PendingDeclList); void (*FreeDeeply) (PendingDeclList, void (*f)(PendingDecl)); PendingDeclList (*FreeDeeplyTo) (PendingDeclList , PendingDeclList, void (*f) (PendingDecl) ); PendingDeclList (*FreeIfSat) (PendingDeclList, void (*f)(PendingDecl), Bool ( *s)(PendingDecl)); PendingDecl (*Elt) (PendingDeclList, Length ); PendingDeclList (*Drop) (PendingDeclList, Length); PendingDeclList (*LastCons) (PendingDeclList); Length (*_Length) (PendingDeclList ); Bool (*IsLength) (PendingDeclList, Length); Bool (*IsShorter ) (PendingDeclList, Length); Bool (*IsLonger) (PendingDeclList , Length); PendingDeclList (*Copy) (PendingDeclList); PendingDeclList (*CopyTo) (PendingDeclList, PendingDeclList); PendingDeclList (*CopyDeeply) (PendingDeclList, PendingDecl (*)(PendingDecl) ); PendingDeclList (*CopyDeeplyTo) (PendingDeclList, PendingDeclList , PendingDecl (*)(PendingDecl)); PendingDeclList (*Map) (PendingDecl (*f)(PendingDecl), PendingDeclList); PendingDeclList (*NMap) (PendingDecl (*f)(PendingDecl), PendingDeclList); PendingDeclList (*Reverse) (PendingDeclList); PendingDeclList (*NReverse) (PendingDeclList ); PendingDeclList (*Concat) (PendingDeclList, PendingDeclList ); PendingDeclList (*NConcat) (PendingDeclList, PendingDeclList ); Bool (*Memq) (PendingDeclList, PendingDecl); Bool (*Member ) (PendingDeclList, PendingDecl, Bool(*eq)(PendingDecl,PendingDecl ) ); Bool (*ContainsAllq) (PendingDeclList, PendingDeclList); Bool (*ContainsAnyq) (PendingDeclList, PendingDeclList); Bool (*ContainsAll) (PendingDeclList, PendingDeclList, Bool (*eq) (PendingDecl, PendingDecl)); Bool (*ContainsAny) (PendingDeclList , PendingDeclList, Bool (*eq)(PendingDecl, PendingDecl)); int (*Posq) (PendingDeclList, PendingDecl); int (*Position) (PendingDeclList , PendingDecl, Bool(*eq)(PendingDecl,PendingDecl) ); PendingDeclList (*NRemove) (PendingDeclList, PendingDecl, Bool(*eq)(PendingDecl ,PendingDecl) ); void (*FillVector) (PendingDecl *, PendingDeclList ); int (*Print) (FILE *, PendingDeclList, int (*pr)(FILE *, PendingDecl ) ); int (*GPrint) (FILE *, PendingDeclList, int (*pr)(FILE * , PendingDecl), char *l,char *m,char *r); int (*Format) (OStream , CString, PendingDeclList); }; extern struct PendingDecl_listOpsStruct const *PendingDecl_listPointer; |
| 31 | CREATE_LIST(PendingDecl)struct PendingDecl_listOpsStruct const *PendingDecl_listPointer = (struct PendingDecl_listOpsStruct const *) &ptrlistOps; |
| 32 | |
| 33 | /* tiDeclPending: decl nodes waiting for processing */ |
| 34 | static PendingDeclList pdPending = NULL((void*)0); |
| 35 | |
| 36 | /***************************************************************************** |
| 37 | * |
| 38 | * :: Selective debug stuff |
| 39 | * |
| 40 | ****************************************************************************/ |
| 41 | |
| 42 | Bool tipDeclDebug = false((int) 0); |
| 43 | #define tipDeclDEBUGif (!tipDeclDebug) { } else afprintf DEBUG_IF(tipDecl)if (!tipDeclDebug) { } else afprintf |
| 44 | |
| 45 | /***************************************************************************** |
| 46 | * |
| 47 | * :: Declarations for breadth-first declaration pass |
| 48 | * |
| 49 | ****************************************************************************/ |
| 50 | |
| 51 | localstatic PendingDecl pdNew(Stab stab, AbSyn absyn, TForm type); |
| 52 | localstatic void tidecl(Stab stab, AbSyn absyn, TForm type); |
| 53 | localstatic void tideclAssign(Stab stab, AbSyn absyn, TForm type); |
| 54 | localstatic void tideclDeclare(Stab stab, AbSyn absyn, TForm type); |
| 55 | localstatic void tideclDefine(Stab stab, AbSyn absyn, TForm type); |
| 56 | localstatic void tideclGeneric(Stab stab, AbSyn absyn, TForm type); |
| 57 | |
| 58 | /***************************************************************************** |
| 59 | * |
| 60 | * :: Support functions for breadth-first declaration pass |
| 61 | * |
| 62 | ****************************************************************************/ |
| 63 | |
| 64 | localstatic PendingDecl |
| 65 | pdNew(Stab stab, AbSyn absyn, TForm type) |
| 66 | { |
| 67 | PendingDecl result = (PendingDecl)stoAlloc(OB_Other0, sizeof(*result)); |
| 68 | result->absyn = absyn; |
| 69 | result->stab = stab; |
| 70 | result->type = type; |
| 71 | return result; |
| 72 | } |
| 73 | |
| 74 | #define pdAbSyn(pd)((pd)->absyn) ((pd)->absyn) |
| 75 | #define pdStab(pd)((pd)->stab) ((pd)->stab) |
| 76 | #define pdType(pd)((pd)->type) ((pd)->type) |
| 77 | |
| 78 | |
| 79 | /***************************************************************************** |
| 80 | * |
| 81 | * :: Declaration pass |
| 82 | * |
| 83 | ****************************************************************************/ |
| 84 | |
| 85 | void |
| 86 | tiDeclarations(Stab stab, AbSyn absyn, TForm type) |
| 87 | { |
| 88 | Scope("tiDeclarations")String scopeName = ("tiDeclarations"); int fluidLevel0 = (scopeLevel ++, fluidLevel); |
| 89 | int passNo = 0; |
| 90 | |
| 91 | PendingDeclList fluid(pdPending)fluidSave_pdPending = ( fluidStack = (fluidLevel==fluidLimit) ? fluidGrow() : fluidStack, fluidStack[fluidLevel].scopeName = scopeName, fluidStack[fluidLevel].scopeLevel = scopeLevel, fluidStack[fluidLevel].pglobal = (Pointer) &(pdPending), fluidStack[fluidLevel].pstack = (Pointer) &fluidSave_pdPending , fluidStack[fluidLevel].size = sizeof(pdPending), fluidLevel ++, (pdPending) ); |
| 92 | PendingDeclList pds; |
| 93 | |
| 94 | pdPending = NULL((void*)0); |
| 95 | |
| 96 | /* Add the top-level node to the pending list */ |
| 97 | pdPending = listCons(PendingDecl)(PendingDecl_listPointer->Cons)(pdNew(stab, absyn, type), pdPending); |
| 98 | |
| 99 | /* Repeatedly process pending nodes */ |
| 100 | while (pdPending) { |
| 101 | /* Grab the pending list for ourselves */ |
| 102 | pds = listNReverse(PendingDecl)(PendingDecl_listPointer->NReverse)(pdPending); |
| 103 | pdPending = NULL((void*)0); |
| 104 | passNo++; |
| 105 | |
| 106 | /* Debugging */ |
| 107 | tipDeclDEBUGif (!tipDeclDebug) { } else afprintf(dbOut,"------>Decl: pass %d\n", passNo); |
| 108 | |
| 109 | /* Process each node in the to-do list */ |
| 110 | for (; pds; pds = listFreeCons(PendingDecl)(PendingDecl_listPointer->FreeCons)(pds)) { |
| 111 | PendingDecl pd = car(pds)((pds)->first); |
| 112 | |
| 113 | tidecl(pdStab(pd)((pd)->stab), pdAbSyn(pd)((pd)->absyn), pdType(pd)((pd)->type)); |
| 114 | stoFree(pd); |
| 115 | } |
| 116 | |
| 117 | /* Debugging */ |
| 118 | tipDeclDEBUGif (!tipDeclDebug) { } else afprintf(dbOut,"<------Decl: pass %d\n", passNo); |
| 119 | } |
| 120 | |
| 121 | /* Clean up and return */ |
| 122 | ReturnNothing{ fluidUnwind(fluidLevel0, ((int) 0)); return;; }; |
| 123 | } |
| 124 | |
| 125 | |
| 126 | /* |
| 127 | * Add all child nodes to pdPending. |
| 128 | */ |
| 129 | localstatic void |
| 130 | tidecl(Stab stab, AbSyn absyn, TForm type) |
| 131 | { |
| 132 | static int serialNo = 0, depthNo = 0; |
| 133 | int serialThis; |
| 134 | assert(absyn)do { if (!(absyn)) _do_assert(("absyn"),"ti_decl.c",134); } while (0); |
| 135 | |
| 136 | /* This ought to be impossible but ... */ |
| 137 | if (abState(absyn)((absyn)->abHdr.state) >= AB_State_HasPoss) return; |
| 138 | |
| 139 | /* Use the local stab if present */ |
| 140 | if (!abIsLeaf(absyn)(((absyn)->abHdr.tag) < AB_NODE_START) && abStab(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->stab : 0)) { |
| 141 | stab = abStab(absyn)((absyn)->abHdr.seman ? (absyn)->abHdr.seman->stab : 0); |
| 142 | stabSeeOuterImports(stab); |
| 143 | stabGetSubstable(stab); |
| 144 | typeInferTForms(stab); |
| 145 | } |
| 146 | |
| 147 | /* Stab processing might have done our job for us */ |
| 148 | if (abState(absyn)((absyn)->abHdr.state) >= AB_State_HasPoss) return; |
| 149 | |
| 150 | /* Debugging stuff */ |
| 151 | serialNo++, depthNo++; |
| 152 | serialThis = serialNo; |
Value stored to 'serialThis' is never read | |
| 153 | |
| 154 | /* Ignore leaf nodes */ |
| 155 | if (abIsLeaf(absyn)(((absyn)->abHdr.tag) < AB_NODE_START)) return; |
| 156 | |
| 157 | /* Process, ignore or add to the pending queue */ |
| 158 | switch (abTag(absyn)((absyn)->abHdr.tag)) { |
| 159 | case AB_Assign: tideclAssign(stab, absyn, type); break; |
| 160 | case AB_Declare: tideclDeclare(stab, absyn, type); break; |
| 161 | case AB_Define: tideclDefine(stab, absyn, type); break; |
| 162 | default: tideclGeneric(stab, absyn, type); break; |
| 163 | } |
| 164 | |
| 165 | /* More debugging stuff */ |
| 166 | depthNo--; |
| 167 | } |
| 168 | |
| 169 | localstatic void |
| 170 | tideclAssign(Stab stab, AbSyn absyn, TForm type) |
| 171 | { |
| 172 | PendingDecl pd; |
| 173 | AbSyn lhs = absyn->abAssign.lhs; |
| 174 | AbSyn rhs = absyn->abAssign.rhs; |
| 175 | |
| 176 | /* We are interested if we have "var:Type := expr" */ |
| 177 | if (abTag(lhs)((lhs)->abHdr.tag) != AB_Declare) { |
| 178 | /* Process the lhs on the next pass */ |
| 179 | pd = pdNew(stab, lhs, type); |
| 180 | pdPending = listCons(PendingDecl)(PendingDecl_listPointer->Cons)(pd, pdPending); |
| 181 | } |
| 182 | else |
| 183 | tideclDeclare(stab, lhs, type); |
| 184 | |
| 185 | /* The RHS is always processed on the next pass */ |
| 186 | pd = pdNew(stab, rhs, type); |
| 187 | pdPending = listCons(PendingDecl)(PendingDecl_listPointer->Cons)(pd, pdPending); |
| 188 | } |
| 189 | |
| 190 | |
| 191 | localstatic void |
| 192 | tideclDeclare(Stab stab, AbSyn absyn, TForm type) |
| 193 | { |
| 194 | /* Debugging */ |
| 195 | if (DEBUG(tipDecl)tipDeclDebug) { |
| 196 | (void)fprintf(dbOut," -->Decl: "); |
| 197 | abPrettyPrint(dbOut, absyn); |
| 198 | fnewline(dbOut); |
| 199 | } |
| 200 | |
| 201 | /* Tinfer the declaration now */ |
| 202 | typeInferAs(stab, absyn, type); |
| 203 | } |
| 204 | |
| 205 | |
| 206 | localstatic void |
| 207 | tideclDefine(Stab stab, AbSyn absyn, TForm type) |
| 208 | { |
| 209 | PendingDecl pd; |
| 210 | AbSyn lhs = absyn->abDefine.lhs; |
| 211 | AbSyn rhs = absyn->abDefine.rhs; |
| 212 | |
| 213 | /* We are interested if we have "var:Type == expr" */ |
| 214 | if (abTag(lhs)((lhs)->abHdr.tag) != AB_Declare) { |
| 215 | /* Process the lhs on the next pass */ |
| 216 | pd = pdNew(stab, lhs, type); |
| 217 | pdPending = listCons(PendingDecl)(PendingDecl_listPointer->Cons)(pd, pdPending); |
| 218 | } |
| 219 | else |
| 220 | tideclDeclare(stab, lhs, type); |
| 221 | |
| 222 | /* The RHS is always processed on the next pass */ |
| 223 | pd = pdNew(stab, rhs, type); |
| 224 | pdPending = listCons(PendingDecl)(PendingDecl_listPointer->Cons)(pd, pdPending); |
| 225 | } |
| 226 | |
| 227 | |
| 228 | localstatic void |
| 229 | tideclGeneric(Stab stab, AbSyn absyn, TForm type) |
| 230 | { |
| 231 | Length i; |
| 232 | PendingDecl pd; |
| 233 | |
| 234 | /* Add all child nodes to the pending queue */ |
| 235 | if (!abIsLeaf(absyn)(((absyn)->abHdr.tag) < AB_NODE_START)) { |
| 236 | for (i = 0; i < abArgc(absyn)((absyn)->abHdr.argc); i++) { |
| 237 | pd = pdNew(stab, abArgv(absyn)((absyn)->abGen.data.argv)[i], tfUnknown); |
| 238 | pdPending = listCons(PendingDecl)(PendingDecl_listPointer->Cons)(pd, pdPending); |
| 239 | } |
| 240 | } |
| 241 | } |
| 242 |