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


/* Get Function */

int get_function(
char * instr,
listnode dst,
defined_op oda,
listnode inl,
int skipname,
struct type_listoflist PTR types,
struct vardecl_listoflist PTR vars,
listnode fnlist)
{
listnode ltmp=NULL;
int namelen,i;
char * str,tok[33];
str=instr;
memset(tok,0,34);
if(!skipname)
	{
	namelen=get_expression(str,dst,oda,inl,1,types,vars,fnlist);
	if (!namelen)
		{
		namelen=get_variable(str)-str;
		if (!namelen) return 0;
		Strncpy(tok,str,namelen);
	/*	printf("Function %s \n",tok); */

		if(!Strcmp(tok,"sizeof"))
			{
			struct typerec PTR tmptype;
			str+=namelen;
			while(*str==32) str++;
			if(*str!='(')
				{
				printf("# !!! Seems to be a problem with sizeof - no \"(\" !!!\n");
				return 0;
				};
			str++;

			while(*str==32) str++;

			namelen=get_type_from_code(str,NULL,fnlist,types,vars,")",inl,oda,NULL,&tmptype);
			if(!namelen)
				{
				tmptype=NULL;
				namelen=get_variable(str)-str;
				if(namelen)
					{
					memset(tok,0,33);
					Strncpy(tok,str,namelen);
					};
				};

			if(!namelen)
				{
				printf("# !!! Can't get the arg of sizeof !!!\n");
				return 0;
				};
			str+=namelen;
			while(*str==32) str++;

			if(*str!=')')
				{
				printf("# !!! Seems to be a problem with sizeof - no \")\" !!!\n");
				return 0;
				};
			str++;

			if(tmptype!=NULL)
				{
				mk_set_lnd(dst,Strdup("\4sizeof_T"),FUNCTION);
				mk_set_lnd(dst,tmptype,TYPEDEFN);
				}
			else
				{
				mk_set_lnd(dst,Strdup("\4sizeof_V"),FUNCTION);
				mk_set_lnd(dst,Strdup(tok),VARIABLE);
				};

			return str-instr;
			}
		else if(!Strcmp(tok,"lambda"))
			{
			struct vardecl_listoflist argsl,fargsl;
			int chg;
			char * new_buffer,* keep_curr_glb_buf;
			struct typerec * tmptype=NULL,* ttype=NULL;

			str+=namelen;
			while(*str==' ') str++;
			if(*str!='(')
				return 0;
			str++;
			while(*str==' ') str++;

			chg=get_type_from_code(str,NULL,fnlist,types,vars,")",inl,oda,NULL,&tmptype);

			if(!chg)
				return 0;
			str+=chg;

			while(*str==' ') str++;
			if(*str!=')')
				return 0;
			str++;
			while(*str==' ') str++;
			if(*str!='(')
				return 0;
			str++;
			while(*str==' ') str++;

			mk_set_lnd(dst,Strdup("\4lambda"),FUNCTION);

			memset(tok,0,sizeof(tok));
			sprintf(tok,"\4tmptype%lx",global_tmp_type++);

			if(types->tlist==NULL)
				{
				types->tlist=my_malloc(sizeof(struct type_list));
				types->tlist->next=NULL;
				types->tlist->convert_lock=OFF;
				types->tlist->type=my_malloc(sizeof(struct typerec));
				set_typerec(types->tlist->type,4,Strdup(tok),ACTIONCLASS,NONE,__void__,NULL);
				ttype=types->tlist->type;
				}
			else
				ttype=install_type(types->tlist,4,Strdup(tok),ACTIONCLASS,NONE,__void__,NULL)->type;

			ttype->typebody.actionclass=my_malloc(sizeof(struct actionclass));
			ttype->typebody.actionclass->res_type=tmptype;

			argsl.next=vars;
			argsl.vlist=NULL;
			fargsl.next=&argsl;
			fargsl.vlist=NULL;

			chg=get_fn_arg_decl(str,types,&argsl,NULL,fnlist,oda,inl,NULL,1);
			if(chg==0)
				return 0;
			str+=chg;
			while(*str==' ') str++;
			if(*str!=')')
				return 0;
			str++;
			while(*str==' ') str++;
			if(*str!='(')
				return 0;
			str++;
			while(*str==' ') str++;

			chg=get_fn_arg_decl(str,types,&fargsl,NULL,fnlist,oda,NULL,NULL,1);
			if(chg==0)
				return 0;
			str+=chg;
			while(*str==' ') str++;
			if(*str!=')')
				return 0;
			str++;
			while(*str==' ') str++;

			mk_set_lnd(dst,argsl.vlist,VARDLIST);
			ttype->typebody.actionclass->args=fargsl.vlist;
			ttype->typebody.actionclass->attr=is_normal;

			ttype->typebody.actionclass->top_class=NULL;
			ttype->typebody.actionclass->local_vars=NULL;
			ttype->typebody.actionclass->local_types=NULL;
			ttype->typebody.actionclass->local_funcs=NULL;

			mk_set_lnd(dst,ttype,TYPEDEFN);
			
			keep_curr_glb_buf=current_global_buffer;
			new_buffer=create_new_buffer(str,64);
			ltmp=mk_set_lnd(NULL,NULL,PARTOFOP);
			get_code_block(new_buffer,ltmp,inl,oda,NULL,NULL,&fargsl,types,fnlist,1);
			current_global_buffer=keep_curr_glb_buf;
			normalize_buffer(str,64);

			lnd_rapnde(dst,rm_cdr_next(ltmp));
			ltmp=NULL;

			while(*str==' ')
				str++;		
			return str-instr;
			}
		else
			lnd_asapnde(dst,tok,FUNCTION);
		};
	str+=namelen;
	while(*str==32) str++;
	if (*str!='(')
		{
		rm_last_node(dst);
		return 0;
		};
	};
/* lnd_asapnde(dst,"(",256);
   lnd_stat=lnd_count(dst); */

do
	{
	str++;
	ltmp=mk_set_lnd(NULL,NULL,VARIABLE);
	namelen=get_expression(str,ltmp,oda,inl,0,types,vars,fnlist);
	if (namelen)
		lnd_rapnde(dst,op_to_function(rm_cdr_next(ltmp)));
	else
		{
		/*rm_listnode(get_nth_lnd(dst,lnd_stat+1));*/
		rm_lnd_all(ltmp);
		ltmp=NULL;
		namelen=get_variable(str)-str;
		if (!namelen)
			{
			while (*str==32) str++;
			if(*str!=')')
				{
				fprintf(stderr,"Syntax error in function !\n");
				return 0;
				};
/*			printf("It seems to be a function without arguments\n"); */
			str++;
/*			lnd_asapnde(dst,")",256); */
			return str-instr;
			};
		/******* Check for function ***/
		i=0;
		while (*(str+namelen+i)==32) i++;
		if (*(str+namelen+i)=='(') 
			namelen=get_function(str,dst,oda,inl,0,types,vars,fnlist);
		else
			{
			for(i=0;i<34;i++) tok[i]=0;
			Strncpy(tok,str,namelen);
/*			printf("Function argument %s \n",tok); */
			lnd_asapnde(dst,tok,VARIABLE);
			};
		};
		if (!namelen)
			{
			fprintf(stderr,"Syntax error in function !\n");
			return 0;
			};
/*		lnd_stat=lnd_count(dst); */
		str+=namelen;
		while(*str==32) str++;
	} while(*str==',');
if (*str!=')')
	{
	fprintf(stderr,"Syntax error in function !\n");
	return 0;
	};
str++;
/* lnd_asapnde(dst,")",256); */
return str-instr;
}


/* End get_function */

/******************************************************************************/
/*              Gets expression. IT MUST BE ((((( IN BRACKETS )))))           */
/*              Uses op_recognize several times to get multiple ops.          */
/******************************************************************************/

int get_expression(
char * instr,
listnode dst,
defined_op oda,
listnode inl,
int usebrct,
struct type_listoflist PTR types,
struct vardecl_listoflist PTR vars,
listnode fnlist)
{
char * str,tok[33];
listnode l1,l2;
int change=0;
/* int lnd_stat; // To remove garbage */
/* usebrct: 0 - no brackets, 1 - single brackets, 2 -multiple brackets,
3 - no brackets, but must be op starting with TOKEN, not var */

str=instr;
while(*str==' ') str++;
if ((usebrct==1)&(*str!='(')) return 0;

l1=mk_set_lnd(NULL,NULL,VARIABLE);
/* lnd_stat=lnd_count(l1); // Keep initial length */
if (usebrct==1)
	change=get_expression(str+1,l1,oda,inl,0,types,vars,fnlist)+1;
	/* To skip brackett */
if (!change)
	{
	if (usebrct==1)
		rm_listnode(l1); /* If there can be garbage lets clean it ! */
	if(usebrct==3)
		change=op_recognize(str,l1,oda,inl,-1,types,vars,fnlist);
		/* must be FIXED part of op at the beginning */
	else
		{
		if((!Strncmp(str,"lambda",6))&(!isidch(*(str+6))))
			change=get_function(str,l1,oda,inl,0,types,vars,fnlist);
		else
			change=op_recognize(str,l1,oda,inl,0,types,vars,fnlist);

		};
	};
if (!change)
	{
	rm_listnode(l1); /* Clear garbage */
	change=get_function(str,l1,oda,inl,0,types,vars,fnlist);
	};
if (!change)
	{
	rm_listnode(l1);  /* Clean garbage */
	if ((usebrct!=1)&(*str=='('))
		{
		char * keep_str;
		struct typerec PTR conv_type=NULL;

		keep_str=str;
		str++;
		while(*str==32) str++;

		str=str+get_type_from_code(str,NULL,fnlist,types,vars,")",inl,oda,NULL,&conv_type);

		if(conv_type!=NULL)
			{
			while(*str==32) str++;
			if(*str!=')')
				{
				printf("Internal error\n");
				exit(0);
				};
			str++;

			l2=mk_set_lnd(NULL,NULL,VARIABLE);

			while(*str==32) str++;

			change=get_expression(str,l2,oda,inl,usebrct,types,vars,fnlist);

			if(!change) /* maybe variable ? */
				{
				rm_listnode(l2);
				change=get_variable(str)-str;
				if(change)
					{
					memset(tok,0,33);
					strncpy(tok,str,change);
					lnd_asapnde(l2,tok,VARIABLE);
					};
				};

			if(!change)
				{
				rm_lnd_all(l2);
				str=keep_str;
				}
			else
				{
				change+=(str-keep_str);

				mk_set_lnd(l1,"\4typeadjust",FUNCTION);
				mk_set_lnd(l1,conv_type,TYPEDEFN);

				if(l2->next->attr==VARIABLE)
					lnd_rapnde(l1,l2->next);
				else
					mk_set_lnd(l1,l2->next,TWOLISTS);

				str=keep_str;
				};
			}
		else
			{
			str=keep_str;
			usebrct=1;
			change=get_expression(str+1,l1,oda,inl,2,types,vars,fnlist)+1;
			};
		}
	else
		if(usebrct==2) /* variable ((((( in brackets ))))) */
			{
			for (change=0;change<34;change++) tok[change]=0;
			change=get_variable(str)-str;
			/* maybe it's just a variable */
			if (change)
				{
				Strncpy(tok,str,change);
				lnd_asapnde(l1,tok,VARIABLE);
				};
			};

	};
if (change)
	l1=rm_cdr_next(l1);

if ((usebrct==1)&(!!change))
	{
	while(*(str+change)==32) change++;
	if (*(str+change)==')')
		{
		change++;
		str+=change;
		lnd_rapnde(dst,l1);
		return str-instr;
		}
	else
		return 0;
	}

while(change)
	{
	str+=change;
	l2=mk_set_lnd(NULL,NULL,VARIABLE);
	change=op_recognize(str,l2,oda,inl,1,types,vars,fnlist);

	if (!change)
		rm_lnd_all(l2);
	else    /* if (change!=0) then ... */
		l1=get_exp_lst_ins(l1,l2,usebrct);
	if (usebrct==1) usebrct--; /* (2+3)^5*6 */
	};


lnd_rapnde(dst,l1);

while(*str==32) str++;
/*
if (usebrct)
	{
	if (*str!=')')
		{
		fprintf(stderr,"Syntax error !\n");
//		rm_listnode(get_nth_lnd(dst,lnd_stat));// Clear garbage
		return 0;
		};
	str++;
//	lnd_asapnde(dst,")",256);
	};
//if (!(str-instr)) rm_listnode(get_nth_lnd(dst,lnd_stat));// Clear garbage
*/
return str-instr;
}


/***************************** End get_expression *********************************/








/* get_exp__lst_ins */
listnode get_exp_lst_ins(listnode mainlist,listnode toappend,int usebrct)
{
listnode l1,l3,ltmp;
int priority;

/* keep_m_list=mainlist; */
toappend->data=NULL;
ltmp=toappend;
toappend=toappend->next;
l3=mainlist;

if((l3->attr==VARIABLE)||usebrct) /* variable at the beginning */
	{
	((listnode)(toappend->next)->data)->next=l3; /* put the variable */
	Free(ltmp);
	return toappend;   /* we are done !!! */
	};

priority=(toappend->attr==OPDEFPTR)?((defined_op)toappend->data)->prec:FUNC_PREC;

((listnode)(toappend->next)->data)->next=ltmp;

	if(((l3->attr==OPDEFPTR)?((defined_op)l3->data)->prec:FUNC_PREC) < priority)
		{
		while (((l3->attr==OPDEFPTR)?((defined_op)l3->data)->prec:FUNC_PREC) < priority)
			{

			l3=lnd_cdre(l3->next);
			if(l3->attr==TWOLISTS)
				{
				l1=l3;
				l3=(listnode)l3->data;
				if (l3->next!=NULL) l3=l3->next;
				} else break;
			};
		if(((l3->attr==OPDEFPTR)?((defined_op)l3->data)->prec:FUNC_PREC) < priority)
			{
			*ltmp=*((listnode)l1->data)->next;
			((listnode)l1->data)->next=toappend;
			}
		else
			{
			ltmp->next=l3->next;
			ltmp->data=l3->data;
			ltmp->attr=l3->attr;

			l3->attr=TWOLISTS;
			l3->next=NULL;
			l3->data=(char PTR) toappend; /* dumb AIX cc  needs this */
			};
		} else

	{
	ltmp->attr=TWOLISTS;
	ltmp->next=NULL;
	ltmp->data=(char PTR) mainlist;/* dumb AIX cc */
	mainlist=toappend;
	};
return mainlist;
}

listnode op_to_function(listnode l)
{
  enum opdef_attr attr;
  listnode out1,lptr,assocptr,ltmp;
  struct type_list * tl=NULL;
  if(l==NULL)
    return NULL;
  if (l->attr==TWOLISTS) 
    l->data=(char PTR)op_to_function((listnode)l->data);/* dumb AIX cc */ 
  if (l->attr==FUNCAVAR)
    {
      for(ltmp=(listnode)l->data;ltmp->next!=NULL;ltmp=ltmp->next)
        ltmp->next=op_to_function(ltmp->next);
      l->attr=TWOLISTS;
    };

if (l->attr!=OPDEFPTR) return l;
if(((defined_op)l->data)->fdef.opdef==NULL) return l;
attr=((defined_op)l->data)->attr;
out1=copylist(((defined_op)l->data)->fdef.opdef);
for(lptr=out1;lptr->next!=NULL;)
	{
	if((lptr->next->attr!=VARIABLE)&(lptr->next->attr!=ASSOCVAR))
		{
		  if(lptr->next->attr==TWOLISTS)
		    {
		      if((((listnode)lptr->next->data)->attr==VARIABLE)
			 &(((listnode)lptr->next->data)->next==NULL))
			{
			  assocptr=(listnode)lptr->next->data;
			  lptr->next=lptr->next->next;
			  Free(lptr->next); /* we don't need this */
			  lptr->next=assocptr;
			}
		      else if(((listnode)lptr->next->data)->next!=NULL)
			{
			  if(((listnode)lptr->next->data)->next->attr=TYPEDEFN)
			    {
			      struct type_list * tmp_tl;
			      tmp_tl=tl;
			      tl=my_malloc(sizeof(struct type_list));
			      tl->next=tmp_tl;
			      tl->type=my_malloc(sizeof(struct typerec));
			      tl->type->name=strdup(((listnode)lptr->next->data)->data);
			      tl->type->typekind=TYPEREFR;
			      tl->type->typemodf=NONE;
			      tl->type->typebody.pointer_to=(struct typerec *)((listnode)lptr->next->data)->next->data;
			      global_type_id_count++;
			      tl->type->typeid=global_type_id_count;
			    }
		        };
		      lptr=lptr->next;
		      continue; /* we need variable */
		   };
		};
	for(assocptr=l;assocptr!=NULL;assocptr=assocptr->next)
		{
		if (assocptr->attr!=TWOLISTS) continue; /* It can't be associated var */
		/* recursively converting op's */
		((listnode)assocptr->data)->next=op_to_function(((listnode)assocptr->data)->next);
		if (!Strcmp(lptr->next->data,((listnode)assocptr->data)->data))
			/* equal,got it ! */
			{
			Free(lptr->next->data); /* collect garbage */
			lptr->next->data=(char PTR)copylist(((listnode)assocptr->data)->next);
			/* we copied assocptr already, use it as tmp var */
			assocptr=(listnode)lptr->next->data;
			if(assocptr->attr==FUNCTION)
				{
				lptr->next->attr=TWOLISTS;
				lptr=lptr->next;
				}
			else
				{
				ltmp=lnd_cdre(assocptr);
				ltmp->next=lptr->next->next;
				Free(lptr->next);
				lptr->next=assocptr;
				lptr=ltmp;/* go to the end of the list */
				};
			break;/* we found what we was looking for */
			};
		};
	if(assocptr==NULL)
		{
		if(attr==NOTYPECK) /* in that case we may not
		need to substitute vars, as in "->" */
			lptr=lptr->next;
		else
			{
			fprintf(stderr,"op_to_function: can't find associated var for %s !\n",lptr->next->data);
			lptr=lptr->next;
			};
		};
	};
rm_lnd_all(l);/* we are done ... */
if(tl!=NULL)
  out1=mk_head_lnd(mk_head_lnd(mk_head_lnd(NULL,tl,TYPELIST),out1,TWOLISTS),strdup("\4add_var_type_layer"),FUNCTION);
return out1;
}


/* get_fn_arg_decl - gets "function-style" vars declaration, i.e. declarations
separated by comas */

int get_fn_arg_decl(
char * instr,
struct type_listoflist PTR tlist,
struct vardecl_listoflist PTR vlist,
listnode labels,listnode fnlist,
defined_op d_ops,
listnode inl,listnode inl_lab,
int usevars /* determines if I need to have varnames or just types */
)
{
int chg=0;
char * str;
str=instr;
while((*str!=0)&(*str!=')'))
	{
	   if(get_var_decl(str,tlist,vlist,labels,fnlist,d_ops,inl,inl_lab,(usevars)?10:9,&chg)==0)
		return 0;
	str+=chg;
	while(*str==' ')
		str++;
	if(*str==',')
		{
		str++;
		while(*str==' ')
			str++;
		if(*str==')')
			return 0; /* PUT ERROR MESSAGE HERE !!! */
		}
	else if(!Strncmp(str,"...",3))
		return str-instr;
	};
if(*str==')')
	return str-instr;
return 0;
}



int test_get_fn_decl(
char * instr,
struct type_listoflist PTR types,
struct vardecl_listoflist PTR vars,
listnode labels,listnode fnlist,
defined_op d_ops,
listnode inl,listnode inl_lab,
struct fundef PTR* res)
{
char local_buf[34];
char * str;
struct vardecl_listoflist tmpvarll;
int change=0;

str=get_variable_name(instr);
if(instr==str)
	return 0;

memset(local_buf,0,34);
strncpy(local_buf,instr,str-instr);

while(*str==32) str++;
if(*str!='(')
	return 0;

str++;
while(*str==32) str++;
change=str-instr;
instr=str;

(*res)=my_malloc(sizeof(struct fundef));
(*res)->name=Strdup(local_buf);
(*res)->args=NULL;
(*res)->attr=IS_EXPR;

if(*str==')')
	{
	(*res)->args=NULL;
	str++;
	while(*str==32)
		str++;
	change+=str-instr;
	instr=str;
	}
else
	{
	while(1)
		{

		if(!strncmp(str,"...",3))
			{
			printf("## FEXPR function\n");
			(*res)->attr=IS_FEXPR;
			str+=3;
			break;
			};

		if(!isidch(*str))
			{
			printf("## Not a function def !\n");
			Free((*res)->name);
			destroy_vardecl_list((*res)->args);
			Free(*res);
			*res=NULL;
			return 0;
			};

		str=get_variable_name(instr);
		memset(local_buf,0,34);
		strncpy(local_buf,instr,str-instr);

		if((get_type_by_name(local_buf,NONE,types)!=NULL)
		||(!Strcmp(local_buf,"typeof"))
		||(!Strcmp(local_buf,"struct"))
		||(!Strcmp(local_buf,"union"))
		||(!Strcmp(local_buf,"typedef")))
			{
			printf("## Declaration -  function %s\n",(*res)->name);
			tmpvarll.next=NULL;
			tmpvarll.vlist=(*res)->args;
			str=instr+get_fn_arg_decl(instr,types,&tmpvarll,labels,fnlist,d_ops,inl,inl_lab,1);
			(*res)->args=tmpvarll.vlist;

			if(instr==str)
				{
				printf("## Problem with args declaration !\n");
				Free((*res)->name);
				destroy_vardecl_list((*res)->args);
				Free(*res);
				*res=NULL;
				return 0;
				};
			change+=str-instr;
			instr=str;
			}
		else
			{
			if((*res)->args==NULL)
				(*res)->args=insert_var_decl((*res)->args,(char PTR)local_buf,get_type_by_name("int",NONE,types),NULL,0);
			else
				insert_var_decl((*res)->args,(char PTR)local_buf,get_type_by_name("int",NONE,types),NULL,0);

			change+=str-instr;
			instr=str;
			};

		while(*str==' ')
			str++;

		if(*str==')')
			break;

		if(*str!=',')
			{
			printf("## Problem with args declaration - \",\" or \")\" expected !\n");
			Free((*res)->name);
			destroy_vardecl_list((*res)->args);
			Free(*res);
			*res=NULL;
			return 0;
			};

		str++;
		while(*str==32) str++;
		change+=str-instr;
		instr=str;
		};
	if(*str!=')')
		{
		fprintf(stderr,"Error in MY code in test_get_fn_decl() !\n");
		exit(1);
		};
	str++;
	while(*str==32)
		str++;
	change+=str-instr;
	instr=str;

	};
if((*instr=='~')||(*instr=='{'))
	{
	change+=(*instr=='~')?1:0;
	return change;
	};

printf("## Declaration term symbol not found !\n");
Free((*res)->name);
destroy_vardecl_list((*res)->args);
Free(*res);
*res=NULL;
return 0;
}


int test_get_constr_destr(
char * instr,
struct typerec PTR cls,
struct type_listoflist PTR types,
struct vardecl_listoflist PTR vars,
listnode labels,listnode fnlist,
defined_op d_ops,
listnode inl,listnode inl_lab,
struct fundef PTR* fund)
{
struct fundef PTR res;
struct fundef_list PTR fltmp;
char local_buf[34];
char * str;
int mode=0; /* 0 - none, 1 - constructor, 2 - destructor */
int change=0;
struct type_list PTR tl=NULL;
struct typerec PTR type1=NULL;

str=get_variable_name(instr);
if(instr==str)
	return 0;

while(1)
	{
	struct type_list PTR tltmp;

	memset(local_buf,0,34);
	strncpy(local_buf,instr,str-instr);

	if(*local_buf=='~')
		{
		if(!Strcmp(local_buf+1,cls->name))
			{
			mode=2; /* destructor */
			break;
			};
		}
	else
		if(!Strcmp(local_buf,cls->name))
			{
			mode=1; /* constructor; */
			break;
			};

	if((type1=get_type_by_name(local_buf,NONE,types))==NULL)
		return 0;

	if(type1->typekind!=ACTIONCLASS)
		return 0;

	tltmp=tl;
	tl=my_malloc(sizeof(struct type_list));
	tl->next=tltmp;
	tl->type=type1;

	change+=str-instr;
	instr=str;
	str=get_variable_name(instr);
	if(instr==str)
		return 0;
	};

change+=test_get_fn_decl(instr,types,vars,labels,fnlist,d_ops,inl,inl_lab,&res);
if(res==NULL)
	return 0;
global_tmp_constr++;
sprintf(local_buf,"%c%lx%s",(mode==1)?'C':'D',global_tmp_constr,res->name);
res->def_to_use.name_in_code=Strdup(local_buf);
if(tl!=NULL)
	res->actionclass=tl->type;
else	/* LOOK THIS UP AGAIN */
	res->actionclass=NULL;
res->res_type=cls;

if(mode==1)
	{
	fltmp=cls->typebody.class_def->constructors;
	cls->typebody.class_def->constructors=my_malloc(sizeof (struct fundef_list));
	cls->typebody.class_def->constructors->next=fltmp;
	cls->typebody.class_def->constructors->fundef=res;
	}
else
	{
	fltmp=cls->typebody.class_def->destructors;
	cls->typebody.class_def->destructors=my_malloc(sizeof (struct fundef_list));
	cls->typebody.class_def->destructors->next=fltmp;
	cls->typebody.class_def->destructors->fundef=res;
	};
*fund=res;
return change;
}
