Add array accessing

This commit is contained in:
Augusto Gunsch 2020-12-31 16:49:38 -03:00
parent 2e86c2b9e5
commit b9a553b107
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
8 changed files with 114 additions and 56 deletions

View File

@ -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
CFLAGS = -std=c99 -g -Wall
OUTFILE = jack-compiler
main: ${FILES}

View File

@ -26,11 +26,11 @@ SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name);
// Scope adding
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 addlocalvar(SCOPE* s, VARDEC* v, int* i);
void addstaticvar(COMPILER* c, 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 addparameter(SCOPE* s, PARAMETER* p, int i);
void addparameter(SCOPE* s, PARAMETER* p, int* i);
// Error messages
void doubledeclaration(const char* name, DEBUGINFO* d1, DEBUGINFO* d2) {
@ -223,32 +223,33 @@ void addvar(SCOPE* s, VAR** dest, VAR* v) {
*dest = v;
}
void addlocalvar(SCOPE* s, VARDEC* v, int i) {
void addlocalvar(SCOPE* s, VARDEC* v, int* i) {
STRINGLIST* currname = v->names;
while(currname != NULL) {
addvar(s, &(s->localvars), mkvar(v->type, currname->content, v->primitive, v->debug, local, i));
addvar(s, &(s->localvars), mkvar(v->type, currname->content, v->primitive, v->debug, local, *i));
currname = currname->next;
(*i)++;
}
}
void addstaticvar(COMPILER* c, SCOPE* s, CLASSVARDEC* v) {
pthread_mutex_lock(&(c->staticmutex));
static int count = 0;
int i = count;
count++;
pthread_mutex_unlock(&(c->staticmutex));
STRINGLIST* currname = v->base->names;
pthread_mutex_lock(&(c->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));
}
void addfield(SCOPE* s, CLASSVARDEC* v, int i) {
void addfield(SCOPE* s, CLASSVARDEC* v, int* i) {
STRINGLIST* currname = v->base->names;
while(currname != NULL) {
addvar(s, &(s->fields), mkvar(v->base->type, currname->content, v->base->primitive, v->base->debug, fieldseg, i));
addvar(s, &(s->fields), mkvar(v->base->type, currname->content, v->base->primitive, v->base->debug, fieldseg, *i));
currname = currname->next;
(*i)++;
}
}
@ -256,13 +257,13 @@ void addclassvardec(COMPILER* c, SCOPE* s, CLASSVARDEC* v, int* i) {
if(v->type == stat)
addstaticvar(c, s, v);
else {
addfield(s, v, *i);
*i++;
addfield(s, v, i);
}
}
void addparameter(SCOPE* s, PARAMETER* p, int i) {
addvar(s, &(s->parameters), mkvar(p->type, p->name, p->primitive, p->debug, arg, i));
void addparameter(SCOPE* s, PARAMETER* p, int* i) {
addvar(s, &(s->parameters), mkvar(p->type, p->name, p->primitive, p->debug, arg, *i));
(*i)++;
}
// Group adding
@ -277,8 +278,7 @@ void addclassvardecs(COMPILER* c, SCOPE* s, CLASSVARDEC* classvardecs) {
void addlocalvars(SCOPE* s, VARDEC* localvars) {
int i = 0;
while(localvars != NULL) {
addlocalvar(s, localvars, i);
i++;
addlocalvar(s, localvars, &i);
localvars = localvars->next;
}
}
@ -286,8 +286,7 @@ void addlocalvars(SCOPE* s, VARDEC* localvars) {
void addparameters(SCOPE* s, PARAMETER* params) {
int i = 0;
while(params != NULL) {
addparameter(s, params, i);
i++;
addparameter(s, params, &i);
params = params->next;
}
}

View File

@ -85,15 +85,13 @@ LINE* mathopln(char op) {
char* tokens[] = { "call", "Math.divide", "2" };
return mksimpleln(tokens, strcount(tokens));
}
if(op == '*') {
char* tokens[] = { "call", "Math.multiply", "2" };
return mksimpleln(tokens, strcount(tokens));
}
}
LINEBLOCK* pushconstant(int n) {
LINE* pushconstant(int n) {
char* tokens[] = { "push", "constant", itoa(n) };
return mklnblk(mksimpleln(tokens, strcount(tokens)));
return mksimpleln(tokens, strcount(tokens));
}
LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t) {
@ -107,47 +105,77 @@ LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t) {
return blk;
}
LINEBLOCK* opvarraw(SCOPE* s, char* op, VAR* v) {
LINE* opvarraw(SCOPE* s, char* op, VAR* v) {
char* tokens[] = { op, v->memsegment, itoa(v->index) };
return mklnblk(mksimpleln(tokens, strcount(tokens)));
return mksimpleln(tokens, strcount(tokens));
}
LINEBLOCK* opvar(SCOPE* s, char* op, const char* name) {
LINE* opvar(SCOPE* s, char* op, const char* name) {
VAR* v = getvar(s, name);
return opvarraw(s, op, v);
}
LINEBLOCK* pushvarraw(SCOPE*s, VAR* v) {
LINE* pushvarraw(SCOPE*s, VAR* v) {
return opvarraw(s, "push", v);
}
LINEBLOCK* pushvar(SCOPE* s, const char* name) {
LINE* pushvar(SCOPE* s, const char* name) {
return opvar(s, "push", name);
}
LINEBLOCK* popvar(SCOPE* s, const char* name) {
LINE* popvar(SCOPE* s, const char* name) {
return opvar(s, "pop", name);
}
LINEBLOCK* pushfalse() {
LINE* pushfalse() {
return pushconstant(0);
}
LINEBLOCK* pushtrue() {
LINEBLOCK* blk = pushfalse();
LINEBLOCK* blk = mklnblk(pushfalse());
appendln(blk, onetoken("not"));
return blk;
}
LINEBLOCK* pushthis() {
char* pushthis[] = { "push", "pointer", "0" };
return mklnblk(mksimpleln(pushthis, strcount(pushthis)));
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));
}
LINE* popthat() {
char* popthat[] = { "pop", "that", "0" };
return mksimpleln(popthat, strcount(popthat));
}
LINE* pushthat() {
char* pushthat[] = { "push", "that", "0" };
return mksimpleln(pushthat, strcount(pushthat));
}
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 pushfalse();
if(!strcmp(t->string, "this")) return pushthis();
if(!strcmp(t->string, "false")) return mklnblk(pushfalse());
if(!strcmp(t->string, "this")) return mklnblk(pushthisadd());
eprintf("Unsupported keyword '%s'\n", t->string);
exit(1);
}
@ -185,16 +213,31 @@ LINEBLOCK* compilestrconst(char* str) {
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 pushconstant(t->integer);
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 pushvar(s, t->string);
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) {
@ -248,16 +291,15 @@ LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call) {
if(d->subroutclass == method) {
if(call->parentname == NULL)
blk = mergelnblks(pushthis(), blk);
appendlnbefore(blk, pushthisadd());
else
blk = mergelnblks(pushvarraw(s, v), blk);
appendlnbefore(blk, pushvarraw(s, v));
}
// void functions always return 0
// therefore must be thrown away
if(!strcmp(d->type, "void")) {
char* tokens[] = { "pop", "temp", "0" };
appendln(blk, mksimpleln(tokens, sizeof(tokens) / sizeof(char*)));
appendln(blk, poptemp());
}
return blk;
@ -316,7 +358,6 @@ LINEBLOCK* compileif(COMPILER* c, SCOPE* s, IFSTATEMENT* st) {
appendln(blk, mksimpleln(endlabelln, strcount(endlabelln)));
}
return blk;
}
@ -351,9 +392,20 @@ LINEBLOCK* compilewhile(COMPILER* c, SCOPE* s, CONDSTATEMENT* w) {
}
LINEBLOCK* compilelet(SCOPE* s, LETSTATEMENT* l) {
// missing array ind
LINEBLOCK* blk = compileexpression(s, l->expression);
blk = mergelnblks(blk, popvar(s, l->varname));
if(l->arrayind != NULL) {
appendlnbefore(blk, onetoken("add"));
appendlnbefore(blk, pushvar(s, l->varname));
blk = mergelnblks(compileexpression(s, l->arrayind), blk);
appendln(blk, poptemp());
appendln(blk, popthatadd());
appendln(blk, pushtemp());
appendln(blk, popthat());
}
else
appendln(blk, popvar(s, l->varname));
return blk;
}

2
main.c
View File

@ -135,6 +135,6 @@ int main(int argc, char* argv[]) {
currunit = currunit->next;
}
freeos();
//freeos();
return 0;
}

View File

@ -78,11 +78,12 @@ bool isdotjack(char* f, int len) {
bool isdir(char* f, int len) {
bool readsmt = false;
for(int i = len-1; i >= 0; i--) {
if(f[i] == '.')
if(f[i] == '.') {
if(readsmt)
return false;
else
continue;
}
if(f[i] == '/')
return 1;
readsmt = true;

View File

@ -14,7 +14,7 @@ CLASS* addclass(const char* name) {
return c;
}
CLASS* adddec(CLASS* c, SUBROUTCLASS subroutclass, char* type, const char* name) {
void adddec(CLASS* c, SUBROUTCLASS subroutclass, char* type, const char* name) {
SUBROUTDEC* dec = (SUBROUTDEC*)malloc(sizeof(SUBROUTDEC));
dec->class = c;
dec->subroutclass = subroutclass;
@ -151,5 +151,5 @@ SUBROUTDEC* getossubroutdec(SUBROUTCALL* call) {
CLASS* c = getosclass(call->parentname);
if(c == NULL)
return NULL;
getsubroutdecinclass(c, call->name);
return getsubroutdecinclass(c, call->name);
}

View File

@ -99,10 +99,11 @@ TERM* parsecalltermnullified(PARSER* p) {
TERM* parsearrayterm(PARSER* p) {
TERM* t = mkterm(arrayitem);
t->string = p->current->token;
t->array = (ARRAY*)malloc(sizeof(ARRAY));
t->array->name = p->current->token;
next(p);
checkcontent(p, "[");
t->arrayexp = parseexpression(p);
t->array->exp = parseexpression(p);
checkcontent(p, "]");
return t;
}

View File

@ -120,6 +120,11 @@ typedef enum {
varname, intconstant, stringconstant, keywordconstant, arrayitem, subroutcall, innerexpression, unaryopterm
} TERMTYPE;
typedef struct {
char* name;
struct term* exp;
} ARRAY;
typedef struct term {
TERMTYPE type;
union {
@ -127,8 +132,8 @@ typedef struct term {
int integer;
struct subroutcall* call;
struct term* expression;
ARRAY* array;
};
struct term* arrayexp;
char op;
char unaryop;
struct term* next;