view runtime/func.h @ 75:0083b2f7b3c7

Partially working implementation of List. Modified build scripts to allow use of other compilers. Fixed some bugs involving method implementations on different types returning different numbers of outputs. Added Fold to the 'builtins' in the comipler.
author Mike Pavone <pavone@retrodev.com>
date Tue, 06 Jul 2010 07:52:59 -0400
parents a844c623c7df
children 6d10b5b9ebc3
line wrap: on
line source

#ifndef _FUNC_H_
#define _FUNC_H_

typedef struct object object;
typedef struct calldata calldata;

typedef enum {
	NORMAL_RETURN=0,
	EXCEPTION_RETURN,
	TAIL_RETURN,
	NO_CONVERSION,
	STACK_UNWIND
} returntype;


typedef returntype (*rhope_func)(calldata *);
typedef void (*special_func) (object *);

#define MethodName(name,type) f_ ## name ## AT_ ## type


#define Func(name,numparams) \
f_ ## name:\
		for(idx = numparams; idx < cdata->num_params; ++idx)\
			release_ref(cdata->params[idx]); cdata->num_params = numparams;\
sf_ ## name:\
		lv_ ## name = alloc_stack(ct, sizeof(lt_ ## name));\
		my_cdata = cdata;


#define FuncNoLocals(name,numparams) \
f_ ## name:\
		for(idx = numparams; idx < cdata->num_params; ++idx)\
			release_ref(cdata->params[idx]); cdata->num_params = numparams;\
sf_ ## name:\
		my_cdata = cdata;		

#define EndFunc(name)	\
		free_stack(ct, lv_ ## name);\
		func = cdata->func;
	
#define EndFuncNoLocals	\
		func = cdata->func;

#define Method(name) \
f_ ## name:\
sf_ ## name:\
		switch(get_blueprint(cdata->params[0])->type_id)\
		{
			
#define EndMethod(name) \
		default:\
			printf("Type %d does not implement method %s\n", get_blueprint(cdata->params[0])->type_id, #name);\
			cdata = alloc_cdata(ct, cdata, 0);\
			cdata->func = FUNC_ ## name;\
			goto _exception;\
		}
			
			
#define MethodDispatch(type_id,name,type_name) \
		case type_id:\
			goto m_ ## name ## AT_ ## type_name;
			
#define MethodImpl(name,type_name,mytype_id,numparams) \
f_ ## name ## AT_ ## type_name:\
sf_ ## name ## AT_ ## type_name:\
		if (cdata->num_params < 1)\
		{\
			cdata = alloc_cdata(ct, cdata, 0);\
			cdata->func = FUNC_ ## name ## AT_ ## type_name;\
			goto _exception;\
		}\
		if(get_blueprint(cdata->params[0])->type_id != mytype_id)\
		{\
			puts("uh oh, need conversion and that's not implemented yet!");\
			exit(1);\
		}\
m_ ## name ## AT_ ## type_name:\
		for(idx = numparams; idx < cdata->num_params; ++idx)\
			release_ref(cdata->params[idx]); cdata->num_params = numparams;\
		lv_ ## name ## AT_ ## type_name = alloc_stack(ct, sizeof(lt_ ## name ## AT_ ## type_name));\
		my_cdata = cdata;
			
				
#define MethodImplNoLocals(name,type_name,mytype_id,numparams) \
f_ ## name ## AT_ ## type_name:\
sf_ ## name ## AT_ ## type_name:\
		if (cdata->num_params < 1)\
			cdata = alloc_cdata(ct, cdata, 0);\
			cdata->func = FUNC_ ## name ## AT_ ## type_name;\
			goto _exception;\
		if(get_blueprint(cdata->params[0])->type_id != mytype_id)\
		{\
			puts("uh oh, need conversion and that's not implemented yet!");\
			exit(1);\
		}\
m_ ## name ## AT_ ## type_name:\
		for(idx = numparams; idx < cdata->num_params; ++idx)\
			release_ref(cdata->params[idx]); cdata->num_params = numparams;\
		my_cdata = cdata;
			
#define NumParams
#define CallSpace

#define Param(num,convtypeid) \
	if(get_blueprint(cdata->params[num])->type_id != convtypeid)\
	{\
		printf("uh oh, need conversion from type %d to type %d for param %d and that's not implemented yet!", get_blueprint(cdata->params[num])->type_id, convtypeid, num);\
		goto _exception;\
	}

#define CopiedParam(num,convtypeid) Param(num,convtypeid) cdata->params[num] = copy_object(cdata->params[num]);
#define Ret(num,val) cdata->params[num] = (object *)(val);
#define NumRet(num) cdata->num_params = num;
#define Exception
#define FuncDef(name) lt_ ## name * lv_ ## name;
#define MethodDef(name) lt_ ## name ## AT_ ## type_name * lv_ ## name ## AT_ ## type_name;


#define PrepCall(callspace) cdata = alloc_cdata(ct, cdata, callspace);

#define SetParam(num,value) cdata->params[num] = value;

#define VCPrepCall(func,numparams) \
	cdata = alloc_cdata(ct, cdata, numparams + ((t_Worker *)func)->payload.Count);\
	vcparam_offset = 0;

#define VCSetParam(func,num,value) \
	while((num+vcparam_offset) < ((t_Worker *)func)->payload.Size && ((object **)(((t_Worker *)func)+1))[num+vcparam_offset])\
	{\
		cdata->params[num+vcparam_offset] = add_ref(((object **)(((t_Worker *)func)+1))[num+vcparam_offset]);\
		++vcparam_offset;\
	}\
	cdata->params[num+vcparam_offset] = value;\
	last_vcparam = num+vcparam_offset;

#define ValCall(tocall,numparams,resumeto,myname)\
	last_vcparam++;\
	while(last_vcparam < ((t_Worker *)tocall)->payload.Size)\
	{\
		if (((object **)(((t_Worker *)tocall)+1))[last_vcparam]) \
			cdata->params[last_vcparam] = add_ref(((object **)(((t_Worker *)tocall)+1))[last_vcparam]);\
		++last_vcparam;\
	}\
	cdata->func = RES_  ## resumeto ## _ ## myname;\
	cdata->num_params = numparams + ((t_Worker *)tocall)->payload.Count;\
	cdata->vars = lv_ ## myname;\
	func = ((t_Worker *)tocall)->payload.Index;

#define ValCallPostlude(resumeto,myname)\
r ## resumeto ## _ ## myname:\
	my_cdata = cdata->lastframe;\
	lv_ ## myname = cdata->vars;


#define Call(tocall, numparams, resumeto, myname)\
			cdata->func = RES_  ## resumeto ## _ ## myname;\
			cdata->num_params = numparams;\
			cdata->vars = lv_ ## myname;\
			goto sf_ ## tocall;\
r ## resumeto ## _ ## myname:\
			my_cdata = cdata->lastframe;\
			lv_ ## myname = cdata->vars;
			
	
#define FreeCall\
			temp_cdata = cdata->lastframe;\
			free_stack(ct, cdata);\
			cdata = temp_cdata;

#define FreeCallMethod(myname,mytype)\
			temp_cdata = cdata->lastframe;\
			free_stack(ct, cdata);\
			cdata = temp_cdata;\
			lv_ ## myname ## AT_ ## type_name = (lt_ ## myname ## AT_ ## type_name *)(cdata+1);
			
#define TPrepCall(callspace) \
			func = cdata->lastframe->func;\
			temp_cdata = cdata->lastframe->lastframe;\
			free_stack(ct, cdata->lastframe);\
			cdata = alloc_cdata(ct, temp_cdata, callspace);\
			cdata->func = func;
			
#define TCall(tocall, numparams)\
			cdata->num_params = numparams;\
			goto sf_ ## tocall;
	
	
#endif //_FUNC_H_