Fix bugs, memory leaks and small fixes
This commit is contained in:
@@ -207,11 +207,10 @@ LINEBLOCK* compileexpression(SCOPE* s, TERM* e) {
|
||||
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;
|
||||
if(e->next == NULL)
|
||||
break;
|
||||
appendln(blk, mathopln(e->op));
|
||||
e = e->next;
|
||||
}
|
||||
}
|
||||
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);
|
||||
void addvar(SCOPE* s, VAR** dest, VAR* v);
|
||||
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 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);
|
||||
|
||||
// Error messages
|
||||
@@ -67,6 +67,8 @@ void ensurenoduplicate(SCOPE* s, char* name) {
|
||||
SCOPE* mkscope(SCOPE* prev) {
|
||||
SCOPE* s = (SCOPE*)malloc(sizeof(SCOPE));
|
||||
s->previous = prev;
|
||||
if(prev != NULL)
|
||||
s->compiler = prev->compiler;
|
||||
s->localvars = NULL;
|
||||
s->fields = NULL;
|
||||
s->staticvars = NULL;
|
||||
@@ -113,7 +115,7 @@ CLASS* getclass(SCOPE* s, const char* name) {
|
||||
}
|
||||
if(s->previous != NULL)
|
||||
return getclass(s->previous, name);
|
||||
return getosclass(name);
|
||||
return getosclass(s->compiler->os, name);
|
||||
}
|
||||
|
||||
SUBROUTDEC* getsubroutdecfromlist(SUBROUTDEC* start, char* name) {
|
||||
@@ -174,7 +176,7 @@ SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call, VAR** varret) {
|
||||
SUBROUTDEC* d;
|
||||
*varret = NULL;
|
||||
if(call->parentname != NULL) {
|
||||
d = getossubroutdec(call);
|
||||
d = getossubroutdec(s->compiler->os, call);
|
||||
if(d == NULL)
|
||||
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;
|
||||
pthread_mutex_lock(&(c->staticmutex));
|
||||
pthread_mutex_lock(&(s->compiler->staticmutex));
|
||||
static int i = 0;
|
||||
while(currname != NULL) {
|
||||
addvar(s, &(s->staticvars), mkvar(v->base->type, currname->content, v->base->primitive, v->base->debug, staticseg, i));
|
||||
currname = currname->next;
|
||||
i++;
|
||||
}
|
||||
pthread_mutex_unlock(&(c->staticmutex));
|
||||
pthread_mutex_unlock(&(s->compiler->staticmutex));
|
||||
}
|
||||
|
||||
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)
|
||||
addstaticvar(c, s, v);
|
||||
addstaticvar(s, v);
|
||||
else {
|
||||
addfield(s, v, i);
|
||||
}
|
||||
@@ -267,10 +269,10 @@ void addparameter(SCOPE* s, PARAMETER* p, int* i) {
|
||||
}
|
||||
|
||||
// Group adding
|
||||
void addclassvardecs(COMPILER* c, SCOPE* s, CLASSVARDEC* classvardecs) {
|
||||
void addclassvardecs(SCOPE* s, CLASSVARDEC* classvardecs) {
|
||||
int i = 0;
|
||||
while(classvardecs != NULL) {
|
||||
addclassvardec(c, s, classvardecs, &i);
|
||||
addclassvardec(s, classvardecs, &i);
|
||||
classvardecs = classvardecs->next;
|
||||
}
|
||||
}
|
||||
@@ -290,3 +292,19 @@ void addparameters(SCOPE* s, bool isformethod, PARAMETER* params) {
|
||||
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;
|
||||
|
||||
typedef struct scope {
|
||||
struct compiler* compiler;
|
||||
DEBUGINFO* currdebug;
|
||||
CLASS* currclass;
|
||||
|
||||
@@ -38,7 +39,7 @@ typedef struct scope {
|
||||
struct compiler;
|
||||
|
||||
// Group adding
|
||||
void addclassvardecs(struct compiler* c, SCOPE* s, CLASSVARDEC* classvardecs);
|
||||
void addclassvardecs(SCOPE* s, CLASSVARDEC* classvardecs);
|
||||
void addlocalvars(SCOPE* s, VARDEC* localvars);
|
||||
void addparameters(SCOPE* s, bool isformethod, PARAMETER* params);
|
||||
|
||||
@@ -51,4 +52,7 @@ CLASS* getclass(SCOPE* s, const char* name);
|
||||
|
||||
// Generic getters
|
||||
VAR* getvar(SCOPE* s, const char* name);
|
||||
|
||||
// Freeing
|
||||
void freescope(SCOPE* s);
|
||||
#endif
|
||||
|
@@ -13,10 +13,10 @@ char* mkcondlabel(char* name, int count);
|
||||
|
||||
// Handling individual statements
|
||||
LINEBLOCK* compileret(SCOPE* s, TERM* e);
|
||||
LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st);
|
||||
LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w);
|
||||
LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st);
|
||||
LINEBLOCK* compilewhile(SCOPE* s, CONDSTATEMENT* w);
|
||||
LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l);
|
||||
LINEBLOCK* compilestatement(COMPILER* c, SCOPE* s, STATEMENT* st);
|
||||
LINEBLOCK* compilestatement(SCOPE* s, STATEMENT* st);
|
||||
|
||||
/* END FORWARD DECLARATIONS */
|
||||
|
||||
@@ -55,14 +55,14 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) {
|
||||
return blk;
|
||||
}
|
||||
|
||||
LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
||||
LINEBLOCK* compileif(SCOPE* s, IFSTATEMENT* st) {
|
||||
LINEBLOCK* blk = compileexpression(s, st->base->expression);
|
||||
|
||||
pthread_mutex_lock(&(c->ifmutex));
|
||||
pthread_mutex_lock(&(s->compiler->ifmutex));
|
||||
static int ifcount = 0;
|
||||
int mycount = ifcount;
|
||||
ifcount++;
|
||||
pthread_mutex_unlock(&(c->ifmutex));
|
||||
pthread_mutex_unlock(&(s->compiler->ifmutex));
|
||||
|
||||
char* truelabel = mkcondlabel("IF_TRUE", mycount);
|
||||
char* ifgoto[] = { "if-goto", truelabel };
|
||||
@@ -75,7 +75,7 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
||||
char* truelabelln[] = { "label", truelabel };
|
||||
appendln(blk, mkln(truelabelln));
|
||||
|
||||
blk = mergelnblks(blk, compilestatements(c, s, st->base->statements));
|
||||
blk = mergelnblks(blk, compilestatements(s, st->base->statements));
|
||||
|
||||
char* endlabel;
|
||||
bool haselse = st->elsestatements != NULL;
|
||||
@@ -89,7 +89,7 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
||||
appendln(blk, mkln(falselabelln));
|
||||
|
||||
if(haselse) {
|
||||
blk = mergelnblks(blk, compilestatements(c, s, st->elsestatements));
|
||||
blk = mergelnblks(blk, compilestatements(s, st->elsestatements));
|
||||
char* endlabelln[] = { "label", endlabel };
|
||||
appendln(blk, mkln(endlabelln));
|
||||
free(endlabel);
|
||||
@@ -101,14 +101,14 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
|
||||
return blk;
|
||||
}
|
||||
|
||||
LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w) {
|
||||
LINEBLOCK* compilewhile(SCOPE* s, CONDSTATEMENT* w) {
|
||||
LINEBLOCK* blk = compileexpression(s, w->expression);
|
||||
|
||||
pthread_mutex_lock(&(c->whilemutex));
|
||||
pthread_mutex_lock(&(s->compiler->whilemutex));
|
||||
static int whilecount = 0;
|
||||
int mycount = whilecount;
|
||||
whilecount++;
|
||||
pthread_mutex_unlock(&(c->whilemutex));
|
||||
pthread_mutex_unlock(&(s->compiler->whilemutex));
|
||||
|
||||
char* explabel = mkcondlabel("WHILE_EXP", mycount);
|
||||
char* explabelln[] = { "label", explabel };
|
||||
@@ -120,7 +120,7 @@ LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w) {
|
||||
char* ifgoto[] = { "if-goto", endlabel };
|
||||
appendln(blk, mkln(ifgoto));
|
||||
|
||||
blk = mergelnblks(blk, compilestatements(c, s, w->statements));
|
||||
blk = mergelnblks(blk, compilestatements(s, w->statements));
|
||||
|
||||
char* gotoln[] = { "goto", explabel };
|
||||
appendln(blk, mkln(gotoln));
|
||||
@@ -152,21 +152,19 @@ LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l) {
|
||||
return blk;
|
||||
}
|
||||
|
||||
LINEBLOCK* compilestatement(COMPILER* c, SCOPE* s, STATEMENT* st) {
|
||||
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(c, s, st->ifstatement);
|
||||
if(st->type == whilestatement) return compilewhile(c, s, st->whilestatement);
|
||||
if(st->type == letstatement) return compilelet(s, st->letstatement);
|
||||
eprintf("UNSUPPORTED type %i\n", st->type);
|
||||
exit(1);
|
||||
if(st->type == ifstatement) return compileif(s, st->ifstatement);
|
||||
if(st->type == whilestatement) return compilewhile(s, st->whilestatement);
|
||||
return compilelet(s, st->letstatement);
|
||||
}
|
||||
|
||||
LINEBLOCK* compilestatements(COMPILER* c, SCOPE* s, STATEMENT* sts) {
|
||||
LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts) {
|
||||
LINEBLOCK* head = NULL;
|
||||
while(sts != NULL) {
|
||||
head = mergelnblks(head, compilestatement(c, s, sts));
|
||||
head = mergelnblks(head, compilestatement(s, sts));
|
||||
sts = sts->next;
|
||||
}
|
||||
return head;
|
||||
|
@@ -5,5 +5,5 @@
|
||||
/* compiler-statements
|
||||
* Single function for compiling statements */
|
||||
|
||||
LINEBLOCK* compilestatements(COMPILER* c, SCOPE* s, STATEMENT* sts);
|
||||
LINEBLOCK* compilestatements(SCOPE* s, STATEMENT* sts);
|
||||
#endif
|
||||
|
@@ -12,10 +12,10 @@ int getobjsize(CLASS* c);
|
||||
LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd);
|
||||
|
||||
// Compiling methods
|
||||
LINEBLOCK* compilefunbody(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTBODY* b);
|
||||
LINEBLOCK* compilefundec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* f);
|
||||
LINEBLOCK* compileconstructor(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* con);
|
||||
LINEBLOCK* compilemethod(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* m);
|
||||
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTBODY* b);
|
||||
LINEBLOCK* compilefundec(SCOPE* s, CLASS* cl, SUBROUTDEC* f);
|
||||
LINEBLOCK* compileconstructor(SCOPE* s, CLASS* cl, SUBROUTDEC* con);
|
||||
LINEBLOCK* compilemethod(SCOPE* s, CLASS* cl, SUBROUTDEC* m);
|
||||
|
||||
/* END FORWARD DECLARATIONS */
|
||||
|
||||
@@ -64,20 +64,21 @@ LINE* mksubdeclabel(CLASS* c, SUBROUTDEC* sd) {
|
||||
}
|
||||
|
||||
// Compiling methods
|
||||
LINEBLOCK* compilefunbody(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTBODY* b) {
|
||||
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* cl, SUBROUTBODY* b) {
|
||||
SCOPE* myscope = mkscope(s);
|
||||
myscope->currclass = cl;
|
||||
if(b->vardecs != NULL)
|
||||
addlocalvars(s, b->vardecs);
|
||||
LINEBLOCK* head = compilestatements(c, myscope, b->statements);
|
||||
addlocalvars(myscope, b->vardecs);
|
||||
LINEBLOCK* head = compilestatements(myscope, b->statements);
|
||||
freescope(myscope);
|
||||
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);
|
||||
|
||||
if(f->body->statements != NULL) {
|
||||
LINEBLOCK* body = compilefunbody(c, s, cl, f->body);
|
||||
LINEBLOCK* body = compilefunbody(s, cl, f->body);
|
||||
appendlnbefore(body, label);
|
||||
return body;
|
||||
}
|
||||
@@ -85,7 +86,7 @@ LINEBLOCK* compilefundec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* f) {
|
||||
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);
|
||||
LINEBLOCK* blk = mklnblk(label);
|
||||
|
||||
@@ -98,12 +99,12 @@ LINEBLOCK* compileconstructor(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* con)
|
||||
free(size[2]);
|
||||
|
||||
if(con->body != NULL)
|
||||
return mergelnblks(blk, compilefunbody(c, s, cl, con->body));
|
||||
return mergelnblks(blk, compilefunbody(s, cl, con->body));
|
||||
else
|
||||
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);
|
||||
LINEBLOCK* blk = mklnblk(label);
|
||||
|
||||
@@ -113,18 +114,22 @@ LINEBLOCK* compilemethod(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* m) {
|
||||
appendln(blk, mkln(poppointer));
|
||||
|
||||
if(m->body != NULL)
|
||||
return mergelnblks(blk, compilefunbody(c, s, cl, m->body));
|
||||
return mergelnblks(blk, compilefunbody(s, cl, m->body));
|
||||
else
|
||||
return blk;
|
||||
}
|
||||
|
||||
LINEBLOCK* compilesubroutdec(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* sd) {
|
||||
LINEBLOCK* compilesubroutdec(SCOPE* s, CLASS* cl, SUBROUTDEC* sd) {
|
||||
SCOPE* myscope = mkscope(s);
|
||||
LINEBLOCK* blk;
|
||||
if(sd->parameters != NULL)
|
||||
addparameters(myscope, sd->subroutclass == method, sd->parameters);
|
||||
if(sd->subroutclass == function)
|
||||
return compilefundec(c, myscope, cl, sd);
|
||||
if(sd->subroutclass == constructor)
|
||||
return compileconstructor(c, myscope, cl, sd);
|
||||
return compilemethod(c, myscope, cl, sd);
|
||||
blk = compilefundec(myscope, cl, sd);
|
||||
else if(sd->subroutclass == constructor)
|
||||
blk = compileconstructor(myscope, cl, sd);
|
||||
else
|
||||
blk = compilemethod(myscope, cl, sd);
|
||||
freescope(myscope);
|
||||
return blk;
|
||||
}
|
||||
|
@@ -5,5 +5,5 @@
|
||||
/* compiler-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
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
#include "os.h"
|
||||
#include "compiler-structure.h"
|
||||
#include "compiler.h"
|
||||
|
||||
@@ -7,24 +8,27 @@
|
||||
LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
|
||||
SCOPE* topscope = mkscope(c->globalscope);
|
||||
if(class->vardecs != NULL)
|
||||
addclassvardecs(c, topscope, class->vardecs);
|
||||
addclassvardecs(topscope, class->vardecs);
|
||||
if(class->subroutdecs != NULL)
|
||||
topscope->subroutines = class->subroutdecs;
|
||||
|
||||
LINEBLOCK* output = NULL;
|
||||
SUBROUTDEC* curr = class->subroutdecs;
|
||||
while(curr != NULL) {
|
||||
output = mergelnblks(output, compilesubroutdec(c, topscope, class, curr));
|
||||
output = mergelnblks(output, compilesubroutdec(topscope, class, curr));
|
||||
curr = curr->next;
|
||||
}
|
||||
freescope(topscope);
|
||||
return output;
|
||||
}
|
||||
|
||||
COMPILER* mkcompiler(CLASS* classes) {
|
||||
COMPILER* c = (COMPILER*)malloc(sizeof(COMPILER));
|
||||
c->globalscope = mkscope(NULL);
|
||||
c->globalscope->compiler = c;
|
||||
c->globalscope->classes = classes;
|
||||
c->classes = classes;
|
||||
c->os = mkos();
|
||||
pthread_mutex_init(&(c->ifmutex), NULL);
|
||||
pthread_mutex_init(&(c->whilemutex), NULL);
|
||||
pthread_mutex_init(&(c->staticmutex), NULL);
|
||||
@@ -36,5 +40,7 @@ void freecompiler(COMPILER* c) {
|
||||
pthread_mutex_destroy(&(c->whilemutex));
|
||||
pthread_mutex_destroy(&(c->staticmutex));
|
||||
// to be continued
|
||||
freeos(c->os);
|
||||
freescope(c->globalscope);
|
||||
free(c);
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ typedef struct compiler {
|
||||
pthread_mutex_t whilemutex;
|
||||
pthread_mutex_t staticmutex;
|
||||
CLASS* classes;
|
||||
CLASS* os;
|
||||
struct scope* globalscope;
|
||||
} COMPILER;
|
||||
|
||||
|
Reference in New Issue
Block a user