diff --git a/Makefile b/Makefile index dcae36a..5944b36 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ FILES = *.c */*.c LIBRARIES = -lpthread INCLUDES = -I. -I./parser/ -I./compiler/ -I./vm/ -I./tokenizer/ -I./misc/ -CFLAGS = -std=c99 -Wall +CFLAGS = -std=c99 -Wall -O3 OUTFILE = jack-compiler main: ${FILES} diff --git a/compiler/compiler-expressions.c b/compiler/compiler-expressions.c index 27d4432..5e517f0 100644 --- a/compiler/compiler-expressions.c +++ b/compiler/compiler-expressions.c @@ -15,10 +15,10 @@ char* toascii(char c); // Dealing with singular terms LINEBLOCK* compilestrconst(char* str); LINEBLOCK* compilekeywordconst(SCOPE* s, TERM* t); -LINEBLOCK* compilearrayitem(SCOPE* s, TERM* t); +LINEBLOCK* compilearrayitem(SCOPE* s, DEBUGINFO* d, TERM* t); LINEBLOCK* compilecallln(SCOPE* s, SUBROUTDEC* d, SUBROUTCALL* call); -LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t); -LINEBLOCK* compileterm(SCOPE* s, TERM* t); +LINEBLOCK* pushunaryopterm(SCOPE* s, DEBUGINFO* d, TERM* t); +LINEBLOCK* compileterm(SCOPE* s, DEBUGINFO* d, TERM* t); /* END FORWARD DECLARATIONS */ @@ -128,9 +128,9 @@ LINEBLOCK* compilekeywordconst(SCOPE* s, TERM* t) { return mklnblk(pushconstant(0)); } -LINEBLOCK* compilearrayitem(SCOPE* s, TERM* t) { - LINEBLOCK* blk = compileexpression(s, t->array->exp); - appendln(blk, pushvar(s, t->array->name)); +LINEBLOCK* compilearrayitem(SCOPE* s, DEBUGINFO* d, TERM* t) { + LINEBLOCK* blk = compileexpression(s, d, t->array->exp); + appendln(blk, pushvar(s, d, t->array->name)); appendln(blk, onetoken("add")); @@ -161,7 +161,7 @@ LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call) { LINEBLOCK* blk = compilecallln(s, d, call); if(call->parameters != NULL) - blk = mergelnblks(compileexplist(s, call->parameters), blk); + blk = mergelnblks(compileexplist(s, call->debug, call->parameters), blk); if(d->subroutclass == method) { if(call->parentname == NULL) @@ -179,8 +179,8 @@ LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call) { return blk; } -LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t) { - LINEBLOCK* blk = compileexpression(s, t->expression); +LINEBLOCK* pushunaryopterm(SCOPE* s, DEBUGINFO* d, TERM* t) { + LINEBLOCK* blk = compileexpression(s, d, t->expression); LINE* neg; if(t->unaryop == '-') neg = onetoken("neg"); @@ -190,23 +190,23 @@ LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t) { return blk; } -LINEBLOCK* compileterm(SCOPE* s, TERM* t) { - if(t->type == varname) return mklnblk(pushvar(s, t->string)); +LINEBLOCK* compileterm(SCOPE* s, DEBUGINFO* d, TERM* t) { + if(t->type == varname) return mklnblk(pushvar(s, d, t->string)); if(t->type == intconstant) return mklnblk(pushconstant(t->integer)); if(t->type == stringconstant) return compilestrconst(t->string); if(t->type == keywordconstant) return compilekeywordconst(s, t); - if(t->type == arrayitem) return compilearrayitem(s, t); + if(t->type == arrayitem) return compilearrayitem(s, d, t); if(t->type == subroutcall) return compilesubroutcall(s, t->call); - if(t->type == innerexpression) return compileexpression(s, t->expression); - return pushunaryopterm(s, t); + if(t->type == innerexpression) return compileexpression(s, d, t->expression); + return pushunaryopterm(s, d, t); } // Dealing with whole expressions -LINEBLOCK* compileexpression(SCOPE* s, TERM* e) { +LINEBLOCK* compileexpression(SCOPE* s, DEBUGINFO* d, TERM* e) { LINEBLOCK* blk = NULL; if(e != NULL) { while(true) { - blk = mergelnblks(blk, compileterm(s, e)); + blk = mergelnblks(blk, compileterm(s, d, e)); if(e->next == NULL) break; appendln(blk, mathopln(e->op)); @@ -216,10 +216,10 @@ LINEBLOCK* compileexpression(SCOPE* s, TERM* e) { return blk; } -LINEBLOCK* compileexplist(SCOPE* s, EXPRESSIONLIST* explist) { +LINEBLOCK* compileexplist(SCOPE* s, DEBUGINFO* d, EXPRESSIONLIST* explist) { LINEBLOCK* head = NULL; while(explist != NULL) { - head = mergelnblks(head, compileexpression(s, explist->expression)); + head = mergelnblks(head, compileexpression(s, d, explist->expression)); explist = explist->next; } return head; diff --git a/compiler/compiler-expressions.h b/compiler/compiler-expressions.h index 01eccbf..059f466 100644 --- a/compiler/compiler-expressions.h +++ b/compiler/compiler-expressions.h @@ -10,6 +10,6 @@ LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call); // Dealing with whole expressions -LINEBLOCK* compileexpression(SCOPE* s, TERM* e); -LINEBLOCK* compileexplist(SCOPE* s, EXPRESSIONLIST* explist); +LINEBLOCK* compileexpression(SCOPE* s, DEBUGINFO* d, TERM* e); +LINEBLOCK* compileexplist(SCOPE* s, DEBUGINFO* d, EXPRESSIONLIST* explist); #endif diff --git a/compiler/compiler-scopes.c b/compiler/compiler-scopes.c index 6f22673..7002b8b 100644 --- a/compiler/compiler-scopes.c +++ b/compiler/compiler-scopes.c @@ -106,6 +106,13 @@ VAR* getvar(SCOPE* s, const char* name) { return NULL; } +VAR* getvarmustexist(SCOPE* s, DEBUGINFO* d, const char* name) { + VAR* v = getvar(s, name); + if(v == NULL) + notdeclared(name, d); + return v; +} + CLASS* getclass(SCOPE* s, const char* name) { CLASS* curr = s->classes; while(curr != NULL) { diff --git a/compiler/compiler-scopes.h b/compiler/compiler-scopes.h index 1994f77..fa3055c 100644 --- a/compiler/compiler-scopes.h +++ b/compiler/compiler-scopes.h @@ -52,6 +52,7 @@ CLASS* getclass(SCOPE* s, const char* name); // Generic getters VAR* getvar(SCOPE* s, const char* name); +VAR* getvarmustexist(SCOPE* s, DEBUGINFO* d, const char* name); // Freeing void freescope(SCOPE* s); diff --git a/compiler/compiler-statements.c b/compiler/compiler-statements.c index f25adcc..4043e27 100644 --- a/compiler/compiler-statements.c +++ b/compiler/compiler-statements.c @@ -12,10 +12,10 @@ LINE* pushtemp(); char* mkcondlabel(char* name, int count); // Handling individual statements -LINEBLOCK* compileret(SCOPE* s, TERM* e); -LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st); -LINEBLOCK* compilewhile(SCOPE* s, CONDSTATEMENT* w); -LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l); +LINEBLOCK* compileret(SCOPE* s, STATEMENT* st); +LINEBLOCK* compileif(SCOPE* s, STATEMENT* st); +LINEBLOCK* compilewhile(SCOPE* s, STATEMENT* st); +LINEBLOCK* compilelet(SCOPE* s, STATEMENT* st); LINEBLOCK* compilestatement(SCOPE* s, STATEMENT* st); /* END FORWARD DECLARATIONS */ @@ -41,7 +41,8 @@ char* mkcondlabel(char* name, int count) { } // Handling individual statements -LINEBLOCK* compileret(SCOPE* s, TERM* e) { +LINEBLOCK* compileret(SCOPE* s, STATEMENT* st) { + TERM* e = st->retstatement; LINE* ret = onetoken("return"); LINEBLOCK* blk = mklnblk(ret); @@ -50,13 +51,14 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) { char* tokens[] = { "push", "constant", "0" }; appendlnbefore(blk, mkln(tokens)); } else - blk = mergelnblks(compileexpression(s, e), blk); + blk = mergelnblks(compileexpression(s, st->debug, e), blk); return blk; } -LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st) { - LINEBLOCK* blk = compileexpression(s, st->base->expression); +LINEBLOCK* compileif(SCOPE* s, STATEMENT* st) { + IFSTATEMENT* ifst = st->ifstatement; + LINEBLOCK* blk = compileexpression(s, st->debug, ifst->base->expression); pthread_mutex_lock(&(s->compiler->ifmutex)); static int ifcount = 0; @@ -75,10 +77,10 @@ LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st) { char* truelabelln[] = { "label", truelabel }; appendln(blk, mkln(truelabelln)); - blk = mergelnblks(blk, compilestatements(s, st->base->statements)); + blk = mergelnblks(blk, compilestatements(s, ifst->base->statements)); char* endlabel; - bool haselse = st->elsestatements != NULL; + bool haselse = ifst->elsestatements != NULL; if(haselse) { endlabel = mkcondlabel("IF_END", mycount); char* endgoto[] = { "goto", endlabel }; @@ -89,7 +91,7 @@ LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st) { appendln(blk, mkln(falselabelln)); if(haselse) { - blk = mergelnblks(blk, compilestatements(s, st->elsestatements)); + blk = mergelnblks(blk, compilestatements(s, ifst->elsestatements)); char* endlabelln[] = { "label", endlabel }; appendln(blk, mkln(endlabelln)); free(endlabel); @@ -101,8 +103,9 @@ LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st) { return blk; } -LINEBLOCK* compilewhile(SCOPE* s, CONDSTATEMENT* w) { - LINEBLOCK* blk = compileexpression(s, w->expression); +LINEBLOCK* compilewhile(SCOPE* s, STATEMENT* st) { + CONDSTATEMENT* w = st->whilestatement; + LINEBLOCK* blk = compileexpression(s, st->debug, w->expression); pthread_mutex_lock(&(s->compiler->whilemutex)); static int whilecount = 0; @@ -134,13 +137,14 @@ LINEBLOCK* compilewhile(SCOPE* s, CONDSTATEMENT* w) { return blk; } -LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l) { - LINEBLOCK* blk = compileexpression(s, l->expression); +LINEBLOCK* compilelet(SCOPE* s, STATEMENT* st) { + LETSTATEMENT* l = st->letstatement; + LINEBLOCK* blk = compileexpression(s, st->debug, l->expression); if(l->arrayind != NULL) { appendlnbefore(blk, onetoken("add")); - appendlnbefore(blk, pushvar(s, l->varname)); - blk = mergelnblks(compileexpression(s, l->arrayind), blk); + appendlnbefore(blk, pushvar(s, st->debug, l->varname)); + blk = mergelnblks(compileexpression(s, st->debug, l->arrayind), blk); appendln(blk, poptemp()); appendln(blk, popthatadd()); @@ -148,17 +152,17 @@ LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l) { appendln(blk, popthat()); } else - appendln(blk, popvar(s, l->varname)); + appendln(blk, popvar(s, st->debug, l->varname)); return blk; } LINEBLOCK* compilestatement(SCOPE* s, STATEMENT* st) { s->currdebug = st->debug; if(st->type == dostatement) return compilesubroutcall(s, st->dostatement); - if(st->type == returnstatement) return compileret(s, st->retstatement); - if(st->type == ifstatement) return compileif(s, st->ifstatement); - if(st->type == whilestatement) return compilewhile(s, st->whilestatement); - return compilelet(s, st->letstatement); + if(st->type == returnstatement) return compileret(s, st); + if(st->type == ifstatement) return compileif(s, st); + if(st->type == whilestatement) return compilewhile(s, st); + return compilelet(s, st); } LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts) { diff --git a/compiler/compiler-util.c b/compiler/compiler-util.c index a699e3d..9839fe3 100644 --- a/compiler/compiler-util.c +++ b/compiler/compiler-util.c @@ -8,21 +8,16 @@ LINE* opvarraw(SCOPE* s, char* op, VAR* v) { return ln; } -LINE* opvar(SCOPE* s, char* op, const char* name) { - VAR* v = getvar(s, name); - return opvarraw(s, op, v); -} - -LINE* pushvarraw(SCOPE*s, VAR* v) { +LINE* pushvarraw(SCOPE* s, VAR* v) { return opvarraw(s, "push", v); } -LINE* pushvar(SCOPE* s, const char* name) { - return opvar(s, "push", name); +LINE* pushvar(SCOPE* s, DEBUGINFO* d, const char* name) { + return opvarraw(s, "push", getvarmustexist(s, d, name)); } -LINE* popvar(SCOPE* s, const char* name) { - return opvar(s, "pop", name); +LINE* popvar(SCOPE* s, DEBUGINFO* d, const char* name) { + return opvarraw(s, "pop", getvarmustexist(s, d, name)); } LINE* poptemp() { diff --git a/compiler/compiler-util.h b/compiler/compiler-util.h index 01fa4c2..f282569 100644 --- a/compiler/compiler-util.h +++ b/compiler/compiler-util.h @@ -12,9 +12,9 @@ LINE* onetoken(char* str); LINE* mksimpleln(char** tokens, int count); -LINE* pushvarraw(SCOPE*s, VAR* v); -LINE* pushvar(SCOPE* s, const char* name); -LINE* popvar(SCOPE* s, const char* name); +LINE* pushvarraw(SCOPE* s, VAR* v); +LINE* pushvar(SCOPE* s, DEBUGINFO* d, const char* name); +LINE* popvar(SCOPE* s, DEBUGINFO* d, const char* name); LINE* poptemp(); LINE* popthatadd();