| File: | src/gf_prog.c |
| Warning: | line 134, column 7 Dereference of null pointer |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /***************************************************************************** | |||
| 2 | * | |||
| 3 | * gf_prog.c: Common declarations and macros for foam prog generation. | |||
| 4 | * | |||
| 5 | * Copyright (c) 1990-2007 Aldor Software Organization Ltd (Aldor.org). | |||
| 6 | * | |||
| 7 | ****************************************************************************/ | |||
| 8 | ||||
| 9 | #include "debug.h" | |||
| 10 | #include "gf_prog.h" | |||
| 11 | #include "gf_util.h" | |||
| 12 | #include "optinfo.h" | |||
| 13 | #include "store.h" | |||
| 14 | #include "syme.h" | |||
| 15 | #include "strops.h" | |||
| 16 | #include "fbox.h" | |||
| 17 | #include "tform.h" | |||
| 18 | ||||
| 19 | Bool genfEnvDebug = false((int) 0); | |||
| 20 | ||||
| 21 | /***************************************************************************** | |||
| 22 | * | |||
| 23 | * :: Local function declarations. | |||
| 24 | * | |||
| 25 | ****************************************************************************/ | |||
| 26 | localstatic void gen0ProgTransferState(GenFoamState, GenFoamState); | |||
| 27 | ||||
| 28 | localstatic Foam gen0IssueStmts (void); | |||
| 29 | localstatic Foam gen0IssueParams (void); | |||
| 30 | localstatic Foam gen0IssueLocals (void); | |||
| 31 | localstatic Foam gen0IssueFluids (void); | |||
| 32 | localstatic Foam gen0IssueLevels (void); | |||
| 33 | ||||
| 34 | /***************************************************************************** | |||
| 35 | * | |||
| 36 | * :: Foam prog construction operations. | |||
| 37 | * | |||
| 38 | ****************************************************************************/ | |||
| 39 | ||||
| 40 | /* | |||
| 41 | * Build a foam prog from a piece of abstract syntax. | |||
| 42 | */ | |||
| 43 | Foam | |||
| 44 | gen0BuildFunction(ProgType pt, String name, AbSyn expr) | |||
| 45 | { | |||
| 46 | GenFoamState saved; | |||
| 47 | Foam foam, clos, ret; | |||
| 48 | AInt fmt; | |||
| 49 | FoamTag tag; | |||
| 50 | extern TForm gen0AbContextType(AbSyn); | |||
| 51 | ||||
| 52 | clos = gen0ProgClosEmpty(); | |||
| 53 | foam = gen0ProgInitEmpty(name, expr); | |||
| 54 | ||||
| 55 | saved = gen0ProgSaveState(pt); | |||
| 56 | ||||
| 57 | if (tfIsNone(gen0AbContextType(expr))((((gen0AbContextType(expr))->tag) == TF_Multiple) && tfMultiArgc(gen0AbContextType(expr)) == 0)) { | |||
| 58 | genFoamStmt(expr); | |||
| 59 | gen0AddStmt(foamNewReturn(foamNew(FOAM_Values, (Length) 0))foamNew(FOAM_Return, 1, foamNew(FOAM_Values, (Length) 0)), expr); | |||
| 60 | } | |||
| 61 | else { | |||
| 62 | ret = genFoamValAs(gen0AbContextType(expr), expr); | |||
| 63 | if (ret) gen0AddStmt(foamNewReturn(ret)foamNew(FOAM_Return, 1, ret), expr); | |||
| 64 | } | |||
| 65 | gen0ProgPushFormat(emptyFormatSlot4); | |||
| 66 | gen0IssueDCache(); | |||
| 67 | ||||
| 68 | tag = gen0Type(gen0AbContextType(expr), &fmt); | |||
| 69 | ||||
| 70 | gen0ProgFiniEmpty(foam, tag, fmt); | |||
| 71 | ||||
| 72 | gen0AddLexLevels(foam, 1); | |||
| 73 | ||||
| 74 | foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0)); | |||
| 75 | ||||
| 76 | gen0ProgRestoreState(saved); | |||
| 77 | return clos; | |||
| 78 | } | |||
| 79 | ||||
| 80 | /* | |||
| 81 | * Push a new prog state. | |||
| 82 | */ | |||
| 83 | ||||
| 84 | void | |||
| 85 | gen0ProgPushState(Stab stab, GenFoamTag tag) | |||
| 86 | { | |||
| 87 | AInt index = gen0FormatNum--; | |||
| 88 | GenFoamState state = gen0NewState(stab, index, tag); | |||
| 89 | SlotUsageList fu; | |||
| 90 | AIntList fs, ef; | |||
| 91 | Length i, argc; | |||
| 92 | ||||
| 93 | assert(state && state->parent)do { if (!(state && state->parent)) _do_assert(("state && state->parent" ),"gf_prog.c",93); } while (0); | |||
| 94 | fu = state->parent->formatUsage; | |||
| 95 | fs = state->parent->formatStack; | |||
| 96 | ef = state->parent->envFormatStack; | |||
| 97 | ||||
| 98 | argc = listLength(AInt)(AInt_listPointer->_Length)(ef); | |||
| 99 | for (i = 0; i < argc - 1; i += 1) | |||
| 100 | fu = listCons(SlotUsage)(SlotUsage_listPointer->Cons)(suFrFormat(emptyFormatSlot)(((4) << 2) | 2), fu); | |||
| 101 | ||||
| 102 | if (ef) ef = listNReverse(AInt)(AInt_listPointer->NReverse)(cdr(listReverse(AInt)(ef))(((AInt_listPointer->Reverse)(ef))->rest)); | |||
| 103 | fs = listNConcat(AInt)(AInt_listPointer->NConcat)(ef, fs); | |||
| 104 | ||||
| 105 | state->formatUsage = fu; | |||
| 106 | state->formatStack = fs; | |||
| 107 | ||||
| 108 | gen0State = state; | |||
| 109 | } | |||
| 110 | ||||
| 111 | /* | |||
| 112 | * Pop a prog state. | |||
| 113 | */ | |||
| 114 | ||||
| 115 | void | |||
| 116 | gen0ProgPopState() | |||
| 117 | { | |||
| 118 | GenFoamState state = gen0State; | |||
| 119 | SlotUsageList fu, ofu; | |||
| 120 | int i; | |||
| 121 | gen0State = gen0State->parent; | |||
| 122 | ||||
| 123 | if (genfEnvDebug) { | |||
| ||||
| 124 | afprintf(dbOut, "Pop state - pre formatUsage parent %pSlotUsageList\n", state->parent->formatUsage); | |||
| 125 | afprintf(dbOut, "Pop state - pre formatUsage current %pSlotUsageList\n", state->formatUsage); | |||
| 126 | } | |||
| 127 | ||||
| 128 | ofu = state->parent->formatUsage; | |||
| 129 | fu = cdr(state->formatUsage)((state->formatUsage)->rest); | |||
| 130 | /* Copy usage information downwards */ | |||
| 131 | for (i=0; i<state->parent->whereNest; i++) | |||
| 132 | fu = cdr(fu)((fu)->rest); | |||
| 133 | while (fu != listNil(SlotUsage)((SlotUsageList) 0)) { | |||
| 134 | if (suVal(car(ofu))( (((ofu)->first) & 2) == 2 ? ((((ofu)->first)) >> 2): *(int*) 0) == emptyFormatSlot4) | |||
| ||||
| 135 | car(ofu)((ofu)->first) = car(fu)((fu)->first); | |||
| 136 | ofu = cdr(ofu)((ofu)->rest); | |||
| 137 | fu = cdr(fu)((fu)->rest); | |||
| 138 | } | |||
| 139 | vpFree(state->localPool); | |||
| 140 | vpFree(state->lexPool); | |||
| 141 | listFree(Foam)(Foam_listPointer->Free)(state->inits); | |||
| 142 | listFree(Foam)(Foam_listPointer->Free)(state->lines); | |||
| 143 | listFree(Syme)(Syme_listPointer->Free)(state->funImportList); | |||
| 144 | listFree(TForm)(TForm_listPointer->Free)(state->domImportList); | |||
| 145 | listFree(Foam)(Foam_listPointer->Free)(state->domList); | |||
| 146 | ||||
| 147 | if (genfEnvDebug) { | |||
| 148 | afprintf(dbOut, "Pop state - formatUsage %pAIntList\n", state->formatUsage); | |||
| 149 | afprintf(dbOut, "Pop state - formatUsage %pAIntList\n", state->parent->formatUsage); | |||
| 150 | } | |||
| 151 | stoFree(state); | |||
| 152 | } | |||
| 153 | ||||
| 154 | /* | |||
| 155 | * Save the state for a prog which doesn't need its own. | |||
| 156 | */ | |||
| 157 | ||||
| 158 | GenFoamState | |||
| 159 | gen0ProgSaveState(ProgType pt) | |||
| 160 | { | |||
| 161 | GenFoamState state = gen0State; | |||
| 162 | GenFoamState saved = gen0NewState(NULL((void*)0), emptyFormatSlot4, GF_Saved); | |||
| 163 | ||||
| 164 | if (genfEnvDebug) { | |||
| 165 | afprintf(dbOut, "Save state %pSlotUsageList\n", state->formatUsage); | |||
| 166 | } | |||
| 167 | gen0ProgTransferState(saved, state); | |||
| 168 | ||||
| 169 | if (!gen0InDeep(state->progType)((state->progType) >= PT_DeepStart)) | |||
| 170 | state->base = saved; | |||
| 171 | ||||
| 172 | state->formatUsage = state->formatUsage; | |||
| 173 | state->params = fboxNew(foamNewEmptyDDecl(FOAM_DDecl_Param)foamNew(FOAM_DDecl, 1, (AInt) FOAM_DDecl_Param)); | |||
| 174 | state->localPool = vpNew(fboxNew(foamNewEmptyDDecl(FOAM_DDecl_Local)foamNew(FOAM_DDecl, 1, (AInt) FOAM_DDecl_Local))); | |||
| 175 | state->fluidsUsed = listNil(AInt)((AIntList) 0); | |||
| 176 | state->labelNo = 0; | |||
| 177 | state->yieldCount = 0; | |||
| 178 | state->yieldLabels = listNil(AInt)((AIntList) 0); | |||
| 179 | state->lines = listNil(Foam)((FoamList) 0); | |||
| 180 | state->inits = listNil(Foam)((FoamList) 0); | |||
| 181 | state->progType = pt; | |||
| 182 | state->domCache = NULL((void*)0); | |||
| 183 | state->dbgContext = (Foam)NULL((void*)0); | |||
| 184 | ||||
| 185 | return saved; | |||
| 186 | } | |||
| 187 | ||||
| 188 | void | |||
| 189 | gen0ProgPushFormat(AInt index) | |||
| 190 | { | |||
| 191 | GenFoamState state = gen0State; | |||
| 192 | SlotUsageList fu; | |||
| 193 | AIntList ef; | |||
| 194 | ||||
| 195 | fu = state->formatUsage; | |||
| 196 | ef = state->envFormatStack; | |||
| 197 | ||||
| 198 | assert(fu)do { if (!(fu)) _do_assert(("fu"),"gf_prog.c",198); } while ( 0); | |||
| 199 | if (ef && cdr(ef)((ef)->rest)) { | |||
| 200 | //fu = listConcat(SlotUsage)((SlotUsageList) ef, cdr(fu)); | |||
| 201 | fu = cdr(fu)((fu)->rest); | |||
| 202 | AIntList l2 = listReverse(AInt)(AInt_listPointer->Reverse)(ef); | |||
| 203 | while (l2 != listNil(AInt)((AIntList) 0)) { | |||
| 204 | fu = listCons(SlotUsage)(SlotUsage_listPointer->Cons)(suFrFormat(car(l2))(((((l2)->first)) << 2) | 2), fu); | |||
| 205 | l2 = listFreeCons(AInt)(AInt_listPointer->FreeCons)(l2); | |||
| 206 | } | |||
| 207 | } | |||
| 208 | fu = listCons(SlotUsage)(SlotUsage_listPointer->Cons)(suFrFormat(index)(((index) << 2) | 2), fu); | |||
| 209 | ||||
| 210 | state->formatUsage = fu; | |||
| 211 | state->envFormatStack = listNil(AInt)((AIntList) 0); | |||
| 212 | } | |||
| 213 | ||||
| 214 | /* | |||
| 215 | * Restore the state for a prog which doesn't need its own. | |||
| 216 | */ | |||
| 217 | ||||
| 218 | void | |||
| 219 | gen0ProgRestoreState(GenFoamState saved) | |||
| 220 | { | |||
| 221 | GenFoamState state = gen0State; | |||
| 222 | ||||
| 223 | gen0ProgTransferState(state, saved); | |||
| 224 | ||||
| 225 | if (!gen0InDeep(gen0State->progType)((gen0State->progType) >= PT_DeepStart)) | |||
| 226 | state->base = NULL((void*)0); | |||
| 227 | ||||
| 228 | if (genfEnvDebug) { | |||
| 229 | afprintf(dbOut, "Restore state %pSlotUsageList\n", state->formatUsage); | |||
| 230 | } | |||
| 231 | stoFree(saved); | |||
| 232 | } | |||
| 233 | ||||
| 234 | void | |||
| 235 | gen0ProgUseBaseState() | |||
| 236 | { | |||
| 237 | struct gfs tmp; | |||
| 238 | gen0ProgTransferState(&tmp, gen0State); | |||
| 239 | gen0ProgTransferState(gen0State, gen0State->base); | |||
| 240 | gen0ProgTransferState(gen0State->base, &tmp); | |||
| 241 | } | |||
| 242 | ||||
| 243 | void | |||
| 244 | gen0ProgUseUpperState() | |||
| 245 | { | |||
| 246 | struct gfs tmp; | |||
| 247 | gen0ProgTransferState(&tmp, gen0State); | |||
| 248 | gen0ProgTransferState(gen0State, gen0State->base); | |||
| 249 | gen0ProgTransferState(gen0State->base, &tmp); | |||
| 250 | } | |||
| 251 | ||||
| 252 | localstatic void | |||
| 253 | gen0ProgTransferState(GenFoamState to, GenFoamState from) | |||
| 254 | { | |||
| 255 | to->formatUsage = from->formatUsage; | |||
| 256 | to->formatStack = from->formatStack; | |||
| 257 | to->envFormatStack= from->envFormatStack; | |||
| 258 | to->params = from->params; | |||
| 259 | to->localPool = from->localPool; | |||
| 260 | to->fluidsUsed = from->fluidsUsed; | |||
| 261 | to->labelNo = from->labelNo; | |||
| 262 | to->yieldCount = from->yieldCount; | |||
| 263 | to->yieldLabels = from->yieldLabels; | |||
| 264 | to->yieldValueVar = from->yieldValueVar; | |||
| 265 | to->lines = from->lines; | |||
| 266 | to->inits = from->inits; | |||
| 267 | to->progType = from->progType; | |||
| 268 | to->domCache = from->domCache; | |||
| 269 | to->dbgContext = from->dbgContext; | |||
| 270 | } | |||
| 271 | ||||
| 272 | ||||
| 273 | /* | |||
| 274 | * Create an empty prog. | |||
| 275 | */ | |||
| 276 | Foam | |||
| 277 | gen0ProgInitEmpty(String name, AbSyn absyn) | |||
| 278 | { | |||
| 279 | Foam foam, decl; | |||
| 280 | int idx; | |||
| 281 | ||||
| 282 | if (genfEnvDebug) { | |||
| 283 | idx = gen0NumProgs; | |||
| 284 | afprintf(dbOut, "(Creating function %d\n", idx); | |||
| 285 | } | |||
| 286 | foam = foamNewProg(int0,int0,int0,int0,int0,NULL,NULL,NULL,NULL,NULL)foamNew(FOAM_Prog, 13, (AInt)(((int) 0)),(AInt)(((int) 0)),(AInt )(((int) 0)),(AInt)(((int) 0)), (AInt)(((int) 0)), (AInt)0, ( AInt)0, (AInt)0 , ((void*)0), ((void*)0), ((void*)0), ((void* )0), ((void*)0)); | |||
| 287 | ||||
| 288 | #ifdef MODS | |||
| 289 | name = gen0InitialiserName(name)(strCopy(name)); | |||
| 290 | #else | |||
| 291 | name = strCopy(name); | |||
| 292 | #endif | |||
| 293 | decl = foamNewDecl(FOAM_Prog, name, emptyFormatSlot)foamNew(FOAM_Decl,4,(AInt)(FOAM_Prog),name, (AInt) (0x7FFF), 4 ); | |||
| 294 | gen0ConstAdd(decl, foam); | |||
| 295 | if (absyn) foamPos(foam)((foam)->hdr.pos) = abPos(absyn)(spstackFirst((absyn)->abHdr.pos)); | |||
| 296 | ||||
| 297 | if (genfEnvDebug) { | |||
| 298 | afprintf(dbOut, "..created function %d - %s)\n", idx, name); | |||
| 299 | } | |||
| 300 | ||||
| 301 | return foam; | |||
| 302 | } | |||
| 303 | ||||
| 304 | void | |||
| 305 | gen0ConstAdd(Foam decl, Foam prog) | |||
| 306 | { | |||
| 307 | /** FIXME: Better names needed here */ | |||
| 308 | gen0ProgList = listCons(Foam)(Foam_listPointer->Cons)(prog, gen0ProgList); | |||
| 309 | gen0DeclList = listCons(Foam)(Foam_listPointer->Cons)(decl, gen0DeclList); | |||
| 310 | gen0NumProgs += 1; | |||
| 311 | } | |||
| 312 | ||||
| 313 | ||||
| 314 | /* | |||
| 315 | * Collect the fields of a prog. | |||
| 316 | */ | |||
| 317 | void | |||
| 318 | gen0ProgFiniEmpty(Foam prog, AInt retType, AInt format) | |||
| 319 | { | |||
| 320 | assert(foamTag(prog) == FOAM_Prog)do { if (!(((prog)->hdr.tag) == FOAM_Prog)) _do_assert(("foamTag(prog) == FOAM_Prog" ),"gf_prog.c",320); } while (0); | |||
| 321 | ||||
| 322 | prog->foamProg.nLabels = gen0NLabels()(gen0State->labelNo); | |||
| 323 | prog->foamProg.retType = retType; | |||
| 324 | prog->foamProg.format = format; | |||
| 325 | prog->foamProg.params = gen0IssueParams(); | |||
| 326 | prog->foamProg.locals = gen0IssueLocals(); | |||
| 327 | prog->foamProg.fluids = gen0IssueFluids(); | |||
| 328 | prog->foamProg.levels = gen0IssueLevels(); | |||
| 329 | prog->foamProg.body = gen0IssueStmts(); | |||
| 330 | ||||
| 331 | if (genfEnvDebug) { | |||
| 332 | afprintf(dbOut, "Fini - fmtStack: %pAIntList, usage: %pSlotUsageList)\n", | |||
| 333 | gen0State->formatStack, gen0State->formatUsage); | |||
| 334 | } | |||
| 335 | } | |||
| 336 | ||||
| 337 | Foam | |||
| 338 | gen0ProgClosEmpty(void) | |||
| 339 | { | |||
| 340 | GenFoamState state = gen0State; | |||
| 341 | Foam env; | |||
| 342 | ||||
| 343 | if (genfEnvDebug && gen0State) { | |||
| 344 | afprintf(dbOut, "ClosEmpty - fmtStack: %pAIntList, usage: %pSlotUsageList\n", | |||
| 345 | gen0State->formatStack, gen0State->formatUsage); | |||
| 346 | } | |||
| 347 | ||||
| 348 | env = state ? foamCopy(car(state->envVarStack)((state->envVarStack)->first)) : foamNewEnv(int0)foamNew(FOAM_Env, 1, (AInt)(((int) 0))); | |||
| 349 | if (state && suVal(car(state->formatUsage))( (((state->formatUsage)->first) & 2) == 2 ? ((((state ->formatUsage)->first)) >> 2): *(int*) 0) == emptyFormatSlot4) | |||
| 350 | car(state->formatUsage)((state->formatUsage)->first) = suFrFormat(envUsedSlot)(((0) << 2) | 2); | |||
| 351 | return foamNewClos(env, foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, env, foamNew(FOAM_Const, 1, (AInt)(gen0NumProgs ))); | |||
| 352 | } | |||
| 353 | ||||
| 354 | Foam | |||
| 355 | gen0ProgEnv0(void) | |||
| 356 | { | |||
| 357 | GenFoamState state = gen0State; | |||
| 358 | Foam env; | |||
| 359 | ||||
| 360 | if (genfEnvDebug && gen0State) { | |||
| 361 | afprintf(dbOut, "EnvEmpty - fmtStack: %pAIntList, usage: %pAIntList\n", | |||
| 362 | gen0State->formatStack, gen0State->formatUsage); | |||
| 363 | } | |||
| 364 | ||||
| 365 | env = state ? foamCopy(car(state->envVarStack)((state->envVarStack)->first)) : foamNewEnv(int0)foamNew(FOAM_Env, 1, (AInt)(((int) 0))); | |||
| 366 | ||||
| 367 | if (state) { | |||
| 368 | car(state->formatUsage)((state->formatUsage)->first) = suSetUse(car(state->formatUsage))( (((state->formatUsage)->first)) | 1); | |||
| 369 | if (genfEnvDebug) { | |||
| 370 | afprintf(dbOut, "EnvEmpty - usage: %pSlotUsageList\n", | |||
| 371 | gen0State->formatUsage); | |||
| 372 | } | |||
| 373 | } | |||
| 374 | return env; | |||
| 375 | } | |||
| 376 | ||||
| 377 | ||||
| 378 | /* | |||
| 379 | * Generate decls for variables needed by the prog. | |||
| 380 | */ | |||
| 381 | void | |||
| 382 | gen0ProgAddParams(Length argc, String *argv) | |||
| 383 | { | |||
| 384 | Length i; | |||
| 385 | String name; | |||
| 386 | Foam decl; | |||
| 387 | ||||
| 388 | for (i = 0; i < argc; i += 1) { | |||
| 389 | name = strCopy(argv[i]); | |||
| 390 | decl = foamNewDecl(FOAM_Word, name, emptyFormatSlot)foamNew(FOAM_Decl,4,(AInt)(FOAM_Word),name, (AInt) (0x7FFF), 4 ); | |||
| 391 | gen0AddParam(decl); | |||
| 392 | } | |||
| 393 | } | |||
| 394 | ||||
| 395 | void | |||
| 396 | gen0ProgAddStateFormat(AInt index) | |||
| 397 | { | |||
| 398 | Foam format = fboxMake(gen0State->lexPool->fbox); | |||
| 399 | gen0ProgAddFormat(index, format); | |||
| 400 | } | |||
| 401 | ||||
| 402 | void | |||
| 403 | gen0ProgAddFormat(AInt index, Foam format) | |||
| 404 | { | |||
| 405 | AInt nindex; | |||
| 406 | ||||
| 407 | if (genfEnvDebug) { | |||
| 408 | afprintf(dbOut, "ProgAddFormat format %d %pFoam\n", index, format); | |||
| 409 | afprintf(dbOut, "ProgAddFormat stack %pAIntList\n", gen0State->formatStack); | |||
| 410 | afprintf(dbOut, "ProgAddFormat usage %pSlotUsageList\n", gen0State->formatUsage); | |||
| 411 | afprintf(dbOut, "ProgAddFormat ddecl %pAInt Used %oBool\n", foamDDeclArgc(format)(((format)->hdr.argc) - (1)), suIsUsed(car(gen0State->formatUsage))( (((gen0State->formatUsage)->first)) & 1)); | |||
| 412 | } | |||
| 413 | ||||
| 414 | if (foamDDeclArgc(format)(((format)->hdr.argc) - (1)) == 0 && !suIsUsed(car(gen0State->formatUsage))( (((gen0State->formatUsage)->first)) & 1)) { | |||
| 415 | nindex = emptyFormatSlot4; | |||
| 416 | } | |||
| 417 | else { | |||
| 418 | // Not sure why this is happening here; looks like it should be at a | |||
| 419 | // higher level | |||
| 420 | if (gen0State->hasTemps) setcar(gen0State->formatUsage, suFrFormat(index))((gen0State->formatUsage)->first = ((((index) << 2 ) | 2))); | |||
| 421 | gen0FormatList = listCons(Foam)(Foam_listPointer->Cons)(format, gen0FormatList); | |||
| 422 | nindex = gen0RealFormatNum++; | |||
| 423 | } | |||
| 424 | ||||
| 425 | gen0AddFormat(index, nindex); | |||
| 426 | } | |||
| 427 | ||||
| 428 | ||||
| 429 | /***************************************************************************** | |||
| 430 | * | |||
| 431 | * :: Functions for updating the exporter with parameter lists. | |||
| 432 | * | |||
| 433 | ****************************************************************************/ | |||
| 434 | ||||
| 435 | AbSyn | |||
| 436 | gen0ProgGetExporter() | |||
| 437 | { | |||
| 438 | GenFoamState state; | |||
| 439 | ||||
| 440 | for (state = gen0State; state; state = state->parent) | |||
| 441 | if (state->exporter) return state->exporter; | |||
| 442 | ||||
| 443 | return NULL((void*)0); | |||
| 444 | } | |||
| 445 | ||||
| 446 | AbSyn | |||
| 447 | gen0ProgPushExporter(AbSyn lhs) | |||
| 448 | { | |||
| 449 | AbSyn old; | |||
| 450 | old = gen0State->exporter; | |||
| 451 | gen0State->exporter = lhs; | |||
| 452 | return old; | |||
| 453 | } | |||
| 454 | ||||
| 455 | void | |||
| 456 | gen0ProgPopExporter(AbSyn old) | |||
| 457 | { | |||
| 458 | gen0State->exporter = old; | |||
| 459 | } | |||
| 460 | ||||
| 461 | void | |||
| 462 | gen0ProgAddExporterArgs(AbSyn param) | |||
| 463 | { | |||
| 464 | AbSyn *argv, exporter; | |||
| 465 | Length i, argc; | |||
| 466 | ||||
| 467 | assert(gen0ProgGetExporter())do { if (!(gen0ProgGetExporter())) _do_assert(("gen0ProgGetExporter()" ),"gf_prog.c",467); } while (0); | |||
| 468 | ||||
| 469 | switch (abTag(param)((param)->abHdr.tag)) { | |||
| 470 | case AB_Nothing: | |||
| 471 | argc = 0; | |||
| 472 | argv = 0; | |||
| 473 | break; | |||
| 474 | case AB_Comma: | |||
| 475 | argc = abArgc(param)((param)->abHdr.argc); | |||
| 476 | argv = abArgv(param)((param)->abGen.data.argv); | |||
| 477 | break; | |||
| 478 | default: | |||
| 479 | argc = 1; | |||
| 480 | argv = ¶m; | |||
| 481 | break; | |||
| 482 | } | |||
| 483 | ||||
| 484 | exporter = abNewEmpty(AB_Apply, 1 + argc); | |||
| 485 | exporter->abApply.op = gen0ProgGetExporter(); | |||
| 486 | for (i = 0; i < argc; i += 1) | |||
| 487 | exporter->abApply.argv[i] = argv[i]; | |||
| 488 | ||||
| 489 | gen0State->exporter = exporter; | |||
| 490 | } | |||
| 491 | ||||
| 492 | void | |||
| 493 | gen0ProgPopExporterArgs() | |||
| 494 | { | |||
| 495 | AbSyn exporter = gen0State->exporter; | |||
| 496 | ||||
| 497 | assert(abHasTag(exporter, AB_Apply))do { if (!(((exporter)->abHdr.tag == (AB_Apply)))) _do_assert (("abHasTag(exporter, AB_Apply)"),"gf_prog.c",497); } while ( 0); | |||
| 498 | gen0State->exporter = exporter->abApply.op; | |||
| 499 | abFreeNode(exporter); | |||
| 500 | } | |||
| 501 | ||||
| 502 | Bool | |||
| 503 | gen0ProgHasReturn(void) | |||
| 504 | { | |||
| 505 | GenFoamState state = gen0State; | |||
| 506 | return state->lines && foamTag(state->lines->first)((state->lines->first)->hdr.tag) == FOAM_Return; | |||
| 507 | } | |||
| 508 | ||||
| 509 | /***************************************************************************** | |||
| 510 | * | |||
| 511 | * :: Functions which add to a prog state. | |||
| 512 | * | |||
| 513 | ****************************************************************************/ | |||
| 514 | ||||
| 515 | void | |||
| 516 | gen0AddInit(Foam foam) | |||
| 517 | { | |||
| 518 | GenFoamState state = gen0State; | |||
| 519 | Foam *argv; | |||
| 520 | int argc, i; | |||
| 521 | ||||
| 522 | if (foamTag(foam)((foam)->hdr.tag) == FOAM_Seq) { | |||
| 523 | argv = foam->foamSeq.argv; | |||
| 524 | argc = foamArgc(foam)((foam)->hdr.argc); | |||
| 525 | } else { | |||
| 526 | argv = &foam; | |||
| 527 | argc = 1; | |||
| 528 | } | |||
| 529 | ||||
| 530 | for (i=0; i<argc; i++) | |||
| 531 | state->inits = listCons(Foam)(Foam_listPointer->Cons)(argv[i], state->inits); | |||
| 532 | } | |||
| 533 | ||||
| 534 | void | |||
| 535 | gen0AddStmt(Foam foam, AbSyn absyn) | |||
| 536 | { | |||
| 537 | GenFoamState state = gen0State; | |||
| 538 | Foam *argv; | |||
| 539 | int argc, i; | |||
| 540 | ||||
| 541 | if (foamTag(foam)((foam)->hdr.tag) == FOAM_Seq) { | |||
| 542 | argv = foam->foamSeq.argv; | |||
| 543 | argc = foamArgc(foam)((foam)->hdr.argc); | |||
| 544 | } else { | |||
| 545 | argv = &foam; | |||
| 546 | argc = 1; | |||
| 547 | } | |||
| 548 | ||||
| 549 | for (i=0; i<argc; i++) { | |||
| 550 | assert(foamTag(foam) != FOAM_Cast)do { if (!(((foam)->hdr.tag) != FOAM_Cast)) _do_assert(("foamTag(foam) != FOAM_Cast" ),"gf_prog.c",550); } while (0); | |||
| 551 | ||||
| 552 | if (absyn) foamPos(argv[i])((argv[i])->hdr.pos) = abPos(absyn)(spstackFirst((absyn)->abHdr.pos)); | |||
| 553 | state->lines = listCons(Foam)(Foam_listPointer->Cons)(argv[i], state->lines); | |||
| 554 | } | |||
| 555 | } | |||
| 556 | ||||
| 557 | AInt | |||
| 558 | gen0AddParam(Foam decl) | |||
| 559 | { | |||
| 560 | return fboxAdd(gen0State->params, decl); | |||
| 561 | } | |||
| 562 | ||||
| 563 | AInt | |||
| 564 | gen0AddLocal(Foam decl) | |||
| 565 | { | |||
| 566 | return vpNewVarDecl(gen0State->localPool, decl); | |||
| 567 | } | |||
| 568 | ||||
| 569 | AInt | |||
| 570 | gen0AddLex(Foam decl) | |||
| 571 | { | |||
| 572 | return vpNewVarDecl(gen0State->lexPool, decl); | |||
| 573 | } | |||
| 574 | ||||
| 575 | AInt | |||
| 576 | gen0AddLexNth(Foam decl, AInt n, AInt offset) | |||
| 577 | { | |||
| 578 | GenFoamState state = gen0NthState(n); | |||
| 579 | VarPool vp; | |||
| 580 | ||||
| 581 | if (offset == 0) | |||
| 582 | vp = state->lexPool; | |||
| 583 | else | |||
| 584 | vp = listElt(VarPool)(VarPool_listPointer->Elt)(state->envLexPools, offset - 1); | |||
| 585 | ||||
| 586 | return vpNewVarDecl(vp, decl); | |||
| 587 | } | |||
| 588 | ||||
| 589 | /***************************************************************************** | |||
| 590 | * | |||
| 591 | * :: Local function definitions. | |||
| 592 | * | |||
| 593 | ****************************************************************************/ | |||
| 594 | ||||
| 595 | localstatic Foam | |||
| 596 | gen0IssueStmts(void) | |||
| 597 | { | |||
| 598 | GenFoamState s = gen0State; | |||
| 599 | Foam seq; | |||
| 600 | ||||
| 601 | s->lines = listNConcat(Foam)(Foam_listPointer->NConcat)(s->lines, s->inits); | |||
| 602 | s->inits = listNil(Foam)((FoamList) 0); | |||
| 603 | ||||
| 604 | s->lines = listNReverse(Foam)(Foam_listPointer->NReverse)(s->lines); | |||
| 605 | seq = foamNewOfList(FOAM_Seq, s->lines); | |||
| 606 | ||||
| 607 | listFree(Foam)(Foam_listPointer->Free)(s->lines); | |||
| 608 | s->lines = listNil(Foam)((FoamList) 0); | |||
| 609 | ||||
| 610 | return seq; | |||
| 611 | } | |||
| 612 | ||||
| 613 | localstatic Foam | |||
| 614 | gen0IssueParams(void) | |||
| 615 | { | |||
| 616 | return fboxMake(gen0State->params); | |||
| 617 | } | |||
| 618 | ||||
| 619 | localstatic Foam | |||
| 620 | gen0IssueLocals(void) | |||
| 621 | { | |||
| 622 | return fboxMake(gen0State->localPool->fbox); | |||
| 623 | } | |||
| 624 | ||||
| 625 | localstatic Foam | |||
| 626 | gen0IssueFluids(void) | |||
| 627 | { | |||
| 628 | return foamNewOfList(FOAM_DFluid, (FoamList) gen0State->fluidsUsed); | |||
| 629 | } | |||
| 630 | ||||
| 631 | localstatic Foam | |||
| 632 | gen0IssueLevels(void) | |||
| 633 | { | |||
| 634 | SlotUsageList fu = gen0State->formatUsage; | |||
| 635 | Length i, argc = listLength(SlotUsage)(SlotUsage_listPointer->_Length)(fu); | |||
| 636 | Foam levels; | |||
| 637 | ||||
| 638 | levels = foamNewEmpty(FOAM_DEnv, argc); | |||
| 639 | for (i = 0; fu; i += 1, fu = cdr(fu)((fu)->rest)) | |||
| 640 | levels->foamDEnv.argv[i] = suVal(car(fu))( (((fu)->first) & 2) == 2 ? ((((fu)->first)) >> 2): *(int*) 0); | |||
| 641 | ||||
| 642 | if (genfEnvDebug) { | |||
| 643 | afprintf(dbOut, "Issue levels - stack %pAIntList\n", gen0State->formatStack); | |||
| 644 | afprintf(dbOut, "Issue levels - usage %pSlotUsageList\n", gen0State->formatUsage); | |||
| 645 | afprintf(dbOut, "Issue levels - %pFoam\n", levels); | |||
| 646 | } | |||
| 647 | return levels; | |||
| 648 | } | |||
| 649 | ||||
| 650 | /* | |||
| 651 | * :: Utilities | |||
| 652 | */ | |||
| 653 | ||||
| 654 | Foam | |||
| 655 | gen0BuildFunFromFoam(String name, FoamTag retType, Foam body) | |||
| 656 | { | |||
| 657 | return gen0BuildFunFromFoam0(name, retType, int0((int) 0), body); | |||
| 658 | } | |||
| 659 | ||||
| 660 | Foam | |||
| 661 | gen0BuildFunFromFoam0(String name, FoamTag retType, AInt retFmt, Foam body) | |||
| 662 | { | |||
| 663 | GenFoamState saved; | |||
| 664 | Foam foam, clos; | |||
| 665 | ||||
| 666 | clos = foamNewClos(foamNewEnv(-1), foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(-1)), foamNew (FOAM_Const, 1, (AInt)(gen0NumProgs))); | |||
| 667 | foam = gen0ProgInitEmpty(name, NULL((void*)0)); | |||
| 668 | ||||
| 669 | saved = gen0ProgSaveState(PT_Gener); | |||
| 670 | ||||
| 671 | gen0AddStmt(foamNewReturn(body)foamNew(FOAM_Return, 1, body), NULL((void*)0)); | |||
| 672 | ||||
| 673 | gen0UseStackedFormat(int0((int) 0)); | |||
| 674 | gen0ProgPushFormat(emptyFormatSlot4); | |||
| 675 | gen0ProgPushFormat(emptyFormatSlot4); | |||
| 676 | gen0ProgFiniEmpty(foam, retType, retFmt); | |||
| 677 | ||||
| 678 | gen0AddLexLevels(foam, 2); | |||
| 679 | ||||
| 680 | foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0)); | |||
| 681 | ||||
| 682 | gen0ProgRestoreState(saved); | |||
| 683 | return clos; | |||
| 684 | } | |||
| 685 | ||||
| 686 | Foam | |||
| 687 | gen0BuildFunFromFoam1(String name, FoamTag retType, AInt retFmt, Foam body) | |||
| 688 | { | |||
| 689 | GenFoamState saved; | |||
| 690 | Foam foam, clos; | |||
| 691 | ||||
| 692 | clos = foamNewClos(foamNewEnv(0), foamNewConst(gen0NumProgs))foamNew(FOAM_Clos,2, foamNew(FOAM_Env, 1, (AInt)(0)), foamNew (FOAM_Const, 1, (AInt)(gen0NumProgs))); | |||
| 693 | foam = gen0ProgInitEmpty(name, NULL((void*)0)); | |||
| 694 | ||||
| 695 | saved = gen0ProgSaveState(PT_Gener); | |||
| 696 | ||||
| 697 | gen0AddStmt(foamNewReturn(body)foamNew(FOAM_Return, 1, body), NULL((void*)0)); | |||
| 698 | ||||
| 699 | gen0UseStackedFormat(int0((int) 0)); | |||
| 700 | gen0ProgPushFormat(emptyFormatSlot4); | |||
| 701 | gen0ProgPushFormat(emptyFormatSlot4); | |||
| 702 | gen0ProgFiniEmpty(foam, retType, retFmt); | |||
| 703 | ||||
| 704 | gen0AddLexLevels(foam, 1); | |||
| 705 | ||||
| 706 | foamOptInfo(foam)((foam)->hdr.info.opt) = optInfoNew(NULL((void*)0), foam, NULL((void*)0), false((int) 0)); | |||
| 707 | ||||
| 708 | gen0ProgRestoreState(saved); | |||
| 709 | return clos; | |||
| 710 | } |