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

int get_typeof_decl(
char * instr,
struct type_listoflist PTR tlist,
struct vardecl_listoflist PTR vlist,
defined_op d_ops,
listnode inl,
struct typerec PTR * res)
{
struct vardecl_list PTR vars=NULL;
char * str;
char local_buf[34];
listnode ltmp;
int change=0;

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

Strncpy(local_buf,instr,str-instr);
if(Strcmp(local_buf,"typeof")) /* NOT "typeof" */
	return 0;

change=str-instr;
instr=str;
ltmp=mk_set_lnd(NULL,NULL,VARIABLE);
str+=get_expression(instr,ltmp,d_ops,inl,1,tlist,vlist,NULL);
if(str==instr)
	{
	while(*str==32) str++;
	if(*str!='(')
		{
		printf("Error in \"typeof\" : no \'(\'\n");
		return 0;
		};
	str++;
	change+=str-instr;
	instr=str;

	str=get_variable_name(instr);
	memset(local_buf,0,34);
	Strncpy(local_buf,instr,str-instr);
	vars=global_find_var_decl((char PTR)local_buf,vlist);

	if(vars!=NULL)
		*res=vars->var->type;
	else
		printf("## Warning : variable %s isn't defined at this time !\n",local_buf);

	while(*str==32) str++;
	if(*str!=')')
		{
		printf("Error in \"typeof\" : no \')\'\n");
		return 0;
		};
	str++;

	rm_lnd_all(ltmp);

	if(vars!=NULL)
		{
		change+=str-instr;
		return change;
		}
	else
		ltmp=mk_set_lnd(NULL,Strdup(local_buf),VARIABLE);
	}
else
	{
	ltmp->next=op_to_function(ltmp->next);
	ltmp=rm_cdr_next(ltmp);
	};

memset(local_buf,0,34);
sprintf(local_buf,"\4tmptype%lx",global_tmp_type++);

if(tlist->tlist==NULL)
	{
	tlist->tlist=my_malloc(sizeof(struct type_list));
	tlist->tlist->next=NULL;
	tlist->tlist->convert_lock=OFF;
	tlist->tlist->type=my_malloc(sizeof(struct typerec));
	set_typerec(tlist->tlist->type,4,Strdup(local_buf),ISTYPEOF,NONE,__void__,NULL);
	*res=tlist->tlist->type;
	}
else
	*res=install_type(tlist->tlist,4,Strdup(local_buf),ISTYPEOF,NONE,__void__,NULL)->type;

(*res)->typebody.typeof=ltmp;

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




int get_var_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 mode,
/* 0 - normal, 1 - struct/union, 2 - class, 3 - getting "type" var 
4 - special for "::" (???), 5,6,7,8 - special for getting args of type1
9,10 - function arguments mode (9 if we DO need vars, 10 if we may skip vars),
11,12 - reserved in case we have "type" var as function argument */
int * changelen
)
{
   struct type_list PTR tl;
   struct vardecl_list PTR vars;
   int change=0;
   int chg=0;
   int inline_flag=0;
   char * str,* keep_instr;
   char tname[34],vname[34];
   enum typemodf tmodf;
   struct typerec PTR type1=NULL, PTR type2=NULL,PTR acls=NULL;
   listnode fn_constr=NULL,modif_lst=NULL,base_constr=NULL;
   struct fundef_list PTR fund_tmp;
   struct fundef PTR fund=NULL;
   char local_buf[34];
   struct typerec PTR tmptype=NULL;
   
   /* tl=tlist->tlist;*/
   vars=vlist->vlist;
   
   keep_instr=instr;

   do	/* loop to get modifiers */
     {
	str=get_variable_name(instr);
	memset(tname,0,34);
	
	tmodf=NONE;
	Strncpy(tname,instr,str-instr);
	
	if((!Strcmp(tname,"struct"))
	   ||(!Strcmp(tname,"union"))
	   ||(!Strcmp(tname,"class"))
	   ||(!Strcmp(tname,"aclass"))
	   ||(!Strcmp(tname,"typedef"))
	   ||(!Strcmp(tname,"modif")))
	  {
	     type1=get_new_type_declaration(instr,tlist,vlist,labels,fnlist,d_ops,inl,inl_lab);
	     if(type1==NULL)
	       return 0;
	     str=instr;
	     while(*str==32) str++;
	     
	     if(!isidch(*str)) /* No variable after struct/union declaration */
	       return 1;
	  }
	else
	  if((type1=get_type_by_name(tname,NONE,tlist))==NULL)
	    if((type1=get_type_by_name(tname,FUNC,tlist))==NULL)
	  {
	     if(Strcmp(tname,"typeof")) /* NOT "typeof" */
	       {
		  printf("Type %s unknown\n",tname);
		  return 0;
	       }
	     else  /* "typeof" */
	       {
		  str=instr;
		  str+=get_typeof_decl(instr,tlist,vlist,d_ops,inl,&type1);
		  if(str==instr)
		    return 0;
	       };
	  };
	if(type1->typekind==ISMODIF)
	  {
	     while(*str==32) str++;
	     modif_lst=mk_head_lnd(modif_lst,type1,TYPEDEFN);
	     change+=str-instr;
	     instr=str;
	     if(*str=='<')
	       {
		  struct typerec PTR tmptype;
		  str++;
		  while(*str==' ') str++;
		  change+=str-instr;
		  instr=str;
		  modif_lst->attr=TWOLISTS;
		  modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
		  while((*str!='>')&(!!*str))
		    {	
		       str+=get_type_from_code(instr,labels,fnlist,tlist,vlist,",>",inl,d_ops,inl_lab,&tmptype);
		       if(str==instr)
			 {
			    fprintf(stderr,"get_var_decl():can't get modifier args\n");
			    rm_lnd_all(modif_lst);
			    return 0;
			 };
		       mk_set_lnd((listnode)modif_lst->data,tmptype,TYPEDEFN);
		       while(*str==' ') str++;
		       if(*str==',') str++;
		       while(*str==' ') str++;
		       change+=str-instr;
		       instr=str;
		    };
		  if(*str!='>') 
		    {
		       fprintf(stderr,"get_var_decl():error in modifier args\n");
		       rm_lnd_all(modif_lst);
		       return 0;
		    };
		  str++;
		  while(*str==' ') str++;
		  
		  if((mode==9)||(mode==10)) 
		    /* function, i.e. no guarantee that keep_instr
		     points to the beginning of the buffer */
		    {
		       change+=str-instr;
		       instr=str;
		    }
		  else
		    {
		       refresh_buffer(keep_instr,change+str-instr,64);
		       instr=str=keep_instr;
		    };
	       };
	  };
	if(*str=='(')
	  {
	     listnode mconstr;
	     if(type1->typekind==ISMODIF) 
	       /* since I'm lazy this code would get constructors for both
		modifiers and regular types */
	       {
		  if(modif_lst->attr==TYPEDEFN)
		    {
		       modif_lst->attr=TWOLISTS;
		       modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
		    };
	       };
	     mconstr=mk_set_lnd((type1->typekind==ISMODIF)?((listnode)modif_lst->data):base_constr,mk_set_lnd(NULL,Strdup("\4objpart"),FUNCTION),TWOLISTS);
	     mk_set_lnd((listnode)mconstr->data,type1,TYPEDEFN);
	     
	     str+=get_function(str,(listnode)mk_set_lnd((listnode)mconstr->data,mk_head_lnd(NULL,NULL,FUNCTION),TWOLISTS)->data,d_ops,inl,1,tlist,vlist,fnlist);
	     
	     if(str==instr)
	       {
		  printf("Error with %s constructor call !!!\n",(type1->typekind=ISMODIF)?"modifier":"base type");
		  rm_lnd_all(modif_lst);
		  if(type1->typekind!=ISMODIF)
		    rm_lnd_all(mconstr);
		  return 0;
	       };
	     ((listnode)((listnode)mconstr->data)->next->next->data)->data=Strdup(type1->name);
	     while(*str==' ') str++;
	     
	     if((mode==9)||(mode==10)) 
	       /* function, i.e. no guarantee that keep_instr
		points to the beginning of the buffer */
	       {
		  change+=str-instr;
		  instr=str;
	       }
	     else
	       {
		  refresh_buffer(keep_instr,change+str-instr,64);
		  instr=str=keep_instr;
	       };
	     
	     if(type1->typekind!=ISMODIF)
	       base_constr=mconstr;
	  };
     }
   while(type1->typekind==ISMODIF);
   
   type1=apply_modifier(type1,modif_lst,&base_constr,tlist);
   rm_lnd_all(modif_lst);
   modif_lst=NULL;

   if(!Strcmp(type1->name,"type"))
     {
	printf("## Dynamic type declaration ...\n");
	memset(vname,0,sizeof(vname));
	global_tmp_type++;
	sprintf(vname,"\4tmptype%lx",global_tmp_type);
	
	if(vars==NULL)
	  vlist->vlist=vars=insert_var_decl(NULL,(char PTR)vname,NULL,NULL,0);
	else
	  vars=insert_var_decl(vars,(char PTR)vname,NULL,NULL,0);
	
	if(tlist->tlist==NULL)
	  {
	     tlist->tlist=my_malloc(sizeof(struct type_list));
	     tlist->tlist->next=NULL;
	     tlist->tlist->convert_lock=OFF;
	     tlist->tlist->type=my_malloc(sizeof(struct typerec));
	     set_typerec(tlist->tlist->type,sizeof(long),Strdup(vname),VAR_TYPE,NONE,__void__,NULL);
	     type1=tlist->tlist->type;
	  }
	else
	  type1=install_type(tlist->tlist,sizeof(long),Strdup(vname),VAR_TYPE,NONE,__void__,NULL)->type;
	type1->typebody.var_type=vars->var;
	vars->var->attr=TYPE_VAR;
	vars=vlist->vlist;
	while(*str==32) str++;
	refresh_buffer(instr,str-instr,64);
	str=instr;
	mode=((mode==9)||(mode==10))?mode+2:3;
     };

   while(1)
     {
	type2=type1;
	
	while(*str==' ') str++;
	
	if((*str=='('))
	  {
	     if((mode==3)||(mode==11)||(mode==12))
	       {
		  fprintf(stderr,"\"type\" can't take any args as a constructor !\n"); 
		  return 0;
	       }
	     else if(mode!=1)
	       mode=((mode==9)||(mode==10))?mode-2:mode+5; /* "special" mode to get args*/
	  };
	
	while(*str==' ') str++;
	change=str-instr;
	instr=str;
	str=get_variable_name(instr);
	while(*str==' ') str++;
	
	if(type2->typekind==ACTIONCLASS)
	  {
	     acls=type2;
	     
	     if(acls->typemodf==FUNC)
	       type2=acls->typebody.actionclass->res_type;
	  };
	
	while((*str!=',')&(((mode>=7)&(mode<=12))?(*str!=')'):(*str!=';')&(*str!='}')&(*str!='[')))
		{
		   
		   if(type2->typekind==ACTIONCLASS)
		     {
			acls=type2;
			
			if(acls->typemodf==FUNC)
			  type2=acls->typebody.actionclass->res_type;
		     };
		   
		   if((*str=='(')||((mode==0)&(*str==':')&(*(str+1)==':')))
		     {
			listnode inline_body=NULL;
			if(mode==1)
			  {
			     fprintf(stderr,"Can't use functions insige struct or union !\n");
			     exit(1);
			  };
			if((mode==9)||(mode==10))
			  {
			     fprintf(stderr,"Can't declare functions inside function arg decl !\n");
			     exit(1);
			  };
			
			if((mode==0)&(*str==':')&(*(str+1)==':'))
			  {
			     str--;
			     while(*str==32) str--;
			     str++;
			     memset(local_buf,0,34);
			     strncpy(local_buf,instr,str-instr);
			     
			     if((tmptype=get_type_by_name(local_buf,NONE,tlist))==NULL)
			       {
				  printf("## Can't define member function of non-existent class %s !\n",local_buf);
				  return 0;
			       };
			     
				tmptype=eval_type_refr(tmptype,fnlist,vlist,tlist,labels,0);
			     
			     if(tmptype==NULL)
			       {
				  fprintf(stderr,"Can't resolve reffered type %s !\n",local_buf);
				  exit(1);
			       };
			     
			     if(tmptype->typekind!=CLASS)
			       {
				  printf("## Type %s isn't a class - can't define member function !\n",tmptype->name);
			       };
			     
			     while(*str==32) str++;
			     str+=2; /* skip "::" */
			     while(*str==32) str++;
			     change+=str-instr;
			     instr=str;
			     mode=4; /* special mode, to parse the rest of fn; */
			  };
			
			if((chg=test_get_fn_decl(instr,tlist,vlist,labels,fnlist,d_ops,inl,inl_lab,&fund))!=0)
			  {
			     if(fnlist->attr!=FUNCDEFN)
			       {
				  printf("Internal problem !\n");
				  exit(1);
			       };
			     
			     if(mode!=4)
			       { /* "normal" mode */
				  fund_tmp=((struct fundef_list PTR)fnlist->data);
				  fnlist->data=my_malloc(sizeof(struct fundef_list));
				  ((struct fundef_list PTR) fnlist->data)->next=fund_tmp;
				  ((struct fundef_list PTR) fnlist->data)->fundef=fund;
			       }
			     else
			       { /* "special" mode, member function */
				  if((*fund->name=='~')&(!Strcmp(fund->name+1,tmptype->name)))
				    {
				       fund_tmp=tmptype->typebody.class_def->destructors;
				       tmptype->typebody.class_def->destructors=my_malloc(sizeof(struct fundef_list));
				       tmptype->typebody.class_def->destructors=fund_tmp;
				       tmptype->typebody.class_def->destructors->fundef=fund;
				    }
				  else if(!Strcmp(fund->name,tmptype->name))
				    {
				       fund_tmp=tmptype->typebody.class_def->constructors;
				       tmptype->typebody.class_def->constructors=my_malloc(sizeof(struct fundef_list));
				       tmptype->typebody.class_def->constructors=fund_tmp;
				       tmptype->typebody.class_def->constructors->fundef=fund;
				    }
				  else
				    {
				       fund_tmp=tmptype->typebody.class_def->funcs;
				       tmptype->typebody.class_def->funcs=my_malloc(sizeof(struct fundef_list));
				       tmptype->typebody.class_def->funcs=fund_tmp;
				       tmptype->typebody.class_def->funcs->fundef=fund;
				    };
			       };
			     fund->res_type=type2;
			     
			     if(acls!=NULL)
			       if(acls->typemodf!=FUNC) /* not function type */
				 fund->actionclass=acls;
			     
				/* TEMPORARY !!! */
			     if(mode!=2)
			       fund->def_to_use.name_in_code=fund->name;
			     else
			       {
				  memset(local_buf,0,34);
				  sprintf(local_buf,"\4_tfn%lx",global_tmp_fn++);
				  fund->def_to_use.name_in_code=Strdup(local_buf);
			       };
			     
			     str=instr+chg;
			     chg=0;
			     
			     change+=str-instr;
			     instr=str;
			     
			     /* str=get_variable_name(instr);
			      while(*str==32) str++; */
			     
			     printf("## Installed function %s\n",fund->name);

			     refresh_buffer(keep_instr,change,64);
			     if(*keep_instr=='{')
			       {
				  struct vardecl_listoflist local_vll;
				  struct type_listoflist PTR local_tlist;
				  
				  if(!inline_flag)
				    {
				       memset(local_buf,0,34);
				       sprintf(local_buf,"tmplab%lx",global_label_count++);
				       printf("jmp %s\n",local_buf);
			
				       if(*fund->def_to_use.name_in_code!=4)
					 printf("_%s :\n",fund->def_to_use.name_in_code);
				       else
					 printf("%s :\n",fund->def_to_use.name_in_code+2);
				    };
				  if(acls!=NULL)
				    {
				       local_vll.next=my_malloc(sizeof(struct vardecl_listoflist));
				       local_vll.next->next=vlist;
				       local_vll.next->vlist=fund->args;
				       local_vll.vlist=acls->typebody.actionclass->local_vars;
				       local_tlist=my_malloc(sizeof(struct type_listoflist));
				       local_tlist->next=tlist;
				       local_tlist->tlist=acls->typebody.actionclass->local_types;
				    }
				  else
				    {
				       local_vll.next=vlist;
				       local_vll.vlist=fund->args;
				       local_tlist=tlist;
				    };
				  
				  if(!get_code_block(keep_instr,inline_flag?(inline_body=mk_head_lnd(NULL,NULL,PARTOFOP)):NULL,inl,d_ops,inl_lab,labels,&local_vll,local_tlist,fnlist,inline_flag))
				    {
				       fprintf(stderr,"Error in function body !!!\n");
				       if(acls!=NULL)
					 {
					    Free(local_vll.next);
					    Free(local_tlist);
					 };
				       return 0;
				    };
				  if(acls!=NULL)
				    {
				       Free(local_vll.next);
				       Free(local_tlist);
				    };
				  if(!inline_flag)
				    printf("%s : \n",local_buf);
					else 
				    {
				       printf("#Creating inline function\n");
				 
				       if(inline_body->next==NULL)
					 fprintf(stderr,"get_var_decl(): empty body of inline function\n");
				       else
					 {
					    fund->kind=is_inline;
					    fund->def_to_use.inline_fndef=my_malloc(sizeof(struct inline_fndef));
					    fund->def_to_use.inline_fndef->vars=NULL;
					    fund->def_to_use.inline_fndef->types=NULL;
					    fund->def_to_use.inline_fndef->body=NULL;
					    inline_body=rm_cdr_next(inline_body);
					    if(inline_body->attr==TYPELIST)
					      {
						 fund->def_to_use.inline_fndef->types=(struct type_list PTR)inline_body->data;
						 inline_body->data=NULL;
						 inline_body=rm_cdr_next(inline_body);
					      };
					    if(inline_body!=NULL)
					      if(inline_body->attr==VARDLIST)
					      {
						 fund->def_to_use.inline_fndef->vars=(struct vardecl_list PTR)inline_body->data;
						 inline_body->data=NULL;
						 inline_body=rm_cdr_next(inline_body);
					      };
					    fund->def_to_use.inline_fndef->body=inline_body;
					 };
				       inline_body=NULL;
				    };
			       };
			     return 1 ;
			  };
			
			
			printf("# Functional constructor call !\n");
			
			if((mode>=5)&(mode<=8)) 
			  /* constructor of the first type */
			  tmptype=type1; /* to add to the list */
			else
			  {
			     tmodf=NONE;
			     
			     chg=get_variable(instr)-instr;
			     
			     memset(tname,0,34);
			     Strncpy(tname,instr,chg);
			     
			     if((tmptype=get_type_by_name(tname,NONE,tlist))==NULL)
			       if((tmptype=get_type_by_name(tname,FUNC,tlist))==NULL)
				 return 0;
			     if(tmptype!=NULL)				
			       if(tmptype->typekind==ACTIONCLASS)
			       {
				  printf("#### tmptype is action class !!!\n");
				  /*	acls=tmptype;
				   tmptype=NULL; */
			       };
			  };	
			
			fn_constr=mk_head_lnd(fn_constr,mk_set_lnd(NULL,Strdup("\4objpart"),FUNCTION),TWOLISTS);
			
			if(tmptype!=NULL) 
			  /* if this is a constructor of a specific type ... */
			  mk_set_lnd((listnode)fn_constr->data,tmptype,TYPEDEFN);
			else 
			  /* this is either a general constructor or a mistake ... */ 
			  mk_set_lnd((listnode)fn_constr->data,vname,VARIABLE);
			/*** Trick - I will put var name at "vname" later ***/
			
			mk_set_lnd((listnode)fn_constr->data,mk_set_lnd(NULL,NULL,FUNCTION),TWOLISTS);
			
			chg=get_function(str,(listnode)((listnode)fn_constr->data)->next->next->data,d_ops,inl,1,tlist,vlist,fnlist);
			
			if(!chg)
			  {
			     printf("Error with functional constructor call !!!\n");
			     return 0;
			  };
			while(*(str+chg)==' ')
			  chg++;
			
			if((*(str+chg)==',')||(*(str+chg)==';'))
			  {
			     ((listnode)((listnode)fn_constr->data)->next->next->data)->data=Strdup(type2->name);
			     break;
			  };
		     }
		   
		   if((mode>=5)||(mode<=8))
		     mode=((mode==5)||(mode==6))?mode-5:mode+2;
		   else
		     {
			if ((*str=='*')||(*str=='&'))
			  {
			     switch(*str)
			       {
				case '*': tmodf=POINTER;break;
				case '&': tmodf=REFERENCE;break;
			       };
			     str++;while(*str==' ') str++;
			     type2=mk_ref_type_from_type(type2,tmodf,tlist,0); 
			     /* create or find reference type */
			     tmodf=NONE;
			     change+=str-instr;
			     instr=str;
			  }
			else /* Not any kind of '*' type modifier */
			  {
			     str--;
			     while((*str==' ')&(str>=instr)) str--;
			     if(*str!=' ') str++; /* go back for spaces */
			     
			     tmodf=NONE;
			     
			     memset(tname,0,34);
			     Strncpy(tname,instr,str-instr);
			     
			     if(!Strcmp(tname,"inline"))
			       {
				  printf("## Inline function\n");
				  inline_flag=1;
			       }
			     else
			       {
				  if((tmptype=get_type_by_name(tname,NONE,tlist))==NULL)
				    if((tmptype=get_type_by_name(tname,FUNC,tlist))==NULL)
				    {
				       fprintf(stderr,"Type %s unknown\n",tname);
				       return 0;
				    };
				  
				  if(tmptype->typekind==ACTIONCLASS)
				    acls=tmptype;
				  else if(tmptype->typekind==ISMODIF)
				    {
				       modif_lst=mk_head_lnd(modif_lst,tmptype,TYPEDEFN);
				       
				       while(*str==' ') str++;
				       if(*str=='<')
					 {
					    struct typerec PTR ttype;
					    str++;
					    while(*str==' ') str++;
					    modif_lst->attr=TWOLISTS;
					    modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
					    change+=str-instr;
					    instr=str;
					    while((*str!='>')&(!!*str))
					      {	
						 str+=get_type_from_code(instr,labels,fnlist,tlist,vlist,",>",inl,d_ops,inl_lab,&ttype);
						 if(str==instr)
						   {
						      fprintf(stderr,"get_var_decl():can't get modifier args\n");
						      rm_lnd_all(modif_lst);
						      return 0;
						   };
						 mk_set_lnd((listnode)modif_lst->data,ttype,TYPEDEFN);
						 while(*str==' ') str++;
						 if(*str==',') str++;
						 while(*str==' ') str++;
						 change+=str-instr;
						 instr=str;
					      };
					    if(*str!='>') 
					      {
						 fprintf(stderr,"get_var_decl():error in modifier args\n");
						 rm_lnd_all(modif_lst);
						 return 0;
					      };
					    str++;
					    while(*str==' ') str++;
					    change+=str-instr;
					    instr=str;
					 };
				       if(*str=='(')
					 {
					    listnode mconstr;
					    if(modif_lst->attr==TYPEDEFN)
					      {
						 modif_lst->attr=TWOLISTS;
						 modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
					      };
					    mconstr=mk_set_lnd((listnode)modif_lst->data,mk_set_lnd(NULL,Strdup("\4objpart"),FUNCTION),TWOLISTS);
					    mk_set_lnd((listnode)mconstr->data,tmptype,TYPEDEFN);
					    
					    str+=get_function(str,(listnode)mk_set_lnd((listnode)mconstr->data,mk_head_lnd(NULL,NULL,FUNCTION),TWOLISTS)->data,d_ops,inl,1,tlist,vlist,fnlist);
					    
					    if(str==instr)
					      {
						 printf("Error with modifier constructor call !!!\n");
						 rm_lnd_all(modif_lst);
						 return 0;
					      };
					    ((listnode)((listnode)mconstr->data)->next->next->data)->data=Strdup(tmptype->name);
					    while(*str==' ') str++;
					    change+=str-instr;
					    instr=str;
					 };
				    }
				  else 
				    {
				       /* Apply modifiers before making subtype */
				       
				       tmptype=apply_modifier(tmptype,modif_lst,&fn_constr,tlist);
				       rm_lnd_all(modif_lst);
				       modif_lst=NULL;
				       
				       if((type2=mk_subtype_by_type(type2,tmptype,tlist,0))==NULL)
					 {
					    printf("Type %s unknown\n",tname);
					    return 0;
					 };
				    };
			       };
			  };
		     }; /* if mode!= 5-8 */
		   if(chg)
		     {
			((listnode)((listnode)fn_constr->data)->next->next->data)->data=Strdup(tname);
			while(*str==32) str++;
			str+=chg-1;
			chg=0;
		     };
		   while(*str==' ') str++;
		   change+=str-instr;
		   instr=str;
		   
		   str=get_variable_name(instr);
		   while(*str==32) str++;
		   
		};
	
	str=instr; /* the token was identifier ! */
	while (*str==32) str++;
	change+=str-instr;
	instr=str;
	
	while(isidch(*str)) str++;
	
	memset(vname,0,34);

	if(str!=instr)
		{	
		   Strncpy(vname,instr,str-instr);
		   change+=str-instr;
		   if((mode==10)||(mode==12))
		     mode--;
		}
	else if((mode==10)||(mode==12))
	  {
	     Strcpy(vname,"\4tmpvar");
	     printf("## Anonymous function arg variable\n");
	  }
	else
	  {
	     if(type2!=type1)
	       Free(type2);
	     Free(type1);
	     rm_lnd_all(modif_lst);
		return 0;
	  };
	
	if((acls!=NULL)&((mode==10)||(mode==12)))
	  type2=acls;
	else if(acls!=NULL)
		{
		   fund=my_malloc(sizeof(struct fundef));
		   fund->name=Strdup(vname);

		   if(*acls->name==4) /* temporary actionclass */
		     {
			fund->args=acls->typebody.actionclass->args;
			acls->typebody.actionclass->args=NULL;
			}
		   else
			fund->args=copy_vardecl_list(acls->typebody.actionclass->args);
		   
		   fund->attr=acls->typebody.actionclass->attr;
		   fund->kind=(acls->typemodf==FUNC)?is_virtual:is_actionclass;
		   fund->res_type=acls->typebody.actionclass->res_type;
		   

		   /* TEMPORARY */
		   fund->def_to_use.name_in_code=fund->name;
		   
		   
		   fund_tmp=(struct fundef_list PTR) fnlist->data;
		   fnlist->data = my_malloc(sizeof(struct fundef_list));
		   ((struct fundef_list PTR) fnlist->data)->next=fund_tmp;
		   ((struct fundef_list PTR) fnlist->data)->fundef=fund;
		   
		   if(vars==NULL)
		     vlist->vlist=vars=insert_var_decl(NULL,(char PTR)vname,acls,NULL,0);
		   else
		     vars=insert_var_decl(vlist->vlist,(char PTR)vname,acls,NULL,0);
		   
		   vars->var->attr=VAR_FUNC;
		   
		   printf("## %s %s variable %s installed\n",(acls->typemodf==FUNC)?"Function type":"Action class",acls->name,vname);
		   
		   if(!((mode>=9)&(mode<=12)))
		     acls=NULL;
		   
		   instr=str;
		   while(*str==32)
		     str++;
		   
		   if((mode>=9)&(mode<=12))
		     {
			change+=str-instr;
			instr=str;
			if(changelen==NULL)
			  printf("## get_var_decl():mode=%d & changelen = NULL !\n",mode);
			else
			  *changelen=change;
			
			return (*str==',')||(*str==')');
		     }
		   else if(*str!=',')
		     break;
		   else
		     {
			change+=str-instr+1;
			str++;
			instr=str;
		     };
		   continue;
		};
	
	if((type1->typekind==VAR_TYPE)&(type1==type2)&((mode==3)||(mode==11)||(mode==12)))
	  {
	     change-=str-instr; /* we'll move str ahead to skip spaces */
	     while(*str==' ') str++;
	     change+=str-instr; /* now the correct value of change */
	     
	     if(((mode==3)&(*str==';'))||((mode!=3)&((*str==',')||(*str==')'))))
	       {
		Free(type1->name);
		  type1->name=Strdup(vname);
		  Free(type1->typebody.var_type->name);
		  type1->typebody.var_type->name=Strdup(vname);
		  
		  refresh_buffer(instr,change,64);
		  return 1;
	       }
	     else if((mode==3)&(*str==','))
	       {
		  printf("# Need to duplicate types ...\n");
		  type2=my_malloc(sizeof(struct typerec));
		  *type2=*type1;
		  global_type_id_count++;
		  type2->typeid=global_type_id_count;
		  
		  if(vars==NULL)
		    vlist->vlist=vars=insert_var_decl(NULL,(char PTR)vname,NULL,NULL,0);
		  else
		    vars=insert_var_decl(vars,(char PTR)vname,NULL,NULL,0);
		  
		  type2->typebody.var_type=vars->var;
		  vars->var->attr=TYPE_VAR;
		  vars=vlist->vlist;
		  type2->name=Strdup(vname);
		  
		  change++; /* skip comma */
		  while(*(str+change)==' ') change++;
		  refresh_buffer(instr,change,64);
		  change=0;
		  str=instr;
		  continue;
	       }
	     else
	       {
		  fprintf(stderr,"Parse error:%s",str);
		  return 0;
	       }
	  };
	
	type2=apply_modifier(type2,modif_lst,&fn_constr,tlist);
	rm_lnd_all(modif_lst);
	modif_lst=NULL;

	printf("# Declared variable %s of known type %s:%d\n",vname,type2->name,type2->typemodf);
	if(lookup_var_decl((char PTR)vname,vlist->vlist)==NULL)
	  {
	     printf("# Variable %s has no previous declaration\n",vname);
	     if(vars==NULL)
	       {
		  vlist->vlist=vars=insert_var_decl(vars,(char PTR)vname,type2,NULL,0);

		  if(acls==type2)
		    vlist->vlist->var->attr=VAR_FUNC;
	       }
	     else
	       insert_var_decl(vars,(char PTR)vname,type2,NULL,0)->var->attr=(acls==type2)?VAR_FUNC:VAR_NORM;
	  }
	else
	  {
	     printf("Variable %s already defined !\n",vname);
	     return 0;
	  };
	
	if(inline_flag)
	  {
	     printf("Warning: variable %s have modifier \"inline\",which is applied only to functions\n",vname);
	     inline_flag=0;
	  };
	instr=str;
	
	while(*str==32)
	  str++;

	if((mode>=9)&(mode<=12))
	  {
	     change+=str-instr;
	     instr=str;
	     if(changelen==NULL)
	       printf("## get_var_decl():mode=%d & changelen = NULL !\n",mode);
	     else
	       *changelen=change;
	     return (*str==',')||(*str==')');
	  }
	
	
	if ((fn_constr!=NULL)||(base_constr!=NULL))
	  {
	     fn_constr=lnd_reverse_r(fn_constr);
	     fn_constr=lnd_rapnde(lnd_reverse_r(copylist(base_constr)),fn_constr);
	     while(fn_constr!=NULL)
	       {
		  if(fn_constr->attr!=TWOLISTS)
		    fprintf(stderr,"get_var_decl():fn_constr->attr==%d != TWOLISTS\n",fn_constr->attr);

		  if(((listnode)fn_constr->data)->next->attr==TYPEDEFN)
		    /* if this is a constructor of a specific type */
		    {
		       /* make it a call to "\4anchestor" */
		       ((listnode)fn_constr->data)->next->attr=TWOLISTS;
		       ((listnode)fn_constr->data)->next->data=(char PTR)mk_head_lnd(mk_head_lnd(mk_head_lnd(NULL,((listnode)fn_constr->data)->next->data,TYPEDEFN),Strdup(vname),VARIABLE),Strdup("\4anchestor"),FUNCTION);
		    }
		  else /* general constructor call */
		    ((listnode)fn_constr->data)->next->data=Strdup(vname);
		  
		  mk_asm_output((listnode)fn_constr->data,labels,vlist,tlist,fnlist);
		  
		  fn_constr=rm_cdr_next(fn_constr);
	       };
	  }
	else if((type2->typekind==CLASS)&(*type2->name!=4))
	  {
	     /* Try default (empty) constructor like cls::cls() .
	      Temporary classes do not have it, but validate_function
	      would return success on validation, since it would count
	      the "constructor" as a special (prefixed by 4) function. */
	     
	     fn_constr=mk_set_lnd(NULL,Strdup("\4objpart"),FUNCTION);
	     mk_set_lnd(fn_constr,Strdup(vname),VARIABLE);
	     mk_set_lnd(fn_constr,mk_set_lnd(NULL,Strdup(type2->name),FUNCTION),TWOLISTS);
	     
	     if(validate_function(fn_constr,fnlist,vlist,tlist,labels,1)!=NULL)
	       { /* Have constructor ! */
		  print_asm_output(fn_constr,labels,vlist,tlist,fnlist);
	       };
	     rm_lnd_all(fn_constr);
	     fn_constr=NULL;
	  };
	
	if(*str!=',')
	  break;
	else
	  {
	     change+=str-instr+1;
	     str++;
	     instr=str;
	  };
     };
   
   refresh_buffer(keep_instr,change,64);
   return 1;
};



struct typerec PTR get_new_type_declaration(
char * instr,
struct type_listoflist PTR types,
struct vardecl_listoflist PTR vars,
listnode labels,listnode fnlist,
defined_op ops,
listnode inl,listnode inl_lab
)
{
   char * str;
   int typeknd=0;
   /* type: 0 - NONE, 1 - struct, 2 - union, 3 - typedef,
    4 - forward pointer to struct/union, 5 - class,6 - modifier,
    7 - action class */

   char local_buf[34];
   struct typerec PTR type=NULL, PTR type1=NULL;
   struct type_list PTR top_classes=NULL,PTR tcls1=NULL;
   struct vardecl_list PTR vlst,* ac_args=NULL;
   struct typerec * ac_rest=NULL,* tmptype=NULL;
   struct vardecl_listoflist tmpvarll;
   struct type_listoflist PTR tmptypelp=types;
   enum typemodf tmodf;
   listnode ltmp=NULL,modif_lst=NULL;
   int change=0;
   
   memset(local_buf,0,34);
   str=get_variable_name(instr);
   strncpy(local_buf,instr,str-instr);
   
   if(!Strcmp(local_buf,"struct"))
     typeknd=1;
   else if(!Strcmp(local_buf,"union"))
     typeknd=2;
   else if(!Strcmp(local_buf,"typedef"))
     typeknd=3;
   else if(!Strcmp(local_buf,"class"))
     typeknd=5;
   else if(!Strcmp(local_buf,"modif"))
     typeknd=6;
   else if(!Strcmp(local_buf,"aclass"))
     typeknd=7;
   
   if((typeknd==1)||(typeknd==2)||(typeknd==5)||(typeknd==6)||(typeknd==7))
     {
	while(*str==' ') str++;
	refresh_buffer(instr,str-instr,64);
	str=instr;
	
	memset(local_buf,0,34);

	if(((typeknd==7)||(typeknd==6))&(*str=='('))
	  {
	     struct type_list PTR tclsptr;
	     printf("# Getting top classes of the modifier\n");
	     str++;
	     while(*str==' ') str++;
	     refresh_buffer(instr,str-instr,64);
	     str=instr;

	     if(*str!=')')
	       {
		  top_classes=my_malloc(sizeof(struct type_list));
		  top_classes->next=NULL;
		  top_classes->type=NULL;
		  tclsptr=top_classes;
	       }
	     else
	       printf("### Empty brackets ... Strange ...\n");
	     
	     while(*str!=')')
	       {
		  struct typerec PTR tmptype;
		  str+=get_type_from_code(instr,labels,fnlist,types,vars,",)",inl,ops,inl_lab,&tmptype);
		  if(instr==str)
		    {
		       fprintf(stderr,"Error getting top classes of %s - can't get type from code\n",local_buf);
		       return NULL;
		    };
		  tclsptr->type=tmptype;
		  if (*str==',')
		    {
		       str++;
		       while(*str==' ') str++;
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       tclsptr->next=my_malloc(sizeof(struct type_list));
		       tclsptr=tclsptr->next;
		       tclsptr->next=NULL;
		       tclsptr->type=NULL;
		    };
	       };
	     str++;
	     while(*str==' ') str++;
	     refresh_buffer(instr,str-instr,64);
	     str=instr;
	  };
	
	if(*str!='{')
	  {
	     str=get_variable_name(instr);
	     if(str==instr)
	       return NULL;
	     strncpy(local_buf,instr,str-instr);
	     while(*str==' ') str++;
	     if(typeknd==7)
	       /* actionclass must have res type */
	       {
		  while(1)
		    {
		       if((tmptype=get_type_by_name(local_buf,NONE,types))==NULL)
			 if((tmptype=get_type_by_name(local_buf,FUNC,types))==NULL)
			 {
			    fprintf(stderr,"get_new_type_declaration(): uncorrect type name %s for actionclass return type\n",local_buf);
			    return NULL;
			 };
		       
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       

		       
		       if(tmptype->typekind==ISMODIF)
			 {
			    modif_lst=mk_head_lnd(modif_lst,tmptype,TYPEDEFN);
			    
			    if(*str=='<')
			      {
				 struct typerec PTR ttype;
				 str++;
				 while(*str==' ') str++;
				 modif_lst->attr=TWOLISTS;
				 modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
				 refresh_buffer(instr,str-instr,64);
				 str=instr;
				 while((*str!='>')&(!!*str))
				   {	
				      str+=get_type_from_code(instr,labels,fnlist,types,vars,",>",inl,ops,inl_lab,&ttype);
				      if(str==instr)
					{
					   fprintf(stderr,"get_new_type_decl():can't get modifier args\n");
					   rm_lnd_all(modif_lst);
					   return NULL;
					};
				      mk_set_lnd((listnode)modif_lst->data,ttype,TYPEDEFN);
				      while(*str==' ') str++;
				      if(*str==',') str++;
				      while(*str==' ') str++;
				      refresh_buffer(instr,str-instr,64);
				      str=instr;
				   };
				 if(*str!='>') 
				   {
				      fprintf(stderr,"get_new_type_declaration():error in modifier args\n");
				      rm_lnd_all(modif_lst);
				      return NULL;
				   };
				 str++;
				 while(*str==' ') str++;
				 refresh_buffer(instr,str-instr,64);
				 str=instr;
			      };
			 }
		       else
			 {
			    if(modif_lst!=NULL)
			      {
				 tmptype=apply_modifier(tmptype,modif_lst,NULL,types);
				 rm_lnd_all(modif_lst);
				 modif_lst=NULL;
			      };
			 };
		       
		       while((*str=='*')||(*str=='&'))
			 {
			    if((tmptype=mk_ref_type_from_type(tmptype,(*str=='*')?POINTER:REFERENCE,types,0))==NULL)
			      {
				 fprintf(stderr,"get_new_type_declaration():error creating reference type\n");
				 return NULL;
			      };
			    str++;
			    while(*str==' ') str++;
			    refresh_buffer(instr,str-instr,64);
			    str=instr;
			 };
		       
		       str=get_variable_name(str);
		       strncpy(local_buf,instr,str-instr);
		       while(*str==' ') str++;
		  
		       if((!*str)||(*str=='(')||(*str=='{'))
			 break;
		    };		  
		  if(modif_lst!=NULL)
		    {
		       tmptype=apply_modifier(tmptype,modif_lst,NULL,types);
		       rm_lnd_all(modif_lst);
		       modif_lst=NULL;
		    };
		  ac_rest=tmptype;
		  tmptype=NULL;
	       }
	     else if(*str=='*')
	       {
		  printf("# Forward of pointer to structural object\n");
		  str++;
		  while(*str==' ') str++;
		  refresh_buffer(instr,str-instr,64);
		  str=instr;
		  
		  typeknd=4;
	       };
	  }
	else
	  sprintf(local_buf,"\4tmp%s%x",(typeknd==1)?"struc":((typeknd==2)?"union":"class"),global_tmp_struct++);
	
	if(typeknd!=4)
	  {
	     if((*str=='('))
	       {
		  struct vardecl_listoflist tmpvarll;
		  struct type_list PTR tclsptr;
		  switch(typeknd)
		    {
		     case 5:
		       str++;
		       while(*str==' ') str++;
		       printf("## getting top classes of class %s\n",local_buf);
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       
		       if(*str!=')')
			 {
			    vlst=my_malloc(sizeof(struct vardecl_list));
			    vlst->next=NULL;
			    vlst->var=NULL;
			 }
		       else
			 printf("### Empty brackets ... Strange ...\n");
		       
		       while(*str!=')')
			 {
			    str+=get_type_from_code(instr,labels,fnlist,types,vars,",)",inl,ops,inl_lab,&tmptype);
			    if(instr==str)
			      {
				 fprintf(stderr,"Error getting top classes of %s - can't get type from code\n",local_buf);
				 return NULL;
			      };
			    tclsptr->type=tmptype;
			    if (*str==',')
			      {
				 str++;
				 while(*str==' ') str++;
				 refresh_buffer(instr,str-instr,64);
				 str=instr;
				 tclsptr->next=my_malloc(sizeof(struct type_list));
				 tclsptr=tclsptr->next;
				 tclsptr->next=NULL;
				 tclsptr->type=NULL;
			      };
			 };
		       str++;
		       while(*str==' ') str++;
		       break;
		     case 6:
		       printf("# Getting modifier args ...\n");
		       str++;
		       while(*str==' ') str++;
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       
		       if(*str!=')')
			 {
			    tcls1=my_malloc(sizeof(struct type_list));  
			    tcls1->next=NULL;
			    tcls1->type=NULL;
			    tclsptr=tcls1;
			 }
		       else
			 printf("### Empty brackets ... Strange ...\n");
		       
		       while(*str!=')')
			 {
			    struct type_list * modarg_top=NULL,*modarg_tptr=NULL;
			    char buf[32];
			    listnode modif_lst=NULL;
			  
			    tmptype=NULL;
			    
			    while(1)
			      {
				 str=get_variable_name(instr);
				 if(instr==str)
				   {
				      fprintf(stderr,"Error getting args of %s - can't get name from code\n",local_buf);
				      return NULL;
				   };
				 while(*str==' ') str++;
				 
				 if((*str==',')||(*str==')'))
				   break;
				 
				 memset(buf,0,sizeof(buf));
				 strncpy(buf,instr,get_variable(instr)-instr);
				 
				 
				 if((tmptype=get_type_by_name(buf,NONE,types))==NULL)
				   if((tmptype=get_type_by_name(buf,FUNC,types))==NULL)
				   {
				      fprintf(stderr,"get_new_type_declaration(): when defining parent\nclasses of modifier args: Type %s unknown\n",buf);
				      return NULL;
				   };
				 
				 refresh_buffer(instr,str-instr,64);
				 str=instr;
				 
				 if(tmptype->typekind==ISMODIF)
				   {
				      modif_lst=mk_head_lnd(modif_lst,tmptype,TYPEDEFN);
				      
				      if(*str=='<')
					{
					   struct typerec PTR ttype;
					   str++;
					   while(*str==' ') str++;
					   modif_lst->attr=TWOLISTS;
					   modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
					   refresh_buffer(instr,str-instr,64);
					   str=instr;
					   while((*str!='>')&(!!*str))
					     {	
						str+=get_type_from_code(instr,labels,fnlist,types,vars,",>",inl,ops,inl_lab,&ttype);
						if(str==instr)
						  {
						     fprintf(stderr,"get_new_type_decl():can't get modifier args\n");
						     rm_lnd_all(modif_lst);
						     return NULL;
						  };
						mk_set_lnd((listnode)modif_lst->data,ttype,TYPEDEFN);
						while(*str==' ') str++;
						if(*str==',') str++;
						while(*str==' ') str++;
						refresh_buffer(instr,str-instr,64);
						str=instr;
					     };
					   if(*str!='>') 
					     {
						fprintf(stderr,"get_var_decl():error in modifier args\n");
						rm_lnd_all(modif_lst);
						return NULL;
					     };
					   str++;
					   while(*str==' ') str++;
					   refresh_buffer(instr,str-instr,64);
					   str=instr;
					};
				   }
				 else
				   {
				      if(modif_lst!=NULL)
					{
					   tmptype=apply_modifier(tmptype,modif_lst,NULL,types);
					   rm_lnd_all(modif_lst);
					   modif_lst=NULL;
					};
				      if((*str=='*')||(*str=='&'))
					{
					   if((tmptype=mk_ref_type_from_type(tmptype,(*str=='*')?POINTER:REFERENCE,types,0))==NULL)
					     {
						fprintf(stderr,"get_new_type_declaration():error creating reference type\n");
						return NULL;
					     };
					   str++;
					   while(*str==' ') str++;
					   refresh_buffer(instr,str-instr,64);
					   str=instr;
					}
				      else
					{
					   if(modarg_top==NULL)
					     {
						modarg_top=my_malloc(sizeof(struct type_list));
						modarg_tptr=modarg_top;
					     }
					   else
					     {
						modarg_tptr->next=my_malloc(sizeof(struct type_list));
						modarg_tptr=modarg_tptr->next;
					     };
					   modarg_tptr->next=NULL;
					   modarg_tptr->type=tmptype;
					   tmptype=NULL;
					};
				   };
			      };
			    
			    tclsptr->type=my_malloc(sizeof(struct typerec));
			    tclsptr->type->name=my_malloc(str-instr);
			    Strncpy(tclsptr->type->name,instr,str-instr);
			    tclsptr->type->typemodf=NONE;
			    tclsptr->type->typekind=MODIFARG;
			    tclsptr->type->typebody.class_list=modarg_top;
			    
			    if (*str==',')
			      {
				 str++;
				 while(*str==' ') str++;
				 refresh_buffer(instr,str-instr,64);
				 str=instr;
				 tclsptr->next=my_malloc(sizeof(struct type_list));
				 tclsptr=tclsptr->next;
				 tclsptr->next=NULL;
				 tclsptr->type=NULL;
			      };
			 };
		       str++;
		       while(*str==' ') str++;
		       tmptypelp=my_malloc(sizeof(struct type_listoflist)); 
		       tmptypelp->next=types;
		       tmptypelp->tlist=tcls1;
		       /* we need one more layer of temporary types */
		       break;
		     case 7:
		       printf("# Getting action class args ...\n");
		       str++;
		       while(*str==' ') str++;
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       
		       if(*str!=')')
			 {
			    tmpvarll.vlist=ac_args;
			    tmpvarll.next=vars;
			 }
		       else
			 printf("### Empty brackets ... Strange ...\n");
		       
		       while(*str!=')')
			 {
			    int chg=0;

			    if(!get_var_decl(str,types,&tmpvarll,labels,fnlist,ops,inl,inl_lab,9,&chg))
			      return NULL;
			    
			    str+=chg;
			    while(*str==' ') str++;
			    if(*str==',') str++;
			    while(*str==' ') str++;
			    refresh_buffer(instr,str-instr,64);
			    str=instr;
			 };
		       str++;
		       while(*str==' ') str++;
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       ac_args=tmpvarll.vlist;
		       tmptypelp=my_malloc(sizeof(struct type_listoflist)); 
		       tmptypelp->next=types;
		       tmptypelp->tlist=tcls1;
		       /* we need one more layer of temporary types */
		       break;
		     default:
		       printf("# Unexpected symbol \"(\" at \"get_new_type_declaration()\" !\n");
		       return NULL;
		    };
	       };
	     
	     if(*str!='{')
	       return NULL;
	     str++;
	     
	     refresh_buffer(instr,str-instr,64);
	     str=instr;
	  };
	
	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));
	     type=set_typerec(types->tlist->type,0,Strdup(local_buf),(typeknd==1)?STRUCT:((typeknd==2)?UNION:(typeknd==6)?ISMODIF:CLASS),NONE,__void__,NULL);
	     global_type_id_count++;
	     type->typeid=global_type_id_count;
	  }
	else
	  type=install_type(types->tlist,0,Strdup(local_buf),(typeknd==1)?STRUCT:((typeknd==2)?UNION:(typeknd==6)?ISMODIF:CLASS),NONE,__void__,NULL)->type;
	
	
	if(typeknd==4)
	  {
	     type->typekind=SYMBREFR;
	     type->typebody.symbrefr=Strdup(local_buf);
	     type->typemodf=POINTER;
	     return type;
	  };
	
	if((typeknd!=5)&(typeknd!=6)&(typeknd!=7))/* Struct/union */
	  {
	     type->typebody.struct_def=my_malloc(sizeof(struct struct_def));
	     type->typebody.struct_def->s_or_u=typeknd-1;
	     ltmp=fnlist;
	  }
	else if(typeknd==6) /* modifier */
	  {
	     printf("# Creating modifier decl\n");
	     type->typebody.class_def=my_malloc(sizeof(struct class_def));
	     ltmp=mk_head_lnd(fnlist,NULL,FUNCDEFN);
	     type->typebody.class_def->types=tcls1;
	     /*		type->typebody.modif_def->args=NULL;*/
	     type->typebody.class_def->top_class=top_classes; /* top_classes=NULL by default */
	     type->typebody.class_def->variable_constructors=NULL;
	  }
	else if(typeknd==7) /* action class */
	  {
	     printf("# Creating action class decl\n");
	     type->typebody.actionclass=my_malloc(sizeof(struct actionclass));
	     ltmp=mk_head_lnd(fnlist,NULL,FUNCDEFN);
	     type->typebody.actionclass->args=ac_args;
	     type->typebody.actionclass->res_type=ac_rest;
	     /*		type->typebody.modif_def->args=NULL;*/
	     type->typebody.actionclass->top_class=top_classes; 
	     /* top_classes=NULL by default */
	     type->typekind=ACTIONCLASS;
	  }
	else if(typeknd==5)/* Class */
	  {
	     type->typebody.class_def=my_malloc(sizeof(struct class_def));
	     ltmp=mk_head_lnd(fnlist,NULL,FUNCDEFN);
	     type->typebody.class_def->constructors=NULL;
	     type->typebody.class_def->destructors=NULL;
	     type->typebody.class_def->top_class=top_classes; /* top_classes=NULL by default */
	     type->typebody.class_def->variable_constructors=NULL;
	  };
	
	tmpvarll.next=vars;
	tmpvarll.vlist=NULL;
	
	while(1)
	  {
	     struct fundef PTR fund;
	
	     while(*str==32) str++;
	     refresh_buffer(instr,str-instr,64);
	     str=instr;
	     
	     if((typeknd==5)||(typeknd==6)||(typeknd==7)) 
		/* test for constructors/destructors */
	       
	       str+=test_get_constr_destr(instr,type,tmptypelp,vars,labels,fnlist,ops,inl,inl_lab,&fund);
	     
	     if(str!=instr)
	       {
		  if(typeknd==5)
		    {
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       while(*str==32) str++;
		       if(*str=='{')
			 {
			    struct vardecl_listoflist local_vll;
		       
			    refresh_buffer(instr,str-instr,64);
			    str=instr;
			    
			    memset(local_buf,0,34);
			    sprintf(local_buf,"tmplab%lx",global_label_count++);
			    printf("jmp %s\n",local_buf);
			    
			    if(*fund->def_to_use.name_in_code!=4)
			      printf("O%s :\n",fund->def_to_use.name_in_code);
			    else
			      printf("%s :\n",fund->def_to_use.name_in_code+2);
			    
			    local_vll.next=&tmpvarll;
			    local_vll.vlist=fund->args;
			    
			    if(!get_code_block(instr,NULL,inl,ops,inl_lab,labels,&local_vll,tmptypelp,fnlist,0))
			      {
				 fprintf(stderr,"Error in function body !!!\n");
				 return 0;
			      };
			    printf("%s : \n",local_buf);
			 };
		    }
		  else if((typeknd==6)||(typeknd==7))
		    {
		       printf("# Getting %s function\n",(typeknd==6)?"modifier":"action class");
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       while(*str==32) str++;
		       if(*str=='{')
			 {
			    struct vardecl_listoflist local_vll;
			    listnode tmpdst=mk_head_lnd(NULL,NULL,0);
			    
			    refresh_buffer(instr,str-instr,64);
			    str=instr;
			    local_vll.next=&tmpvarll;
			    local_vll.vlist=fund->args;
			    
			    if(!get_code_block(instr,tmpdst,inl,ops,inl_lab,labels,&local_vll,tmptypelp,fnlist,0))
			      {
				 fprintf(stderr,"Error in function body !!!\n");
				 return 0;
			      };
			    if(ltmp->data==NULL)
			      ltmp->data=my_malloc(sizeof(struct fundef_list));
			    else
			      {
				 struct fundef_list PTR ftmp;
				 ftmp=(struct fundef_list PTR) ltmp->data;
				 ltmp->data=my_malloc(sizeof(struct fundef_list));
				 ((struct fundef_list PTR) ltmp->data)->next=ftmp;
			      };
			    
			 };
		    };
	       }
	     else
	       if(!get_var_decl(instr,tmptypelp,&tmpvarll,labels,ltmp,ops,inl,inl_lab,((typeknd==5)||(typeknd==6))?2:1,NULL))
		 /* Only class/modif can have subfuncs */
	       {
		  printf("Error in %s definition !\n",(typeknd<2)?"structure":"union");
		  return NULL;
	       };
	
	     while(*str==32) str++;
	     
	     if(*str=='}')
	       break;
	
	     if(*str!=';')
	       {
		  printf("Error in %s definition - \";\" expected !\n",(typeknd<2)?"structure":"union");
		  return NULL;
	       };
	     str++;
	  };
	
	while(*str==32) str++;
	
	if(*str!='}')
	  {
	     printf("Error - \'}\' expected !\n");
	     return NULL;
	  };
	str++;
	
	refresh_buffer(instr,str-instr,64);
	str=instr;
	
	if(typeknd==5)
	  {
	     type->typebody.class_def->size=0;
	     for(vlst=tmpvarll.vlist;vlst!=NULL;vlst=vlst->next) 
	       /* Calculate size regarding is it struct or union !!! */
	       type->typebody.class_def->size+=vlst->var->type->size;
	     type->typebody.class_def->vars=tmpvarll.vlist;
	     
	     type->typebody.class_def->funcs=(struct fundef_list PTR)ltmp->data;
	     Free(ltmp);
	  }
	else if(typeknd==6) /* modifier */
	  {
	     type->size=0;
	     for(vlst=tmpvarll.vlist;vlst!=NULL;vlst=vlst->next) 
	       type->size+=vlst->var->type->size;
	     type->typebody.class_def->vars=tmpvarll.vlist;
	     type->typebody.class_def->funcs=(struct fundef_list PTR)ltmp->data;
	     Free(ltmp);
	     /*		type->typebody.modif_def->code->code=ltmp;*/
	  }
	else if(typeknd==7) /* action class */
	  {
	     type->size=0;
	     for(vlst=tmpvarll.vlist;vlst!=NULL;vlst=vlst->next) 
	       type->size+=vlst->var->type->size;
	     type->typebody.actionclass->local_vars=tmpvarll.vlist;
	     type->typebody.actionclass->local_types=tmptypelp->tlist;
	     type->typebody.actionclass->local_funcs=(struct fundef_list PTR)ltmp->data;
	     Free(ltmp);
	  }
	else
	  {
	     type->typebody.struct_def->size=0;
	     for(vlst=tmpvarll.vlist;vlst!=NULL;vlst=vlst->next) 
	       /* Calculate size regarding is it struct or union !!! */
	       if(typeknd>1)
	       {
		  if(type->typebody.struct_def->size < vlst->var->type->size)
		    type->typebody.struct_def->size=vlst->var->type->size;
	       }
	     else
	       type->typebody.struct_def->size+=vlst->var->type->size;
	     
	     type->typebody.struct_def->fields=tmpvarll.vlist;
	  };
     }
   else if(typeknd==3)
     {
	printf("# Parsing \"typedef\" now !\n");
	while (*str==32) str++;
	refresh_buffer(instr,str-instr,64);
	str=instr;

	do	/* loop to get modifiers */
	  {
	     memset(local_buf,0,34);
	     str=get_variable_name(instr);
	     strncpy(local_buf,instr,str-instr);
	     
	     tmodf=NONE;
	     
	     if(!Strcmp(local_buf,"typeof"))
	       {
		  str=instr;
		  str+=get_typeof_decl(instr,types,vars,ops,inl,&type);
		  if(str==instr)
		    return NULL;
		  refresh_buffer(instr,str-instr,64);
		  str=instr;
	       }
	     else if((!Strcmp(local_buf,"struct"))
		||(!Strcmp(local_buf,"union"))
		     ||(!Strcmp(local_buf,"class"))
		     ||(!Strcmp(local_buf,"typedef")))
	       {
		  type=get_new_type_declaration(instr,types,vars,labels,fnlist,ops,inl,inl_lab);
		  if(type==NULL)
		    {
		       printf("Error in \"typedef\" - error in declaration of %s \n",local_buf);
		       return NULL;
		    };
		  str=instr;
	       }
	     else
	       {
		  type=get_type_by_name(local_buf,NONE,types);
		  if(type==NULL)
		    {
		       printf("Error in \"typedef\" - no such a type \"%s\"\n",local_buf);
		       return NULL;
		    };
	       };
	     
	while(*str==32) str++;
	     
	     refresh_buffer(instr,str-instr,64);
	     str=instr;
	     tmodf=NONE;
	     
	     if(type->typekind==ISMODIF)
	       {
		  while(*str==32) str++;
		  modif_lst=mk_head_lnd(modif_lst,type,TYPEDEFN);
		  refresh_buffer(instr,str-instr,64);
		  str=instr;
		  if(*str=='<')
		    {
		       struct typerec PTR tmptype;
		       str++;
		       while(*str==' ') str++;
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		       modif_lst->attr=TWOLISTS;
		       modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
		       while((*str!='>')&(!!*str))
			 {	
			    str+=get_type_from_code(instr,labels,fnlist,types,vars,",>",inl,ops,inl_lab,&tmptype);
			    if(str==instr)
			      {
				 fprintf(stderr,"get_var_decl():can't get modifier args\n");
				 rm_lnd_all(modif_lst);
				 return 0;
			      };
			    mk_set_lnd((listnode)modif_lst->data,tmptype,TYPEDEFN);
			    while(*str==' ') str++;
			    if(*str==',') str++;
			    while(*str==' ') str++;
			    refresh_buffer(instr,str-instr,64);
			    str=instr;
			 };
		       if(*str!='>') 
			 {
			    fprintf(stderr,"get_var_decl():error in modifier args\n");
			    rm_lnd_all(modif_lst);
			    return 0;
			 };
		       str++;
		       while(*str==' ') str++;
		       
		       refresh_buffer(instr,str-instr,64);
		       str=instr;
		    };
	       };
	  }
	while(type->typekind==ISMODIF);
	
	type=apply_modifier(type,modif_lst,NULL,types);
	rm_lnd_all(modif_lst);
	modif_lst=NULL;
	
	str=get_variable_name(instr);
	while(*str==32) str++;
	
	while((*str!=',')&(*str!=';')&(*str!='}')&(*str!='('))
	  {
	     
	     if ((*str=='*')||(*str=='&'))
	       {
		  switch(*str)
		    {
		     case '*': tmodf=POINTER;break;
		     case '&': tmodf=REFERENCE;break;
		    };
		  str++;
		  type=mk_ref_type_from_type(type,tmodf,types,1); 
		  /* CREATE (not find) new reference type */
		  
		  tmodf=NONE;
		  refresh_buffer(instr,str-instr,64);
		  str=instr;
	       }
	     else /* Not any kind of '*' type modifier */
	       {
		  struct typerec * tmptype;
		  str--;
		  while((*str==32)&(str>=instr)) str--;
		  if(*str!=32) str++; /* go back for spaces */
		  
		  tmodf=NONE;
		  
		  memset(local_buf,0,34);
		  Strncpy(local_buf,instr,str-instr);
		  while(*str==32) str++;
		  
		  if((tmptype=get_type_by_name(local_buf,NONE,types))==NULL)
		    if((tmptype=get_type_by_name(local_buf,FUNC,types))==NULL)
		    {
		       fprintf(stderr,"Type %s unknown\n",local_buf);
		       return 0;
		    };
		  
		  if(tmptype->typekind==ISMODIF)
		    {
		       modif_lst=mk_head_lnd(modif_lst,tmptype,TYPEDEFN);
		       
		       while(*str==32) str++;
		       if(*str=='<')
			 {
			    struct typerec PTR ttype;
			    str++;
			    while(*str==' ') str++;
			    modif_lst->attr=TWOLISTS;
			    modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
			    change+=str-instr;
			    instr=str;
			    while((*str!='>')&(!!*str))
			      {	
				str+=get_type_from_code(instr,labels,fnlist,types,vars,",>",inl,ops,inl_lab,&ttype);
				 if(str==instr)
				   {
				      fprintf(stderr,"get_new_type_declaration():can't get modifier args\n");
				      rm_lnd_all(modif_lst);
				      return 0;
				   };
				 mk_set_lnd((listnode)modif_lst->data,ttype,TYPEDEFN);
				 while(*str==' ') str++;
				 if(*str==',') str++;
				 while(*str==' ') str++;
				 change+=str-instr;
				 instr=str;
			      };
			    if(*str!='>') 
			      {
				 fprintf(stderr,"get_net_type_declaration():error in modifier args\n");
				 rm_lnd_all(modif_lst);
				 return 0;
			      };
			    str++;
			    while(*str==' ') str++;
			    change+=str-instr;
			    instr=str;
			 };
		    };
		  
		  if((type1=mk_subtype_by_type(type,tmptype,types,0))==NULL)
		    {
		       if(*str!='(')
			 {
			    printf("Type %s unknown\n",local_buf);
			    return NULL;
			 }
		       else
			 break;
		    }
		  else
		    type=type1;
	       };
	     while(*str==32) str++;
	     refresh_buffer(instr,str-instr,64);
	     str=instr;
	     
	     if(*instr=='(') /* break here to get all "type-related" tokens */
	       break;
	     
	     str=get_variable_name(instr);
	     while(*str==32) str++;
	     
	  };
	
	/*	refresh_buffer(instr,change,64); */
	change=0;
	type1=NULL;
	
	memset(local_buf,0,34);
	
	if(*str=='(')
	  {
	     char PTR str1=NULL;
	     struct vardecl_listoflist tmpvarll;
	     
	     if(*instr=='(') /* if there are no tokens which can be names */
	       {
		  str+=get_subtype_from_code(instr,type,labels,fnlist,types,vars,inl,ops,inl_lab,&str1,&type1);
		  
		  if(instr!=str)
		    {
		       while(*str==32) str++;
		       if(*str!='(')
			 str=instr;
		    };
		  if(instr!=str) /* functional brackets after this brackets */
		    {
		       refresh_buffer(instr,str-instr,64);
		       Strcpy(local_buf,str1); /* save str1 */
		       Free(str1); /* and free it's memory */
		    };
	       }
	     else
	       type1=NULL;
	     
	     if(instr!=str)
	       {
		  str=get_variable_name(instr);
		  memset(local_buf,0,34);
		  strncpy(local_buf,instr,str-instr);
		  refresh_buffer(instr,str-instr,64);
	       };
	     
	     str=instr;
	     while(*str==32)
	       str++;
	     
	     if(*str=='(')
	       {
		  str++;
		  while(*str==32)
		    str++;
	       };
	     
	     refresh_buffer(instr,str-instr,64);
	     str=instr;
	     
	     tmpvarll.next=NULL;
	     tmpvarll.vlist=NULL;
	     str1=(char PTR)(str=instr);
	     
	     while(1)
	       {
		  str=(char *)str1+get_fn_arg_decl(str,types,&tmpvarll,labels,fnlist,ops,inl,inl_lab,0);
		  
		  if((char *)str1==str)
		    {
		       printf("typedef - can't get arguments at actionclass declaration !");
		       return NULL;
		    };
		  
		  if((*str!=',')&(*str!=')'))
		    {
		       printf("typedef - unexpected symbol %c at actionclass declaration !",*str);
		       return NULL;
		    };
		  
		  if(*str==')')
		    break;
		  
		  str++;

		  while(*str==32)
		    str++;
		  
		  str1=(char PTR)str;
	       };
	     str++;
	     while(*str==32) str++;
	     refresh_buffer(instr,str-instr,64);
	     
	     if(type1!=NULL) 
	       /* complex type in brackets - require structure manupulating */
	       {
		  struct typerec PTR type2;
		  type2=my_malloc(sizeof(struct typerec));
		  *type2=*type; /* full copy of memory image of "type" */
		  type=my_malloc(sizeof(struct typerec));
		  type->typekind=ACTIONCLASS;
		  type->typemodf=FUNC;/*NONE;*/
		  type->typeconv=NULL;
		  type->typebody.actionclass=my_malloc(sizeof(struct actionclass));
		  type->typebody.actionclass->top_class=NULL;
		  type->typebody.actionclass->res_type=type2;
		  type->typebody.actionclass->local_vars=tmpvarll.vlist;
		  type->typebody.actionclass->local_types=NULL;
		  type->typebody.actionclass->local_funcs=NULL;
		  global_type_id_count++;
		  type->typeid=global_type_id_count;
		  type=type1; /* actual final type */
	       }
	     else
	       {
		  type1=type;
		  type=my_malloc(sizeof(struct typerec));
		  type->typekind=ACTIONCLASS;
		  type->typemodf=FUNC;/*NONE;*/
		  type->typeconv=NULL;
		  type->typebody.actionclass=my_malloc(sizeof(struct actionclass));
		  type->typebody.actionclass->top_class=NULL;
		  type->typebody.actionclass->res_type=type1;
		  type->typebody.actionclass->args=tmpvarll.vlist;
		  type->typebody.actionclass->local_vars=NULL; 
		  type->typebody.actionclass->local_types=NULL;
		  type->typebody.actionclass->local_funcs=NULL;
		  global_type_id_count++;
		  type->typeid=global_type_id_count;
	       };
	     
	     type->name=Strdup(local_buf);
	     
	     type1=(struct typerec PTR) types->tlist;
	     types->tlist=my_malloc(sizeof(struct type_list));
	     types->tlist->convert_lock=OFF;
	     types->tlist->type=type;
	     types->tlist->next=(struct type_list PTR) type1;
	     
	     return type;
	  }
	else
	  {
	     str=get_variable_name(instr);
	     
	     memset(local_buf,0,34);
	     strncpy(local_buf,instr,str-instr);
	     refresh_buffer(instr,str-instr,64);
	  };
	
	if(*type->name!=4)
	  {
	     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));
		  type1=set_typerec(types->tlist->type,0,Strdup(local_buf),TYPEREFR,NONE,__void__,NULL);
		  global_type_id_count++;
		  type1->typeid=global_type_id_count;
	       }
	     else
	       type1=install_type(types->tlist,0,Strdup(local_buf),TYPEREFR,NONE,__void__,NULL)->type;
	     
	     if(type1==NULL)
	       return NULL;
	     
	     type1->typebody.pointer_to=type;
	     type=type1;
	     
	  }
	else /*   *type->name==4, i.e. temporary type */
	  {
	     if(type->name!=NULL)
	       Free(type->name);
	     type->name=my_malloc(strlen(local_buf));
	     Strcpy(type->name,local_buf);
	  };
     }
   else
     {
	printf("Whoops - problem in \"get_new_type_declaration()\" !!!\n");
	return NULL;
     };
   
   return type;
};


int get_type_from_code(
char * instr,
listnode labels,listnode fnlist,
struct type_listoflist PTR tlist,
struct vardecl_listoflist PTR vlist,
char * stopchars,
listnode inl,defined_op d_ops,
listnode inl_lab,
struct typerec PTR* res)
{
struct type_list PTR tl;
struct vardecl_list PTR vars;
int change=0;
char * str;
char tname[34],vname[34];
enum typemodf tmodf;
struct typerec PTR type=NULL;
listnode modif_lst=NULL;

do	/* loop to get modifiers */
	{
	str=get_variable_name(instr);
	memset(tname,0,34);

	tmodf=NONE;
	Strncpy(tname,instr,str-instr);

	if((!Strcmp(tname,"struct"))
	||(!Strcmp(tname,"union"))
	||(!Strcmp(tname,"typedef"))
	||(!Strcmp(tname,"class"))
	||(!Strcmp(tname,"modif")))
		{
		type=get_new_type_declaration(instr,tlist,vlist,labels,fnlist,d_ops,inl,inl_lab);

		if(type==NULL)
			return 0;
		str=instr;
		while(*str==32) str++;

		if(strchr(stopchars,*str)!=NULL) /* No variable after struct/union declaration */
			{
			*res=type;
			return str-instr;
			};
		}
	else
		if((type=get_type_by_name(tname,NONE,tlist))==NULL)
			{
			if(Strcmp(tname,"typeof")) /* NOT "typeof" */
				{
				printf("## Type %s unknown\n",tname);
				return 0;
				}
			else  /* "typeof" */
				{
				str=instr;
				str+=get_typeof_decl(instr,tlist,NULL,NULL,NULL,&type);
				if(str==instr)
					return 0;
				};
			};

	if(type->typekind==ISMODIF)
		{
		while(*str==32) str++;
		modif_lst=mk_head_lnd(modif_lst,type,TYPEDEFN);
		change+=str-instr;
		instr=str;
		if(*str=='<')
			{
			struct typerec PTR tmptype;
			str++;
			while(*str==' ') str++;
			change+=str-instr;
			instr=str;
			modif_lst->attr=TWOLISTS;
			modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
			while((*str!='>')&(!!*str))
				{	
				str+=get_type_from_code(instr,labels,fnlist,tlist,vlist,",>",inl,d_ops,inl_lab,&tmptype);
				if(str==instr)
					{
					fprintf(stderr,"get_type_from_code():can't get modifier args\n");
					rm_lnd_all(modif_lst);
					return 0;
					};
				mk_set_lnd((listnode)modif_lst->data,tmptype,TYPEDEFN);
				while(*str==' ') str++;
				if(*str==',') str++;
				while(*str==' ') str++;
				change+=str-instr;
				instr=str;
				};
			if(*str!='>') 
				{
				fprintf(stderr,"get_type_from_code():error in modifier args\n");
				rm_lnd_all(modif_lst);
				return 0;
				};
			str++;
			while(*str==' ') str++;

			change+=str-instr;
			instr=str;
			};
		};
	}
	while(type->typekind==ISMODIF);

type=apply_modifier(type,modif_lst,NULL,tlist);
rm_lnd_all(modif_lst);
modif_lst=NULL;

if(!Strcmp(type->name,"type"))
		{
		printf("## Dynamic type declaration ...\n");
		memset(vname,0,sizeof(vname));
		global_tmp_type++;
		sprintf(vname,"\4tmptype%lx",global_tmp_type);

		if(vars==NULL)
			vlist->vlist=vars=insert_var_decl(NULL,(char PTR)vname,NULL,NULL,0);
		else
			vars=insert_var_decl(vars,(char PTR)vname,NULL,NULL,0);

		if(tlist->tlist==NULL)
			{
			tlist->tlist=my_malloc(sizeof(struct type_list));
			tlist->tlist->next=NULL;
			tlist->tlist->convert_lock=OFF;
			tlist->tlist->type=my_malloc(sizeof(struct typerec));
			set_typerec(tlist->tlist->type,sizeof(long),Strdup(vname),VAR_TYPE,NONE,__void__,NULL);
			type=tlist->tlist->type;
			}
		else
			type=install_type(tlist->tlist,sizeof(long),Strdup(vname),VAR_TYPE,NONE,__void__,NULL)->type;

		type->typebody.var_type=vars->var;
		vars->var->attr=TYPE_VAR;
		vars=vlist->vlist;
		};

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

while(strchr(stopchars,*str)==NULL)
	{
	if ((*str=='*')||(*str=='&'))
		{
		switch(*str)
			{
			case '*': tmodf=POINTER;break;
			case '&': tmodf=REFERENCE;break;
			};
		str++;
		type=mk_ref_type_from_type(type,tmodf,tlist,0); /* create or find reference type */
		tmodf=NONE;
		change+=str-instr;
		instr=str;
		}
	else /* Not any kind of '*' type modifier */
		{
		struct typerec * tmptype;
		tmodf=NONE;
		memset(tname,0,34);
		Strncpy(tname,instr,str-instr);

		if((tmptype=get_type_by_name(tname,NONE,tlist))==NULL)
			if((tmptype=get_type_by_name(tname,FUNC,tlist))==NULL)
				{
				fprintf(stderr,"Type %s unknown\n",tname);
				return 0;
				};

		if(tmptype->typekind==ISMODIF)
			{
			modif_lst=mk_head_lnd(modif_lst,tmptype,TYPEDEFN);

			while(*str==32) str++;
			if(*str=='<')
				{
				struct typerec PTR ttype;
				str++;
				while(*str==' ') str++;
				modif_lst->attr=TWOLISTS;
				modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
				change+=str-instr;
				instr=str;
				while((*str!='>')&(!!*str))
					{	
					str+=get_type_from_code(instr,labels,fnlist,tlist,vlist,",>",inl,d_ops,inl_lab,&ttype);
					if(str==instr)
						{
						fprintf(stderr,"get_type_from_code():can't get modifier args\n");
						rm_lnd_all(modif_lst);
						return 0;
						};
					mk_set_lnd((listnode)modif_lst->data,ttype,TYPEDEFN);
					while(*str==' ') str++;
					if(*str==',') str++;
					while(*str==' ') str++;
					change+=str-instr;
					instr=str;
					};
				if(*str!='>') 
					{
					fprintf(stderr,"get_type_from_code():error in modifier args\n");
					rm_lnd_all(modif_lst);
					return 0;
					};
				str++;
				while(*str==' ') str++;
				change+=str-instr;
				instr=str;
				};
			}
		else
			{
			tmptype=apply_modifier(tmptype,modif_lst,NULL,tlist);
			rm_lnd_all(modif_lst);
			modif_lst=NULL;

			if((type=mk_subtype_by_type(type,tmptype,tlist,0))==NULL)
				{
				fprintf(stderr,"get_type_from_code():cant's create new type !\n",tname);
				return 0;
				};
			};
		};

	change+=str-instr;
	instr=str;

	};

*res=type;

return change;
};

int get_subtype_from_code(
char * instr,
struct typerec PTR basetype,
listnode labels,listnode fnlist,
struct type_listoflist PTR tlist,
struct vardecl_listoflist PTR vlist,
listnode inl,defined_op d_ops,
listnode inl_lab,
char PTR * res_name,
struct typerec PTR * res_type)
{
struct type_list PTR tl;
int change=0;
char * str;
char tname[34];
enum typemodf tmodf=NONE;
struct typerec PTR type=basetype;
listnode modif_lst=NULL;

while(*str==32) str++;
if(*str!='(')
	return 0;
str++;
while(*str==32) str++;
change=instr-str;
instr=str;
str=get_variable(instr);
while(*str==32) str++;

while((!!*str)&(*str!=')'))
	{
	if ((*str=='*')||(*str=='&'))
		{
		switch(*str)
			{
			case '*': tmodf=POINTER;break;
			case '&': tmodf=REFERENCE;break;
			};
		str++;
		type=mk_ref_type_from_type(type,tmodf,tlist,0); /* create or find reference type */
		tmodf=NONE;
		change+=str-instr;
		instr=str;
		}
	else /* Not any kind of '*' type modifier */
		{
		struct typerec * tmptype;

		tmodf=NONE;
		memset(tname,0,34);
		Strncpy(tname,instr,str-instr);

		if((tmptype=get_type_by_name(tname,NONE,tlist))==NULL)
			if((tmptype=get_type_by_name(tname,FUNC,tlist))==NULL)
				{
				fprintf(stderr,"Type %s unknown\n",tname);
				return 0;
				};

		if(tmptype->typekind==ISMODIF)
			{
			modif_lst=mk_head_lnd(modif_lst,tmptype,TYPEDEFN);

			while(*str==32) str++;
			if(*str=='<')
				{
				struct typerec PTR ttype;
				str++;
				while(*str==' ') str++;
				modif_lst->attr=TWOLISTS;
				modif_lst->data=(char PTR)mk_head_lnd(NULL,modif_lst->data,TYPEDEFN);
				change+=str-instr;
				instr=str;
				while((*str!='>')&(!!*str))
					{	
					str+=get_type_from_code(instr,labels,fnlist,tlist,vlist,",>",inl,d_ops,inl_lab,&ttype);
					if(str==instr)
						{
						fprintf(stderr,"get_type_from_code():can't get modifier args\n");
						rm_lnd_all(modif_lst);
						return 0;
						};
					mk_set_lnd((listnode)modif_lst->data,ttype,TYPEDEFN);
					while(*str==' ') str++;
					if(*str==',') str++;
					while(*str==' ') str++;
					change+=str-instr;
					instr=str;
					};
				if(*str!='>') 
					{
					fprintf(stderr,"get_type_from_code():error in modifier args\n");
					rm_lnd_all(modif_lst);
					return 0;
					};
				str++;
				while(*str==' ') str++;
				change+=str-instr;
				instr=str;
				};
			}
		else
			{
			tmptype=apply_modifier(tmptype,modif_lst,NULL,tlist);
			rm_lnd_all(modif_lst);
			modif_lst=NULL;

			if((type=mk_subtype_by_type(type,tmptype,tlist,0))==NULL)
				{
				fprintf(stderr,"get_subtype_from_code():cant's create new type !\n",tname);
				return 0;
				};
			};
		};

	change+=str-instr;
	instr=str;

	};

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

str++;
change+=str-instr;
str--;
while(*str==32)str--;
str++;
memset(tname,0,34);
Strncpy(tname,instr,str-instr);
*res_name=Strdup(tname);
*res_type=type;

return change;
};
