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