diff --git a/Makefile b/Makefile index 5b164f7..6340dcc 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 -g -Wall +CFLAGS = -std=c99 -g OUTFILE = jack-compiler main: ${FILES} diff --git a/compiler/compiler-expressions.c b/compiler/compiler-expressions.c new file mode 100644 index 0000000..b96ec7a --- /dev/null +++ b/compiler/compiler-expressions.c @@ -0,0 +1,225 @@ +#include +#include +#include "compiler-expressions.h" +#include "compiler-util.h" + +/* BEGIN FORWARD DECLARATIONS */ + +// Miscelaneous +LINE* pushconstant(int n); +LINE* mathopln(char op); +LINE* pushthat(); +int countexpressions(EXPRESSIONLIST* explist); +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* compilecallln(SCOPE* s, SUBROUTDEC* d, SUBROUTCALL* call); +LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t); +LINEBLOCK* compileterm(SCOPE* s, TERM* t); + +/* END FORWARD DECLARATIONS */ + + + +// Miscelaneous +LINE* mathopln(char op) { + if(op == '+') + return onetoken("add"); + if(op == '-') + return onetoken("sub"); + if(op == '=') + return onetoken("eq"); + if(op == '>') + return onetoken("gt"); + if(op == '<') + return onetoken("lt"); + if(op == '|') + return onetoken("or"); + if(op == '&') + return onetoken("and"); + if(op == '/') { + char* tokens[] = { "call", "Math.divide", "2" }; + return mkln(tokens); + } + char* tokens[] = { "call", "Math.multiply", "2" }; + return mkln(tokens); +} + +LINE* pushconstant(int n) { + char* tokens[] = { "push", "constant", itoa(n) }; + return mkln(tokens); +} + +LINE* pushthat() { + char* pushthat[] = { "push", "that", "0" }; + return mkln(pushthat); +} + +int countexpressions(EXPRESSIONLIST* explist) { + int i = 0; + while(explist != NULL) { + i++; + explist = explist->next; + } + return i; +} + +char* toascii(char c) { + char* result = (char*)malloc(sizeof(char) * (countplaces(c) + 1)); + sprintf(result, "%i", c); + return result; +} + +// Dealing with singular terms +LINEBLOCK* compilestrconst(char* str) { + if(str[0] == '\0') + return NULL; + + char* pushchar[] = { "push", "constant", toascii(str[0]) }; + LINEBLOCK* blk = mklnblk(mksimpleln(pushchar, strcount(pushchar))); + free(pushchar[2]); + + char* appendchar[] = { "call", "String.appendChar", "2" }; + appendln(blk, mkln(appendchar)); + + int i = 1; + char c; + while(c = str[i], c != '\0') { + pushchar[2] = toascii(c); + appendln(blk, mksimpleln(pushchar, strcount(pushchar))); + free(pushchar[2]); + appendln(blk, mksimpleln(appendchar, strcount(appendchar))); + i++; + } + + char* strsize[] = { "push", "constant", itoa(i) }; + char* mknew[] = { "call", "String.new", "1" }; + appendlnbefore(blk, mkln(mknew)); + appendlnbefore(blk, mkln(strsize)); + free(strsize[2]); + + return blk; +} + +LINE* pushthisadd() { + char* pushthisadd[] = { "push", "pointer", "0" }; + return mkln(pushthisadd); +} + +LINE* pushfalse() { + return pushconstant(0); +} + +LINEBLOCK* pushtrue() { + LINEBLOCK* blk = mklnblk(pushfalse()); + appendln(blk, onetoken("not")); + return blk; +} + +LINEBLOCK* compilekeywordconst(SCOPE* s, TERM* t) { + if(!strcmp(t->string, "this")) return mklnblk(pushthisadd()); + if(!strcmp(t->string, "false")) return mklnblk(pushfalse()); + if(!strcmp(t->string, "true")) return pushtrue(); + return mklnblk(pushconstant(0)); +} + +LINEBLOCK* compilearrayitem(SCOPE* s, TERM* t) { + LINEBLOCK* blk = compileexpression(s, t->array->exp); + appendln(blk, pushvar(s, t->array->name)); + + appendln(blk, onetoken("add")); + + appendln(blk, popthatadd()); + appendln(blk, pushthat()); + + return blk; +} + +LINEBLOCK* compilecallln(SCOPE* s, SUBROUTDEC* d, SUBROUTCALL* call) { + LINE* ln = mkline(3); + + addtoken(ln, ezheapstr("call")); + + addtoken(ln, dotlabel(d->class->name, call->name)); + + int count = countexpressions(call->parameters); + if(d->subroutclass == method) + count++; + addtoken(ln, itoa(count)); + + return mklnblk(ln); +} + +LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call) { + VAR* v; + SUBROUTDEC* d = getsubroutdecfromcall(s, call, &v); + LINEBLOCK* blk = compilecallln(s, d, call); + + if(call->parameters != NULL) + blk = mergelnblks(compileexplist(s, call->parameters), blk); + + if(d->subroutclass == method) { + if(call->parentname == NULL) + appendlnbefore(blk, pushthisadd()); + else + appendlnbefore(blk, pushvarraw(s, v)); + } + + // void functions always return 0 + // therefore must be thrown away + if(!strcmp(d->type, "void")) { + appendln(blk, poptemp()); + } + + return blk; +} + +LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t) { + LINEBLOCK* blk = compileexpression(s, t->expression); + LINE* neg; + if(t->unaryop == '-') + neg = onetoken("neg"); + else + neg = onetoken("not"); + appendln(blk, neg); + return blk; +} + +LINEBLOCK* compileterm(SCOPE* s, TERM* t) { + if(t->type == varname) return mklnblk(pushvar(s, 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 == subroutcall) return compilesubroutcall(s, t->call); + if(t->type == innerexpression) return compileexpression(s, t->expression); + return pushunaryopterm(s, t); +} + +// Dealing with whole expressions +LINEBLOCK* compileexpression(SCOPE* s, TERM* e) { + LINEBLOCK* blk = NULL; + if(e != NULL) { + while(true) { + blk = mergelnblks(blk, compileterm(s, e)); + if(e->next != NULL) { + appendln(blk, mathopln(e->op)); + e = e->next; + } + else break; + } + } + return blk; +} + +LINEBLOCK* compileexplist(SCOPE* s, EXPRESSIONLIST* explist) { + LINEBLOCK* head = NULL; + while(explist != NULL) { + head = mergelnblks(head, compileexpression(s, explist->expression)); + explist = explist->next; + } + return head; +} diff --git a/compiler/compiler-expressions.h b/compiler/compiler-expressions.h new file mode 100644 index 0000000..f84da31 --- /dev/null +++ b/compiler/compiler-expressions.h @@ -0,0 +1,15 @@ +#ifndef COMPILER_EXPRESSIONS_H +#define COMPILER_EXPRESSIONS_H +#include "vm-lines.h" +#include "compiler.h" + +/* compiler-expressions + * Subroutines for dealing and compiling expressions and singular terms. */ + +// Dealing with singular terms +LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call); + +// Dealing with whole expressions +LINEBLOCK* compileexpression(SCOPE* s, TERM* e); +LINEBLOCK* compileexplist(SCOPE* s, EXPRESSIONLIST* explist); +#endif diff --git a/compiler/compiler-util.c b/compiler/compiler-util.c new file mode 100644 index 0000000..9b44059 --- /dev/null +++ b/compiler/compiler-util.c @@ -0,0 +1,48 @@ +#include "compiler-util.h" + +LINE* opvarraw(SCOPE* s, char* op, VAR* v) { + char* tokens[] = { op, v->memsegment, itoa(v->index) }; + return mksimpleln(tokens, strcount(tokens)); +} + +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) { + return opvarraw(s, "push", v); +} + +LINE* pushvar(SCOPE* s, const char* name) { + return opvar(s, "push", name); +} + +LINE* popvar(SCOPE* s, const char* name) { + return opvar(s, "pop", name); +} + +LINE* poptemp() { + char* poptemp[] = { "pop", "temp", "0" }; + return mksimpleln(poptemp, strcount(poptemp)); +} + +LINE* popthatadd() { + char* popthatadd[] = { "pop", "pointer", "1" }; + return mksimpleln(popthatadd, strcount(popthatadd)); +} + +LINE* onetoken(char* str) { + LINE* ln = mkline(1); + addtoken(ln, ezheapstr(str)); + ln->next = NULL; + return ln; +} + +LINE* mksimpleln(char** tokens, int count) { + LINE* ln = mkline(count); + for(int i = 0; i < count; i++) + addtoken(ln, ezheapstr(tokens[i])); + ln->next = NULL; + return ln; +} diff --git a/compiler/compiler-util.h b/compiler/compiler-util.h new file mode 100644 index 0000000..07d79ac --- /dev/null +++ b/compiler/compiler-util.h @@ -0,0 +1,18 @@ +#ifndef COMPILER_UTIL_H +#define COMPILER_UTIL_H +#include "vm-lines.h" +#include "compiler-scopes.h" +#include "compiler.h" + +#define mkln(id) mksimpleln(id, strcount(id)) + +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* poptemp(); +LINE* popthatadd(); + +#endif diff --git a/compiler/compiler.c b/compiler/compiler.c index b8c5554..380050f 100644 --- a/compiler/compiler.c +++ b/compiler/compiler.c @@ -1,9 +1,10 @@ #include #include #include "compiler.h" +#include "compiler-util.h" +#include "compiler-expressions.h" LINEBLOCK* compilestatements(COMPILER* c, SCOPE* s, STATEMENT* sts); -LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call); LINEBLOCK* compileexpression(SCOPE* s, TERM* e); int countparameters(PARAMETER* params) { @@ -15,15 +16,6 @@ int countparameters(PARAMETER* params) { return i; } -int countexpressions(EXPRESSIONLIST* explist) { - int i = 0; - while(explist != NULL) { - i++; - explist = explist->next; - } - return i; -} - int countlocalvars(VARDEC* decs) { int i = 0; while(decs != NULL) { @@ -37,13 +29,6 @@ int countlocalvars(VARDEC* decs) { return i; } -char* dotlabel(char* n1, char* n2) { - int sz = (strlen(n1) + strlen(n2) + 2) * sizeof(char); - char* result = (char*)malloc(sz); - sprintf(result, "%s.%s", n1, n2); - return result; -} - char* mkcondlabel(char* name, int count) { int sz = (strlen(name) + countplaces(count) + 1) * sizeof(char); char* result = (char*)malloc(sz); @@ -51,257 +36,19 @@ char* mkcondlabel(char* name, int count) { return result; } -LINE* onetoken(char* str) { - LINE* ln = mkline(1); - addtoken(ln, ezheapstr(str)); - ln->next = NULL; - return ln; -} - -LINE* mksimpleln(char** tokens, int count) { - LINE* ln = mkline(count); - for(int i = 0; i < count; i++) - addtoken(ln, ezheapstr(tokens[i])); - ln->next = NULL; - return ln; -} - -LINE* mathopln(char op) { - if(op == '+') - return onetoken("add"); - if(op == '-') - return onetoken("sub"); - if(op == '=') - return onetoken("eq"); - if(op == '>') - return onetoken("gt"); - if(op == '<') - return onetoken("lt"); - if(op == '|') - return onetoken("or"); - if(op == '&') - return onetoken("and"); - if(op == '/') { - char* tokens[] = { "call", "Math.divide", "2" }; - return mksimpleln(tokens, strcount(tokens)); - } - char* tokens[] = { "call", "Math.multiply", "2" }; - return mksimpleln(tokens, strcount(tokens)); -} - -LINE* pushconstant(int n) { - char* tokens[] = { "push", "constant", itoa(n) }; - return mksimpleln(tokens, strcount(tokens)); -} - -LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t) { - LINEBLOCK* blk = compileexpression(s, t->expression); - LINE* neg; - if(t->unaryop == '-') - neg = onetoken("neg"); - else - neg = onetoken("not"); - appendln(blk, neg); - return blk; -} - -LINE* opvarraw(SCOPE* s, char* op, VAR* v) { - char* tokens[] = { op, v->memsegment, itoa(v->index) }; - return mksimpleln(tokens, strcount(tokens)); -} - -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) { - return opvarraw(s, "push", v); -} - -LINE* pushvar(SCOPE* s, const char* name) { - return opvar(s, "push", name); -} - -LINE* popvar(SCOPE* s, const char* name) { - return opvar(s, "pop", name); -} - -LINE* pushfalse() { - return pushconstant(0); -} - -LINEBLOCK* pushtrue() { - LINEBLOCK* blk = mklnblk(pushfalse()); - appendln(blk, onetoken("not")); - return blk; -} - -LINE* pushthisadd() { - char* pushthisadd[] = { "push", "pointer", "0" }; - return mksimpleln(pushthisadd, strcount(pushthisadd)); -} - -LINE* popthatadd() { - char* popthatadd[] = { "pop", "pointer", "1" }; - return mksimpleln(popthatadd, strcount(popthatadd)); -} - LINE* pushthatadd() { char* pushthatadd[] = { "push", "pointer", "1" }; - return mksimpleln(pushthatadd, strcount(pushthatadd)); + return mkln(pushthatadd); } LINE* popthat() { char* popthat[] = { "pop", "that", "0" }; - return mksimpleln(popthat, strcount(popthat)); -} - -LINE* pushthat() { - char* pushthat[] = { "push", "that", "0" }; - return mksimpleln(pushthat, strcount(pushthat)); + return mkln(popthat); } LINE* pushtemp() { char* pushtemp[] = { "push", "temp", "0" }; - return mksimpleln(pushtemp, strcount(pushtemp)); -} - -LINE* poptemp() { - char* poptemp[] = { "pop", "temp", "0" }; - return mksimpleln(poptemp, strcount(poptemp)); -} - -LINEBLOCK* compilekeywordconst(SCOPE* s, TERM* t) { - if(!strcmp(t->string, "true")) return pushtrue(); - if(!strcmp(t->string, "false")) return mklnblk(pushfalse()); - if(!strcmp(t->string, "this")) return mklnblk(pushthisadd()); - return mklnblk(pushconstant(0)); -} - -char* toascii(char c) { - char* result = (char*)malloc(sizeof(char) * (countplaces(c) + 1)); - sprintf(result, "%i", c); - return result; -} - -LINEBLOCK* compilestrconst(char* str) { - if(str[0] == '\0') - return NULL; - - char* pushchar[] = { "push", "constant", "" }; - pushchar[2] = toascii(str[0]); - LINEBLOCK* blk = mklnblk(mksimpleln(pushchar, strcount(pushchar))); - free(pushchar[2]); - - char* appendchar[] = { "call", "String.appendChar", "2" }; - appendln(blk, mksimpleln(appendchar, strcount(appendchar))); - - int i = 1; - char c; - while(c = str[i], c != '\0') { - pushchar[2] = toascii(c); - appendln(blk, mksimpleln(pushchar, strcount(pushchar))); - free(pushchar[2]); - appendln(blk, mksimpleln(appendchar, strcount(appendchar))); - i++; - } - - char* strsize[] = { "push", "constant", itoa(i) }; - char* mknew[] = { "call", "String.new", "1" }; - appendlnbefore(blk, mksimpleln(mknew, strcount(mknew))); - appendlnbefore(blk, mksimpleln(strsize, strcount(strsize))); - free(strsize[2]); - - return blk; -} - -LINEBLOCK* compilearrayitem(SCOPE* s, TERM* t) { - LINEBLOCK* blk = compileexpression(s, t->array->exp); - appendln(blk, pushvar(s, t->array->name)); - - appendln(blk, onetoken("add")); - - appendln(blk, popthatadd()); - appendln(blk, pushthat()); - - return blk; -} - -LINEBLOCK* compileterm(SCOPE* s, TERM* t) { - if(t->type == intconstant) return mklnblk(pushconstant(t->integer)); - if(t->type == unaryopterm) return pushunaryopterm(s, t); - if(t->type == innerexpression) return compileexpression(s, t->expression); - if(t->type == varname) return mklnblk(pushvar(s, t->string)); - if(t->type == subroutcall) return compilesubroutcall(s, t->call); - if(t->type == keywordconstant) return compilekeywordconst(s, t); - if(t->type == stringconstant) return compilestrconst(t->string); - return compilearrayitem(s, t); -} - -LINEBLOCK* compileexpression(SCOPE* s, TERM* e) { - LINEBLOCK* blk = compileterm(s, e); - TERM* curr = e->next; - if(curr != NULL) { - while(true) { - blk = mergelnblks(blk, compileterm(s, curr)); - if(curr->next != NULL) { - appendln(blk, mathopln(curr->op)); - curr = curr->next; - } - else break; - } - appendln(blk, mathopln(e->op)); - } - return blk; -} - -LINEBLOCK* compileexplist(SCOPE* s, EXPRESSIONLIST* explist) { - LINEBLOCK* head = NULL; - while(explist != NULL) { - head = mergelnblks(head, compileexpression(s, explist->expression)); - explist = explist->next; - } - return head; -} - -LINEBLOCK* compilecallln(SCOPE* s, SUBROUTDEC* d, SUBROUTCALL* call) { - LINE* ln = mkline(3); - - addtoken(ln, ezheapstr("call")); - - addtoken(ln, dotlabel(d->class->name, call->name)); - - int count = countexpressions(call->parameters); - if(d->subroutclass == method) - count++; - addtoken(ln, itoa(count)); - - return mklnblk(ln); -} - -LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call) { - VAR* v; - SUBROUTDEC* d = getsubroutdecfromcall(s, call, &v); - LINEBLOCK* blk = compilecallln(s, d, call); - - if(call->parameters != NULL) - blk = mergelnblks(compileexplist(s, call->parameters), blk); - - if(d->subroutclass == method) { - if(call->parentname == NULL) - appendlnbefore(blk, pushthisadd()); - else - appendlnbefore(blk, pushvarraw(s, v)); - } - - // void functions always return 0 - // therefore must be thrown away - if(!strcmp(d->type, "void")) { - appendln(blk, poptemp()); - } - - return blk; + return mkln(pushtemp); } LINEBLOCK* compileret(SCOPE* s, TERM* e) { @@ -311,7 +58,7 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) { // void subroutdecs return 0 if(e == NULL) { char* tokens[] = { "push", "constant", "0" }; - appendlnbefore(blk, mksimpleln(tokens, strcount(tokens))); + appendlnbefore(blk, mkln(tokens)); } else blk = mergelnblks(compileexpression(s, e), blk); @@ -329,14 +76,14 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) { char* truelabel = mkcondlabel("IF_TRUE", mycount); char* ifgoto[] = { "if-goto", truelabel }; - appendln(blk, mksimpleln(ifgoto, strcount(ifgoto))); + appendln(blk, mkln(ifgoto)); char* falselabel = mkcondlabel("IF_FALSE", mycount); char* gotofalse[] = { "goto", falselabel }; - appendln(blk, mksimpleln(gotofalse, strcount(gotofalse))); + appendln(blk, mkln(gotofalse)); char* truelabelln[] = { "label", truelabel }; - appendln(blk, mksimpleln(truelabelln, strcount(truelabelln))); + appendln(blk, mkln(truelabelln)); blk = mergelnblks(blk, compilestatements(c, s, st->base->statements)); @@ -345,16 +92,16 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) { if(haselse) { endlabel = mkcondlabel("IF_END", mycount); char* endgoto[] = { "goto", endlabel }; - appendln(blk, mksimpleln(endgoto, strcount(endgoto))); + appendln(blk, mkln(endgoto)); } char* falselabelln[] = { "label", falselabel}; - appendln(blk, mksimpleln(falselabelln, strcount(falselabelln))); + appendln(blk, mkln(falselabelln)); if(haselse) { blk = mergelnblks(blk, compilestatements(c, s, st->elsestatements)); char* endlabelln[] = { "label", endlabel }; - appendln(blk, mksimpleln(endlabelln, strcount(endlabelln))); + appendln(blk, mkln(endlabelln)); } return blk; @@ -371,21 +118,21 @@ LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w) { char* explabel = mkcondlabel("WHILE_EXP", mycount); char* explabelln[] = { "label", explabel }; - appendlnbefore(blk, mksimpleln(explabelln, strcount(explabelln))); + appendlnbefore(blk, mkln(explabelln)); appendln(blk, onetoken("not")); char* endlabel = mkcondlabel("WHILE_END", mycount); char* ifgoto[] = { "if-goto", endlabel }; - appendln(blk, mksimpleln(ifgoto, strcount(ifgoto))); + appendln(blk, mkln(ifgoto)); blk = mergelnblks(blk, compilestatements(c, s, w->statements)); char* gotoln[] = { "goto", explabel }; - appendln(blk, mksimpleln(gotoln, strcount(gotoln))); + appendln(blk, mkln(gotoln)); char* endlabelln[] = { "label", endlabel }; - appendln(blk, mksimpleln(endlabelln, strcount(endlabelln))); + appendln(blk, mkln(endlabelln)); return blk; } @@ -439,7 +186,7 @@ LINEBLOCK* compilefunbody(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTBODY* b) { LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd) { char* labelstrs[] = { "function", dotlabel(c->name, sd->name), itoa(countlocalvars(sd->body->vardecs)) }; - LINE* label = mksimpleln(labelstrs, strcount(labelstrs)); + LINE* label = mkln(labelstrs); free(labelstrs[1]); free(labelstrs[2]); label->next = NULL; @@ -485,9 +232,9 @@ LINEBLOCK* compileconstructor(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* con) char* size[] = { "push", "constant", itoa(getobjsize(cl)) }; char* memalloc[] = { "call", "Memory.alloc", "1" }; char* poppointer[] = { "pop", "pointer", "0" }; - appendln(blk, mksimpleln(size, strcount(size))); - appendln(blk, mksimpleln(memalloc, strcount(memalloc))); - appendln(blk, mksimpleln(poppointer, strcount(poppointer))); + appendln(blk, mkln(size)); + appendln(blk, mkln(memalloc)); + appendln(blk, mkln(poppointer)); free(size[2]); if(con->body != NULL) @@ -502,8 +249,8 @@ LINEBLOCK* compilemethod(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* m) { char* pusharg0[] = { "push", "argument", "0" }; char* poppointer[] = { "pop", "pointer", "0" }; - appendln(blk, mksimpleln(pusharg0, strcount(pusharg0))); - appendln(blk, mksimpleln(poppointer, strcount(poppointer))); + appendln(blk, mkln(pusharg0)); + appendln(blk, mkln(poppointer)); if(m->body != NULL) return mergelnblks(blk, compilefunbody(c, s, cl, m->body)); diff --git a/compiler/compiler.h b/compiler/compiler.h index 1d57959..11d6ae7 100644 --- a/compiler/compiler.h +++ b/compiler/compiler.h @@ -5,12 +5,14 @@ #include "vm-lines.h" #include "compiler-scopes.h" +struct scope; + typedef struct compiler { pthread_mutex_t ifmutex; pthread_mutex_t whilemutex; pthread_mutex_t staticmutex; CLASS* classes; - SCOPE* globalscope; + struct scope* globalscope; } COMPILER; COMPILER* mkcompiler(CLASS* classes); diff --git a/misc/util.c b/misc/util.c index 82b0ad5..600876e 100644 --- a/misc/util.c +++ b/misc/util.c @@ -40,6 +40,13 @@ char* itoa(int i) { return a; } +char* dotlabel(char* n1, char* n2) { + int sz = (strlen(n1) + strlen(n2) + 2) * sizeof(char); + char* result = (char*)malloc(sz); + sprintf(result, "%s.%s", n1, n2); + return result; +} + STRINGLIST* onestr(const char* str) { STRINGLIST* strlist = (STRINGLIST*)malloc(sizeof(STRINGLIST)); strlist->content = ezheapstr(str); diff --git a/misc/util.h b/misc/util.h index 4e62c1f..f43fd84 100644 --- a/misc/util.h +++ b/misc/util.h @@ -27,6 +27,7 @@ char* ezheapstr(const char* str); int countplaces(int n); char* itoa(int i); void* copy(void* v, int size); +char* dotlabel(char* n1, char* n2); STRINGLIST* onestr(const char* str); STRINGLIST* initstrlist(const char** strs, int count);