Add 'if' and 'while' support
This commit is contained in:
parent
d65bcc202f
commit
02fc8307a4
|
@ -116,6 +116,7 @@ SCOPE* mkscope(SCOPE* prev) {
|
||||||
s->vardecs = NULL;
|
s->vardecs = NULL;
|
||||||
s->classes = NULL;
|
s->classes = NULL;
|
||||||
s->previous = prev;
|
s->previous = prev;
|
||||||
|
s->condlabelcount = 0;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@ typedef struct scope {
|
||||||
CLASSVARDEC* classvardecs;
|
CLASSVARDEC* classvardecs;
|
||||||
VARDEC* vardecs;
|
VARDEC* vardecs;
|
||||||
CLASS* classes;
|
CLASS* classes;
|
||||||
|
int condlabelcount;
|
||||||
struct scope* previous;
|
struct scope* previous;
|
||||||
} SCOPE;
|
} SCOPE;
|
||||||
|
|
||||||
|
|
88
compiler.c
88
compiler.c
|
@ -2,6 +2,8 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
|
|
||||||
|
LINEBLOCK* compilestatements(SCOPE* s, CLASS* c, STATEMENT* sts);
|
||||||
|
|
||||||
int countparameters(EXPRESSIONLIST* params) {
|
int countparameters(EXPRESSIONLIST* params) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while(params != NULL) {
|
while(params != NULL) {
|
||||||
|
@ -27,8 +29,10 @@ char* dotlabel(char* n1, char* n2) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* subroutdecname(CLASS* c, SUBROUTDEC* sd) {
|
char* mkcondlabel(SCOPE* s) {
|
||||||
return dotlabel(c->name, sd->name);
|
char* label = dotlabel("cond-label", itoa(s->condlabelcount));
|
||||||
|
s->condlabelcount++;
|
||||||
|
return label;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINE* onetoken(char* str) {
|
LINE* onetoken(char* str) {
|
||||||
|
@ -87,6 +91,10 @@ LINEBLOCK* compileexpression(SCOPE* s, TERM* e) {
|
||||||
else if(e->type == innerexpression) {
|
else if(e->type == innerexpression) {
|
||||||
myblk = compileexpression(s, e->expression);
|
myblk = compileexpression(s, e->expression);
|
||||||
}
|
}
|
||||||
|
else if(e->type == varname) {
|
||||||
|
eprintf("TO BE IMPLEMENTED\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
eprintf("Unsupported term yet %i\n", e->type);
|
eprintf("Unsupported term yet %i\n", e->type);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -165,22 +173,78 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) {
|
||||||
// void subroutdecs return 0
|
// void subroutdecs return 0
|
||||||
if(e == NULL) {
|
if(e == NULL) {
|
||||||
char* tokens[] = { "push", "constant", "0" };
|
char* tokens[] = { "push", "constant", "0" };
|
||||||
appendlnbefore(block, mksimpleln(tokens, sizeof(tokens) / sizeof(char*)));
|
appendlnbefore(block, mksimpleln(tokens, strcount(tokens)));
|
||||||
} else
|
} else
|
||||||
block = mergelnblks(compileexpression(s, e), block);
|
block = mergelnblks(compileexpression(s, e), block);
|
||||||
|
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilestatement(SCOPE* s, CLASS* c, STATEMENT* st) {
|
LINEBLOCK* compileif(SCOPE* s, CLASS* c, IFSTATEMENT* st) {
|
||||||
if(st->type == dostatement)
|
LINEBLOCK* block = compileexpression(s, st->base->expression);
|
||||||
return compilesubroutcall(s, c, st->dostatement);
|
appendln(block, onetoken("not"));
|
||||||
else if(st->type == returnstatement)
|
|
||||||
return compileret(s, st->retstatement);
|
char* label1 = mkcondlabel(s);
|
||||||
else {
|
char* ifgoto[] = { "if-goto", label1 };
|
||||||
eprintf("UNSUPPORTED\n");
|
appendln(block, mksimpleln(ifgoto, strcount(ifgoto)));
|
||||||
exit(1);
|
|
||||||
|
block = mergelnblks(block, compilestatements(s, c, st->base->statements));
|
||||||
|
|
||||||
|
char* label2;
|
||||||
|
bool haselse = st->elsestatements != NULL;
|
||||||
|
if(haselse) {
|
||||||
|
char* label2 = mkcondlabel(s);
|
||||||
|
char* gotoln[] = { "goto", label2 };
|
||||||
|
appendln(block, mksimpleln(gotoln, strcount(gotoln)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* label1ln[] = { "label", label1 };
|
||||||
|
appendln(block, mksimpleln(label1ln, strcount(label1ln)));
|
||||||
|
|
||||||
|
if(haselse) {
|
||||||
|
block = mergelnblks(block, compilestatements(s, c, st->elsestatements));
|
||||||
|
char* label2ln[] = { "label", label2 };
|
||||||
|
appendln(block, mksimpleln(label2ln, strcount(label2ln)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
LINEBLOCK* compilewhile(SCOPE* s, CLASS* c, CONDSTATEMENT* w) {
|
||||||
|
LINEBLOCK* block = compileexpression(s, w->expression);
|
||||||
|
|
||||||
|
char* label1 = mkcondlabel(s);
|
||||||
|
char* label1ln[] = { "label", label1 };
|
||||||
|
appendlnbefore(block, mksimpleln(label1ln, strcount(label1ln)));
|
||||||
|
|
||||||
|
appendln(block, onetoken("not"));
|
||||||
|
|
||||||
|
char* label2 = mkcondlabel(s);
|
||||||
|
char* ifgoto[] = { "if-goto", label2 };
|
||||||
|
appendln(block, mksimpleln(ifgoto, strcount(ifgoto)));
|
||||||
|
|
||||||
|
block = mergelnblks(block, compilestatements(s, c, w->statements));
|
||||||
|
|
||||||
|
char* gotoln[] = { "goto", label1 };
|
||||||
|
appendln(block, mksimpleln(gotoln, strcount(gotoln)));
|
||||||
|
|
||||||
|
char* label2ln[] = { "label", label2 };
|
||||||
|
appendln(block, mksimpleln(label2ln, strcount(label2ln)));
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
LINEBLOCK* compilelet(SCOPE* s, CLASS* c, LETSTATEMENT* l) {
|
||||||
|
}
|
||||||
|
|
||||||
|
LINEBLOCK* compilestatement(SCOPE* s, CLASS* c, STATEMENT* st) {
|
||||||
|
if(st->type == dostatement) return compilesubroutcall(s, c, st->dostatement);
|
||||||
|
if(st->type == returnstatement) return compileret(s, st->retstatement);
|
||||||
|
if(st->type == ifstatement) return compileif(s, c, st->ifstatement);
|
||||||
|
if(st->type == whilestatement) return compilewhile(s, c, st->whilestatement);
|
||||||
|
if(st->type == letstatement) return compilelet(s, c, st->letstatement);
|
||||||
|
eprintf("UNSUPPORTED type %i\n", st->type);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilestatements(SCOPE* s, CLASS* c, STATEMENT* sts) {
|
LINEBLOCK* compilestatements(SCOPE* s, CLASS* c, STATEMENT* sts) {
|
||||||
|
@ -201,7 +265,7 @@ LINEBLOCK* compilefunbody(SCOPE* s, CLASS* c, SUBROUTBODY* b) {
|
||||||
LINEBLOCK* compilefundec(SCOPE* s, CLASS* c, SUBROUTDEC* f) {
|
LINEBLOCK* compilefundec(SCOPE* s, CLASS* c, SUBROUTDEC* f) {
|
||||||
LINE* label = mkline(3);
|
LINE* label = mkline(3);
|
||||||
addtoken(label, ezheapstr("function"));
|
addtoken(label, ezheapstr("function"));
|
||||||
addtoken(label, subroutdecname(c, f));
|
addtoken(label, dotlabel(c->name, f->name));
|
||||||
addtoken(label, itoa(countlocalvars(f->body->vardecs)));
|
addtoken(label, itoa(countlocalvars(f->body->vardecs)));
|
||||||
label->next = NULL;
|
label->next = NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue