Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #define GRIZRAZ "Izraz"
- #define DUGAKONST "String"
- #define OCEKIVANO "Ocekivano "
- #define IMEFUN "Ime funkcije"
- #define DEFFUN "Def. funkcije"
- #define OCEKDOD "Dodjeljivanje"
- #define PSL "Ime varijable"
- #define FALSE 0
- #define TRUE 1
- FILE *ulaz, *izlaz;
- long pozicija, trenlabela, brojaclinija;
- char znak;
- char linija[256], aktivnafunkcija[256];
- int DodjelaKarakteru;
- void IzrazDodjeljivanja(void);
- void Blok(void);
- void NovaLabela(char *ImeLabele) {
- trenlabela++;
- sprintf(ImeLabele, "%d", trenlabela);
- }
- void Greska(char *poruka) {
- puts(poruka);
- fprintf(stderr,"%d:%s\n",
- brojaclinija, linija);
- if (ulaz != NULL)
- fclose(ulaz);
- ulaz = NULL;
- if (izlaz != NULL)
- fclose(izlaz);
- izlaz = NULL;
- exit(0);
- }
- void Emit(char *st) {
- fprintf(izlaz, "%s\r\n", st);
- }
- void Novi(void) {
- char *TEMP;
- char STR1[256];
- do {
- pozicija++;
- if (pozicija>strlen(linija))
- {
- brojaclinija++;
- if (!feof(ulaz)) {
- fgets(linija,256, ulaz);
- TEMP=
- strchr(linija,'\n');
- if (TEMP != NULL)
- *TEMP = 0;
- }
- sprintf(STR1,";%s",linija);
- Emit(STR1);
- pozicija = 1;
- }
- if (*linija != '\0')
- znak = linija[pozicija-1];
- else
- znak = ' ';
- if(znak == '>'){
- if(linija[pozicija] == '=')
- {
- pozicija++;
- znak = -1;
- }
- }
- if (znak == '`')
- pozicija = strlen(linija);
- } while (!((znak > ' ' && znak != '`') | feof(ulaz) | (znak == -1)));
- }
- void MoraBiti(char z) {
- char STR1[12];
- if (znak != z) {
- sprintf(STR1, "%s%c",
- OCEKIVANO, z);
- Greska(STR1);
- }
- Novi();
- }
- long UzmiKonstantu(void) {
- long rezult = 0;
- while (isdigit(znak)) {
- rezult=rezult*10+znak-'0';
- Novi();
- }
- return rezult;
- }
- void UzmiIme(char *Ime) {
- *Ime = '\0';
- while (isalpha(znak)) {
- sprintf(Ime+strlen(Ime),"%c",
- znak);
- Novi();
- }
- }
- int Slijedi(char * ocekivano) {
- char STR1[256];
- int i,n,len1,len2;
- len1=strlen(linija);
- len2=strlen(ocekivano);
- i=pozicija-1;
- n=0;
- while(linija[i]==ocekivano[n])
- {
- i++; n++;
- }
- if (ocekivano[n]==0) {
- pozicija+=strlen(ocekivano)-1;
- return TRUE;
- }
- else
- return FALSE;
- }
- void EmitGetVal(int ChrIzraz) {
- if (ChrIzraz) {
- Emit(" MOV AL,[EBX]");
- Emit(" AND EAX,255");
- } else
- Emit(" MOV EAX,[EBX]");
- }
- void PokazivacINiz(int ChrIzraz) {
- Novi();
- Emit(" PUSH EAX");
- IzrazDodjeljivanja();
- Emit(" POP EBX");
- if (!ChrIzraz)
- Emit(" SAL EAX,2");
- Emit(" ADD EBX,EAX");
- EmitGetVal(ChrIzraz);
- MoraBiti(']');
- }
- void StringKonstanta(void) {
- char strtekst[256], lab[256];
- char STR1[256], STR2[256];
- NovaLabela(strtekst);
- Emit("section .data");
- sprintf(lab, "L%s", strtekst);
- pozicija++;
- do {
- if (pozicija>strlen(linija))
- Greska(DUGAKONST);
- znak = linija[pozicija-1];
- pozicija++;
- if (znak != '"') {
- sprintf(STR2,
- "%s DB %d", lab, znak);
- Emit(STR2);
- *lab = '\0';
- }
- } while (znak != '"');
- pozicija--;
- Novi();
- sprintf(STR2, "%s DB 0", lab);
- Emit(STR2);
- Emit("section .text");
- sprintf(STR1," LEA EAX,[L%s]",
- strtekst);
- Emit(STR1);
- }
- void PozivFunkcije(void) {
- long lokalnih = 0;
- char ImeFunkcije[256], staddr[256];
- char STR1[256], STR2[256];
- UzmiIme(ImeFunkcije);
- if (znak==' ' || znak == '`')
- Novi();
- MoraBiti('(');
- NovaLabela(staddr);
- sprintf(STR1, " SUB ESP,L%s",
- staddr);
- Emit(STR1);
- while (znak != ')') {
- IzrazDodjeljivanja();
- sprintf(STR2,
- " MOV [ESP+%d],EAX",
- lokalnih);
- Emit(STR2);
- lokalnih += 4;
- if (znak != ')')
- MoraBiti(',');
- }
- MoraBiti(')');
- sprintf(STR2, "L%s EQU %d",
- staddr, lokalnih);
- Emit(STR2);
- sprintf(STR1, "_%s@%d",
- ImeFunkcije,lokalnih);
- strcpy(ImeFunkcije,STR1);
- sprintf(STR2, " CALL %s",
- ImeFunkcije);
- Emit(STR2);
- }
- void Varijabla(void) {
- char ImeVarijable[256], znak1;
- int chrIzraz;
- char STR1[256], STR2[256];
- chrIzraz = FALSE;
- znak1 = znak;
- UzmiIme(ImeVarijable);
- switch (znak1) {
- case 'l':
- case 'p':
- sprintf(STR1,
- " LEA EBX,[EBP+%s%s]",
- aktivnafunkcija,
- ImeVarijable);
- Emit(STR1);
- break;
- default:
- sprintf(STR2," LEA EBX,[%s]"
- , ImeVarijable);
- Emit(STR2);
- chrIzraz = (znak1 == 'c');
- break;
- }
- if (znak != '[') {
- EmitGetVal(FALSE);
- return;
- }
- Emit(" MOV EAX,[EBX]");
- PokazivacINiz(chrIzraz);
- if (znak == ':' && chrIzraz)
- DodjelaKarakteru = TRUE;
- }
- void Faktor(void) {
- long rezultat;
- char STR1[256];
- switch (znak) {
- case '-':
- Novi();
- Faktor();
- Emit(" NEG EAX");
- break;
- case '~':
- Novi();
- Faktor();
- Emit(" NOT EAX");
- break;
- case '&':
- Novi();
- Faktor();
- Emit(" MOV EAX,EBX");
- break;
- case '*':
- Novi();
- Faktor();
- Emit(" MOV EBX,EAX");
- Emit(" MOV EAX,[EBX]");
- break;
- case '!':
- Novi();
- Faktor();
- Emit(" CMP EAX,0");
- Emit(" SETE AL");
- Emit(" AND EAX,0FFh");
- break;
- case '"':
- StringKonstanta();
- break;
- case '(':
- Novi();
- IzrazDodjeljivanja();
- MoraBiti(')');
- break;
- default:
- if (isdigit(znak)) {
- rezultat =UzmiKonstantu();
- sprintf(STR1,
- " MOV EAX,%d",rezultat);
- Emit(STR1);
- } else if (isupper(znak))
- PozivFunkcije();
- else if (islower(znak))
- Varijabla();
- else
- Greska(GRIZRAZ);
- break;
- }
- }
- void Clan(void) {
- char z;
- Faktor();
- while (znak == '%' ||
- znak == '/' ||
- znak == '*') {
- z = znak;
- Emit(" PUSH EAX");
- Novi();
- Faktor();
- switch (z) {
- case '*':
- Emit(" POP EBX");
- Emit(" IMUL EBX");
- break;
- case '/':
- case '%':
- Emit(" MOV EBX,EAX");
- Emit(" POP EAX");
- Emit(" CDQ");
- Emit(" IDIV EBX");
- if (z == '%')
- Emit(" MOV EAX,EDX");
- break;
- }
- }
- }
- void Izraz(void) {
- char z;
- Clan();
- while (znak == '^' || znak ==
- '|' || znak == '&' ||
- znak == '-' ||
- znak == '+') {
- Emit(" PUSH EAX");
- z = znak;
- Novi();
- Clan();
- switch (z) {
- case '+':
- Emit(" POP EBX");
- Emit(" ADD EAX,EBX");
- break;
- case '-':
- Emit(" MOV EBX,EAX");
- Emit(" POP EAX");
- Emit(" SUB EAX,EBX");
- break;
- case '&':
- Emit(" POP EBX");
- Emit(" AND EAX,EBX");
- break;
- case '|':
- Emit(" POP EBX");
- Emit(" OR EAX,EBX");
- break;
- case '^':
- Emit(" POP EBX");
- Emit(" XOR EAX,EBX");
- break;
- }
- }
- }
- void IzrazDodjeljivanja(void) {
- char z;
- int ChrIzraz;
- DodjelaKarakteru = FALSE;
- Izraz();
- switch (znak) {
- case ':':
- if (!Slijedi(":="))
- Greska(OCEKDOD);
- Emit(" PUSH EBX");
- Novi();
- ChrIzraz = DodjelaKarakteru;
- IzrazDodjeljivanja();
- Emit(" POP EBX");
- if (ChrIzraz)
- Emit(" MOV [EBX],AL");
- else
- Emit(" MOV [EBX],EAX");
- break;
- case '=':
- case -1:
- case '>':
- case '<':
- case '#':
- Emit(" PUSH EAX");
- z = znak;
- Novi();
- Izraz();
- Emit(" POP EBX");
- Emit(" CMP EBX,EAX");
- switch (z) {
- case '=':
- Emit(" SETE AL");
- break;
- case -1:
- Emit("SETGE AL");
- break;
- case '>':
- Emit(" SETG AL");
- break;
- case '<':
- Emit(" SETL AL");
- break;
- case '#':
- Emit(" SETNE AL");
- break;
- }
- Emit(" AND EAX,0FFh");
- break;
- }
- }
- void Uslov(void) {
- char sonda[256], sinace[256],
- skraj[256];
- char STR1[256], STR2[256];
- Novi();
- IzrazDodjeljivanja();
- Emit(" CMP EAX,0");
- NovaLabela(sonda);
- NovaLabela(sinace);
- NovaLabela(skraj);
- sprintf(STR1," JNE L%s",
- sonda);
- Emit(STR1);
- sprintf(STR1," JMP L%s",
- sinace);
- Emit(STR1);
- MoraBiti('{');
- sprintf(STR2, "L%s:", sonda);
- Emit(STR2);
- Blok();
- sprintf(STR2, " JMP L%s",
- skraj);
- Emit(STR2);
- sprintf(STR1, "L%s:", sinace);
- Emit(STR1);
- if (Slijedi("inace")) {
- Novi();
- MoraBiti('{');
- Blok();
- }
- sprintf(STR2, "L%s:", skraj);
- Emit(STR2);
- }
- void Asembler(void) {
- char *TEMP;
- do {
- fgets(linija, 256, ulaz);
- TEMP = strchr(linija, '\n');
- if (TEMP != NULL)
- *TEMP = 0;
- if (strcmp(linija, "\\"))
- Emit(linija);
- if (feof(ulaz))
- strcpy(linija, "\\");
- } while (linija[0] != '\\');
- pozicija = 1;
- znak = linija[pozicija-1];
- MoraBiti('\\');
- }
- void Petlja(void) {
- char sdok[256], skraj [256],
- suslov[256];
- char STR1[256], STR2[256];
- Novi();
- NovaLabela(suslov);
- sprintf(STR2, "L%s:", suslov);
- Emit(STR2);
- IzrazDodjeljivanja();
- Emit(" CMP EAX,0");
- NovaLabela(sdok);
- NovaLabela(skraj);
- sprintf(STR2, " JNE L%s", sdok);
- Emit(STR2);
- sprintf(STR2,
- " JMP L%s",skraj);
- Emit(STR2);
- MoraBiti('{');
- sprintf(STR1, "L%s:", sdok);
- Emit(STR1);
- Blok();
- sprintf(STR1," JMP L%s",
- suslov);
- Emit(STR1);
- sprintf(STR2,"L%s:",skraj);
- Emit(STR2);
- }
- void Blok(void) {
- while (znak != '}') {
- if (Slijedi("dok")) {
- Petlja();
- continue;
- }
- if (Slijedi("ako"))
- Uslov();
- else if(Slijedi("asembler"))
- Asembler();
- else {
- IzrazDodjeljivanja();
- MoraBiti(';');
- }
- }
- MoraBiti('}');
- }
- void DefFunkcija(void) {
- char ImeFunkcije[256],
- ImeVarijable[256];
- long paradresa = 0;
- long lokadresa;
- char STR1[256];
- if (znak < 'A' || znak > 'Z')
- Greska(IMEFUN);
- UzmiIme(ImeFunkcije);
- strcpy(aktivnafunkcija,
- ImeFunkcije);
- MoraBiti('(');
- while (znak != ')') {
- if (znak != 'p')
- Greska(PSL);
- UzmiIme(ImeVarijable);
- paradresa += 4;
- sprintf(STR1, "%s%s EQU %d",
- ImeFunkcije, ImeVarijable,
- paradresa + 4);
- Emit(STR1);
- if (znak != ')')
- MoraBiti(',');
- }
- MoraBiti(')');
- switch (znak) {
- case '{':
- MoraBiti('{');
- lokadresa = 0;
- if (Slijedi("varijable")) {
- Novi();
- do {
- if (islower(znak)) {
- if (znak != 'l')
- Greska(PSL);
- UzmiIme(ImeVarijable);
- lokadresa += 4;
- sprintf(STR1,
- "%s%s EQU %d",
- ImeFunkcije,
- ImeVarijable,
- -lokadresa);
- Emit(STR1);
- if (znak != ';')
- MoraBiti(',');
- }
- } while (znak != ';');
- MoraBiti(';');
- }
- sprintf(STR1, "_%s@%d",
- ImeFunkcije,paradresa);
- strcpy(ImeFunkcije,STR1);
- sprintf(STR1, "GLOBAL %s",
- ImeFunkcije);
- Emit(STR1);
- sprintf(STR1,"%s:",ImeFunkcije);
- Emit(STR1);
- Emit(" PUSH EBP");
- Emit(" MOV EBP,ESP");
- sprintf(STR1, " SUB ESP,%d",
- lokadresa);
- Emit(STR1);
- Blok();
- Emit(" MOV ESP,EBP");
- Emit(" POP EBP");
- sprintf(STR1, " RET %d",
- paradresa);
- Emit(STR1);
- break;
- case ';':
- sprintf(STR1,"extern _%s@%d",
- ImeFunkcije,paradresa);
- Emit(STR1);
- MoraBiti(';');
- break;
- default:
- Greska(DEFFUN);
- break;
- }
- }
- void Prevedi(void) {
- char imevarijable[256];
- char STR1[256];
- Emit("EXTERN _ExitProcess@4");
- Emit("section .data");
- pozicija = 0;
- Novi();
- if (Slijedi("varijable")) {
- Novi();
- do {
- if (islower(znak)) {
- UzmiIme(imevarijable);
- sprintf(STR1, "%s DD 0",
- imevarijable);
- Emit(STR1);
- if (znak != ';')
- MoraBiti(',');
- }
- } while (znak != ';');
- MoraBiti(';');
- }
- Emit("section .text");
- while (Slijedi("funkcija")) {
- Novi();
- DefFunkcija();
- }
- *aktivnafunkcija = '\0';
- MoraBiti('{');
- if (znak == '}') {
- return;
- }
- Emit(" global start");
- Emit("start:");
- Blok();
- Emit(" PUSH 0");
- Emit(" CALL _ExitProcess@4");
- }
- void Glavni(void) {
- char linija[256];
- char STR1[256];
- trenlabela = 0;
- brojaclinija = 0;
- *linija = '\0';
- Prevedi();
- fclose(ulaz);
- fclose(izlaz);
- printf("Prevedeno! \n");
- }
- int main(int argc,char *argv[]){
- if (argc == 3) {
- if(!(ulaz=fopen(argv[1],"rb")))
- {
- fprintf(stderr,
- "Necitljiva %s \n", argv[1]);
- exit(0);
- }
- if(!(izlaz=fopen(argv[2],"wb"))){
- fprintf(stderr,
- "Neupisiva %s \n", argv[2]);
- exit(0);
- }
- }
- else {
- fprintf(stderr,
- "KOMP ime.fil ime.asm \n");
- exit(0);
- }
- Glavni();
- fclose(ulaz);
- fclose(izlaz);
- return(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement