
// C Source File TIGCC 0.94 SP4
// Created 07/11/2003; 18:26:20

#define USE_TI89              // Compile for TI-89
#define USE_TI92PLUS          // Compile for TI-92 Plus
#define USE_V200              // Compile for V200

#define NEWPROG_VERSION 100	//max2.55

#define CHARVAR_TAG 0xEA
#define INTVAR_TAG 0xEB
#define LONGVAR_TAG 0xEC
#define PTRVAR_TAG 0xED

#define NB_FOR 100		//shall be the same value than in the interpreter or will crash
#define NB_WHILE 30		//shall be the same value than in the interpreter or will crash
#define NB_BLOCK_MAX	50
#define IFS_MAX 10	//for the ifshort if:

// #define OPTIMIZE_ROM_CALLS // Use ROM Call Optimization

#define MIN_AMS 200           // Compile for AMS 1.01 or higher

#define SAVE_SCREEN           // Save/Restore LCD Contents

#include <tigcclib.h>         // Include All Header Files

//#include "pile.h"
//#include "preproc.h"

int nalloc2,nalloc;
unsigned char /*nalloc2 for freeh,*/i_userfunc,defined_as_function_AND_nb_arg[256],*lbl_str[100],*goto_str[100],*ptr,*srcptr,*lineptr,*dataptr,*elineptr,*temp_puc,*temp_puc2/*dispo partout pour temporaire*/,tempptr,ndeffonc,IN_for_or_while_12[100],pile_index_for_or_while;		//srcptr = pointe au premier char ; line_ptr = pointe la ligne ; tempptr pointe un caractere dans la ligne
unsigned char varnum,srcname[20],pileblock[NB_BLOCK_MAX],temp/*,outputfile[20],commandstr[80],leftstr[40],rightstr[40],nameblocklist[17*10],v[10],charstrlist[9*50],intstrlist[9*50],longstrlist[9*50],ptrstrlist[9*50],charvars[50]*/;
char *fposlbl[100],*fposgoto[100]/*,*whilefpos[20],*endwhilefpos[20]*/,current_func_str[10];
unsigned int nb_warning,/*nalloc,*/dim_list,numlbl,lblnum,numgoto,gotonum,foncnum,foncnum2,srcsize,numline,line,iblock/*,lineblocklist[10]*/,nc,ni,nl,np/*,intvars[50]*/,nfonc,size,nsvar,ndvar,sizevarlist,posnum,linen;
unsigned long nbelemm,dim_nilist,nbloop,temp_long,temp_long2/*peut être utilisé en variable temporaire partout dans le programme*/;
int numblock,current_user_func_definition;

//unsigned char last_WHILE_or_FOR_12;	//=0 si dans aucune boucle for ou while, 1 si dans une while, 2 si dans une for
//IFS IF:
long ifs_pile[IFS_MAX];	//position where to store the num of byte to skip if condition false, used with ftell
unsigned char ifs_i,ifs_just_triggered;	//ifscount : total amount of ifs detected, ifs_i : current ifs
//IF ELSE ENDIF
unsigned char alif[257],aif,aeif;
//WHILE ENDWHILE
unsigned char alw[NB_WHILE],aw,aew;
//FOR ENDFOR
unsigned char pilefor[NB_FOR],af,ifor;
//LOOP ENDLOOP
//unsigned char all[257],al,ael;		//attention ! LOOP ENDLOOP a ne pas utiliser


//tampon pour les string de var de a à z
char str_az[]={'k','z','y','w','a',0};


char is_ok;	//ok pour END_TAG

//unsigned int else_num_init[257];
//unsigned int numwhile,numfor,numif,iflevel,ne,ni,nf,ifi,nj;
ESI tmp_esi,argtemp;
ESI file_pos;
ESI file_ori;
ESI esi_end_nilist;
ESI esi_start_nilist;
ESI tmp_esi2;	//sert localement pour sto_var_tag
char *nilist_size_array_ptr;

fpos_t pos1;
fpos_t pos2;

//numlbl=nombre de labels
//lblnum=num du lbl
//nfonc=nombre de fonctions
//foncnum=num de la fonction
//varnum=numero de la var si deja defini
unsigned char *special_var[]={"endbasic","basic","svar","enddef"}; //correspond aux variable non utilisable dim=nsvar
unsigned char *def_var[256]; //correspond aux variables definies dim=ndvar et labels
unsigned int nb_var_called[256];		//correspond au nombre de fois qu'une variable a été appelée, afin de vérifier les variables solitaires
//unsigned char *fonc[]={"init","clrscr","keywait","enddef"};
							//0				1					2					3					4					5					6					7					8					9

unsigned char
 *fonc[]={		""		,"GUCHAR"	,	"GSLVAR",		""		,		"FLBL",	"FGOTO"	,"keywait",		"isz"	,		"dsz"	,		"iff"	, //0
						"freeh"	,"basich"	,	"exech"	,		""		,	"INDIR"	,"printf1","printf2","newline","prints",	"elsee"	, //1
					"svscroff","fedwhil",	"finish",	"when"	,"strlen"	,	"printc","sprintf",	"char"	,	"strcat","atol"		, //2
					"execnpp"	,"GUINT"	,	"GINT"	,	"gsprt8","gsprt16","printld","printxy",	"GLONG"	,"GULONG"	,	"inter"	, //3
						"dline"	,"dmline"	,	"gmode"	,"sprt8"	,"sprt16"	,		""		,	"ord"		,"sprt82"	,"sprt162","sprt322", //4
						"setlcd",	"dpix"	,"gpix"		,"sprt32","fillrect","clrlcd"	,"keytest","keyclear","keydisp","ifthen", //5
						"getlcd",	"fwhile",		"off"	,"gsprt32","realloc","isover16","strcat2","next"	,	"break" ,	"elsee"	, //6
					"grayon"	,"grayoff","light"	,	"dark"	,		""		,"drawstr","setfont","freet"	,"settimer","endiff", //7
					"gotopos"	,	"pos"		,		"jsr" ,	"rts"		,"pause"	,"unsigb"	,	"unsigw","timerexp","timerval",	"if:"	, //8
					"lscroll"	,"rscroll","uscroll","bscroll",		"lrol",	"rrol"	,"osvar"	,  "idle" ,	"memcpy",		""		, //9
						"clrscr",	"rand"	,	"gsprt"	,"lscroll2","rscroll2","uscroll2","bscroll2",""		,"memmove",		""		, //10
					"fopen"		,"disperr",	"fcreate",	""		,	"files"	,		"reps",		""		,	"gets"	,		""		,		""		, //11
							"nott",		"orb"	,		"neg"	,	"notb"	,"dcircle","fillcirc",	""		,		""		,		"sto"	,		""		, //12
							"xorr",		"orl"	,		"andl",		"inf"	,	"infeq"	,		"eq"	,	"supeq"	,	"sup"		,	"noteq"	,		"add", //13
						"textt"	,		"sub"	,	"andb"	,		"mul"	,		""		,		"div"	,		"eqs"	,	"esc"		,		"up"	,	"second", //14
							"def"	,	"enddef",		""		,		"fc"	,"sprt8x"	,		"rtn"	,	"group"	,		""		,		"down",	"shiftt", //15
						"repeat",		""		,"savescr","loadscr",	"mod"		,		"lb"	,		"lw"	,		"ll"	,	"leftt"	,"diamond", //16
						"moveto",	"os"		,		"toos",	"newstr","gsprt8x",		"wb"	,		"ww"	,		"wl"	,	"rightt",	"alpha"	, //17
						"strcmp","strcpy"	,	"gkey","keydelay"	,"keyspeed","FFORR"	,"ENDFFOR",		""		,		""		,		""		, //18
					"pokeb"		,	"pokew"	,	"pokel"	,"lscroll4","archi","unarchi"	,		"i"		,		"b"		,		"w"		,		"l"		, //19
					"peekb"		,	"peekw"	,	"peekl"	,"isarchi","loadasm",		""		,		"x"		,		"y"		,		""		,		""		, //20
					"newstr"	,		"expr",	"string",		""		,"execasm",		""		,"nilist"	,	"mklist",		""		,		""		, //21
							"map"	,	"multi"	,		"two"	,"memchr"	,"closeasm",	""		,"catalog",	"open"	,		""		,"ENDTAG"	, //22
							""		,		""		,"settype",	"finish",	"seqb"	,	"lcdup"	,"lcddown","drawpic","getpic"	,		""		, //23
					"debugon"	,"debugoff",	"seqs",	"seqe"	,	"seqw"	,"prettyxy","getwbt",	"cwidth","EXECBASX",	""		, //24
							"nop"	,	"malloc",		"free","memset"	,	"seql" 	,"asmcall",	"enddef",		""		,		""		,	"enddef"}; //25


						//0						1					2				3						4					5					6					7					8					9
unsigned char
fonc_nbarg[]
			={		0				,			0		,			0		,		1			,			1		,			1		,			0		,			1		,			1		,			1		,	//0
						1				,			1		,			1		,		0			,			1		,			2		,			3		,			0		,			1		,			0		,	//1
						0				,			0		,			0		,		3			,			1		,			1		,			3		,			1		,			2		,			1		,	//2
						1				,			0		,			0		,		4			,			4		,			1		,			4		,			0		,			0		,			3		,	//3
						4				,			3		,			1		,		4			,			4		,			0		,			1		,			4		,			4		,			4		,	//4
						1				,			2		,			2		,		4			,			4		,			0		,			2		,			0		,			0		,			1		,	//5
						0				,			1		,			0		,		4			,			2		,			7		,			2		,			0		,			0		,			0		,	//6
						0				,			0		,			0		,		0			,			0		,			3		,			1		,			1		,			2		,			0		,	//7
						1				,			0		,			1		,		0			,			1		,			1		,			1		,			1		,			1		,			0		,	//8
						1				,			1		,			1		,		1			,			2		,			2		,			1		,			0		,			3		,			0		,	//9
						0				,			1		,			4		,		1			,			1		,			1		,			1		,			0		,			3		,			0		,	//10
						1				,			1		,			2		,		0			,			2		,			1		,			0		,			1		,			0		,			0		,	//11
						1				,			2		,			1		,		1			,			3		,			3		,			0		,			0		,			2		,			0		,	//12
						2				,			2		,			2		,		2			,			2		,			2		,			2		,			2		,			2		,			2		,	//13
						1				,			2		,			2		,		2			,			0		,			2		,			2		,			0		,			0		,			0		,	//14
						1				,			1		,			0		,		2			,			5		,			1		,			1		,			0		,			0		,			0		,	//15
						2				,			0		,			1		,		1			,			2		,			2		,			2		,			2		,			0		,			0		,	//16
						2				,			1		,			2		,		2			,			5		,			3		,			3		,			3		,			0		,			0		,	//17
						2				,			2		,			0		,		1			,			1		,			4		,			0		,			0		,			0		,			0		,	//18
						2				,			2		,			2		,		2			,			1		,			1		,			1		,			1		,			1		,			1		,	//19
						1				,			1		,			1		,		1			,			1		,			0		,			0		,			0		,			0		,			0		,	//20
						2				,			1		,			1		,		0			,			1		,			0		,			0		,			2		,			0		,			0		,	//21
						5				,			1		,			2		,		3			,			0		,			0		,			0		,			1		,			0		,			0		,	//22
						0				,			0		,			2		,		1			,			6		,			0		,			0		,			3		,			5		,			0		,	//23
						0				,			0		,			6		,		6			,			6		,			3		,			4		,			1		,			0		,			0		,	//24
						0				,			1		,			1		,		3			,			6		,			1		,			0		,			0		,			0		,			0		};	//25



unsigned char
*CONST_STR[]
				={	"lcdsize"	,"strtag","listtag","texttag","asmtag","functag","posexpr"	,"negexpr","exprtag","othtag"	,	//strtag
						"up"			,	"down"	,"rightt" ,"leftt"	,"shiftt","second","diamond"	,"alpha"	,		"esc"	,	"pictag",
						"up2"			,	"down2"	,"rightt2","leftt2"	,"shiftt2","second2","diamond2","alpha2",		""		,	""			,
						"onesec"  ,	"gor"		,"greplace","gxor"	,"greverse",	"gand","gerase"	,
		
		
					"enddef"};

long
CONST_VAL[]
				={	LCD_SIZE	,STR_TAG	,LIST_TAG	,	0xE0		,ASM_TAG	,	0xDC	,		0x1F	,		0x20		,		0x0	,		0xF8	,
						337				,		340	,		344			,		338		,	8192		,	4096	,	16384		,		32768		,		264	,		0xDF	,
						338				,		344	,		340			,		337		,	16384		,	4096	,	8192		,		32768		,		0		,			0		,
							18			,		0		,		1				,		2			,		1			,		3		,			1		,
		
							0		};
/*

TI-89: 

Key 	Normal +Shift +2nd +Diamond +alpha 
Up 		337	 	8529	4433		16721 	33105 
Right 344 	8536 	4440 		16728 	33112 
Down 	340 	8532 	4436 		16724 	33108 
Left 	338 	8530 	4434 		16722 	33106 

TI-92+: 

Key 	Normal +Shift	 +2nd +Diamond +alpha 
Up 		338	 	16722	 	4434 		8530	 	33106 
Right	340 	16724 	4436 		8532 		33108 
Down 	344 	16728 	4440 		8536 		33112 
Left 	337 	16721	 	4433		8529 		33105 
*/


char nconst;


unsigned char narglist[]={0,      0   ,0         ,   0};


struct cellule
{
	struct cellule* pt;		//pointeur de la prochaine cellule
	ESI pos;							//valeur du bookmark
};
typedef struct cellule CELLULE;
struct BKM
{
	CELLULE *p1;
	CELLULE *p2;
	CELLULE *p3;
	int n1,n2,n3;
} bkm;
FILE *fout;
ESI argptr;
//0x01 = CHAR_TAG
//IM_TAG (TAG deja defini)
long mabs(long n);


//LES FONCTIONS CI DESSOUS SONT UNE COPIE DU HEADER PREPROC.h
void AppendCharToFile2 (HANDLE h, unsigned char c)
{
  char *base = HeapDeref(h);
  unsigned short len = *(unsigned short*)base;
  if (len > HeapSize(h) - 10) return;
  *(unsigned short*)base = len + 1;
  base[len+2] = c;
}
void AppendBlockToFile2 (HANDLE h, void *addr, unsigned short len)
{
  unsigned short i;
  for (i = len; i; i--) AppendCharToFile2 (h, *((char*)addr)++);
}
void CloseCreatedFile_type (HANDLE h,int type)
{
  if(type==STR_TAG) AppendCharToFile2 (h,0);
  AppendCharToFile2 (h,type);
  HeapUnlock (h);
  HeapRealloc (h, *(unsigned short*)HeapDeref(h) + 3);
}
void AppendStrToFile1 (HANDLE handle, void *str)
{
	AppendBlockToFile2 (handle, str, strlen(str));
}
HANDLE CreateFile2 (const char *FileName)
// Returns a handle, H_NULL in case of error
{
  HANDLE h;
  SYM_ENTRY *sym_entry;
  char str[30], *sptr = str;
  *sptr = 0; while ((*++sptr = *FileName++));
  if (!(h = HeapAlloc (HeapMax ()))) return H_NULL;
  if (!(sym_entry = DerefSym (SymAdd (sptr))))
    {
      HeapFree (h);
      return H_NULL;
    }
  *(long*) HeapDeref (sym_entry->handle = h) = 0x00010000;	//Je pense que ça inscrit la taille (1 + 3 = 4 octets) du fichier et le type (ici type =0x00)
  return h;
}


long dim_tios_list(ESI listptr)
{
	long d;
	ESI argdeb;
	d=0;
	if(*listptr!=LIST_TAG) exit2("dim_tios_list : error");
	listptr--;
	while(*listptr!=END_TAG) { d++;listptr=next_expression_index (listptr);}
	if(*listptr!=END_TAG) exit2("\nEND_TAG expected");
	esi_end_nilist=listptr;
	//printf("\ndim list=%d",(int)d);
	return d;
}
HANDLE CreateFile (const char *FileName)
// Returns a handle, H_NULL in case of error
{
  HANDLE h;
  SYM_ENTRY *sym_entry;
  char str[30], *sptr = str;
  *sptr = 0; while ((*++sptr = *FileName++));
  if (!(h = HeapAlloc (/*HeapMax ()*/1000))) return H_NULL;
  if (!(sym_entry = DerefSym (SymAdd (sptr))))
    {
      HeapFree (h);
      return H_NULL;
    }
  *(long*) HeapDeref (sym_entry->handle = h) = 0x00010000;
  return h;
}

/*
  HANDLE h;
  SYM_ENTRY *sym_entry;
  char str[30], *sptr = str;
  *sptr = 0; while ((*++sptr = *FileName++));
  if (!(h = HeapAlloc (HeapMax ()))) return H_NULL;
  if (!(sym_entry = DerefSym (SymAdd (sptr))))
    {
      HeapFree (h);
      return H_NULL;
    }
  *(long*) HeapDeref (sym_entry->handle = h) = 0x00010000;	//Je pense que ça inscrit la taille (1 + 3 = 4 octets) du fichier et le type (ici type =0x00)
  return h;
*/

void AppendCharToFile (HANDLE h, unsigned char c)
{
  char *base = HeapDeref(h);
  unsigned short len = *(unsigned short*)base;
  if (len > HeapSize(h) - 10) return;
  *(unsigned short*)base = len + 1;
  base[len+2] = c;
}

void AppendBlockToFile (HANDLE h, void *addr, unsigned short len)
{
  unsigned short i;
  for (i = len; i; i--) AppendCharToFile (h, *((char*)addr)++);
}

void CloseFile (HANDLE h)
{
  AppendCharToFile (h,0); AppendCharToFile (h,0x2D);
  HeapUnlock (h);
  HeapRealloc (h, *(unsigned short*)HeapDeref(h) + 3);
}

void mem_to_file(const char* ptrr,unsigned int size_buffer,const char* filenamee)
{
  HANDLE h;
  h = CreateFile (filenamee);
  if(h==H_NULL) exit2("Mem error");
  AppendBlockToFile (h, ptrr, size_buffer);
  CloseFile (h);
}

void fputc2(short c, FILE *stream)
{
	file_pos++;
	//FontSetSys(0); printf("\nc=%d, func=%s",c,current_func_str); FontSetSys(1);//if(ngetchx()=='f') {exit2("aborted by f");}
	fputc(c,stream);
}
void cancel_last_fputc2(FILE *stream)
{
	stream->fpos--;
	file_pos--;
}
void init_bkm(void)
{
	bkm.n1=0; bkm.n2=0; bkm.n3=0;
	if(	(bkm.p1=(CELLULE*)malloc(sizeof(CELLULE)))==NULL || (bkm.p2=(CELLULE*)malloc(sizeof(CELLULE)))==NULL || (bkm.p3=(CELLULE*)malloc(sizeof(CELLULE)))==NULL)
	{
		exit2("memory alloc error");
	}
	(bkm.p1)->pt=NULL; (bkm.p2)->pt=NULL; (bkm.p3)->pt=NULL;
	(bkm.p1)->pos=NULL; (bkm.p2)->pos=NULL; (bkm.p3)->pos=NULL;
}


CELLULE* get_ptr_cellule(char type, int elem)
{
	int i;
	CELLULE* pcel;
	switch(type)
	{
		case 1:
		pcel=bkm.p1;
		break;
		case 2:
		pcel=bkm.p2;
		break;
		case 3:
		pcel=bkm.p3;
		break;
		exit2("erreur de stockage de bookmark2");
	}
	if(elem==0) { return pcel;}
	pcel=pcel->pt;	//pointe sur la premiere cellule de donnée(meme si =NULL)
	for(i=1;i<elem;i++)
	{
		pcel=pcel->pt;
		if(pcel==NULL) exit2("erreur dans la pile, NULL unexpect");
	}
	return pcel;
}
void push_varnum(unsigned char varnn)
{
	nb_var_called[varnn]++;
	fputc2(varnn,fout);
}
void push_varr(unsigned char varnn)
{
		//nb_var_called[varnn]++;
		fputc2(2,fout);	//tag des variables
		push_varnum(varnn);
		//fputc2(varnn,fout);
}
char CONST_process(unsigned char *str)	//retourne -1 si pas trouvé aussinon retourne le numéro de la constante. La variable globale nconst mémorise le résultat de la dernière recherche
{
	nconst=0;
	//printf("str = %s",str); ngetchx();
	while(strcmp(CONST_STR[nconst],"enddef")!=0)
	{
		if(strcmp(CONST_STR[nconst],str)==0) {/*printf("trouve"); ngetchx();*/ return nconst;}
		nconst++;
	}
	nconst=-1;
	return nconst;	//pas trouvé
}

void push_end_attributes_sequence(void)
{
	fputc2(ndeffonc,fout);	//store the number of var used
	fputc2(ndvar,fout);	//store the number of var used
	fputc2(NEWPROG_VERSION,fout);
}

void add_bkm(ESI val, char type)
{
	CELLULE *pcel,*r;
	int elem;
	if(val==NULL) exit2("BOOKMARK==NULL");
	switch(type)
	{
		case 1:
		elem=++bkm.n1;
		break;
		case 2:
		elem=++bkm.n2;
		break;
		case 3:
		elem=++bkm.n3;
		break;
		exit2("erreur de stockage de bookmark");
	}
	r=get_ptr_cellule(type,elem-1);
	if((r->pt=(CELLULE*)malloc(sizeof(CELLULE)))==NULL) exit2("mem alloc err.");
	(r->pt)->pt=NULL;
	(r->pt)->pos=val;
	}

ESI depiler_bkm(int type)
{
	CELLULE *pcel,*c,*cb;
	ESI r;
	int elem;
	switch(type)
	{
		case 1:
		elem=bkm.n1--;
		break;
		case 2:
		elem=bkm.n2--;
		break;
		case 3:
		elem=bkm.n3--;
		break;
	}
	cb=get_ptr_cellule(type,elem-1);
  r=cb->pt->pos;
  free(cb->pt);
  cb->pt=NULL;
  if(r==NULL) exit2("ERROR:dépilage=NULL");
	return r;
}
void del_bkm(void)
{
	int i;
	for(i=1;i<=bkm.n1;i++) depiler_bkm(1);
	for(i=1;i<=bkm.n2;i++) depiler_bkm(2);
	for(i=1;i<=bkm.n3;i++) depiler_bkm(3);
	free(bkm.p1);
	free(bkm.p2);
	free(bkm.p3);
}

void exec_cmd(unsigned char *cmd)
{
	//int ans;
	HANDLE handle;
	push_parse_text (cmd);
	handle = HS_popEStack ();
  NG_execute (handle, FALSE);
	HeapFree (handle);
	//ans = GetIntArg (top_estack);
}
void disp_are_alone_var(void)		//display warning if a var is alone at the end of the compilation
{
	unsigned int i,temp;
	temp=0;
	clrscr();
	for(i=0;i<256;i++)
	{
		if(nb_var_called[i]==1)
		{
			printf("Warning : variable not used : %s\n",def_var[i]);
			temp=1;
		}
	}
	if(temp) ngetchx();
}
void exit2(unsigned char *str_error) //Execute this function if there is a compilation error.
{
	HANDLE houtput;
	if(nb_warning!=0) ngetchx(); //fait une pause pour pouvoir voir les warning
	if(strcmp("\nSource string expected.\n",str_error)==0) 
{
		clrscr(); printf("\n%s",str_error); ngetchx();
	}
	else 
	{
	printf("\nCOMPILATION ABORTED:Error\n%s",str_error);
	printf("\nLast function : %s",fonc[foncnum2]);
	printf("\nLast var used : %s",ptr);
	printf("\nLine : %d",linen);
	ngetchx();

	//Creation of the error output string 
	houtput=CreateFile2 ("npout");								//name of the error output file
	AppendStrToFile1 (houtput, "NewProg ERROR REPORT");
	AppendStrToFile1 (houtput, str_error);
	AppendStrToFile1 (houtput, "\nLast function used : ");
	AppendStrToFile1 (houtput, fonc[foncnum2]);
	AppendStrToFile1 (houtput, "\nLast var name used : ");
	AppendStrToFile1 (houtput, ptr);
	CloseCreatedFile_type (houtput,STR_TAG);
	}
	
	fclose (fout);

	exit(4);
}

char get_foncnum(void)
{
	unsigned char *ptr;
	char error_strr[50];
	foncnum2=0;
	ptr=GetStrnArg(argptr);

	if(strcmp(ptr,"nl")==0) ptr="newline";		//particular case of the newline() function that can be also write with nl() because shorter.
	strcpy (current_func_str, ptr);	//For error indication purpose (in exit2).
	//printf("\n nfonc=%d",nfonc); ngetchx();
	//printf("\n%s",ptr); ngetchx();
	for(foncnum2=0;foncnum2</*nfonc*/255;foncnum2++)
	{
		//if(foncnum2==172) {printf("\nstr:%s num:%d",fonc[foncnum2],foncnum2); ngetchx();}
		if(strcmp(ptr,fonc[foncnum2])==0) 
		{
			return 1;
		}
	}
	//printf("\npassé par la");
//	sprintf(error_strr,"\nUnknown function : %s",ptr);
//	exit2(error_strr);
	//printf("\nfonction inco:%s\n",ptr);
	return 0;
}

long mabs(long n)
{
	if(n<0) return -n;
	return n;
}
unsigned long muabs(unsigned long n)
{
	if(n<0) return -n;
	return n;
}
void push_posint_value(long v,char *ffpos)
{
	char *fpos_save;
	unsigned char *ptr;
	ptr=&v;
	//fpos_save=fout->fpos;
	//fout->fpos=ffpos;
	//fputc2(POSINT_TAG,fout);
	//fputc2(*(unsigned char*)(ptr+2),fout); fputc2(*(unsigned char*)(ptr+3),fout);
	//fout->fpos=fpos_save;
	*(ffpos)=POSINT_TAG;
	*(ffpos+1)=*(unsigned char*)(ptr+2);
	*(ffpos+2)=*(unsigned char*)(ptr+3);
}
void push_value(long v)
{
	unsigned char *ptr;
	ptr=&v;
	//printf("\nds pushvalue abs=%ld",mabs(v)); ngetchx();
	if(mabs(v)<=255) //chars
	{
		fputc2(0x01,fout);
		fputc2(v,fout);
	}
	else
	{
		if(mabs(v)<=65535) //chars
		{
			//printf("\nC'est un entier=%ld \n *argptr=%x %X\n",v,*argptr,v); ngetchx();
			if(v>=0) fputc2(POSINT_TAG,fout);
			else fputc2(NEGINT_TAG,fout);
			fputc2(*(ptr+2),fout); fputc2(*(ptr+3),fout);
		}
		else
		{
			if(mabs(v)<=4294967295)
			{
				if(v>=0) fputc2(IM_TAG,fout);
				else fputc2(37,fout);
				fputc2(*(ptr),fout); fputc2(*(ptr+1),fout); fputc2(*(ptr+2),fout); fputc2(*(ptr+3),fout); 
			}
			else
			{
				exit2("erreur pour cet entier");
			}
		}
	}	
}
char is_special_var(unsigned char *p)
{
	int i;
	for(i=0;i<nsvar;i++)
	{
		if(strcmp(special_var[i],p)==0) return 1;
	}
	return 0;
}
char is_existing_var(unsigned char *p)
{
	for(varnum=0;varnum<ndvar;varnum++)
	{
		if(strcmp(def_var[varnum],p)==0) return 1;
	}
	return 0;
}
char is_existing_lbl(unsigned char *p)
{
	for(lblnum=0;lblnum<numlbl;lblnum++)
	{
		if(strcmp(lbl_str[lblnum],p)==0) return 1;
	}
	return 0;
}
void add_var(unsigned char *p)
{
	def_var[ndvar]=p;
	//nb_var_called[ndvar]++;
	varnum=ndvar;
	ndvar++;
	if(ndvar==255) exit2("Too much variables, labels\nand functions definitions.");
}

void disp_var(void)
{
	int i;
	for(i=0;i<ndvar;i++)
	printf("\n%s",def_var[i]);
	ngetchx();
}

void goto_process(void)
{
	int dif;
	if(*argptr!=0) exit2("\nOnly varentity for lbl");
	ptr=GetStrnArg(argptr);
				if(!is_special_var(ptr)) //si ce n'est pas une speciale var
			{
				if(!is_existing_lbl(ptr)) //si elle n'existe pas
				{
					//exit2("Not yet defined lbl");
					fputc2(13,fout); fposgoto[numgoto]= file_pos; fputc2(0,fout); fputc2(0,fout);
					goto_str[numgoto]=ptr; numgoto++;
				}
				else
				{
					dif=(long)( file_pos)-(long)fposlbl[lblnum];
					//printf("dif=%d base dix",dif); ngetchx();
					if(mabs(dif)<=127) { fputc2(0x05,fout); fputc2(dif,fout);}
					else { fputc2(13,fout); fputc2(*(char*)(&dif),fout);fputc2(*((char*)(&dif)+1),fout);}
				}
			}
			else
			{
				exit2("\nLabel name goto forbiden.");
			}
}
void var_process(void)
{
	ptr=GetStrnArg(argptr);

				if(!is_special_var(ptr)) //si ce n'est pas une speciale var
			{
				if(!is_existing_var(ptr)) //si elle n'existe pas
				{
					add_var(ptr);
				}
			}
			else
			{
				exit2("\nThis var name is forbiden.");
			}
}

void ilist_process(unsigned char type)
{
	long filepos_temp,filepos_temp2,value;
	unsigned int nbelemw,ii,count;
	unsigned char *ptrrr,*ptrrr2,*strr,is_minus;
	//argptr--;
	nbelemw=0;
	switch(type)
	{
		case 1:
		fputc2(197,fout);	//fonction b()
		break;
		case 2:
		fputc2(198,fout);	//fonction w()
		break;
		case 4:
		fputc2(199,fout);	//fonction l()
		break;
	}
	if(*argptr==0)
	{
		var_process();
		//ptr=GetStrnArg(argptr);
		CONST_process(ptr);	//retourne dans nconst l'index de la constante si s'en est une, aussinon retourne -1
		if(nconst!=-1)	exit2("Reserved variable name in b-w-l()");
		push_varr(varnum);;
		/*fputc2(2,fout);	//tag des variables
		fputc2(varnum,fout);*/
	}
	else exit2("Syntax : b-w-l(var_dest):data:y\nvar_dest expected.");
	filepos_temp=ftell(fout);
	fputc2(0,fout); fputc2(0,fout); fputc2(0,fout);	//reserve place for a futur storing (of nb elements of the ilist)

	if((((unsigned long)fout->fpos)%2)==1)		//take care of even adress
	{
		switch(type)
					{
						case 1: //necessary even for one bytes data because can crash the calculator with fcreate function
						case 2:
						case 4:
						fputc2(0xE5,fout);	//to adjust even adress, 0xE5 means nothing
						break;
					}
	}
	
	
	while(*argptr!=0xE9)
	{
try_againw:
		if(*argptr>=0x01 && *argptr<=0x1B)
		{
			if(*argptr==0x09)	//End of the definition : y
			{
				argptr--;
				filepos_temp2=ftell(fout);	//saving position
		
		//STORING nbelem in the file
			fseek (fout, filepos_temp, SEEK_SET);	//goto the previous saved position for storing nbelem

			ptrrr2=fout->fpos;		//operate manually
			value=nbelemw;
			ptrrr=&value;
		
			*ptrrr2=POSINT_TAG;
			*(ptrrr2+1)=*(unsigned char*)(ptrrr+2);
			*(ptrrr2+2)=*(unsigned char*)(ptrrr+3);
			
			fseek (fout, filepos_temp2, SEEK_SET);	//goto the previous saved position
			return;
			}
			else exit2("Variables a-z are forbiden in ilist.");
		}
		
		switch(*argptr)
		{
			case 0:
			if(strcmp(ptr=GetStrnArg(argptr),"basic")==0) exit2("Error in b-w-l-ilist:y expected");
			else
			{
				CONST_process(ptr);	//retourne dans nconst l'index de la constante si s'en est une, aussinon retourne -1
				if(nconst!=-1)	//alors c'est une constante prédéfinie
				{
					value=CONST_VAL[nconst];
					ptrrr2=&value;
					switch(type)
					{
						case 1:
						fputc2(*(ptrrr2+3),fout);
						break;
						case 2:
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
						case 4:
						fputc2(*(ptrrr2),fout);
						fputc2(*(ptrrr2+1),fout);
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
					}
					nbelemw++;
					goto try_againw;
					break;
				}
				else 
				{
					exit2("Variable forbiden in b-w-l() definition");
				}
				
			}
			goto try_againw;
			break;
			case USERFUNC_TAG:
			if(strcmp(ptr=GetStrnArg(argptr),"repeat")==0)		//allow the user to fill automatically the ilist (it can take a large amount of mem with a simple definition)
					{
						if(remaining_element_count(argptr)!=2) exit2("Syntax in b-w-l:repeat(count,value)");
						if(*argptr!=POSINT_TAG) exit2("Syntax in b-w-l:repeat(count,value)\ncount must be an integer");
						count=GetIntArg(argptr);
						//if(*argptr>=0x01 && *argptr<=0x1B) exit2("Syntax in b-w-l:repeat(count,value)\nvalue must be an integer");
						is_minus=0;
						if(*argptr==MINUS_TAG) {is_minus=1; argptr--;}
						if(*argptr==0xE3)
						{
							argptr--;
							if(*argptr==0x2b ||	*argptr==0x2c) argptr--;		//binary or hexadecimal number
							else {printf("111 *argptr=%d",*argptr); ngetchx(); exit2("Syntax in b-w-l:repeat(count,value)\nvalue must be an integer");}
						}
						if(*argptr==STR_TAG)//allow the programmer to put an ascii code of a char
						{
							strr=GetStrnArg(argptr);
							value=*strr;			
						}
						else
						{
							if(*argptr!=POSINT_TAG) {printf("222 *argptr=%d",*argptr); ngetchx(); exit2("Syntax in b-w-l:repeat(count,value)\nvalue must be an integer");}
							value=GetIntArg(argptr);
						}
						
						if(is_minus) value*=-1;
						ptrrr2=&value;
						for(ii=0;ii<count;ii++)
						{
							switch(type)
							{
								case 1:
								fputc2(*(ptrrr2+3),fout);
								break;
								case 2:
								fputc2(*(ptrrr2+2),fout);
								fputc2(*(ptrrr2+3),fout);
								break;
								case 4:
								fputc2(*(ptrrr2),fout);
								fputc2(*(ptrrr2+1),fout);
								fputc2(*(ptrrr2+2),fout);
								fputc2(*(ptrrr2+3),fout);
								break;
							}
							nbelemw++;
						}
						
						goto try_againw;						
					}
			else exit2("This function is forbiden in b-w-l() definition");
			break;
			case 0xE5:
			argptr--;
			goto try_againw;
			break;
			case 0xE3:
			argptr--;
			if(*argptr==0x2b ||	*argptr==0x2c) argptr--;		//binary or hexadecimal number
			else exit2("Unexpected element format.");
			goto try_againw;
			break;
			case 0xE8:
			if(*(argptr-1)==0) {argptr-=2;}
			else argptr-=2;
			linen++;
			//argptr-=2;
			goto try_againw;
			break;
			case 0xE7:
			//linen++;
			if(*(argptr-1)==0) {argptr-=2;}
			else argptr-=2;
			//argptr-=2;
			goto try_againw;
			break;
			case STR_TAG:	//allow the programmer to put an ascii code of a char
			strr=GetStrnArg(argptr);
			value=*strr;
			ptrrr2=&value;
			switch(type)
					{
						case 1:
						fputc2(*(ptrrr2+3),fout);
						break;
						case 2:
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
						case 4:
						fputc2(*(ptrrr2),fout);
						fputc2(*(ptrrr2+1),fout);
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
					}
			nbelemw++;
			goto try_againw;
			break;
			case POSINT_TAG:
			value=GetIntArg(argptr);
			ptrrr2=&value;
			switch(type)
					{
						case 1:
						fputc2(*(ptrrr2+3),fout);
						break;
						case 2:
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
						case 4:
						fputc2(*(ptrrr2),fout);
						fputc2(*(ptrrr2+1),fout);
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
					}
			nbelemw++;
			goto try_againw;
			break;
			case MINUS_TAG:
			argptr--;
			if(*argptr==0xE3)
			{
				argptr--;
				if(*argptr==0x2b ||	*argptr==0x2c) argptr--;		//binary or hexadecimal number
				else exit2("Unexpected element format.");
			}
			value=-GetIntArg(argptr);
			ptrrr2=&value;
			switch(type)
					{
						case 1:
						fputc2(*(ptrrr2+3),fout);
						break;
						case 2:
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
						case 4:
						fputc2(*(ptrrr2),fout);
						fputc2(*(ptrrr2+1),fout);
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
					}
			nbelemw++;
			goto try_againw;
			break;
			case NEGINT_TAG:
			value=GetIntArg(argptr);
			ptrrr2=&value;
			switch(type)
					{
						case 1:
						fputc2(*(ptrrr2+3),fout);
						break;
						case 2:
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
						case 4:
						fputc2(*(ptrrr2),fout);
						fputc2(*(ptrrr2+1),fout);
						fputc2(*(ptrrr2+2),fout);
						fputc2(*(ptrrr2+3),fout);
						break;
					}
			nbelemw++;
			goto try_againw;
			break;
		}
		//printf("*argptr %d",*argptr); ngetchx();
		exit2("Functions unexpected in b-w-l():y");
	}
	exit2("Error in b-w-l-ilist:y expected");
	return;
}
void end_process_0xE9(void)
{
	argptr-=2;	//pointe maintenant sur 0xE9, le tag de fin de programme Tibasic
			if(numblock>0) exit2("y expected.");
			if(numblock<0) exit2("y unexpected");
			if(i_userfunc>0) exit2("Enddef() missing");
			if(nb_warning!=0) ngetchx();
			if(nalloc>0 || nalloc2>0) //Verify if the number of ~malloc is equal to the number of free function just for Warn the programmer
			{
				clrscr();
				printf("Compilation Warning :\nThe number of malloc,ilist,fopen,seqb,seqw,seql,group,newstr functions is not equal to the number of free function.\nPerhaps this is in your intention, but if not, you should verify by your own directly in the program.");
				ngetchx();
			}
			if(i_userfunc!=0) exit2("Enddef() expected");	//verify if a function definition is not closed
			disp_are_alone_var();
			fputc2(0xE9,fout);
			
			push_end_attributes_sequence();
			
			fputc (0, fout);
			fputs ("NPP", fout);
			fputc (0, fout);
			fputc2(OTH_TAG,fout);
			//ngetchx(); 
			fclose(fout);
			//printf("\nSuccess!");			LLAA FFIINN
			//deletePile(pileif);
			//ngetchx();
			exit(4);
}
void tibasic_sequence(char is_basich)
{
	unsigned char *arg,*argg,*ptrr;
	unsigned int i;
	if(*argptr==0xE8 || *argptr==0xE7) argptr-=2;	//pass the end of line : init()
	if(*argptr==0xE4 && *(argptr-1)==0x12 && *(argptr-2)==0xE9)	//si on a atteint la fin du programme
	{
			end_process_0xE9();
	}
	//alors si on a pas encore atteint la fin du programme :
	arg=argptr;	//pointe au début de la première instruction Tibasic
	while (/**argptr!=0xE9*/!(*(argptr)==0xE4 && *(argptr-1)==0x12 && *(argptr-2)==0xE9) || *argptr==0xE9)		//tant qu'on atteint pas la fin du programme, un start n'étant pas la seule condition de fin d'un bloc Tibasic
	{
		//printf("\nargptr=%ld, *argptr=%d",argptr,*argptr); ngetchx();
		if(*argptr==0)		//si c'est une variable, alors c'est peut être le mot endbasic qui signe la fin de la séquence Tibasic
		{
			argtemp=argptr;	//argtemp pointe sur le start (si il y a), instruction qui n'a pas besoin d'être mis dans le code tibasic
			if(strcmp(GetStrnArg (argptr),"endbasic")==0) {argtemp++; break;	}	//si oui, argtemp pointe maintenant sur le dernier octet de l'instruction tibasic à copiée
			continue;
		}
			tmp_esi=argptr;
			if(*argptr==0xE8 || *argptr==0xE7)
			{
				argptr-=2; argtemp=argptr; continue;
			}
			//if(*argptr==0x7F || *argptr==0x3A) {argptr--; continue;}
			if(*argptr!=0xE5)
			{
				//printf(" XX*argptr=%dXX",*argptr); ngetchx();
				TRY
				next_expression_index (argptr);	//si on ne prend pas la peine de vérifier si *argptr=0xE5, l'erreur "internal error" apparait
				ONERR
				//printf("\nError\nargptr=%ld, *argptr=%d",argptr,*argptr); ngetchx();
				argptr--;
				ENDTRY
			}
			else argptr--;
			if(tmp_esi==argptr) argptr--;		
			
			argtemp=argptr;

	}
	//argtemp pointe maintenant sur le dernier octet de l'instruction tibasic à copiée
	if(*argtemp==0xE4) argtemp++;	//cas de la séquence Tibasic de fin de programme, si on ne n'écrit pas cette commande, il y a une erreur à la fin de l'exécution du programme
	i=arg-argtemp+1;
	ptrr=&i;
	//printf("\nPASSED\n*argptr=%d, taille=%d",*argptr,i); ngetchx();
	if(i>0)	//n'inscrit dans le fichier destination que si il y a des instructions tibasic
	{
		//ptrr=&i;
		if(is_basich==0) fputc2(248,fout); //execbas function = OTH_TAG
		else {fputc2(11,fout); push_varnum(varnum);}	//basich tag varnum=destination var
		fputc2(*(ptrr),fout); fputc2(*(ptrr+1),fout);
 		for(argg=argtemp;argg<=arg;argg++)
		{
			fputc2(*argg,fout);
		}	
	}
	else	//i=0, inscrit seulement des données (vides) pour les basich endbasic, car un pointeur valide est nécessaire est nécessaire pour les fonctions exech et freeh
	{
		if(is_basich==1)
		{
			//ptrr=&i;
			fputc2(11,fout);
			push_varnum(varnum);
			fputc2(*(ptrr),fout); fputc2(*(ptrr+1),fout);
 			for(argg=argtemp;argg<=arg;argg++)
			{
				fputc2(*argg,fout);
			}
		}
	}
	
	//argptr-=2;
	//printf("\nPASSED2"); ngetchx();
	
	if(*argptr==0xE4 && *(argptr-1)==0x12 && *(argptr-2)==0xE9)	//si on a atteint la fin du programme
	{
			end_process_0xE9();
	}

}

void _main(void)
{
	ESI arg = top_estack;
	ESI argg,r,argdeb;
	SYM_ENTRY *src_entry;
	unsigned char *temp_str,*ptrr,str_buf[40];
	int *uip,ui;
	int dif;
	unsigned int i,size_handle;
	unsigned long ulv;
	char isifc;
	long lv;
	nalloc2=0; nalloc=0;	//Number of functions detected supposed to allocate dynamically memory (with malloc for example) 
	FILE* f;
	//Pile *pileif;				//ICI ICI
	//mem_to_file("coubnvghcoucou",14,"coucou");
  arg=top_estack; numline = 0; line = 0; i_userfunc=0; current_user_func_definition=-1;
  pile_index_for_or_while=0; ndeffonc=0; nbloop=0; i=0;nfonc=0; size=0; nsvar=0; ndvar=0; sizevarlist=0; lblnum=0; numlbl=0; numgoto=0; linen=0; numblock=0; iblock=0, nb_warning=0; //linen = line readed (for error return)
  
  //IFS
  ifs_i=0; ifs_just_triggered=0;
  //IF
  aif=0; aeif=0;
  
  //last_WHILE_or_FOR_12=0;
  //WHILE
  aw=0; aew=0;
  //FOR
  ifor=0; af=0;
  
  //LOOP
  //al=0; ael=0;
  
  //numwhile=0; numfor=0; numif=0; iflevel=0; ni=0; ne=0; nf=0; ifi=0; nj=0;
  ///init_bkm();
   //pileelse=newPile();
  //initPile(pileelse);
  for(i=0;i<256;i++) {nb_var_called[i]=0; defined_as_function_AND_nb_arg[i]=0;}
  i=0;
  while(strcmp(fonc[i],"enddef")!=0)
  {
  	nfonc++; i++;									//nfonc=nbre exact de fonctions
  }
  //printf("\nnfonc=%d",nfonc); ngetchx();
  i=0;
  while(strcmp(special_var[i],"enddef")!=0)
  {
  	nsvar++; i++;									//nsvar=nbre exact de var definies
  }
  //printf("\nnsvar=%d",nsvar); ngetchx();
  if(GetArgType (arg) != STR_TAG) exit2("\nSource string expected.\n");
  temp_str = GetStrnArg(arg);
  
  strcpy (srcname , temp_str);			

  f=fopen(srcname,"r");
  srcsize=*(unsigned int*)(f->base);
  fclose(f);
  
  clrscr();
  //sprintf(str_buf,"Newprog compilation : Filename : %s",srcname);
  //ST_helpMsg(str_buf);
  printf("Newprog compilation :\nFilename : %s",srcname);// ngetchx();
  src_entry = DerefSym(SymFind(SYMSTR(srcname)));
 
	//printf("\nnom : %s taille : %d", srcname, srcsize);
	argptr=HToESI(src_entry->handle);
	if((fout=fopen("out","wb"))==NULL) exit2("Memory error");

	//printf("\n*argptr-7=%x",*(argptr-7));
	if(*(argptr-7)==0xE8) argptr-=9;
	else argptr-=7;
	
	//printf("\n*argptr=%x",*argptr);
	//ngetchx();
	//ngetchx();
	

	file_ori= fout->fpos;
	file_pos= fout->fpos;
	
	/*fputc (0, fout);
	fputs ("NPP", fout);
	fputc (0, fout);*/
	
	argdeb=argptr;	//pour l'affichage de l'avancement
	
	//printf("\n Valeur de *argptr=%x +2=%x",*argptr, *(argptr+2)); ngetchx();
	if(*argptr!=USERFUNC_TAG)       //se charge de detecter "init()"
	{
		exit2("init() expected line 1");
	}
	else
	{
		if(strcmp(GetStrnArg(argptr),"init")!=0)
		{
			exit2("init() expected line 1  - 2");
		}
		argptr-=1;
	}
	
	
	
	
	//séquence Tibasic initiale
	tibasic:
	//tibasic_sequence();		//Code en TIBASIC copié tel quel dans le fichier destination


	qbasic:
	while(nbloop<30000)  //si l'on ne tourne pas trop en rond (nbloop)
	{
		relaunch2:
		nbloop++;
		
		//FontSetSys(0); printf("\nnewprog : *argptr=%d, argptr=%ld",*argptr,argptr); FontSetSys(1);//if(ngetchx()=='f') {exit2("aborted by f");}
		if(*argptr==0x08)	//x var detected alone : Start of a block
		{
			argptr--;
			//printf("XXX "); ngetchx();
			fputc2(206,fout);	//fonction x(), signifie le début d'un bloc
			pileblock[numblock++]=iblock;	//on met dans la pile
			push_value(iblock++);
			if(iblock>NB_BLOCK_MAX) exit2("Too much i:y or x:y blocks.");
			goto relaunch;
		}
		if(*argptr==0x09)	//y var detected alone : end of a block
		{
			argptr--;
			//printf("YYY ");  ngetchx();
			fputc2(207,fout);	//fonction y(), signifie la fin d'un bloc
			push_value(pileblock[--numblock]);
			if(numblock<0) exit2("y : endblock unexpected");
			goto relaunch;
		}
		if(*argptr==0x13)	//i syntax error : an argument is expected
		{
			exit2("Syntax expected : i(condition):y\ncondition missing.");
		}
		if(*argptr==0x07)	//w var detected alone : start of an word ilist inline
		{
			exit2("Syntax expected : w(var_dest):y\nvar_dest missing.");
			//ilist_process();
			//goto relaunch;
		}
		if(*argptr==0x0C)	//b var detected alone : start of an byte ilist inline
		{
			exit2("Syntax expected : b(var_dest):y\nvar_dest missing.");
			//ilist_process();
			//goto relaunch;
		}
		if(*argptr==0x16)	//l var detected alone : start of an long ilist inline
		{
			exit2("Syntax expected : l(var_dest):y\nvar_dest missing.");
			//ilist_process();
			//goto relaunch;
		}
		if(*argptr>=0x1 && *argptr<=0x1B) //si c'est une variable a------z . En fait, ca traite aussi tout ce qui n'est pas extra_tibasic token. On peut donc rajouter d'autres _TAG mais pas de _ITAG
			{
	
				printf("\n*(argptr+1)=%d *argptr=%d *(argptr-1)=%d",*(argptr+1), *argptr, *(argptr-1));  ngetchx();
				str_az[4]='a'+*argptr;
				//printf("\nstr_az=%s",str_az); ngetchx();
				ptr=str_az;
				///////////
				//if(strcmp(ptr,"end")==0) { fputc2(OTH_TAG,fout); argptr-=2; goto tibasic;}  //on retourne alors au tibasic
				if(!is_special_var(ptr)) //si ce n'est pas une speciale var
				{
					if(!is_existing_var(ptr)) //si elle n'existe pas
					{
						add_var(ptr);
						exit2("Var name a-z and grec\nare frobiden."); //Cette ligne enlève la possibilité d'utiliser les variables de a à z dans les programmes, enlever cette ligne si on souhaite les avoirs mais l'exécution sera parfois buguée
					}
				}
				else
				{
					//exit2("You can't use this\nvar name.");
				}
				
				
				//fputc2(0x2,fout); //Tag des variables
				//fputc2(varnum,fout); //Attention! nombre de variables limités à 256
				//////////
				argptr--;
				//exit2("var a>-<z aren't allowed");
			}
		relaunch:		//si on passe là, alors on a pas de a----z
		if((((int)argptr)%200)==0) {FontSetSys(F_4x6); printf_xy(0,95,"Progress : %d/100, Line  %d",(unsigned int)((argdeb-argptr)*100/srcsize),linen); FontSetSys(F_6x8);}
		switch(*argptr)
		{
			case 0xE9: //fin du programme
			printf("Unexpected exit"); ngetchx();
		/*	if(nb_warning!=0) ngetchx(); //fait une pause pour pouvoir voir les warning
			if(nalloc!=0 || nalloc2!=0) //Verify if the number of ~malloc is equal to the number of free function just for Warn the programmer
			{
				clrscr();
				printf("Compilation Warning :\nThe number of malloc,ilist,fopen,seqb,seqw,seql,group, newstr functions is not equal to the number of free function.\nPerhaps this is in your intention, but if not, you should verify by your own directly in the program.");
				ngetchx();
			}
			if(numblock>0) exit2("y expected.");
			if(numblock<0) exit2("y unexpected.");
			disp_are_alone_var();
			
			fputc2(0xE9,fout); 
			
			push_end_attributes_sequence();
			
			fputc (0, fout);
			fputs ("NPP", fout);
			fputc (0, fout);
			fputc2(OTH_TAG,fout);
			fclose (fout);
			exit(4);*/
			break;
			case 0xE4: //indicateur I_TAG pour fonctions autres
			if(*(argptr-1)==0x30 || *(argptr-1)==0x51) {argptr--; goto relaunch;}  //si label_tag
			if(*(argptr-1)==0x2F /*goto*/|| *(argptr-1)==0x74 /*for_itag*/ || *(argptr-1)==0x0E /*endfor_itag*/ || *(argptr-1)==0x16 || *(argptr-1)==0x3B|| *(argptr-1)==0x10|| *(argptr-1)==0x3D|| *(argptr-1)==0x15 || *(argptr-1)==0x0B || *(argptr-1)==0x18 || *(argptr-1)==0x11) {argptr--; goto relaunch;}  //si goto_tag if_tag for  endfor exit(=break) ifthen endif while endwhile else loop endloop
			if(*(argptr-1)==98) {argptr-=2; fputc2(140,fout); break;}	//Text command
			if(*(argptr-1)==0x3A)	//IF_short
			{
				argptr-=2;
				//printf("Dans 0xE4"); ngetchx();
				fputc2(89,fout);
				ifs_just_triggered=1;
				ifs_pile[ifs_i++]=ftell(fout);	//position where to store the num of byte to skip if condition false
				fputc2(0,fout); //fputc2(0,fout); fputc2(0,fout);	//for a futur push_posint, when reaching 0xE8 or 0xE7
			}
			if(*(argptr-1)==0x12 && *(argptr-2)==0xE9)	//fin du programme dans la séquence newprog
			{
				if(nb_warning!=0) ngetchx(); //fait une pause pour pouvoir voir les warning
				if(nalloc>0 || nalloc2>0) //Verify if the number of ~malloc is equal to the number of free function just for Warn the programmer
				{
					clrscr();
					printf("Compilation Warning :\nThe number of malloc,ilist,fopen,seqb,seqw,seql,group, newstr functions is not equal to the number of free function.\nPerhaps this is in your intention, but if not, you should verify by your own directly in the program.");
					ngetchx();
				}
				if(numblock>0) exit2("y expected.");
				if(numblock<0) exit2("y unexpected.");
				if(i_userfunc!=0) exit2("Enddef() expected");	//verify if a function definition is not closed
				disp_are_alone_var();
				
				fputc2(0xE9,fout); 
				
				push_end_attributes_sequence();
				
					fputc (0, fout);
				fputs ("NPP", fout);
				fputc (0, fout);
				fputc2(OTH_TAG,fout);
				fclose (fout);
				exit(4);
			}
			break;
			case 0x3D:	//WHILE
			fputc2(0x3D,fout);
			aw++; aew++;
			if(aw>=NB_WHILE-2) exit2("Too much While:Endwhile");
			alw[aew]=aw;
			IN_for_or_while_12[++pile_index_for_or_while]=2;		// for the next() function
			push_value(alw[aew]);
			argptr--;
			break;
			case 0x15:		//endwhile			*(ptrg+1)=*((unsigned char*)(&dif)+1);
			fputc2(0x15,fout);
			push_value(alw[aew]);
			pile_index_for_or_while--;		//if pile_index_for_or_while==0; in no loop
			aew-=1;
			argptr-=3;
			break;
			case 0x2F:		//gere GOTO
			argptr--;
			//if(numblock!=0) exit2("goto forbiden in x:y");
			if(*(argptr)!=0) exit2("GOTO must be a variable name");
			fputc2(0x05,fout); //tag pour signifier GOTO
			//goto_process();
			break;
			case 0x3B:		//ifthen
			fputc2(0x3B,fout);
			aif++; aeif++;
			alif[aeif]=aif;
			if(aif==255) exit2("Too much if then else endif.");
			push_value(alif[aeif]);
			argptr--;
			break;
			case MOD_TAG:		//modulo   164
			fputc2(MOD_TAG,fout);
			argptr--;
			break;
			case 0x0B:	//else
			fputc2(0x45,fout);
			push_value(alif[aeif]);
			argptr--;
			break;
			case 0x10:		//endif
			fputc2(0x4F,fout);
			push_value(alif[aeif]);
			aeif=aeif-1;
			argptr--;
			break;
			case 0x18:    //LOOP_ITAG
			exit2("Loop:endloop forbiden.\nUse lbl:goto instead");
			//fputc2(24,fout);
			//al++; ael++;
			//all[ael]=al;
			//push_value(all[ael]);
			argptr--;
			break;
			case 0xE6:		//comment @, will be passed by the compilator
			argptr-=3;
			while(*argptr!=0) argptr--;
			argptr--;
			break;
			case 0x11:		//ENDLOOP_ITAG
			//fputc2(34,fout);
			//push_value(all[ael]);
			//ael=ael-1;
			argptr--;
			break;
			case 0x3A:		//correspond à IF_ITAG ; voir 0xE4
			exit2("\nIF_ITAG unexpected");
			break;
			case EXIT_ITAG:
			argptr--;
			fputc2(0x16,fout);
			break;
			case LIST_TAG:	//217			LIST-TAG,num_of_var,nbelem,size_of_elem
			argptr--;	
			nbelemm=0;
			tmp_esi=argptr;
			ptr=GetStrnArg(argptr);
			CONST_process(ptr);	//retourne dans nconst l'index de la constante si s'en est une, aussinon retourne -1
			argptr=tmp_esi;
			if(*tmp_esi==0 && nconst==-1)		//if start by a variable and if this variable is not a predefined constant, so this is an instanciated list
			{
				nalloc++;
				ptr=GetStrnArg(argptr);
				
				if(!is_special_var(ptr)) //si ce n'est pas une speciale var
			  {
				  if(!is_existing_var(ptr)) //si elle n'existe pas
				  {
				  	add_var(ptr);
				  }
			  }
			  fputc2(LIST_TAG,fout);
				push_varnum(varnum);
				//fputc2(varnum,fout);
				dim_list=GetIntArg(argptr);	//Size of the elements 1,2,4 (voir plus : not implemented yet)
				
				tmp_esi=argptr;
				while(*argptr!=END_TAG)		//Count the number of elements of the instanciated list
				{
//					printf("*argptr=%x",*argptr); ngetchx();
					if(*argptr!=FALSE_TAG && *argptr!=TRUE_TAG && *argptr!=0 /*variables*/&& *argptr!=POSINT_TAG && *argptr!=NEGINT_TAG && *argptr!=MINUS_TAG && !(*argptr==EXT_TAG && (*(argptr-1)==BIN_TAG || *(argptr-1)==HEX_TAG))) 
					{
						//printf("\n*argptr=%x \n*(argptr+1)=%x",*argptr,*(argptr+1)); ngetchx();
						exit2("When making an instanciated list\n with {name_var,...},\n the elements must be an integer or variable.\nFunctions are forbiden.");	
					}
					
					if(*argptr==MINUS_TAG)
					{
						argptr--;
					}
					if(*argptr==EXT_TAG && (*(argptr-1)==BIN_TAG || *(argptr-1)==HEX_TAG))
					{
						//printf("C'est un BIN ou un HEX"); ngetchx();
						argptr-=2;
					}
					
					if(*argptr==0)
					{
						argptr--;
						GetStrnArg(argptr);
						/*ptr=GetStrnArg(argptr);
					if(strcmp(ptr,"end")==0) { fputc2(OTH_TAG,fout); argptr-=2; goto tibasic;}  //on retourne alors au tibasic
					if(!is_special_var(ptr)) //si ce n'est pas une speciale var
					{
						if(!is_existing_var(ptr)) //si elle n'existe pas
						{
							add_var(ptr);
						}
					}
					else
					{
						exit2("\nThis var name is forbiden.");
					}
					fputc2(0x2,fout); //Tag des variables
					fputc2(varnum,fout); //Attention! nombre de variables limités à 256*/
					}
					else GetIntArg(argptr);
					/*GetIntArg(argptr);*/
					nbelemm++;
					//SkipArg(argptr);
					
				}
				push_value(nbelemm);	
				push_value(dim_list);		//Size of the elements 1,2,4 (voir plus : not implemented yet)
				argptr=tmp_esi;
				while(*argptr!=END_TAG)		
				{				
				//printf("\nvarn=%d nbelem=%d wide=%ld",varnum,dim_list,nbelemm);
				//ngetchx();
					switch (*argptr)
					{
						case MINUS_TAG:
						argptr--;
						fputc2(MINUS_TAG,fout);
						
						//rajouter pour la nouvelle année 2010 !
						if(*argptr==0xE3)
						{
							argptr--;
							if(*argptr==0x2b ||	*argptr==0x2c) argptr--;		//binary or hexadecimal number
							else exit2("Unexpected element format.");
						}
						//
						push_value(GetIntArg(argptr));
						break;
						case EXT_TAG:
						if(*(argptr-1)==BIN_TAG || *(argptr-1)==HEX_TAG)
						{
							argptr-=2;
							push_value(GetIntArg(argptr));
						}
						break;
						case POSINT_TAG:
						case NEGINT_TAG:
						push_value(GetIntArg(argptr));
						break;
						case 0:	//variables or predifined constants
						argptr--;
						ptr=GetStrnArg(argptr);

						CONST_process(ptr);	//retourne dans nconst l'index de la constante si s'en est une, aussinon retourne -1
						if(nconst!=-1)	//alors c'est une constante prédéfinie
						{
							push_value(CONST_VAL[nconst]); break;
						}
						
						//Si ce n'est pas une constante, alors le code suivant sera exécuté
						if(!is_special_var(ptr)) //si ce n'est pas une speciale var
						{
							if(!is_existing_var(ptr)) //si elle n'existe pas
							{
								add_var(ptr);
							}
						}
						else
						{
							exit2("\nThis var name is forbiden.");
						}
						push_varr(varnum);
						break;
						/*
						argptr--;
						ptr=GetStrnArg(argptr);
						if(strcmp(ptr,"end")==0) {exit2("end forbiden in an instanciated list.");}  //on retourne alors au tibasic
						if(!is_special_var(ptr)) //si ce n'est pas une speciale var
						{
							if(!is_existing_var(ptr)) //si elle n'existe pas
							{
								add_var(ptr);
							}
						}
						else
						{
							exit2("\nThis var name is forbiden.");
						}
						push_varr(varnum);;
						//fputc2(0x2,fout); //Tag des variables
						//fputc2(varnum,fout); //Attention! nombre de variables limités à 256
						break;*/
					}					
				}
				
				}
				else			//So this is a non instanciated list
			{
				esi_start_nilist=argptr+1;			//point to LIST_TAG
				//nalloc++;
				fputc2(216,fout);								//tag for a list of non instanciate values
				nilist_size_array_ptr=fout->fpos;	//remember the place to store the array size
				//allow memory for future storing of the size of the array , 3 bytes
				fputc2(0,fout);
				fputc2(0,fout);
				fputc2(0,fout);
				//fout->fpos++;
				push_value(dim_tios_list(argptr+1));		//esi_end_nilist affected in this function
			}
			break;
			case 0: //variable	VVV AAA RRR III AAA BBB LLL EEE
			ptr=GetStrnArg(argptr);
			
			if(*(argptr+1)!=0x2F && *(argptr+1)!=0x30)	//Ne pas chercher de constante si la dernière fonction était goto ou bien lbl
			{
			//se charge des constantes	->
			CONST_process(ptr);	//retourne dans nconst l'index de la constante si s'en est une, aussinon retourne -1
			if(nconst!=-1)	//alors c'est une constante prédéfinie
			{
				push_value(CONST_VAL[nconst]); break;
			}
			// <- fin de la section constantes
			}
			
az:
			if(strcmp(ptr,"basic")==0) { 	/*fputc (0, fout); 	fputs ("NPP", fout); fputc (0, fout);*//*fputc2(OTH_TAG,fout);*/ /*argptr-=2; */  /*goto tibasic;*/tibasic_sequence(0); continue;}  //on retourne alors au tibasic
			if(!is_special_var(ptr)) //si ce n'est pas une speciale var
			{
				if(!is_existing_var(ptr)) //si elle n'existe pas
				{
					add_var(ptr);
				}
			}
			else
			{
				exit2("\nThis var name is forbiden.");
			}
			push_varr(varnum);
			break;
			case 0xE3:		//correspond aux extra tibasic token
			argptr--;
			if(*argptr==INDIR_TAG)
			{
				fputc2(14,fout); //indirection
				var_process();
				if(CONST_process(ptr)!=-1) exit2("Syntax : #varname\nvarname shall not be a predifined constant.");
				push_varr(varnum);;
				/*fputc2(2,fout);	//tag des variables
				fputc2(varnum,fout);*/
			}
			switch(*argptr)
			{
			  case 0x2b:	//nombre binaire
			  case 0x2c:	//si nombre Hexadécimal a convertir
			  argptr-=1;
			  push_value(GetIntArg(argptr));
			  break;
			  case 0x14:	//si & de string str1&str2
			  //printf("& de string"); ngetchx();
			  fputc2(66,fout); 
			  argptr--;
			  break;
			  case CHAR_TAG:
			  fputc2(27,fout); 
			  argptr--;
//			  nalloc++;
			  break;
			  case ORD_TAG:
			  if(*(argptr-1)==STR_TAG)
			  {
			  	argptr--;		//now points to the STR_TAG
			  	temp_str=GetStrnArg(argptr);		//pass the string
			  	//fputc2(46,fout);
			  	push_value(*(temp_str));		//ascci code of the first character
			  	break;
			  	//printf("sTR : %s char : %c",temp_str,*(temp_str)); ngetchx();
			  }
			  fputc2(46,fout); 
			  argptr--;
//			  nalloc++;
			  break;
			  case EXPR_TAG:
			  fputc2(211,fout); 
			  argptr--;
			  break;
			  case STRING_TAG:
			  fputc2(212,fout);
			  argptr--;
			  break;
			  	
			}
			break;
			case 	0x91:			//div_tag
			fputc2(DIV_TAG,fout);
			argptr--;
			break;
			case 	0x8F:			//mul_tag
			fputc2(MUL_TAG,fout);
			argptr--;
			break;
			case 	0x8D:			//sub_tag
			fputc2(SUB_TAG,fout);
			argptr--;
			break;
			case 0x8b:		//add_tag
			fputc2(ADD_TAG,fout);
			argptr--;
			break;
			case 0xE7:  // ':'
			if(*(argptr-1)==0) {argptr-=2;}
			else argptr-=2;
			
			if(ifs_i>0 && ifs_just_triggered==0)	//si il y a au moins un ifs IF: actif et que ce n'est pas le ":" entre la condition et l'instruction a exécutée si cond est vrai
			{
				//temp_puc		temp_long		:variable temporaire
				temp_long=ftell(fout);	//saving position
				//printf("\nftell 0xE7 de fin:%ld",temp_long); ngetchx();
				while(ifs_i>0)	//perform all activated ifs
				{
					temp_long2=temp_long-ifs_pile[ifs_i-1];	//decalage, taille en mémoire
					if(temp_long2>=255) exit2("In if cond:instruction\nSize too long");
					
					fseek (fout, ifs_pile[ifs_i-1], SEEK_SET);	//goto the previous saved position for storing nbelem		

					temp_puc=fout->fpos;		//operate manually
					temp_puc2=&temp_long2;
			
					//printf("\nDans 0xE7\ndim=%ld",temp_long2); ngetchx();	

					*(temp_puc)=*(unsigned char*)(temp_puc2+3);
				
					ifs_i--;
				}
				fseek (fout, temp_long, SEEK_SET);	//return to the previous saved position
			
				//push_posint_value((long)((long)(fout->fpos)-(long)ifs_pile[ifs_i]),ifs_pile[ifs_i]);	//sauvegarde la taille de l'instruction (exécutée si la condition du IF cond: est valide)
			}
			if(ifs_just_triggered==1)
			{
				if(*argptr==VAR_B_TAG || *argptr==VAR_W_TAG || *argptr==VAR_L_TAG || *argptr==VAR_I_TAG || *argptr==VAR_X_TAG || *argptr==VAR_Y_TAG) exit2("In If: {b,w,l,i,x,y}\nunexpected");
			}
			ifs_just_triggered=0;
			//linen++;
			//else exit2("line must have no type");
			break;
			case PAUSE_ITAG:
			fputc2(84,fout);
			argptr--;
			break;
			case 0xE8: //enter
		//	printf("\n*(argptr-1)=%d,\n*(argptr-2)=%d,\n*(argptr-3)=%d",*(argptr-1),*(argptr-2),*(argptr-3)); ngetchx();
			if(*(argptr-1)==0) {argptr-=2;}
			else argptr-=2;
			
			if(ifs_i>0 && ifs_just_triggered==0)	//si il y a au moins un ifs IF: actif et que ce n'est pas le ":" entre la condition et l'instruction a exécutée si cond est vrai
			{
				//temp_puc		temp_long		:variable temporaire
				temp_long=ftell(fout);	//saving position
				//printf("\nftell 0xE7 de fin:%ld",temp_long); ngetchx();
				while(ifs_i>0)	//perform all activated ifs
				{
					temp_long2=temp_long-ifs_pile[ifs_i-1];	//decalage, taille en mémoire
					if(temp_long2>=255) exit2("In if cond:instruction\nSize too long");
					
					fseek (fout, ifs_pile[ifs_i-1], SEEK_SET);	//goto the previous saved position for storing nbelem		

					temp_puc=fout->fpos;		//operate manually
					temp_puc2=&temp_long2;
			
					//printf("\nDans 0xE7\ndim=%ld",temp_long2); ngetchx();	

					*(temp_puc)=*(unsigned char*)(temp_puc2+3);
				
					ifs_i--;
				}
				fseek (fout, temp_long, SEEK_SET);	//return to the previous saved position
			
				//push_posint_value((long)((long)(fout->fpos)-(long)ifs_pile[ifs_i]),ifs_pile[ifs_i]);	//sauvegarde la taille de l'instruction (exécutée si la condition du IF cond: est valide)
			}
			if(ifs_just_triggered==1)
			{
				if(*argptr==VAR_B_TAG || *argptr==VAR_W_TAG || *argptr==VAR_L_TAG || *argptr==VAR_I_TAG || *argptr==VAR_X_TAG || *argptr==VAR_Y_TAG) exit2("In If: {b,w,l,i,x,y}\nunexpected");
			}
			ifs_just_triggered=0;
						
			linen++;
			break;
			case 0x58: //je pense que ca correspond a la fin d'un argument 'X'
			fputc2(0x58,fout); argptr--;
			//printf("\nY a un 'X'"); ngetchx();
			break;
			case STORE_TAG:  //sto
			argptr--;
			fputc2(STORE_TAG,fout);
			if(*argptr==0)	//vérifie que la variable de destination n'est pas une constante prédéfinie
			{
				tmp_esi2=argptr;	//sauvegarde de la position
				CONST_process(GetStrnArg(argptr));
				argptr=tmp_esi2;	//restore la position
				if(nconst!=-1) exit2("Syntax:value->vdest\nvdest shall not be a predifined constant.");
			}
			break;
			case 0x30:		//label tag
			//if(numblock!=0) exit2("lbl forbiden in x:y");
			fputc2(0x4,fout); //tag pour signifier LABEL
//			printf("LBL :%d",*)
			argptr--;
			//fputc2(lblnum,fout);
			break;
			/*
			pileblock[numblock++]=iblock;	//on met dans la pile
			push_value(iblock++);
			
			pilefor
			*/
			case FOR_ITAG:		//FOR_ITAG 0h74
			//exit2("For:Endfor instructions\nare forbiden.\n Use While:Endwhile instead");
			if(remaining_element_count(argptr)==4) fputc2(185,fout);  //si le step est présent
			else exit2("Syntax : For var,begin,end,step");  //si pas de valeur de step spécifié par l'utilisateur
			pilefor[af++]=ifor;	//on met dans la pile ; ifor = nombre de for rencontrés dans le programme depuis le début du fichier ; af correspond au nombre de boucles non fermées
			IN_for_or_while_12[++pile_index_for_or_while]=1;		// for the next() and break() functions
			if(ifor>=NB_FOR-2) exit2("Too much FOR:ENDFOR");
			push_value(ifor++);
			//push_value(alif[aef]);
			argptr--;
			//printf("nb arg for %d",remaining_element_count(argptr)); ngetchx();
			break;						//ENDFOR_ITAG
			case ENDFOR_ITAG:		//=0h0E
			//exit2("For:Endfor instructions\nare forbiden.\n Use While:Endwhile instead");
			fputc2(186,fout);
			push_value(pilefor[--af]);
			pile_index_for_or_while--;		// for the next() function
			//push_value(--af);
			//argptr--;
			while(*argptr!=0xE8 && *argptr!=0xE7 && *argptr!=0xE9) argptr--;	//passe le déplacement de la boucle for tibasic
			break;
			case SUBSCRIPT_TAG:		//=0d213  ; List and matrix element(Tibasic). Syntax : var[a,b,...] ou var[a][b]...
			argptr--;
			fputc2(SUBSCRIPT_TAG,fout); 
			tmp_esi=argptr;
			GetStrnArg(argptr);	//skip the var name
			nbelemm=0; //temporary variable
			while (*argptr!=END_TAG)	//search for the dimension of the list/matrix (stored in nbelemm). Tibasic fixed to 2 the maximum dimension
			{
				GetIntArg(argptr); nbelemm++;
			}
			/*if(nbelemm>=2) {exit2("\nWriting var_name[a][b] or\nvar_name[a,b] is forbiden.\nOnly admitted : varname[a]\nMatrix writting forbiden.\nList only admitted.");}
			Cette détection d'erreur à été supprimée car semble ne pas fonctionner certaine fois. Il semblerait que des liste [] soit parfois considérées comme des listes [][] d'ou une impossibilité de compilation.
			*/
			argptr=tmp_esi;
			//printf("Dimension = %ld",nbelemm); ngetchx();
			//exit2("[] not legal, use bv wv or lv"); 
			break;
			case RAND_TAG:
			fputc2(101,fout); argptr--;
			break;
			case WHEN_TAG:
			fputc2(23,fout); argptr--;
			break;
			case FALSE_TAG:
			push_value(0); argptr--;
			break;
			case TRUE_TAG:
			push_value(1); argptr--;
			break;
			case NOT_TAG:
			fputc2(120,fout); argptr--;
			break;
			case OR_TAG:									//orl
			fputc2(131,fout); argptr--;
			break;
			case AND_TAG:										//andl
			fputc2(132,fout); argptr--;
			break;
			case LT_TAG:		//inf
			fputc2(0x85,fout); argptr--;
			break;
			case LE_TAG:	//inf equ
			fputc2(0x86,fout); argptr--;
			break;
			case EQ_TAG:	//eq
			if(*(argptr-1)==STR_TAG)	//Special function for string comparaison, is equivalent to strcmp but simplier to use ; return 1 if equal
			{
				fputc2(146,fout);
			}
			else fputc2(0x87,fout);
			argptr--;
			break;
			case GE_TAG:		//sup eq
			fputc2(0x88,fout); argptr--;
			break;
			case GT_TAG:		//sup
			fputc2(0x89,fout); argptr--;
			break;
			case NE_TAG:		// not equ !=
			fputc2(0x8A,fout); argptr--;
			break;
			case XOR_TAG:
			fputc2(0x82,fout); argptr--;
			break;
			case 0x2D: //STR_TAG
			fputc2(STR_TAG,fout);
			ptr=GetStrnArg(argptr);
			push_value(strlen(ptr));
			fputs(ptr,fout);
			fputc2(0,fout);
			break;
			case END_TAG:
			//if(is_ok==1) {fputc2(END_TAG,fout); is_ok=0;}
			//fputc2(END_TAG,fout);
			if(argptr==esi_end_nilist)
			{
				push_posint_value((long)(fout->fpos)-(long)(nilist_size_array_ptr)+1-6,nilist_size_array_ptr);
			}
			argptr--; break;
			case POSINT_TAG:
			push_value(GetIntArg(argptr));
			break;
			case MINUS_TAG:
			argptr--;
			fputc2(MINUS_TAG,fout);
			break;
			case NEGINT_TAG:
			push_value(GetIntArg(argptr));
			break;
			case USERFUNC_TAG: //fonction a nous
			//les fonctions à un seul caractère sont écrit de la manière suivante dans un PRGM : Var_X_TAG ; Userfunc_tag. Le nom de la fonction n'est pas sauvegardée dans une string
			if(*(argptr-1)!=0)	//si c'est une fonction à un caractère
			{
				argptr-=2;
				if(*(argptr+1)==VAR_I_TAG) 
				{
					fputc2(196,fout);
					pileblock[numblock++]=iblock;
					push_value(iblock++);
					if(iblock>NB_BLOCK_MAX) exit2("Too much i:y or x:y blocks.");
					foncnum2=196;	//for error msg
					//linen++;
					if(remaining_element_count(argptr)<fonc_nbarg[196]) exit2("Syntax expected : i(cond):y");
				}
				if(*(argptr+1)==VAR_W_TAG) 
				{
					if(remaining_element_count(argptr)<fonc_nbarg[198]) exit2("Syntax expected : w(var_dest):y");
					//linen++;
					foncnum2=198;	//for error msg
					ilist_process(2);
				}
				if(*(argptr+1)==VAR_B_TAG) 
				{
					if(remaining_element_count(argptr)<fonc_nbarg[197]) exit2("Syntax expected : b(var_dest):y");
					//linen++;
					foncnum2=197;	//for error msg
					ilist_process(1);
				}
				if(*(argptr+1)==VAR_L_TAG) 
				{
					if(remaining_element_count(argptr)<fonc_nbarg[199]) exit2("Syntax expected : l(var_dest):y");
					//linen++;
					foncnum2=199;	//for error msg
					ilist_process(4);
				}
				break;
			}
			
			if(!(get_foncnum())) 	//It is a Newprog function or not ?
			{ 
				//So this a user defined function
					//current_func_str=nom de la fonction

			//Ce charge de mémoriser le nom de la fonction (par l'intermédaire d'un nom de variable)
				if(!is_special_var(current_func_str)) //si ce n'est pas une speciale var
			{
				if(!is_existing_var(current_func_str)) 
				{		
					add_var(current_func_str);		//si la fonction n'existe pas encore, alors réserve un nom (par l'intermédiaire d'une variable) et retourne le numéro de la fonction dans varnum
				}
				else	//si le nom a déjà été créé, vérifie si une fonction du même nom n'a pas déjà été définie. Si pas défini en fonction, le numéro de la fonction déjà définie est retourné dans varnum
				{
					//if(defined_as_function_AND_nb_arg[varnum]!=0) exit2("Redefinition of a function");
					
				}
				//defined_as_function_AND_nb_arg[varnum]=remaining_element_count(argptr)+1;		//The number +1 for 	
			}
			else
			{
				foncnum2=153; ptr=current_func_str;	//for error displaying purpose (in case of)
				exit2("\nThis function name is forbiden.");
			}
				foncnum2=153; ptr=current_func_str;	//for error displaying purpose (in case of)
				if(defined_as_function_AND_nb_arg[varnum]==0) exit2("Unknown function OR\nUser function not defined above");
				fputc2(153,fout);			//fc() TAG
				//if(CONST_process(ptr)!=-1) exit2("User defined function shall not be a predifined constant."); /*fputc2(varnum,fout);*/ 
				//push_varnum(varnum);		
				fputc2(2,fout);	//var tag
				fputc2(varnum,fout);
				//push_value(varnum);		//number of the function
				if(current_user_func_definition==varnum) exit2("Circular/Recursivity with user function forbiden.");
				//push_value(0); //temporaire. Pour compatibiliter avec l'ancienne écriture de fonction
				//printf("remaining = %d in def=%d",remaining_element_count(argptr),defined_as_function_AND_nb_arg[varnum]-1); ngetchx();
				if(remaining_element_count(argptr)!=(defined_as_function_AND_nb_arg[varnum]-1)) exit2("Wrong number of arg in user defined function");
				goto relaunch2;
			}
			
			
			//if(foncnum2==84) {fputc2(84,fout);	/*lbl_process()*/; goto relaunch; } //si c'est un "fonc()" alors met le nom de la fonc comme un label
			//if(foncnum2==82) {fputc2(82,fout); /*goto_process()*/; goto relaunch; } //si c'est un "call()" alors met le nom de la fonc comme un goto
			//remaining_element_count(argptr)

/*
			if(foncnum2==153)		//traitement spécial pour les fonctions à nombres d'argument variable sans utilisation de nilist
			{
				if(remaining_element_count(argptr)<fonc_nbarg[foncnum2]) exit2("Syntax :\nfc(newprog_function,arg1,arg2,...)");
				push_value(remaining_element_count(argptr)-1);	//inscrit le nombre d'argument de la fonction newprog à lancée
			}
			else
			{
					if(remaining_element_count(argptr)!=fonc_nbarg[foncnum2])
				{
					if(nb_warning==0) clrscr();
					if(nb_warning!=0) printf("\n");
					nb_warning++;
					printf("WARNING %d : Argument count line : %d\nFunction %s() expects %d arguments.",nb_warning,linen,fonc[foncnum2],fonc_nbarg[foncnum2]);// ngetchx();
				}
			}
*/			
			if(foncnum2!=150 && foncnum2!=151 && foncnum2!=153 && foncnum2!=194 && foncnum2!=195)		//si ce n'est pas def(), enddef() et fc() , archi() et unarchi() qui sont des fonctions à arguments variables.
			{
				if(remaining_element_count(argptr)!=fonc_nbarg[foncnum2])		//verify the number of arguments
				{
					if(nb_warning==0) clrscr();
					if(nb_warning!=0) printf("\n");
					nb_warning++;
					printf("WARNING %d : Argument count line : %d\nFunction %s() expects %d arguments.",nb_warning,linen,fonc[foncnum2],fonc_nbarg[foncnum2]);// ngetchx();
				}
			}
			
			
			if((foncnum2==240 || foncnum2==241) && i_userfunc!=0) exit2("Debugon()/Debugoff() shall not be called in a function");
			if(foncnum2==10) nalloc2--;
			if(foncnum2==155 && i_userfunc==0) exit2("rtn() shall be used\nin def()::enddef() block"); 
			if(foncnum2==11) {/*fputc2(11,fout);*/ if(*argptr!=0) exit2("Basich():handle sto in var only"); var_process(); if(CONST_process(ptr)!=-1) exit2("Syntax : basich(varname)\nvarname shall not be a predifined constant."); /*fputc2(varnum,fout);*/ /*push_varnum(varnum);*/ argptr--;/*skip the 0xE5*/ nalloc2++; /*goto tibasic;*/tibasic_sequence(1); continue;} //si c'est endh()
			if(foncnum==102/*gsprt*/ || foncnum2==251/*malloc*/ /*|| foncnum2==27 chars*/|| foncnum2==234/*seqb*/ || foncnum2==244/*seqw*/ || foncnum2==254/*seql*/ || foncnum2==156/*group*/ || foncnum2==110/*fopen*/  || foncnum2==114 /*files*/ || foncnum2==115/*reps*/ || foncnum2==173/*newstr*/ || foncnum2==102/*gsprt*/) nalloc++;
			if(foncnum2==252 /*free*/) nalloc--;
			if(foncnum2==206 || foncnum2==207) exit2("Block syntax :\nx:instructions:y");

			//fputc2(USERFUNC_TAG,fout);
			//printf("\nFONCNUM=%d",foncnum2);
			
			fputc2(foncnum2,fout);		//Enregistrement du numéro de la fonction ici
			
			if(foncnum2==96)	//osvar(tibasic_var) without ""
			{
				//argptr--;
				if(*argptr!=0 && *argptr!=STR_TAG) exit2("Syntax:osvar(var) or\nosvar(""varstr"")");
				fputc2(STR_TAG,fout);
				ptr=GetStrnArg(argptr);
				push_value(strlen(ptr));
				fputs(ptr,fout);	//cette fonction ne copie pas le dernier caractère nul
				fputc2(0,fout);
			}
			
			if(foncnum2==194)	//archi()
			{
				temp=remaining_element_count(argptr);	//plusieurs fichiers pourront être compressés en une instruction
				push_value(temp);

			}
			if(foncnum2==195)	//unarchi()
			{
				temp=remaining_element_count(argptr);	//plusieurs fichiers pourront être décompressés en une instruction
				push_value(temp);
			}
			if(foncnum2==150)		//def()	;	user function definition
			{
				ndeffonc++;
				if(i_userfunc!=0) exit2("A function must not be defined in an other one.");
				i_userfunc++;
				
				if(*argptr==USERFUNC_TAG)
				{
					var_process();		//Sto the name of the function (through a variable name) (if not yet defined)	
					temp=remaining_element_count(argptr)+1;		//temp=nombre d'arguments passer à la fonction + 1 (car comprend le nom de la fonction)
				}
				else
				{
					temp=remaining_element_count(argptr);		//temp=nombre d'arguments passer à la fonction + 1 (car comprend le nom de la fonction)
					if(*argptr!=0 && temp<1) exit2("Syntax:def(func_name,arg1_name,\narg2_name,...)");
					var_process();		//Sto the name of the function (through a variable name) (if not yet defined)	
				}
				if(temp>254) exit2("Too much arg in def()");
				//var_process();		//Sto the name of the function (through a variable name) (if not yet defined)
				if(defined_as_function_AND_nb_arg[varnum]!=0) exit2("User function already defined");
				defined_as_function_AND_nb_arg[varnum]=temp;
				//push_value(varnum);
				fputc2(2,fout);	//var tag
				fputc2(varnum,fout);
				//push_varr(varnum);
				current_user_func_definition=varnum;
				push_value(temp-1);		//nombre d'arguments réel
				
				//Vérifie que les prochains arguments sont bien des noms de variables
				for(i=0;i<temp-1;i++)
				{
					if(*argptr==0) ptr=GetStrnArg(argptr);
					else exit2("Syntax:def(function_name(var_name1,...)");
					CONST_process(ptr);	//retourne dans nconst l'index de la constante si s'en est une, aussinon retourne -1
					if(!is_special_var(ptr) && nconst==-1) //si ce n'est pas une speciale var ou n'est pas une constante
					{
						if(!is_existing_var(ptr)) //si elle n'existe pas
						{
							add_var(ptr);
						}
					}
					else
					{
						exit2("Error : invalid local variable name in def()");
					}
					//push_varr(varnum);	//throw a warning so has been replaced by the code below
					fputc2(2,fout);	//var tag
					fputc2(varnum,fout);
				}
				
			}
			if(foncnum2==151)		//enddef()	;	user function definition (closening)
			{
				i_userfunc--;
				temp=remaining_element_count(argptr);		//temp=nombre d'arguments passer à la fonction + 1 (car comprend le nom de la fonction)
				if(*argptr!=0 && *argptr!=USERFUNC_TAG && temp!=1) exit2("Syntax:enddef(func_name)");
				var_process();		//Sto the name of the function (through a variable name) (if not yet defined)
				if(defined_as_function_AND_nb_arg[varnum]==0) exit2("No such function name defined");
				//push_value(varnum);
				fputc2(2,fout);	//var tag
				fputc2(varnum,fout);
				current_user_func_definition=-1;
				//goto relaunch2;
			}
			
			//if(foncnum2==196) {push_value(numblock++);}	// pour la fonction i, étant un if simple à écrire, rajoute un identifiant de type x,y block. La syntaxe sera donc i(cond):instructions:y
			
			if(foncnum2==232) //settype
			{
				if(*(argptr)==0)		//vérifie que le premier argument est bien une variable
				{
					var_process();
					if(CONST_process(ptr)!=-1) exit2("Syntax : settype(var,type)\nvar shall not be a predefined constant.");
					else
					{
						//printf("ici ici ici"); ngetchx();
						//fputc2(2,fout); fputc2(varnum,fout);	
						push_varr(varnum);;
					}
					
				}
				else exit2("Syntax : settype(var,type)");
			}
			if(foncnum2==27) { fputc2(0,fout); fputc2(0,fout); }	//La string est directement enregistrée dans le fichier
			if(foncnum2==67 || foncnum2==68) //for the next() and break() functions
			{ 
				//printf("pile_index_for_or_while = %d",pile_index_for_or_while); ngetchx();
				if(pile_index_for_or_while==0) {exit2("Break() or next() must be used in For or While loops");}
				if(IN_for_or_while_12[pile_index_for_or_while]!=1 && IN_for_or_while_12[pile_index_for_or_while]!=2) exit2("Internal error in next()");
				push_value(IN_for_or_while_12[pile_index_for_or_while]);
				if(IN_for_or_while_12[pile_index_for_or_while]==1)		//it's a for loop
				{
					push_value(pilefor[af-1]);		//put the number of the open loop
				}
				else	//it's a else loop
				{
					//if(af<=0) exit2("Break() must be used in For or While loops");
					push_value(alw[aew]);		//put the number of the open while
				}
				push_value(pile_index_for_or_while);
			} 
			if(foncnum2==0x3) {var_process(); if(CONST_process(ptr)!=-1) exit2("Syntax : adress(varname)\nvarname shall not be a predifined constant."); push_varnum(varnum);/*fputc2(varnum,fout);*/}
			break;
			SkipArg(argptr);
			printf("\nCase not expected *argptr=%x",*argptr);
		}// fin switch
	  
	}
		//ngetchx();
		//del_bkm();
		exit2("\nUnknown command.");
		//exit2("Error unknown.");
}

