view runtime/func.h @ 57:2174878a6e4b

Avoid unnecessary nested switch
author Mike Pavone <pavone@retrodev.com>
date Thu, 08 Oct 2009 02:12:25 -0400
parents d2f9b0a9403d
children 4c22fe798779
line wrap: on
line source

#ifndef _FUNC_H_
#define _FUNC_H_

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


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

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


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


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

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

#define Method(name) \
	case FUNC_ ## name:\
f_ ## name:\
		if (cdata->num_params < 1)\
			goto _exception;\
		switch(get_blueprint(cdata->params[0])->type_id)\
		{
			
#define EndMethod \
		default:\
			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) \
	case FUNC_ ## name ## _AT_ ## type_name:\
f_ ## name ## _AT_ ## type_name:\
		if (cdata->num_params < 1)\
			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[0-idx]); cdata->num_params = numparams;\
		lv_ ## name ## _AT_ ## type_name = alloc_stack(ct, sizeof(lt_ ## name ## _AT_ ## type_name));
			
				
#define MethodImplNoLocals(name,type_name,mytype_id,numparams) \
		case FUNC_ ## name ## _AT_ ## type_name:\
f_ ## name ## _AT_ ## type_name:\
		if (cdata->num_params < 1)\
			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[0-idx]); cdata->num_params = numparams;
			
#define NumParams
#define CallSpace

#define Param(num,convtypeid) \
	if(get_blueprint(cdata->params[0-num])->type_id != convtypeid)\
	{\
		puts("uh oh, need conversion and that's not implemented yet!");\
		exit(1);\
	}

#define CopiedParam(num,convtypeid) Param(num,convtypeid) cdata->params[num] = copy_object(cdata->params[num]);
#define Ret(num,val) cdata->params[0-num] = (object *)(val);
#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[0-num] = value;

#define Call(tocall, numparams, resumeto, myname)\
			cdata->func = FUNC_ ## myname ## _ ## resumeto;\
			cdata->num_params = numparams;\
			goto f_ ## tocall;\
		case FUNC_ ## myname ## _ ## resumeto:\
			lv_ ## myname = (lt_ ## myname *)(cdata->lastframe+1);
	
#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 TCall(func, numparams)\
	free_stack(cdata->ct, call);\
	cdata->num_params = numparams;\
	cdata->resume = 0;\
	cdata->tail_func = f_ ## func;\
	return TAIL_RETURN;
	
	
#endif //_FUNC_H_