#include "include/glbtypes.h"
#include "include/glbproto.h"
#include "include/globvars.h"

int exec_inline_func(struct fundef PTR fn,listnode args,listnode labels,struct vardecl_listoflist PTR vars,struct type_listoflist PTR types,listnode fnlist)
	{
	listnode l;
	struct vardecl_listoflist this_vars;
	struct type_listoflist this_types;
	struct vardecl_list PTR varind;
	if(fn==NULL)
		{
		fprintf(stderr,"exec_inline_func(): fn==NULL !\n");
		return 0;
		};
	if(fn->kind!=is_inline)
		{
		fprintf(stderr,"exec_inline_func(): function \"%s\" is not inline !\n",fn->name);
		return 0;
		};
	if(fn->def_to_use.inline_fndef==NULL)
		{
		fprintf(stderr,"exec_inline_func(): in function \"%s\" inline_fndef==NULL !\n",fn->name);
 		return 0;
		};
	printf("## Executing inline function %s\n",fn->name);
	this_vars.next=vars;
	this_types.next=types;
	this_vars.vlist=fn->def_to_use.inline_fndef->vars;
	this_types.tlist=fn->def_to_use.inline_fndef->types;

	for(l=fn->def_to_use.inline_fndef->body;l!=NULL;l=l->next)
		{
		listnode out,argind;
		if(l->attr==TWOLISTS)
			{
			if(l->data==NULL)
				continue;
			else
				out=copylist((listnode)l->data);
			}
		else
			{
			fprintf(stderr,"exec_inline_func(): in function \"%s\" in body attr!=TWOLISTS !\n",fn->name);
 			return 0;
			};
		for(varind=fn->args,argind=args;(varind!=NULL)&(argind!=NULL);varind=varind->next,argind=argind->next)
			{
			if(varind->var!=NULL)
				{
				if(varind->var->name!=NULL)
					{
					lnd_replace(out,varind->var->name,ASSOCVAR,(argind->attr==TWOLISTS)?(void *)copylist((listnode)argind->data):Strdup(argind->data),argind->attr,2,0);
					};
				};
			};
		if(((void *)varind)!=((void *)argind))
		/* if one of the lists isn't NULL */
			{
			fprintf(stderr,"exec_inline_func(): in function \"%s\"\n amount of actual arguments is % then amount of formal params\n",fn->name,(argind==NULL)?"smaller":"greater");
			rm_lnd_all(out);
			return 0;
			};
		mk_asm_output(out,labels,&this_vars,&this_types,fnlist);
		rm_lnd_all(out);
		};
	return 1;
	};
