// COMPILER.C Copyright (c) TrSek alias Zdeno Sekerak // Program je pokusom o vlastny compiler s podobnou syntaxou // ako ma Pascal. // // Datum:22.04.96 http://www.trsek.com #define maxx 78 #define maxz 21 #include "klavesy.h" #include #include #include #include #include #include #include #include #define maxx 78 #define maxy 21 #define maxs 128 #define maxznak 128 #define maxsyn 14 #define maxerr 30 #define maxkl 17 #define maxpocs 256 #include "struct.h" char klslov[maxkl+1][maxsyn] = { {"DECL"} , {"INTEGER"} , {"START"} , {"WHILE"} , {"ENDWHILE"} , {"INTEGERREAD"} , {"INTEGERWRITE"} , {"STOP"} , {" "} , {";"} , {":="} , {"("} , {")"} , {"<"} , {">"} , {"+"} , {":"} }; void okno (int, int, int, int, int, int ); /* Definuj okno posledne dve su farby */ /* podklad, pismo */ void editor ( void ); /* Uvodna obrazovka */ void tprintf( char text[]); /* Specialny prvy riadok */ void farba(int x,int y); /* nastavi naraz farbu pisma aj podkladu */ void posunx ( int ); /* Posun text v smere osi x */ void posuny ( int ); /* Posun text v smere osi y */ void deletuj ( int, int ); /* Zmaz znak z poziciou */ void novyr ( int ); /* Novy riadok */ int posledny ( int ); /* Posledny znak v riadku */ void strana ( int, int ); /* Vykresli stranu */ void help ( void ); /* No comment */ void save ( char meno[] ); /* Uloz subor pod menom */ int vypis_sub( char mena[][13], int dlzok ); /* Vypis suborov do okna */ int load ( void ); /* Najdi subor */ int from_disk( char subor[]); /* Precitaj subor z disku */ void run ( void ); /* Spusti program */ void outwin ( void ); /* Pozri OUTPUT obrazovku */ void compile ( void ); /* Skompiluj program */ void option ( void ); /* Opsns */ def_riadok *zaradr( def_riadok *pointer, char text[] ); /* Zaradi text do pola */ def_riadok *vyhodr( def_riadok *pointer ); /* Vyhodi text z pola */ int otazka ( char text[], char pr[], char dr[], char tr[] ); /* Otazka , pr-prva volba, dr-druha volba */ int kluc_slova ( def_syntax * (* syntax) ); /* Doplni klucove slova */ int patri ( char s[] , int x , int *v_rade , void *prvys , int caka ); /* Porovnava dve retazce */ int podmienka ( char s[] , int x , def_syntax *prvys); int aritmetika ( char s[] , int x , void *prvys); /* Je to aritmetika ??? Nie !!!*/ int premenne (int *x, char s[], def_syntax *syntax); /* doplni premenne do syntax */ int comp,pocr; /* pocet riadkov suboru */ char subor[maxs]; /* Meno suboru */ void *prvy,*teraz; /* Pameta pointer na prvy riadok */ // main tu to vsetko zacne void main(int arg, char *args[]) { int key,i; int x=1,y=1,xr=1,yr=1; unsigned insert=0,ulozene=0; editor(); prvy=NULL; pocr=0; comp=0; if (arg>0) { strcpy(subor,args[1]); from_disk(subor); strana(1,1); } gotoxy(x,y); do { key=getch(); if (key==BACKSPACE) {} // nereaguje if (key==0) { key=getch(); switch (key) { case LEFT: x=x-1; if (x<1) { xr--;x=1; if (xr<1) xr=1; else strana(xr,yr); } break; case RIGHT: x=x+1; if (x>maxx) { xr++;x=maxx-3; if ((xr+x)>maxznak) xr=maxznak-x; strana(xr,yr); } break; case UP: y=y-1; if (y<1) { y=1; yr--; if (yr<1) yr=1; strana(xr,yr); } break; case DOWN: y=y+1; if (y>maxy) { y=maxy; yr=yr+1; if ((yr+y)>pocr) { yr=pocr-maxy-y-1; if (yr<1) yr=1; } strana(xr,yr); } break; case ENTER: x=1;y=y+1;novyr(y);posunx(0); break; case DEL: deletuj(x,y); break; case INSERT:insert=!insert; break; case HOME: x=1; break; case END: x=posledny(yr+y-1); xr=1; if (x>maxx) { xr=x-maxx; x=maxx-3; strana(xr,yr); } break; case PGDN: yr=yr+maxy; if ((yr+y)>pocr) { for (i=pocr;i<=(yr+y);i++) novyr(i); yr=pocr-20; } strana(xr,yr); break; case PGUP: yr=yr-maxy; if (yr<1) yr=1; strana(xr,yr); break; case F1: help(); break; case F2: save(subor); break; case F3: load(); window(2,3,79,23); clrscr(); strana(1,1); break; case F4: save(""); break; case F5: if (!comp) compile(); run(); break; case F6: outwin(); break; case F7: break; case F8: option(); break; case F9: compile(); break; case F10: if (!ulozene) { if (otazka("Ulozit prave editovany subor ?"," ^Ano "," ^Nie ","")==1) save(subor); else key=0; } if (key==0) if (otazka(" Chces skoncit ? "," ^Ano "," ^Nie ","")==1) key=F10; break; default: break; } gotoxy(x,y); } } while (key!=F10); clrscr(); } // zobrazi okno v ktorom sa budeme pohybovat void okno (int x1, int y1, int x2, int y2, int col1, int col2 ) { int x,y; window(x1,y1,x1+x2,y1+y2); farba(col2,col1); clrscr(); gotoxy(1,y2);cprintf(""); gotoxy(x2+1,y2);cprintf(""); gotoxy(1,1);insline(); gotoxy(1,1);cprintf(""); gotoxy(x2+1,1);cprintf(""); for (x=2;x<=x2;x++) { gotoxy(x,1);cprintf(""); gotoxy(x,y2+1);cprintf(""); } for (y=2;y<=y2;y++) { gotoxy(1,y);cprintf(""); gotoxy(x2+1,y);cprintf(""); } window(x1+1,y1+1,x1+x2-1,y1+y2-1); } // nakresli prostredie editora void editor( void ) { okno(1,2,79,22,BLUE,YELLOW); window(1,1,80,25); gotoxy(1,1); textbackground(LIGHTGRAY); tprintf("^F^1Help ^F^2Save ^F^3LOAD ^F^4SAVE_AS ^F^5RUN ^F^6OUTWIN ^F^7STEP ^F^8OPTION ^F^9COMPILE ^F^1^0EXIT"); window(2,3,79,24); } // vypise text s tym ze pismena zacinajuce ^ vyfarby inou farbou void tprintf( char text[]) { int i; textcolor(DARKGRAY); for (i=0; iyp) y=yp; if (y>(dlzok-1)) { y=dlzok-1; yr=yr+1; if ((yr+y)>yp) yr=yp-y; else { gotoxy(1,1); delline(); } } break; } break; case ENTER: if ((mena[y+yr][0]=='.') || ((mena[y+yr][0]>='A') && (mena[y+yr][0]<='Z'))) { chdir(mena[y+yr]); clrscr(); yp=vypis_sub(mena,dlzok); y=1; yr=0; key=32; } break; } farba(YELLOW,BLUE); gotoxy(3,y+1); cprintf("%s",mena[y+yr]); } while ((key!=ESC) && (key!=ENTER)); if (key==ENTER) strcpy(subor,mena[y+yr]); if (key==ESC) return(0); // precitaj subor return( from_disk(subor)); } // precita z disku int from_disk( char subor[] ) { FILE *fopen(),*f; int y,err=0; char text[maxznak]; riadok=prvy; prvy=NULL; while ( riadok!=NULL) riadok=vyhodr(riadok); pocr=0; f=fopen(subor,"r"); do { pocr++; y=0; text[y]=' '; do { err=fscanf(f,"%c",&text[++y]); } while ((text[y]!='\n') && (err==1) && (y=strlen(s)) { *v_rade=-1; return(x1); } if (caka==-1) while ( (i*x+i) ) { while (s[*x+i]==' ') i++; *x=*x+i; i=0; while ( (s[*x+i]>='A') && (s[*x+i]<='z') ) { prem[i]=s[*x+i];i++; } prem[i]='\0'; syntax=zarads(syntax,prem); while ( (s[*x+i]==',') || (s[*x+i]==' ') ) i++; } *x=*x+i; if (s[*x]==';') return(0); else return(1); } int podmienka ( char s[] , int x , def_syntax *prvys ) { def_syntax *syntax; syntax=prvys; x=x;s=s; return(0); } void compile ( void ) { def_riadok *riadok; def_syntax *posled; def_error *error; void *prvys; int poc,x,y,caka,i,v_rade,oldi; char chyba[maxerr]; syntax=NULL; error =NULL; riadok=prvy; for (poc=0; pocx) x=i; else { if (caka==-1) error=zarade(error,"Nepoznam",y); else error=zarade(error,klslov[caka],y); v_rade=caka; } if ((caka==-1) && (v_rade>maxkl)) caka=10; if (v_rade==9) caka=-1; if (v_rade==10) if ((i=aritmetika( (*riadok).znaky,x,posled)) >x) { x=i;caka=9; } else error=zarade(error,klslov[caka],y); if (v_rade==11) if ((i=podmienka( (*riadok).znaky,x,posled)) >x) { x=i;caka=12; } else error=zarade(error,klslov[caka],y); if ((v_rade==6) || (v_rade==7)) if ((i=patri( (*riadok).znaky,x,&v_rade,posled,caka))>x) { x=i;caka=9; } else error=zarade(error,klslov[caka],y); if (v_rade==3) caka=11; if (v_rade==2) caka=-1; if (v_rade==1) { i=premenne( &x,(*riadok).znaky,posled); if (i!=0) error=zarade(error,"Zle definovanie premennych.",y); i=oldi+1; caka=2; } if (v_rade==0) caka=1; if (x>=strlen( (*riadok).znaky)-1 ) { riadok=(*riadok).zani;oldi=-1; } if (i==oldi) y=pocr; oldi=i; } if (v_rade!=7) error=zarade(error,klslov[7],y); if (error==NULL) comp=1; } // nastavenia void option ( void ) { } // polozi otazku a caka odpoved Ano/Nie int otazka ( char text[], char pr[], char dr[], char tr[]) { int vo=0,odx,i,x; char pdt[3][10]; int cpdt[3]; char ch; strcpy(pdt[0],pr); strcpy(pdt[1],dr); strcpy(pdt[2],tr); if ((strlen(text)/2)!=(1.00*strlen(text)/2)) text=strcat(text," "); odx=(80-strlen(text))/2-4; okno(odx,10,strlen(text)+8,6,LIGHTGRAY,DARKGRAY); gotoxy(5,2);cprintf("%s",text); cpdt[0]=(strlen(text)-odx-strlen(pdt[0])+strlen(pdt[1])+strlen(pdt[2])+8)/2+4; cpdt[1]=cpdt[0]+strlen(pdt[0])+2; cpdt[2]=cpdt[0]+strlen(pdt[0])+strlen(pdt[1])+4; for (i=0;i<=2;i++) { gotoxy(cpdt[i],4); tprintf(pdt[i]); } textbackground(GREEN); gotoxy(cpdt[0],4);tprintf(pdt[0]); odx=0; vo=-1; do { ch=getch(); textbackground(LIGHTGRAY); gotoxy(cpdt[odx],4);tprintf(pdt[odx]); switch (ch) { case 0: ch=getch(); switch (ch) { case LEFT : odx=odx-1; if (odx<0) odx=2;break; case RIGHT: odx=odx+1; if (odx>2) odx=0;break; } if ((odx==2) && (strcmp(pdt[2],"")==0)) odx=0; if ((odx==1) && (strcmp(pdt[1],"")==0)) odx=0; break; case ESC: vo=0; break; case ENTER: vo=odx+1; break; default : for (i=0;i<=2;i++) for (x=1;x<=strlen(pdt[i]);x++) if ((pdt[i-1][x]=='^') && (pdt[i][x]==ch)) vo=i; break; } textbackground(GREEN); gotoxy(cpdt[odx],4);tprintf(pdt[odx]); } while (vo==-1); return(vo); }