local void testTests() { Foam foam = foamNewSet(foamNewLoc(1), foamNewLoc(1)); testFalse("", foamIsMultiAssign(foam)); foam = foamNewSet(foamNew(FOAM_Values, 2, foamNewLoc(1), foamNewLoc(2)), foamNewLoc(3)); testTrue("", foamIsMultiAssign(foam)); }
Foam genYield(AbSyn absyn) { /* set the place variable */ gen0AddStmt(foamNewSet(yieldPlaceVar, foamNewSInt(++gen0State->yieldCount)), absyn); gen0AddStmt(foamNewSet(foamCopy(gen0State->yieldValueVar), genFoamVal(absyn->abYield.value)), absyn); gen0AddStmt(foamNewGoto(gen0State->yieldPlace), absyn); gen0AddStmt(foamNewLabel(gen0State->labelNo), absyn); gen0State->yieldLabels = listCons(AInt)(gen0State->labelNo++, gen0State->yieldLabels); return 0; }
local Foam gen0GenerStepFun(AbSyn body, TForm tf) { GenFoamState saved; Foam foam, clos, tmp; FoamTag yieldType; AInt startLabel; AInt fmtSlot; clos = foamNewClos(foamNewEnv(-1), foamNewConst(gen0NumProgs)); foam = gen0ProgInitEmpty(stepperFName(), body); saved = gen0ProgSaveState(PT_Gener); startLabel = gen0State->labelNo++; gen0State->yieldPlace = gen0State->labelNo++; tf = tfDefineeType(tf); yieldType = gen0Type(tf, &fmtSlot); gen0State->yieldValueVar = gen0TempLocal0(yieldType, fmtSlot); tmp = foamNewNOp(); gen0AddStmt(tmp, NULL); /* filled by gen0GenerSelect */ gen0AddStmt(foamNewLabel(startLabel), NULL); gen0AddStmt(foamNewSet(yieldDoneVar, foamNewBool(int0)), NULL); genFoamStmt(body); gen0AddStmt(foamNewSet(yieldDoneVar, foamNewBool(1)), NULL); gen0AddStmt(foamNewReturn(foamNew(FOAM_Values, int0)), NULL); gen0AddStmt(foamNewLabel(gen0State->yieldPlace), NULL); gen0AddStmt(foamNewSet(yieldValVar, gen0State->yieldValueVar), NULL); gen0AddStmt(foamNewReturn(foamNew(FOAM_Values, int0)), NULL); gen0UseStackedFormat(int0); gen0ProgPushFormat(emptyFormatSlot); gen0ProgPushFormat(emptyFormatSlot); gen0ProgFiniEmpty(foam, FOAM_NOp, int0); /* fill in the select statement */ foam->foamProg.body->foamSeq.argv[0] = gen0GenerSelect(startLabel); foamFree(tmp); gen0AddLexLevels(foam, 2); foam->foamProg.infoBits = IB_SIDE | IB_INLINEME; foamOptInfo(foam) = inlInfoNew(gen0State->stab, foam, NULL, true); gen0ProgRestoreState(saved); return clos; }
/* * Construct the body of PackedRecordSet: (Ptr, %) -> % */ local void gen0ImplicitPRSet(FoamList pars, FoamTag repTag) { Foam parPtr, parVal, foam, cast; /* Get the pointer and cast to Arr */ assert(pars); parPtr = foamCopy(car(pars)); pars = cdr(pars); parPtr = foamNewCast(FOAM_Arr, parPtr); /* Get the value */ assert(pars); parVal = foamCopy(car(pars)); pars = cdr(pars); assert(!pars); /* Cast to raw type */ cast = foamNewCast(repTag, foamCopy(parVal)); /* Construct an array access */ foam = foamNewAElt(repTag, foamNewSInt(int0), parPtr); /* Create the update */ foam = foamNewSet(foam, cast); gen0AddStmt(foam, (AbSyn)NULL); /* Return the value inserted */ foam = foamNewReturn(parVal); gen0AddStmt(foam, (AbSyn)NULL); }
local Foam gen0RefSetter(Foam rid, AbSyn id, TForm tf) { /* Create the reference setter function */ GenFoamState saved; Foam foam, clos; AInt fmt, paridx; FoamTag type; Foam param; /* Create a closure for the function */ type = gen0Type(tf, &fmt); clos = foamNewClos(foamNewEnv(-1), foamNewConst(gen0NumProgs)); foam = gen0ProgInitEmpty(setterFName(), id); /* Save the current state and create a new one for us */ saved = gen0ProgSaveState(PT_ExFn); /* Update the state of this lambda */ gen0State->type = tfMap(tf, tf); /* T -> T */ gen0State->program = foam; /* Add a parameter */ param = foamNewDecl(type, strCopy("v"), emptyFormatSlot); paridx = gen0AddParam(param); /* Generate the code for { free x:T; x := v; return v } */ /* gen0AddStmt(foamNewSet(gen0RefId(id), foamNewPar(paridx)), id); */ gen0AddStmt(foamNewSet(foamCopy(rid), foamNewPar(paridx)), id); gen0AddStmt(foamNewReturn(foamNewPar(paridx)), id); /* Standard gubbins ... */ gen0UseStackedFormat(int0); gen0ProgPushFormat(emptyFormatSlot); gen0ProgPushFormat(emptyFormatSlot); /* Two lexical levels */ gen0ProgFiniEmpty(foam, type, fmt); gen0AddLexLevels(foam, 2); /* Optimisation bits */ foam->foamProg.infoBits = IB_SIDE | IB_INLINEME; foamOptInfo(foam) = inlInfoNew(NULL, foam, NULL, false); /* Restore the saved state before returning. */ gen0ProgRestoreState(saved); return clos; }
Foam gen0CacheClos(AbSyn ab, int nargs, Foam fnClos) { /* ab is just for position... */ Foam *paramv; RTCacheInfo cache; Foam var, clos, fnVar, foam; Foam call; FoamTag retType = FOAM_Word; AInt index; int i; cache = gen0CacheMakeEmpty(ab); fnVar = gen0TempLex(FOAM_Word); paramv = (Foam*) stoAlloc(OB_Other, nargs* sizeof(Foam)); gen0AddStmt(cache->init, cache->ab); gen0AddStmt(foamNewSet(fnVar, fnClos), ab); gen0AddLexLevels(fnVar, 1); clos = gen0ProgClosEmpty(); foam = gen0ProgInitEmpty(gen0ProgName, NULL); index = gen0FormatNum; gen0ProgPushState(NULL, GF_Lambda); gen0State->type = NULL; gen0State->program = foam; gen0PushFormat(index); call = foamNewEmpty(FOAM_CCall, nargs+2); call->foamCCall.op = foamCopy(fnVar); call->foamCCall.type = FOAM_Word; for (i=0; i < nargs; i++) { paramv[i] = foamNewPar(i); call->foamCCall.argv[i] = foamNewPar(i); } gen0CacheCheck(cache, nargs, paramv); var = gen0CacheReturn(cache, call); gen0AddStmt(foamNewReturn(var), ab); gen0ProgAddFormat(index); gen0ProgFiniEmpty(foam, retType, int0); foamOptInfo(foam) = inlInfoNew(NULL, foam, NULL, false); gen0ProgPopState(); stoFree(paramv); gen0CacheKill(cache); return clos; }
void gen0MakeEmptyTuple(Foam argc, Foam *vals, AbSyn loc) { int format; Foam t1, t2; /*!! This should be a callout to tuple$Tuple(S) */ t1 = gen0TempLocal0(FOAM_Arr, FOAM_Word); gen0AddStmt(foamNewSet(foamCopy(t1), foamNewANew(FOAM_Word, argc)), loc); format = gen0MakeTupleFormat(); t2 = gen0TempLocal0(FOAM_Rec, format); gen0AddStmt(gen0RNew(t2, format), loc); gen0AddStmt(gen0RSet(t2, format, (AInt) 0, foamCopy(argc)), loc); gen0AddStmt(gen0RSet(t2, format, (AInt) 1, t1), loc); vals[0] = foamNewCast(FOAM_Word, t2); vals[1] = t1; }
/* * Construct the body of PackedArraySet: (Arr, SInt, %) -> % */ local void gen0ImplicitPASet(FoamList pars, FoamTag repTag) { Foam parArr, parElt, parVal, foam, cast; /* Get the array */ assert(pars); parArr = foamCopy(car(pars)); pars = cdr(pars); /* Get the index */ assert(pars); parElt = foamCopy(car(pars)); pars = cdr(pars); /* Get the value */ assert(pars); parVal = foamCopy(car(pars)); pars = cdr(pars); assert(!pars); /* Cast to raw type */ cast = foamNewCast(repTag, foamCopy(parVal)); /* Construct an array access */ foam = foamNewAElt(repTag, parElt, parArr); /* Create the update */ foam = foamNewSet(foam, cast); gen0AddStmt(foam, (AbSyn)NULL); /* Return the value inserted */ foam = foamNewReturn(parVal); gen0AddStmt(foam, (AbSyn)NULL); }
local Foam gen0GenerBodyFun(AbSyn iter, TForm tf) { Scope("genBody0"); FoamList topLines; Bool flag; GenerGenInfo fluid(gen0GenInfo); GenBoundCalc calc = NULL; AbSyn body = iter->abGenerate.body; AbSyn bound = iter->abGenerate.count; FoamTag retType = gen0Type(tf, NULL); Foam fluid(gen0GenVars); GenFoamState saved; Foam foam, clos, stmt; Foam done, step, bnd, value; gen0GenInfo = NULL; #ifdef GenerBetterGuesses if (!bound || abTag(bound) == AB_Nothing) { calc = gen0MakeBoundInit(body); gen0ComputeGeners(); } #endif flag = gen0AddImportPlace(&topLines); clos = gen0ProgClosEmpty(); foam = gen0ProgInitEmpty("generBaseFn", body); saved = gen0ProgSaveState(PT_Gener); gen0GenVars = gen0MakeGenerVars(tf); step = gen0GenerStepFun(body, tf); done = gen0GenerDoneFun(); value = gen0GenerValueFun(retType, tf); bnd = gen0GenerBoundFun(bound, calc); stmt = foamNewReturn(foamNew(FOAM_Values, 4, done, step, value, bnd)); gen0AddStmt(stmt, body); gen0UseStackedFormat(int0); gen0ProgPushFormat(int0); gen0ProgFiniEmpty(foam, FOAM_NOp, int0); foam->foamProg.format = gen0MakeGenerRetFormat(); gen0AddLexLevels(foam, 1); foam->foamProg.infoBits = IB_SIDE | IB_INLINEME; foamOptInfo(foam) = inlInfoNew(NULL, foam, NULL, false); if (gen0GenInfo) stoFree(gen0GenInfo); gen0ProgRestoreState(saved); if (flag) gen0ResetImportPlace(topLines); stmt = foamNewSet(yieldPlaceVar, foamNewSInt(int0)); gen0AddStmt(stmt, iter); foamFree(gen0GenVars); gen0GenVars = NULL; Return(clos); }