// 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 // 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;ipt; 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;foncnum2fpos; //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;ifpos)%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;ii0) 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>-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)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