示例#1
0
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;
}
示例#2
0
文件: gf_rtime.c 项目: dokterp/aldor
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;
}
示例#3
0
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);
}
示例#4
0
local void
testCall()
{
	Foam foam;

	foam = foamNew(FOAM_OCall, 3, FOAM_Clos, foamNewNil(), foamNewNil());
	testIntEqual("foamOCallArgc", 0, foamOCallArgc(foam));

	foam = foamNew(FOAM_OCall, 4, FOAM_Clos, foamNewNil(), foamNewNil(), foamNewSInt(1));
	testIntEqual("foamOCallArgc", 1, foamOCallArgc(foam));

	foam = foamNewPCall(FOAM_Proto_C, FOAM_NOp, foamNewGlo(int0), NULL);
	testIntEqual("argc", 0, foamPCallArgc(foam));
	testIntEqual("protocol", FOAM_Proto_C, foam->foamPCall.protocol);

	foam = foamNewCCall(FOAM_Word, foamNewGlo(int0), NULL);
	testIntEqual("argc", 0, foamCCallArgc(foam));
	testTrue("op", foamEqual(foamNewGlo(int0), foam->foamCCall.op));

	foam = foamNewCCall(FOAM_Word, foamNewGlo(int0), foamNewPar(1), NULL);
	testIntEqual("argc", 1, foamCCallArgc(foam));
	testTrue("op", foamEqual(foamNewPar(1), foam->foamCCall.argv[0]));
}