Fix bugs, memory leaks and small fixes
This commit is contained in:
parent
e89b0696d7
commit
f1f4f1ef8a
|
@ -1,2 +1,2 @@
|
||||||
# jack-compiler
|
# jack-compiler
|
||||||
Jack language compiler, as specified in [nand2tetris project 10](https://www.nand2tetris.org/project10).<br>
|
Jack language compiler, as specified in [nand2tetris project 10](https://www.nand2tetris.org/project10) and [project 11](https://www.nand2tetris.org/project11)<br>
|
||||||
|
|
|
@ -207,11 +207,10 @@ LINEBLOCK* compileexpression(SCOPE* s, TERM* e) {
|
||||||
if(e != NULL) {
|
if(e != NULL) {
|
||||||
while(true) {
|
while(true) {
|
||||||
blk = mergelnblks(blk, compileterm(s, e));
|
blk = mergelnblks(blk, compileterm(s, e));
|
||||||
if(e->next != NULL) {
|
if(e->next == NULL)
|
||||||
appendln(blk, mathopln(e->op));
|
break;
|
||||||
e = e->next;
|
appendln(blk, mathopln(e->op));
|
||||||
}
|
e = e->next;
|
||||||
else break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return blk;
|
return blk;
|
||||||
|
|
|
@ -27,9 +27,9 @@ SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name);
|
||||||
VAR* mkvar(char* type, char* name, bool primitive, DEBUGINFO* debug, MEMSEGMENT seg, int i);
|
VAR* mkvar(char* type, char* name, bool primitive, DEBUGINFO* debug, MEMSEGMENT seg, int i);
|
||||||
void addvar(SCOPE* s, VAR** dest, VAR* v);
|
void addvar(SCOPE* s, VAR** dest, VAR* v);
|
||||||
void addlocalvar(SCOPE* s, VARDEC* v, int* i);
|
void addlocalvar(SCOPE* s, VARDEC* v, int* i);
|
||||||
void addstaticvar(COMPILER* c, SCOPE* s, CLASSVARDEC* v);
|
void addstaticvar(SCOPE* s, CLASSVARDEC* v);
|
||||||
void addfield(SCOPE* s, CLASSVARDEC* v, int* i);
|
void addfield(SCOPE* s, CLASSVARDEC* v, int* i);
|
||||||
void addclassvardec(COMPILER* c, SCOPE* s, CLASSVARDEC* v, int* i);
|
void addclassvardec(SCOPE* s, CLASSVARDEC* v, int* i);
|
||||||
void addparameter(SCOPE* s, PARAMETER* p, int* i);
|
void addparameter(SCOPE* s, PARAMETER* p, int* i);
|
||||||
|
|
||||||
// Error messages
|
// Error messages
|
||||||
|
@ -67,6 +67,8 @@ void ensurenoduplicate(SCOPE* s, char* name) {
|
||||||
SCOPE* mkscope(SCOPE* prev) {
|
SCOPE* mkscope(SCOPE* prev) {
|
||||||
SCOPE* s = (SCOPE*)malloc(sizeof(SCOPE));
|
SCOPE* s = (SCOPE*)malloc(sizeof(SCOPE));
|
||||||
s->previous = prev;
|
s->previous = prev;
|
||||||
|
if(prev != NULL)
|
||||||
|
s->compiler = prev->compiler;
|
||||||
s->localvars = NULL;
|
s->localvars = NULL;
|
||||||
s->fields = NULL;
|
s->fields = NULL;
|
||||||
s->staticvars = NULL;
|
s->staticvars = NULL;
|
||||||
|
@ -113,7 +115,7 @@ CLASS* getclass(SCOPE* s, const char* name) {
|
||||||
}
|
}
|
||||||
if(s->previous != NULL)
|
if(s->previous != NULL)
|
||||||
return getclass(s->previous, name);
|
return getclass(s->previous, name);
|
||||||
return getosclass(name);
|
return getosclass(s->compiler->os, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdecfromlist(SUBROUTDEC* start, char* name) {
|
SUBROUTDEC* getsubroutdecfromlist(SUBROUTDEC* start, char* name) {
|
||||||
|
@ -174,7 +176,7 @@ SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call, VAR** varret) {
|
||||||
SUBROUTDEC* d;
|
SUBROUTDEC* d;
|
||||||
*varret = NULL;
|
*varret = NULL;
|
||||||
if(call->parentname != NULL) {
|
if(call->parentname != NULL) {
|
||||||
d = getossubroutdec(call);
|
d = getossubroutdec(s->compiler->os, call);
|
||||||
if(d == NULL)
|
if(d == NULL)
|
||||||
d = getsubroutdecwithparent(s, call, varret);
|
d = getsubroutdecwithparent(s, call, varret);
|
||||||
}
|
}
|
||||||
|
@ -232,16 +234,16 @@ void addlocalvar(SCOPE* s, VARDEC* v, int* i) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addstaticvar(COMPILER* c, SCOPE* s, CLASSVARDEC* v) {
|
void addstaticvar(SCOPE* s, CLASSVARDEC* v) {
|
||||||
STRINGLIST* currname = v->base->names;
|
STRINGLIST* currname = v->base->names;
|
||||||
pthread_mutex_lock(&(c->staticmutex));
|
pthread_mutex_lock(&(s->compiler->staticmutex));
|
||||||
static int i = 0;
|
static int i = 0;
|
||||||
while(currname != NULL) {
|
while(currname != NULL) {
|
||||||
addvar(s, &(s->staticvars), mkvar(v->base->type, currname->content, v->base->primitive, v->base->debug, staticseg, i));
|
addvar(s, &(s->staticvars), mkvar(v->base->type, currname->content, v->base->primitive, v->base->debug, staticseg, i));
|
||||||
currname = currname->next;
|
currname = currname->next;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock(&(c->staticmutex));
|
pthread_mutex_unlock(&(s->compiler->staticmutex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addfield(SCOPE* s, CLASSVARDEC* v, int* i) {
|
void addfield(SCOPE* s, CLASSVARDEC* v, int* i) {
|
||||||
|
@ -253,9 +255,9 @@ void addfield(SCOPE* s, CLASSVARDEC* v, int* i) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void addclassvardec(COMPILER* c, SCOPE* s, CLASSVARDEC* v, int* i) {
|
void addclassvardec(SCOPE* s, CLASSVARDEC* v, int* i) {
|
||||||
if(v->type == stat)
|
if(v->type == stat)
|
||||||
addstaticvar(c, s, v);
|
addstaticvar(s, v);
|
||||||
else {
|
else {
|
||||||
addfield(s, v, i);
|
addfield(s, v, i);
|
||||||
}
|
}
|
||||||
|
@ -267,10 +269,10 @@ void addparameter(SCOPE* s, PARAMETER* p, int* i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group adding
|
// Group adding
|
||||||
void addclassvardecs(COMPILER* c, SCOPE* s, CLASSVARDEC* classvardecs) {
|
void addclassvardecs(SCOPE* s, CLASSVARDEC* classvardecs) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(classvardecs != NULL) {
|
while(classvardecs != NULL) {
|
||||||
addclassvardec(c, s, classvardecs, &i);
|
addclassvardec(s, classvardecs, &i);
|
||||||
classvardecs = classvardecs->next;
|
classvardecs = classvardecs->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,3 +292,19 @@ void addparameters(SCOPE* s, bool isformethod, PARAMETER* params) {
|
||||||
params = params->next;
|
params = params->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void freevars(VAR* v) {
|
||||||
|
if(v != NULL) {
|
||||||
|
VAR* next = v->next;
|
||||||
|
free(v);
|
||||||
|
freevars(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freescope(SCOPE* s) {
|
||||||
|
freevars(s->fields);
|
||||||
|
freevars(s->staticvars);
|
||||||
|
freevars(s->localvars);
|
||||||
|
freevars(s->parameters);
|
||||||
|
free(s);
|
||||||
|
};
|
||||||
|
|
|
@ -21,6 +21,7 @@ typedef struct var {
|
||||||
} VAR;
|
} VAR;
|
||||||
|
|
||||||
typedef struct scope {
|
typedef struct scope {
|
||||||
|
struct compiler* compiler;
|
||||||
DEBUGINFO* currdebug;
|
DEBUGINFO* currdebug;
|
||||||
CLASS* currclass;
|
CLASS* currclass;
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ typedef struct scope {
|
||||||
struct compiler;
|
struct compiler;
|
||||||
|
|
||||||
// Group adding
|
// Group adding
|
||||||
void addclassvardecs(struct compiler* c, SCOPE* s, CLASSVARDEC* classvardecs);
|
void addclassvardecs(SCOPE* s, CLASSVARDEC* classvardecs);
|
||||||
void addlocalvars(SCOPE* s, VARDEC* localvars);
|
void addlocalvars(SCOPE* s, VARDEC* localvars);
|
||||||
void addparameters(SCOPE* s, bool isformethod, PARAMETER* params);
|
void addparameters(SCOPE* s, bool isformethod, PARAMETER* params);
|
||||||
|
|
||||||
|
@ -51,4 +52,7 @@ CLASS* getclass(SCOPE* s, const char* name);
|
||||||
|
|
||||||
// Generic getters
|
// Generic getters
|
||||||
VAR* getvar(SCOPE* s, const char* name);
|
VAR* getvar(SCOPE* s, const char* name);
|
||||||
|
|
||||||
|
// Freeing
|
||||||
|
void freescope(SCOPE* s);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,10 +13,10 @@ char* mkcondlabel(char* name, int count);
|
||||||
|
|
||||||
// Handling individual statements
|
// Handling individual statements
|
||||||
LINEBLOCK* compileret(SCOPE* s, TERM* e);
|
LINEBLOCK* compileret(SCOPE* s, TERM* e);
|
||||||
LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st);
|
LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st);
|
||||||
LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w);
|
LINEBLOCK* compilewhile(SCOPE* s, CONDSTATEMENT* w);
|
||||||
LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l);
|
LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l);
|
||||||
LINEBLOCK* compilestatement(COMPILER* c, SCOPE* s, STATEMENT* st);
|
LINEBLOCK* compilestatement(SCOPE* s, STATEMENT* st);
|
||||||
|
|
||||||
/* END FORWARD DECLARATIONS */
|
/* END FORWARD DECLARATIONS */
|
||||||
|
|
||||||
|
@ -55,14 +55,14 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) {
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st) {
|
||||||
LINEBLOCK* blk = compileexpression(s, st->base->expression);
|
LINEBLOCK* blk = compileexpression(s, st->base->expression);
|
||||||
|
|
||||||
pthread_mutex_lock(&(c->ifmutex));
|
pthread_mutex_lock(&(s->compiler->ifmutex));
|
||||||
static int ifcount = 0;
|
static int ifcount = 0;
|
||||||
int mycount = ifcount;
|
int mycount = ifcount;
|
||||||
ifcount++;
|
ifcount++;
|
||||||
pthread_mutex_unlock(&(c->ifmutex));
|
pthread_mutex_unlock(&(s->compiler->ifmutex));
|
||||||
|
|
||||||
char* truelabel = mkcondlabel("IF_TRUE", mycount);
|
char* truelabel = mkcondlabel("IF_TRUE", mycount);
|
||||||
char* ifgoto[] = { "if-goto", truelabel };
|
char* ifgoto[] = { "if-goto", truelabel };
|
||||||
|
@ -75,7 +75,7 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
||||||
char* truelabelln[] = { "label", truelabel };
|
char* truelabelln[] = { "label", truelabel };
|
||||||
appendln(blk, mkln(truelabelln));
|
appendln(blk, mkln(truelabelln));
|
||||||
|
|
||||||
blk = mergelnblks(blk, compilestatements(c, s, st->base->statements));
|
blk = mergelnblks(blk, compilestatements(s, st->base->statements));
|
||||||
|
|
||||||
char* endlabel;
|
char* endlabel;
|
||||||
bool haselse = st->elsestatements != NULL;
|
bool haselse = st->elsestatements != NULL;
|
||||||
|
@ -89,7 +89,7 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
||||||
appendln(blk, mkln(falselabelln));
|
appendln(blk, mkln(falselabelln));
|
||||||
|
|
||||||
if(haselse) {
|
if(haselse) {
|
||||||
blk = mergelnblks(blk, compilestatements(c, s, st->elsestatements));
|
blk = mergelnblks(blk, compilestatements(s, st->elsestatements));
|
||||||
char* endlabelln[] = { "label", endlabel };
|
char* endlabelln[] = { "label", endlabel };
|
||||||
appendln(blk, mkln(endlabelln));
|
appendln(blk, mkln(endlabelln));
|
||||||
free(endlabel);
|
free(endlabel);
|
||||||
|
@ -101,14 +101,14 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w) {
|
LINEBLOCK* compilewhile(SCOPE* s, CONDSTATEMENT* w) {
|
||||||
LINEBLOCK* blk = compileexpression(s, w->expression);
|
LINEBLOCK* blk = compileexpression(s, w->expression);
|
||||||
|
|
||||||
pthread_mutex_lock(&(c->whilemutex));
|
pthread_mutex_lock(&(s->compiler->whilemutex));
|
||||||
static int whilecount = 0;
|
static int whilecount = 0;
|
||||||
int mycount = whilecount;
|
int mycount = whilecount;
|
||||||
whilecount++;
|
whilecount++;
|
||||||
pthread_mutex_unlock(&(c->whilemutex));
|
pthread_mutex_unlock(&(s->compiler->whilemutex));
|
||||||
|
|
||||||
char* explabel = mkcondlabel("WHILE_EXP", mycount);
|
char* explabel = mkcondlabel("WHILE_EXP", mycount);
|
||||||
char* explabelln[] = { "label", explabel };
|
char* explabelln[] = { "label", explabel };
|
||||||
|
@ -120,7 +120,7 @@ LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w) {
|
||||||
char* ifgoto[] = { "if-goto", endlabel };
|
char* ifgoto[] = { "if-goto", endlabel };
|
||||||
appendln(blk, mkln(ifgoto));
|
appendln(blk, mkln(ifgoto));
|
||||||
|
|
||||||
blk = mergelnblks(blk, compilestatements(c, s, w->statements));
|
blk = mergelnblks(blk, compilestatements(s, w->statements));
|
||||||
|
|
||||||
char* gotoln[] = { "goto", explabel };
|
char* gotoln[] = { "goto", explabel };
|
||||||
appendln(blk, mkln(gotoln));
|
appendln(blk, mkln(gotoln));
|
||||||
|
@ -152,21 +152,19 @@ LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l) {
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilestatement(COMPILER* c, SCOPE* s, STATEMENT* st) {
|
LINEBLOCK* compilestatement(SCOPE* s, STATEMENT* st) {
|
||||||
s->currdebug = st->debug;
|
s->currdebug = st->debug;
|
||||||
if(st->type == dostatement) return compilesubroutcall(s, st->dostatement);
|
if(st->type == dostatement) return compilesubroutcall(s, st->dostatement);
|
||||||
if(st->type == returnstatement) return compileret(s, st->retstatement);
|
if(st->type == returnstatement) return compileret(s, st->retstatement);
|
||||||
if(st->type == ifstatement) return compileif(c, s, st->ifstatement);
|
if(st->type == ifstatement) return compileif(s, st->ifstatement);
|
||||||
if(st->type == whilestatement) return compilewhile(c, s, st->whilestatement);
|
if(st->type == whilestatement) return compilewhile(s, st->whilestatement);
|
||||||
if(st->type == letstatement) return compilelet(s, st->letstatement);
|
return compilelet(s, st->letstatement);
|
||||||
eprintf("UNSUPPORTED type %i\n", st->type);
|
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilestatements(COMPILER* c, SCOPE* s, STATEMENT* sts) {
|
LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts) {
|
||||||
LINEBLOCK* head = NULL;
|
LINEBLOCK* head = NULL;
|
||||||
while(sts != NULL) {
|
while(sts != NULL) {
|
||||||
head = mergelnblks(head, compilestatement(c, s, sts));
|
head = mergelnblks(head, compilestatement(s, sts));
|
||||||
sts = sts->next;
|
sts = sts->next;
|
||||||
}
|
}
|
||||||
return head;
|
return head;
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
/* compiler-statements
|
/* compiler-statements
|
||||||
* Single function for compiling statements */
|
* Single function for compiling statements */
|
||||||
|
|
||||||
LINEBLOCK* compilestatements(COMPILER* c, SCOPE* s, STATEMENT* sts);
|
LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -12,10 +12,10 @@ int getobjsize(CLASS* c);
|
||||||
LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd);
|
LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd);
|
||||||
|
|
||||||
// Compiling methods
|
// Compiling methods
|
||||||
LINEBLOCK* compilefunbody(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTBODY* b);
|
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTBODY* b);
|
||||||
LINEBLOCK* compilefundec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* f);
|
LINEBLOCK* compilefundec(SCOPE* s, CLASS* cl, SUBROUTDEC* f);
|
||||||
LINEBLOCK* compileconstructor(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* con);
|
LINEBLOCK* compileconstructor(SCOPE* s, CLASS* cl, SUBROUTDEC* con);
|
||||||
LINEBLOCK* compilemethod(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* m);
|
LINEBLOCK* compilemethod(SCOPE* s, CLASS* cl, SUBROUTDEC* m);
|
||||||
|
|
||||||
/* END FORWARD DECLARATIONS */
|
/* END FORWARD DECLARATIONS */
|
||||||
|
|
||||||
|
@ -64,20 +64,21 @@ LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compiling methods
|
// Compiling methods
|
||||||
LINEBLOCK* compilefunbody(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTBODY* b) {
|
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTBODY* b) {
|
||||||
SCOPE* myscope = mkscope(s);
|
SCOPE* myscope = mkscope(s);
|
||||||
myscope->currclass = cl;
|
myscope->currclass = cl;
|
||||||
if(b->vardecs != NULL)
|
if(b->vardecs != NULL)
|
||||||
addlocalvars(s, b->vardecs);
|
addlocalvars(myscope, b->vardecs);
|
||||||
LINEBLOCK* head = compilestatements(c, myscope, b->statements);
|
LINEBLOCK* head = compilestatements(myscope, b->statements);
|
||||||
|
freescope(myscope);
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilefundec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* f) {
|
LINEBLOCK* compilefundec(SCOPE* s, CLASS* cl, SUBROUTDEC* f) {
|
||||||
LINE* label = mksubdeclabel(cl, f);
|
LINE* label = mksubdeclabel(cl, f);
|
||||||
|
|
||||||
if(f->body->statements != NULL) {
|
if(f->body->statements != NULL) {
|
||||||
LINEBLOCK* body = compilefunbody(c, s, cl, f->body);
|
LINEBLOCK* body = compilefunbody(s, cl, f->body);
|
||||||
appendlnbefore(body, label);
|
appendlnbefore(body, label);
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
@ -85,7 +86,7 @@ LINEBLOCK* compilefundec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* f) {
|
||||||
return mklnblk(label);
|
return mklnblk(label);
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compileconstructor(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* con) {
|
LINEBLOCK* compileconstructor(SCOPE* s, CLASS* cl, SUBROUTDEC* con) {
|
||||||
LINE* label = mksubdeclabel(cl, con);
|
LINE* label = mksubdeclabel(cl, con);
|
||||||
LINEBLOCK* blk = mklnblk(label);
|
LINEBLOCK* blk = mklnblk(label);
|
||||||
|
|
||||||
|
@ -98,12 +99,12 @@ LINEBLOCK* compileconstructor(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* con)
|
||||||
free(size[2]);
|
free(size[2]);
|
||||||
|
|
||||||
if(con->body != NULL)
|
if(con->body != NULL)
|
||||||
return mergelnblks(blk, compilefunbody(c, s, cl, con->body));
|
return mergelnblks(blk, compilefunbody(s, cl, con->body));
|
||||||
else
|
else
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilemethod(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* m) {
|
LINEBLOCK* compilemethod(SCOPE* s, CLASS* cl, SUBROUTDEC* m) {
|
||||||
LINE* label = mksubdeclabel(cl, m);
|
LINE* label = mksubdeclabel(cl, m);
|
||||||
LINEBLOCK* blk = mklnblk(label);
|
LINEBLOCK* blk = mklnblk(label);
|
||||||
|
|
||||||
|
@ -113,18 +114,22 @@ LINEBLOCK* compilemethod(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* m) {
|
||||||
appendln(blk, mkln(poppointer));
|
appendln(blk, mkln(poppointer));
|
||||||
|
|
||||||
if(m->body != NULL)
|
if(m->body != NULL)
|
||||||
return mergelnblks(blk, compilefunbody(c, s, cl, m->body));
|
return mergelnblks(blk, compilefunbody(s, cl, m->body));
|
||||||
else
|
else
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilesubroutdec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* sd) {
|
LINEBLOCK* compilesubroutdec(SCOPE* s, CLASS* cl, SUBROUTDEC* sd) {
|
||||||
SCOPE* myscope = mkscope(s);
|
SCOPE* myscope = mkscope(s);
|
||||||
|
LINEBLOCK* blk;
|
||||||
if(sd->parameters != NULL)
|
if(sd->parameters != NULL)
|
||||||
addparameters(myscope, sd->subroutclass == method, sd->parameters);
|
addparameters(myscope, sd->subroutclass == method, sd->parameters);
|
||||||
if(sd->subroutclass == function)
|
if(sd->subroutclass == function)
|
||||||
return compilefundec(c, myscope, cl, sd);
|
blk = compilefundec(myscope, cl, sd);
|
||||||
if(sd->subroutclass == constructor)
|
else if(sd->subroutclass == constructor)
|
||||||
return compileconstructor(c, myscope, cl, sd);
|
blk = compileconstructor(myscope, cl, sd);
|
||||||
return compilemethod(c, myscope, cl, sd);
|
else
|
||||||
|
blk = compilemethod(myscope, cl, sd);
|
||||||
|
freescope(myscope);
|
||||||
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,5 +5,5 @@
|
||||||
/* compiler-structure
|
/* compiler-structure
|
||||||
* Module for dealing with and compiling general program structure. */
|
* Module for dealing with and compiling general program structure. */
|
||||||
|
|
||||||
LINEBLOCK* compilesubroutdec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* sd);
|
LINEBLOCK* compilesubroutdec(SCOPE* s, CLASS* cl, SUBROUTDEC* sd);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include "os.h"
|
||||||
#include "compiler-structure.h"
|
#include "compiler-structure.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
|
||||||
|
@ -7,24 +8,27 @@
|
||||||
LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
|
LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
|
||||||
SCOPE* topscope = mkscope(c->globalscope);
|
SCOPE* topscope = mkscope(c->globalscope);
|
||||||
if(class->vardecs != NULL)
|
if(class->vardecs != NULL)
|
||||||
addclassvardecs(c, topscope, class->vardecs);
|
addclassvardecs(topscope, class->vardecs);
|
||||||
if(class->subroutdecs != NULL)
|
if(class->subroutdecs != NULL)
|
||||||
topscope->subroutines = class->subroutdecs;
|
topscope->subroutines = class->subroutdecs;
|
||||||
|
|
||||||
LINEBLOCK* output = NULL;
|
LINEBLOCK* output = NULL;
|
||||||
SUBROUTDEC* curr = class->subroutdecs;
|
SUBROUTDEC* curr = class->subroutdecs;
|
||||||
while(curr != NULL) {
|
while(curr != NULL) {
|
||||||
output = mergelnblks(output, compilesubroutdec(c, topscope, class, curr));
|
output = mergelnblks(output, compilesubroutdec(topscope, class, curr));
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
|
freescope(topscope);
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
COMPILER* mkcompiler(CLASS* classes) {
|
COMPILER* mkcompiler(CLASS* classes) {
|
||||||
COMPILER* c = (COMPILER*)malloc(sizeof(COMPILER));
|
COMPILER* c = (COMPILER*)malloc(sizeof(COMPILER));
|
||||||
c->globalscope = mkscope(NULL);
|
c->globalscope = mkscope(NULL);
|
||||||
|
c->globalscope->compiler = c;
|
||||||
c->globalscope->classes = classes;
|
c->globalscope->classes = classes;
|
||||||
c->classes = classes;
|
c->classes = classes;
|
||||||
|
c->os = mkos();
|
||||||
pthread_mutex_init(&(c->ifmutex), NULL);
|
pthread_mutex_init(&(c->ifmutex), NULL);
|
||||||
pthread_mutex_init(&(c->whilemutex), NULL);
|
pthread_mutex_init(&(c->whilemutex), NULL);
|
||||||
pthread_mutex_init(&(c->staticmutex), NULL);
|
pthread_mutex_init(&(c->staticmutex), NULL);
|
||||||
|
@ -36,5 +40,7 @@ void freecompiler(COMPILER* c) {
|
||||||
pthread_mutex_destroy(&(c->whilemutex));
|
pthread_mutex_destroy(&(c->whilemutex));
|
||||||
pthread_mutex_destroy(&(c->staticmutex));
|
pthread_mutex_destroy(&(c->staticmutex));
|
||||||
// to be continued
|
// to be continued
|
||||||
|
freeos(c->os);
|
||||||
|
freescope(c->globalscope);
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ typedef struct compiler {
|
||||||
pthread_mutex_t whilemutex;
|
pthread_mutex_t whilemutex;
|
||||||
pthread_mutex_t staticmutex;
|
pthread_mutex_t staticmutex;
|
||||||
CLASS* classes;
|
CLASS* classes;
|
||||||
|
CLASS* os;
|
||||||
struct scope* globalscope;
|
struct scope* globalscope;
|
||||||
} COMPILER;
|
} COMPILER;
|
||||||
|
|
||||||
|
|
13
main.c
13
main.c
|
@ -20,13 +20,13 @@ int main(int argc, char* argv[]) {
|
||||||
COMPILEUNIT* head = (COMPILEUNIT*)malloc(sizeof(COMPILEUNIT));
|
COMPILEUNIT* head = (COMPILEUNIT*)malloc(sizeof(COMPILEUNIT));
|
||||||
|
|
||||||
head->file = files;
|
head->file = files;
|
||||||
head->tokens = tokenize(files->fullname);
|
head->parser = mkparser(tokenize(files->fullname), files->name);
|
||||||
|
|
||||||
COMPILEUNIT* currunit = head;
|
COMPILEUNIT* currunit = head;
|
||||||
while(curr != NULL) {
|
while(curr != NULL) {
|
||||||
COMPILEUNIT* newunit = (COMPILEUNIT*)malloc(sizeof(COMPILEUNIT));
|
COMPILEUNIT* newunit = (COMPILEUNIT*)malloc(sizeof(COMPILEUNIT));
|
||||||
newunit->file = curr;
|
newunit->file = curr;
|
||||||
newunit->tokens = tokenize(curr->fullname);
|
newunit->parser = mkparser(tokenize(curr->fullname), curr->name);
|
||||||
currunit->next = newunit;
|
currunit->next = newunit;
|
||||||
currunit = newunit;
|
currunit = newunit;
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
|
@ -52,7 +52,6 @@ int main(int argc, char* argv[]) {
|
||||||
currunit = currunit->next;
|
currunit = currunit->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
populateos();
|
|
||||||
actonunits(head, compileunit);
|
actonunits(head, compileunit);
|
||||||
|
|
||||||
currunit = head;
|
currunit = head;
|
||||||
|
@ -64,9 +63,13 @@ int main(int argc, char* argv[]) {
|
||||||
}
|
}
|
||||||
printlns(currunit->compiled->head, output);
|
printlns(currunit->compiled->head, output);
|
||||||
fclose(output);
|
fclose(output);
|
||||||
currunit = currunit->next;
|
COMPILEUNIT* next = currunit->next;
|
||||||
|
freeunit(currunit);
|
||||||
|
currunit = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
//freeos();
|
freecompiler(compiler);
|
||||||
|
freetree(headclass);
|
||||||
|
freefilelist(files);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ char* getoutname(char* fullname, int len) {
|
||||||
int sz = sizeof(char) * (len-1);
|
int sz = sizeof(char) * (len-1);
|
||||||
char* outname = (char*)malloc(sz);
|
char* outname = (char*)malloc(sz);
|
||||||
sprintf(outname, "%svm", trimmed);
|
sprintf(outname, "%svm", trimmed);
|
||||||
|
free(trimmed);
|
||||||
return outname;
|
return outname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +172,9 @@ FILELIST* getfiles(char* input) {
|
||||||
void freefilelist(FILELIST* fs) {
|
void freefilelist(FILELIST* fs) {
|
||||||
free(fs->name);
|
free(fs->name);
|
||||||
free(fs->fullname);
|
free(fs->fullname);
|
||||||
if(fs->next != NULL)
|
free(fs->outname);
|
||||||
freefilelist(fs->next);
|
FILELIST* next = fs->next;
|
||||||
|
free(fs);
|
||||||
|
if(next != NULL)
|
||||||
|
freefilelist(next);
|
||||||
}
|
}
|
||||||
|
|
98
misc/os.c
98
misc/os.c
|
@ -3,14 +3,11 @@
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
CLASS* classes = NULL;
|
CLASS* mkosclass(CLASS* os, const char* name) {
|
||||||
|
|
||||||
CLASS* addclass(const char* name) {
|
|
||||||
CLASS* c = (CLASS*)malloc(sizeof(CLASS));
|
CLASS* c = (CLASS*)malloc(sizeof(CLASS));
|
||||||
c->name = ezheapstr(name);
|
c->name = ezheapstr(name);
|
||||||
c->subroutdecs = NULL;
|
c->subroutdecs = NULL;
|
||||||
c->next = classes;
|
c->next = os;
|
||||||
classes = c;
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,24 +15,25 @@ void adddec(CLASS* c, SUBROUTCLASS subroutclass, char* type, const char* name) {
|
||||||
SUBROUTDEC* dec = (SUBROUTDEC*)malloc(sizeof(SUBROUTDEC));
|
SUBROUTDEC* dec = (SUBROUTDEC*)malloc(sizeof(SUBROUTDEC));
|
||||||
dec->class = c;
|
dec->class = c;
|
||||||
dec->subroutclass = subroutclass;
|
dec->subroutclass = subroutclass;
|
||||||
dec->type = type;
|
|
||||||
dec->name = ezheapstr(name);
|
dec->name = ezheapstr(name);
|
||||||
|
dec->type = ezheapstr(type);
|
||||||
dec->next = c->subroutdecs;
|
dec->next = c->subroutdecs;
|
||||||
c->subroutdecs = dec;
|
c->subroutdecs = dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populatemath() {
|
CLASS* mkmath(CLASS* os) {
|
||||||
CLASS* mathclass = addclass("Math");
|
CLASS* mathclass = mkosclass(os, "Math");
|
||||||
adddec(mathclass, function, "int", "multiply");
|
adddec(mathclass, function, "int", "multiply");
|
||||||
adddec(mathclass, function, "int", "divide");
|
adddec(mathclass, function, "int", "divide");
|
||||||
adddec(mathclass, function, "int", "abs");
|
adddec(mathclass, function, "int", "abs");
|
||||||
adddec(mathclass, function, "int", "min");
|
adddec(mathclass, function, "int", "min");
|
||||||
adddec(mathclass, function, "int", "max");
|
adddec(mathclass, function, "int", "max");
|
||||||
adddec(mathclass, function, "int", "sqrt");
|
adddec(mathclass, function, "int", "sqrt");
|
||||||
|
return mathclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populatestringclass() {
|
CLASS* mkstringclass(CLASS* os) {
|
||||||
CLASS* strclass = addclass("String");
|
CLASS* strclass = mkosclass(os, "String");
|
||||||
adddec(strclass, constructor, "String", "new");
|
adddec(strclass, constructor, "String", "new");
|
||||||
adddec(strclass, method, "int", "dispose");
|
adddec(strclass, method, "int", "dispose");
|
||||||
adddec(strclass, method, "int", "length");
|
adddec(strclass, method, "int", "length");
|
||||||
|
@ -48,84 +46,96 @@ void populatestringclass() {
|
||||||
adddec(strclass, function, "char", "backSpace");
|
adddec(strclass, function, "char", "backSpace");
|
||||||
adddec(strclass, function, "char", "doubleQuote");
|
adddec(strclass, function, "char", "doubleQuote");
|
||||||
adddec(strclass, function, "char", "newLine");
|
adddec(strclass, function, "char", "newLine");
|
||||||
|
return strclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populatearray() {
|
CLASS* mkarray(CLASS* os) {
|
||||||
CLASS* arrclass = addclass("Array");
|
CLASS* arrclass = mkosclass(os, "Array");
|
||||||
adddec(arrclass, function, "Array", "new");
|
adddec(arrclass, function, "Array", "new");
|
||||||
adddec(arrclass, method, "void", "dispose");
|
adddec(arrclass, method, "void", "dispose");
|
||||||
|
return arrclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateoutput() {
|
CLASS* mkoutput(CLASS* os) {
|
||||||
CLASS* outclass = addclass("Output");
|
CLASS* outclass = mkosclass(os, "Output");
|
||||||
adddec(outclass, function, "void", "moveCursor");
|
adddec(outclass, function, "void", "moveCursor");
|
||||||
adddec(outclass, function, "void", "printChar");
|
adddec(outclass, function, "void", "printChar");
|
||||||
adddec(outclass, function, "void", "printString");
|
adddec(outclass, function, "void", "printString");
|
||||||
adddec(outclass, function, "void", "printInt");
|
adddec(outclass, function, "void", "printInt");
|
||||||
adddec(outclass, function, "void", "println");
|
adddec(outclass, function, "void", "println");
|
||||||
adddec(outclass, function, "void", "backSpace");
|
adddec(outclass, function, "void", "backSpace");
|
||||||
|
return outclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populatescreen() {
|
CLASS* mkscreen(CLASS* os) {
|
||||||
CLASS* scrclass = addclass("Screen");
|
CLASS* scrclass = mkosclass(os, "Screen");
|
||||||
adddec(scrclass, function, "void", "clearScreen");
|
adddec(scrclass, function, "void", "clearScreen");
|
||||||
adddec(scrclass, function, "void", "setColor");
|
adddec(scrclass, function, "void", "setColor");
|
||||||
adddec(scrclass, function, "void", "drawPixel");
|
adddec(scrclass, function, "void", "drawPixel");
|
||||||
adddec(scrclass, function, "void", "drawLine");
|
adddec(scrclass, function, "void", "drawLine");
|
||||||
adddec(scrclass, function, "void", "drawRectangle");
|
adddec(scrclass, function, "void", "drawRectangle");
|
||||||
adddec(scrclass, function, "void", "drawCircle");
|
adddec(scrclass, function, "void", "drawCircle");
|
||||||
|
return scrclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populatekeyboard() {
|
CLASS* mkkeyboard(CLASS* os) {
|
||||||
CLASS* kbdclass = addclass("Keyboard");
|
CLASS* kbdclass = mkosclass(os, "Keyboard");
|
||||||
adddec(kbdclass, function, "char", "keyPressed");
|
adddec(kbdclass, function, "char", "keyPressed");
|
||||||
adddec(kbdclass, function, "char", "readChar");
|
adddec(kbdclass, function, "char", "readChar");
|
||||||
adddec(kbdclass, function, "String", "readLine");
|
adddec(kbdclass, function, "String", "readLine");
|
||||||
adddec(kbdclass, function, "int", "readInt");
|
adddec(kbdclass, function, "int", "readInt");
|
||||||
|
return kbdclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populatememory() {
|
CLASS* mkmemory(CLASS* os) {
|
||||||
CLASS* memclass = addclass("Memory");
|
CLASS* memclass = mkosclass(os, "Memory");
|
||||||
adddec(memclass, function, "int", "peek");
|
adddec(memclass, function, "int", "peek");
|
||||||
adddec(memclass, function, "void", "poke");
|
adddec(memclass, function, "void", "poke");
|
||||||
adddec(memclass, function, "Array", "alloc");
|
adddec(memclass, function, "Array", "alloc");
|
||||||
adddec(memclass, function, "void", "deAlloc");
|
adddec(memclass, function, "void", "deAlloc");
|
||||||
|
return memclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populatesys() {
|
CLASS* mksys(CLASS* os) {
|
||||||
CLASS* sysclass = addclass("Sys");
|
CLASS* sysclass = mkosclass(os, "Sys");
|
||||||
adddec(sysclass, function, "void", "halt");
|
adddec(sysclass, function, "void", "halt");
|
||||||
adddec(sysclass, function, "void", "error");
|
adddec(sysclass, function, "void", "error");
|
||||||
adddec(sysclass, function, "void", "wait");
|
adddec(sysclass, function, "void", "wait");
|
||||||
|
return sysclass;
|
||||||
}
|
}
|
||||||
|
|
||||||
void populateos() {
|
CLASS* mkos() {
|
||||||
populatemath();
|
CLASS* os = mkmath(NULL);
|
||||||
populatestringclass();
|
os = mkstringclass(os);
|
||||||
populatearray();
|
os = mkarray(os);
|
||||||
populateoutput();
|
os = mkoutput(os);
|
||||||
populatescreen();
|
os = mkscreen(os);
|
||||||
populatekeyboard();
|
os = mkkeyboard(os);
|
||||||
populatememory();
|
os = mkmemory(os);
|
||||||
populatesys();
|
os = mksys(os);
|
||||||
|
return os;
|
||||||
}
|
}
|
||||||
|
|
||||||
void freesubroutdecs(SUBROUTDEC* d) {
|
void freeossubroutdecs(SUBROUTDEC* d) {
|
||||||
free(d->name);
|
free(d->name);
|
||||||
free(d->type);
|
free(d->type);
|
||||||
if(d->next != NULL)
|
SUBROUTDEC* next = d->next;
|
||||||
freesubroutdecs(d->next);
|
free(d);
|
||||||
|
if(next != NULL)
|
||||||
|
freeossubroutdecs(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeclasses(CLASS* c) {
|
void freeosclasses(CLASS* c) {
|
||||||
freesubroutdecs(c->subroutdecs);
|
freeossubroutdecs(c->subroutdecs);
|
||||||
free(c->name);
|
free(c->name);
|
||||||
if(c->next != NULL)
|
CLASS* next = c->next;
|
||||||
freeclasses(c->next);
|
free(c);
|
||||||
|
if(next != NULL)
|
||||||
|
freeosclasses(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeos() {
|
void freeos(CLASS* os) {
|
||||||
freeclasses(classes);
|
freeosclasses(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdecinclass(CLASS* c, const char* name) {
|
SUBROUTDEC* getsubroutdecinclass(CLASS* c, const char* name) {
|
||||||
|
@ -138,8 +148,8 @@ SUBROUTDEC* getsubroutdecinclass(CLASS* c, const char* name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASS* getosclass(const char* name) {
|
CLASS* getosclass(CLASS* os, const char* name) {
|
||||||
CLASS* curr = classes;
|
CLASS* curr = os;
|
||||||
while(curr != NULL) {
|
while(curr != NULL) {
|
||||||
if(!strcmp(curr->name, name))
|
if(!strcmp(curr->name, name))
|
||||||
return curr;
|
return curr;
|
||||||
|
@ -148,8 +158,8 @@ CLASS* getosclass(const char* name) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getossubroutdec(SUBROUTCALL* call) {
|
SUBROUTDEC* getossubroutdec(CLASS* os, SUBROUTCALL* call) {
|
||||||
CLASS* c = getosclass(call->parentname);
|
CLASS* c = getosclass(os, call->parentname);
|
||||||
if(c == NULL)
|
if(c == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
return getsubroutdecinclass(c, call->name);
|
return getsubroutdecinclass(c, call->name);
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
#define OS_H
|
#define OS_H
|
||||||
#include "parser-tree.h"
|
#include "parser-tree.h"
|
||||||
|
|
||||||
SUBROUTDEC* getossubroutdec(SUBROUTCALL* call);
|
SUBROUTDEC* getossubroutdec(CLASS* os, SUBROUTCALL* call);
|
||||||
CLASS* getosclass(const char* name);
|
CLASS* getosclass(CLASS* os, const char* name);
|
||||||
void populateos();
|
CLASS* mkos();
|
||||||
void freeos();
|
void freeos(CLASS* os);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
void* parseunit(void* input) {
|
void* parseunit(void* input) {
|
||||||
COMPILEUNIT* unit = (COMPILEUNIT*)input;
|
COMPILEUNIT* unit = (COMPILEUNIT*)input;
|
||||||
|
|
||||||
unit->parsed = parse(unit->tokens, unit->file->name);
|
unit->parsed = parse(unit->parser);
|
||||||
|
|
||||||
pthread_exit(NULL);
|
pthread_exit(NULL);
|
||||||
}
|
}
|
||||||
|
@ -60,3 +60,9 @@ void actonunits(COMPILEUNIT* units, void*(*fun)(void*)) {
|
||||||
|
|
||||||
pthread_attr_destroy(&attr);
|
pthread_attr_destroy(&attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void freeunit(COMPILEUNIT* u) {
|
||||||
|
freeparser(u->parser);
|
||||||
|
freelnblk(u->compiled);
|
||||||
|
free(u);
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
typedef struct unit {
|
typedef struct unit {
|
||||||
FILELIST* file;
|
FILELIST* file;
|
||||||
TOKEN* tokens;
|
PARSER* parser;
|
||||||
CLASS* parsed;
|
CLASS* parsed;
|
||||||
COMPILER* compiler;
|
COMPILER* compiler;
|
||||||
LINEBLOCK* compiled;
|
LINEBLOCK* compiled;
|
||||||
|
@ -21,4 +21,5 @@ void* parseunit(void* input);
|
||||||
void* compileunit(void* input);
|
void* compileunit(void* input);
|
||||||
void waitthreads(pthread_t* threads, int amount);
|
void waitthreads(pthread_t* threads, int amount);
|
||||||
void actonunits(COMPILEUNIT* units, void*(*fun)(void*));
|
void actonunits(COMPILEUNIT* units, void*(*fun)(void*));
|
||||||
|
void freeunit(COMPILEUNIT* u);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -166,6 +166,7 @@ TERM* parseexpression(PARSER* p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTCALL* nullsubroutcall(PARSER* p, SUBROUTCALL* c) {
|
SUBROUTCALL* nullsubroutcall(PARSER* p, SUBROUTCALL* c) {
|
||||||
|
free(c->debug);
|
||||||
free(c);
|
free(c);
|
||||||
rewindparser(p);
|
rewindparser(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -167,9 +167,9 @@ SUBROUTDEC* parsesubroutdecs(PARSER* p, CLASS* c) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PARAMETER* parseparameter(PARSER* p) {
|
PARAMETER* parseparameter(PARSER* p) {
|
||||||
PARAMETER* param = (PARAMETER*)malloc(sizeof(PARAMETER));
|
|
||||||
if(equals(p, ")"))
|
if(equals(p, ")"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
PARAMETER* param = (PARAMETER*)malloc(sizeof(PARAMETER));
|
||||||
param->debug = getdebug(p);
|
param->debug = getdebug(p);
|
||||||
param->primitive = isprimitive(p->current);
|
param->primitive = isprimitive(p->current);
|
||||||
param->type = parsetype(p);
|
param->type = parsetype(p);
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "parser-tree.h"
|
||||||
|
|
||||||
|
void freeexpression(TERM* e);
|
||||||
|
void freeexpressionlist(EXPRESSIONLIST* el);
|
||||||
|
void freestatements(STATEMENT* s);
|
||||||
|
|
||||||
|
void freevardec(VARDEC* v) {
|
||||||
|
freestrlist(v->names);
|
||||||
|
free(v->debug);
|
||||||
|
free(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freevardecs(VARDEC* v) {
|
||||||
|
VARDEC* next = v->next;
|
||||||
|
freevardec(v);
|
||||||
|
if(next != NULL)
|
||||||
|
freevardecs(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeparameters(PARAMETER* p) {
|
||||||
|
free(p->debug);
|
||||||
|
PARAMETER* next = p->next;
|
||||||
|
free(p);
|
||||||
|
if(next != NULL)
|
||||||
|
freeparameters(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freearray(ARRAY* a) {
|
||||||
|
freeexpression(a->exp);
|
||||||
|
free(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freesubroutcall(SUBROUTCALL* call) {
|
||||||
|
if(call->parameters != NULL)
|
||||||
|
freeexpressionlist(call->parameters);
|
||||||
|
free(call->debug);
|
||||||
|
free(call);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeexpression(TERM* e) {
|
||||||
|
if(e->type == arrayitem)
|
||||||
|
freearray(e->array);
|
||||||
|
else if(e->type == innerexpression || e->type == unaryopterm)
|
||||||
|
freeexpression(e->expression);
|
||||||
|
else if(e->type == subroutcall)
|
||||||
|
freesubroutcall(e->call);
|
||||||
|
TERM* next = e->next;
|
||||||
|
free(e);
|
||||||
|
if(next != NULL)
|
||||||
|
freeexpression(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeexpressionlist(EXPRESSIONLIST* el) {
|
||||||
|
freeexpression(el->expression);
|
||||||
|
EXPRESSIONLIST* next = el->next;
|
||||||
|
free(el);
|
||||||
|
if(next != NULL)
|
||||||
|
freeexpressionlist(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freelet(LETSTATEMENT* l) {
|
||||||
|
if(l->arrayind != NULL)
|
||||||
|
freeexpression(l->arrayind);
|
||||||
|
freeexpression(l->expression);
|
||||||
|
free(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freecond(CONDSTATEMENT* cond) {
|
||||||
|
freeexpression(cond->expression);
|
||||||
|
if(cond->statements != NULL)
|
||||||
|
freestatements(cond->statements);
|
||||||
|
free(cond);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeif(IFSTATEMENT* st) {
|
||||||
|
freecond(st->base);
|
||||||
|
if(st->elsestatements != NULL)
|
||||||
|
freestatements(st->elsestatements);
|
||||||
|
free(st);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freestatements(STATEMENT* s) {
|
||||||
|
if(s->type == letstatement)
|
||||||
|
freelet(s->letstatement);
|
||||||
|
else if(s->type == ifstatement)
|
||||||
|
freeif(s->ifstatement);
|
||||||
|
else if(s->type == whilestatement)
|
||||||
|
freecond(s->whilestatement);
|
||||||
|
else if(s->type == dostatement)
|
||||||
|
freesubroutcall(s->dostatement);
|
||||||
|
else if(s->retstatement != NULL)
|
||||||
|
freeexpression(s->retstatement);
|
||||||
|
|
||||||
|
free(s->debug);
|
||||||
|
STATEMENT* next = s->next;
|
||||||
|
free(s);
|
||||||
|
if(next != NULL)
|
||||||
|
freestatements(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freesubroutbody(SUBROUTBODY* b) {
|
||||||
|
if(b->vardecs != NULL)
|
||||||
|
freevardecs(b->vardecs);
|
||||||
|
if(b->statements != NULL)
|
||||||
|
freestatements(b->statements);
|
||||||
|
free(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freesubroutdecs(SUBROUTDEC* sr) {
|
||||||
|
free(sr->debug);
|
||||||
|
if(sr->parameters != NULL)
|
||||||
|
freeparameters(sr->parameters);
|
||||||
|
freesubroutbody(sr->body);
|
||||||
|
SUBROUTDEC* next = sr->next;
|
||||||
|
free(sr);
|
||||||
|
if(next != NULL)
|
||||||
|
freesubroutdecs(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeclassvardecs(CLASSVARDEC* cvd) {
|
||||||
|
freevardec(cvd->base);
|
||||||
|
CLASSVARDEC* next = cvd->next;
|
||||||
|
free(cvd);
|
||||||
|
if(next != NULL)
|
||||||
|
freeclassvardecs(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freetree(CLASS* c) {
|
||||||
|
free(c->debug);
|
||||||
|
|
||||||
|
if(c->vardecs != NULL)
|
||||||
|
freeclassvardecs(c->vardecs);
|
||||||
|
if(c->subroutdecs != NULL)
|
||||||
|
freesubroutdecs(c->subroutdecs);
|
||||||
|
|
||||||
|
CLASS* next = c->next;
|
||||||
|
free(c);
|
||||||
|
if(next != NULL)
|
||||||
|
freetree(next);
|
||||||
|
}
|
|
@ -155,4 +155,6 @@ typedef struct expressionlist {
|
||||||
struct expressionlist* next;
|
struct expressionlist* next;
|
||||||
} EXPRESSIONLIST;
|
} EXPRESSIONLIST;
|
||||||
|
|
||||||
|
|
||||||
|
void freetree(CLASS* c);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5,10 +5,19 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "parser-structure.h"
|
#include "parser-structure.h"
|
||||||
|
|
||||||
CLASS* parse(TOKEN* tokens, char* file) {
|
PARSER* mkparser(TOKEN* t, char* file) {
|
||||||
PARSER* parser = (PARSER*)malloc(sizeof(PARSER));
|
PARSER* parser = (PARSER*)malloc(sizeof(PARSER));
|
||||||
parser->tokens = tokens;
|
parser->tokens = t;
|
||||||
parser->current = tokens;
|
parser->current = t;
|
||||||
parser->file = file;
|
parser->file = file;
|
||||||
return parseclass(parser);
|
return parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
CLASS* parse(PARSER* p) {
|
||||||
|
return parseclass(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeparser(PARSER* p) {
|
||||||
|
freetokens(p->tokens);
|
||||||
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,5 +14,7 @@ typedef struct {
|
||||||
char* file;
|
char* file;
|
||||||
} PARSER;
|
} PARSER;
|
||||||
|
|
||||||
CLASS* parse(TOKEN* tokens, char* file);
|
PARSER* mkparser(TOKEN* t, char* file);
|
||||||
|
CLASS* parse(PARSER* p);
|
||||||
|
void freeparser(PARSER* p);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -78,6 +78,14 @@ TOKEN* appendtokenraw(TOKEN* curitem, STRING* token, int definedat, TOKENTYPE ty
|
||||||
return nextitem;
|
return nextitem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void freetokens(TOKEN* t) {
|
||||||
|
free(t->token);
|
||||||
|
TOKEN* next = t->next;
|
||||||
|
free(t);
|
||||||
|
if(next != NULL)
|
||||||
|
freetokens(next);
|
||||||
|
}
|
||||||
|
|
||||||
TOKEN* appendtoken(TOKEN* curitem, STRING* token, char* file, int definedat) {
|
TOKEN* appendtoken(TOKEN* curitem, STRING* token, char* file, int definedat) {
|
||||||
append(token, '\0');
|
append(token, '\0');
|
||||||
return appendtokenraw(curitem, token, definedat, gettokentype(token, file, definedat));
|
return appendtokenraw(curitem, token, definedat, gettokentype(token, file, definedat));
|
||||||
|
|
|
@ -17,5 +17,5 @@ typedef struct token {
|
||||||
} TOKEN;
|
} TOKEN;
|
||||||
|
|
||||||
TOKEN* tokenize(char* filename);
|
TOKEN* tokenize(char* filename);
|
||||||
void freetokenlist(TOKEN* list);
|
void freetokens(TOKEN* t);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -32,6 +32,7 @@ void printlns(LINE* lns, FILE* stream) {
|
||||||
void freeln(LINE* ln) {
|
void freeln(LINE* ln) {
|
||||||
for(int i = 0; i < ln->count; i++)
|
for(int i = 0; i < ln->count; i++)
|
||||||
free(ln->tokens[i]);
|
free(ln->tokens[i]);
|
||||||
|
free(ln->tokens);
|
||||||
free(ln);
|
free(ln);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +43,11 @@ void freelns(LINE* lns) {
|
||||||
freelns(next);
|
freelns(next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void freelnblk(LINEBLOCK* blk) {
|
||||||
|
freelns(blk->head);
|
||||||
|
free(blk);
|
||||||
|
}
|
||||||
|
|
||||||
LINEBLOCK* mklnblk(LINE* start) {
|
LINEBLOCK* mklnblk(LINE* start) {
|
||||||
LINEBLOCK* blk = (LINEBLOCK*)malloc(sizeof(LINEBLOCK));
|
LINEBLOCK* blk = (LINEBLOCK*)malloc(sizeof(LINEBLOCK));
|
||||||
blk->head = start;
|
blk->head = start;
|
||||||
|
|
|
@ -29,6 +29,7 @@ void printlns(LINE* lns, FILE* stream);
|
||||||
// Line freeing
|
// Line freeing
|
||||||
void freeln(LINE* ln);
|
void freeln(LINE* ln);
|
||||||
void freelns(LINE* lns);
|
void freelns(LINE* lns);
|
||||||
|
void freelnblk(LINEBLOCK* blk);
|
||||||
|
|
||||||
// Line block manipulation
|
// Line block manipulation
|
||||||
LINEBLOCK* mklnblk(LINE* start);
|
LINEBLOCK* mklnblk(LINE* start);
|
||||||
|
|
Loading…
Reference in New Issue