local Foam gen1ImplicitExportArg(TForm tf, Length i) { FoamTag fmtype; Foam decl; Symbol sym; String symstr; /* What was the name of this parameter? */ sym = gen0ImplicitArgName(i); symstr = strCopy(symString(sym)); /* What is the type of this argument? */ fmtype = gen0Type(tf, NULL); /* Create a declaration for this parameter */ decl = foamNewDecl(fmtype, symstr, emptyFormatSlot); /* Add the new parameter to the FOAM prog */ gen0AddParam(decl); /* Return the FOAM for this parameter */ return foamNewPar(i); }
local void testDDecl() { Foam ddecl = foamNewDDecl(FOAM_DDecl_Local, foamNewDecl(FOAM_SInt, strCopy("fred"), emptyFormatSlot), NULL); testIntEqual("tag", FOAM_DDecl, foamTag(ddecl)); testIntEqual("argc", 1, foamDDeclArgc(ddecl)); }
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; }
/* NOTE: the macro vpNewVar(pool, type) can be used if fmtSlot not needed */ int vpNewVar0(VarPool pool, FoamTag type, int fmtSlot) { int var; if (pool->vars[type] != listNil(AInt)) { AIntList l = pool->vars[type]; var = car(l); pool->vars[type] = cdr(l); listFreeCons(AInt)(l); } else { String name = strCopy(""); Foam decl = foamNewDecl(type, name, fmtSlot); var = fboxAdd(pool->fbox, decl); } return var; }