From bf61fcdd30fa0525782b076eccad4e6cd0bd9ae3 Mon Sep 17 00:00:00 2001 From: Augusto Gunsch Date: Mon, 21 Dec 2020 20:35:41 -0300 Subject: [PATCH] Organize parse tree --- compiler-scopes.c | 54 ++++++++--------- compiler-scopes.h | 12 ++-- compiler.c | 30 +++++----- parser-tree.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++ parser.c | 58 +++++++++---------- parser.h | 123 +-------------------------------------- 6 files changed, 222 insertions(+), 199 deletions(-) create mode 100644 parser-tree.h diff --git a/compiler-scopes.c b/compiler-scopes.c index 84d0c8f..86e7556 100644 --- a/compiler-scopes.c +++ b/compiler-scopes.c @@ -26,7 +26,7 @@ OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, char** retname); // Scope adding void addclassvardec(SCOPE* s, CLASSVARDEC* v); void addvardec(SCOPE* s, VARDEC* v); -void addsubdec(SCOPE* s, SUBDEC* sd); +void addsubroutdec(SCOPE* s, SUBROUTDEC* sd); void addclass(SCOPE* s, CLASS* c); // DEFINITIONS @@ -59,8 +59,8 @@ DEBUGINFO* getdebugvardec(OBJ* obj) { return obj->vardec->debug; } -DEBUGINFO* getdebugsubdec(OBJ* obj) { - return obj->subdec->debug; +DEBUGINFO* getdebugsubroutdec(OBJ* obj) { + return obj->subroutdec->debug; } DEBUGINFO* getdebugclass(OBJ* obj) { @@ -150,15 +150,15 @@ CLASSVARDEC* getclassvardec(SCOPE* s, char* name) { return NULL; } -SUBDEC* getsubdec(SCOPE* s, char* name) { - SUBDEC* curr = s->subroutines; +SUBROUTDEC* getsubroutdec(SCOPE* s, char* name) { + SUBROUTDEC* curr = s->subroutines; while(curr != NULL) { if(!strcmp(curr->name, name)) return curr; curr = curr->next; } if(s->previous != NULL) - return getsubdec(s->previous, name); + return getsubroutdec(s->previous, name); return NULL; } @@ -174,8 +174,8 @@ CLASS* getclass(SCOPE* s, char* name) { return NULL; } -SUBDEC* getsubdecfromclass(CLASS* c, char* name) { - SUBDEC* curr = c->subdecs; +SUBROUTDEC* getsubroutdecfromclass(CLASS* c, char* name) { + SUBROUTDEC* curr = c->subroutdecs; while(curr != NULL) { if(!strcmp(curr->name, name)) return curr; @@ -184,34 +184,34 @@ SUBDEC* getsubdecfromclass(CLASS* c, char* name) { return NULL; } -SUBDEC* getsubdecfromvar(SCOPE* s, OBJ* var, SUBROUTCALL* call) { +SUBROUTDEC* getsubroutdecfromvar(SCOPE* s, OBJ* var, SUBROUTCALL* call) { VARDEC* vd = tovardec(var); if(vd == NULL || vd->primitive) invalidparent(call); CLASS* c = getclass(s, vd->type); - return getsubdecfromclass(c, call->name); + return getsubroutdecfromclass(c, call->name); } -SUBDEC* getsubdecfromparent(SCOPE* s, SUBROUTCALL* call) { - SUBDEC* sd; +SUBROUTDEC* getsubroutdecfromparent(SCOPE* s, SUBROUTCALL* call) { + SUBROUTDEC* sd; OBJ* parent = getbyname(s, call->parentname); if(parent == NULL) notdeclared(call->parentname, call->debug); if(parent->type == class) - sd = getsubdecfromclass(parent->class, call->name); + sd = getsubroutdecfromclass(parent->class, call->name); else - sd = getsubdecfromvar(s, parent, call); + sd = getsubroutdecfromvar(s, parent, call); return sd; } -SUBDEC* getsubdecfromcall(SCOPE* s, SUBROUTCALL* call) { - SUBDEC* sd; +SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call) { + SUBROUTDEC* sd; if(call->parentname != NULL) - sd = getsubdecfromparent(s, call); + sd = getsubroutdecfromparent(s, call); else - sd = getsubdec(s, call->name); + sd = getsubroutdec(s, call->name); if(sd == NULL) notdeclared(call->name, call->debug); return sd; @@ -233,14 +233,14 @@ OBJ* getbyname(SCOPE* s, char* name) { if(vd != NULL) { o->vardec = vd; o->type = vardec; - o->getdebug = getdebugsubdec; + o->getdebug = getdebugsubroutdec; return o; } - SUBDEC* sd = getsubdec(s, name); + SUBROUTDEC* sd = getsubroutdec(s, name); if(sd != NULL) { - o->subdec = sd; - o->type = subdec; + o->subroutdec = sd; + o->type = subroutdec; o->getdebug = getdebugclassvardec; return o; } @@ -286,9 +286,9 @@ void addvardec(SCOPE* s, VARDEC* v) { s->vardecs = new; } -void addsubdec(SCOPE* s, SUBDEC* sd) { +void addsubroutdec(SCOPE* s, SUBROUTDEC* sd) { ensurenoduplicate(s, sd->name, sd->debug); - SUBDEC* new = copy(sd, sizeof(SUBDEC)); + SUBROUTDEC* new = copy(sd, sizeof(SUBROUTDEC)); new->next = s->subroutines; s->subroutines = new; } @@ -319,11 +319,11 @@ void addvardecs(SCOPE* s, VARDEC* vs) { } } -void addsubdecs(SCOPE* s, SUBDEC* ss) { - SUBDEC* next; +void addsubroutdecs(SCOPE* s, SUBROUTDEC* ss) { + SUBROUTDEC* next; while(ss != NULL) { next = ss->next; - addsubdec(s, ss); + addsubroutdec(s, ss); ss = next; } } diff --git a/compiler-scopes.h b/compiler-scopes.h index e8c7f28..2cbc7b4 100644 --- a/compiler-scopes.h +++ b/compiler-scopes.h @@ -10,7 +10,7 @@ // Data types typedef struct scope { - SUBDEC* subroutines; + SUBROUTDEC* subroutines; CLASSVARDEC* classvardecs; VARDEC* vardecs; CLASS* classes; @@ -18,13 +18,13 @@ typedef struct scope { } SCOPE; typedef enum { - subdec, classvardec, vardec, class + subroutdec, classvardec, vardec, class } OBJTYPE; typedef struct object { OBJTYPE type; union { - SUBDEC* subdec; + SUBROUTDEC* subroutdec; CLASSVARDEC* classvardec; VARDEC* vardec; CLASS* class; @@ -35,15 +35,15 @@ typedef struct object { // Group adding void addclassvardecs(SCOPE* s, CLASSVARDEC* vs); void addvardecs(SCOPE* s, VARDEC* vs); -void addsubdecs(SCOPE* s, SUBDEC* ss); +void addsubroutdecs(SCOPE* s, SUBROUTDEC* ss); void addclasses(SCOPE* s, CLASS* c); // Scope handling SCOPE* mkscope(SCOPE* prev); // Single type getters -SUBDEC* getsubdec(SCOPE* s, char* name); -SUBDEC* getsubdecfromcall(SCOPE* s, SUBROUTCALL* call); +SUBROUTDEC* getsubroutdec(SCOPE* s, char* name); +SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call); CLASS* getclass(SCOPE* s, char* name); // Generic getters diff --git a/compiler.c b/compiler.c index e840f84..c78d21d 100644 --- a/compiler.c +++ b/compiler.c @@ -27,7 +27,7 @@ char* dotlabel(char* n1, char* n2) { return result; } -char* subdecname(CLASS* c, SUBDEC* sd) { +char* subroutdecname(CLASS* c, SUBROUTDEC* sd) { return dotlabel(c->name, sd->name); } @@ -126,10 +126,10 @@ LINEBLOCK* compilecallln(CLASS* c, SUBROUTCALL* call) { } // temporary ignore list for OS functions -char* ignoresubdecs[] = { +char* ignoresubroutdecs[] = { "printInt", "void", "peek", "int" }; -int ignorecount = sizeof(ignoresubdecs) / sizeof(char*); +int ignorecount = sizeof(ignoresubroutdecs) / sizeof(char*); LINEBLOCK* compilesubroutcall(SCOPE* s, CLASS* c, SUBROUTCALL* call) { LINEBLOCK* block = compilecallln(c, call); @@ -143,13 +143,13 @@ LINEBLOCK* compilesubroutcall(SCOPE* s, CLASS* c, SUBROUTCALL* call) { // gambiarra char* type = NULL; for(int i = 0; i < ignorecount; i += 2) { - if(!strcmp(call->name, ignoresubdecs[i])) { - type = ignoresubdecs[i+1]; + if(!strcmp(call->name, ignoresubroutdecs[i])) { + type = ignoresubroutdecs[i+1]; break; } } if(type == NULL) - type = getsubdecfromcall(s, call)->type; + type = getsubroutdecfromcall(s, call)->type; if(!strcmp(type, "void")) { char* tokens[] = { "pop", "temp", "0" }; appendln(block, mksimpleln(tokens, sizeof(tokens) / sizeof(char*))); @@ -162,7 +162,7 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) { LINE* ret = onetoken("return"); LINEBLOCK* block = mklnblk(ret); - // void subdecs return 0 + // void subroutdecs return 0 if(e == NULL) { char* tokens[] = { "push", "constant", "0" }; appendlnbefore(block, mksimpleln(tokens, sizeof(tokens) / sizeof(char*))); @@ -174,9 +174,9 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) { LINEBLOCK* compilestatement(SCOPE* s, CLASS* c, STATEMENT* st) { if(st->type == dostatement) - return compilesubroutcall(s, c, st->dost); + return compilesubroutcall(s, c, st->dostatement); else if(st->type == returnstatement) - return compileret(s, st->retst); + return compileret(s, st->retstatement); else { eprintf("UNSUPPORTED\n"); exit(1); @@ -198,10 +198,10 @@ LINEBLOCK* compilefunbody(SCOPE* s, CLASS* c, SUBROUTBODY* b) { return head; } -LINEBLOCK* compilefundec(SCOPE* s, CLASS* c, SUBDEC* f) { +LINEBLOCK* compilefundec(SCOPE* s, CLASS* c, SUBROUTDEC* f) { LINE* label = mkline(3); addtoken(label, ezheapstr("function")); - addtoken(label, subdecname(c, f)); + addtoken(label, subroutdecname(c, f)); addtoken(label, itoa(countlocalvars(f->body->vardecs))); label->next = NULL; @@ -214,7 +214,7 @@ LINEBLOCK* compilefundec(SCOPE* s, CLASS* c, SUBDEC* f) { return mklnblk(label); } -LINEBLOCK* compilesubdec(SCOPE* s, CLASS* c, SUBDEC* sd) { +LINEBLOCK* compilesubroutdec(SCOPE* s, CLASS* c, SUBROUTDEC* sd) { // 'this' and arguments are pushed by caller // Must have a 'return' at the end // Label names must have class name too (see mapping) @@ -228,12 +228,12 @@ LINEBLOCK* compilesubdec(SCOPE* s, CLASS* c, SUBDEC* sd) { LINEBLOCK* compileclass(COMPILER* c, CLASS* class) { SCOPE* topscope = mkscope(c->globalscope); addclassvardecs(topscope, class->vardecs); - addsubdecs(topscope, class->subdecs); + addsubroutdecs(topscope, class->subroutdecs); LINEBLOCK* output = NULL; - SUBDEC* curr = class->subdecs; + SUBROUTDEC* curr = class->subroutdecs; while(curr != NULL) { - output = mergelnblks(output, compilesubdec(topscope, class, curr)); + output = mergelnblks(output, compilesubroutdec(topscope, class, curr)); curr = curr->next; } return output; diff --git a/parser-tree.h b/parser-tree.h new file mode 100644 index 0000000..41da1c8 --- /dev/null +++ b/parser-tree.h @@ -0,0 +1,144 @@ +#ifndef PARSER_TREE_H +#define PARSER_TREE_H +#include "tokenizer.h" +#include "util.h" + +// Forward declarations +struct classvardec; +struct parameter; +struct subroutbody; +struct subroutdec; +struct vardec; +struct letstatement; +struct ifstatement; +struct condstatement; +struct subroutcall; +struct term; +struct expressionlist; + +// Misc +typedef struct { + char* file; + int definedat; +} DEBUGINFO; + +// Program structure + +typedef struct class { + char* name; + struct classvardec* vardecs; + struct subroutdec* subroutdecs; + DEBUGINFO* debug; + struct class* next; +} CLASS; + +typedef enum { + stat, field +} CLASSVARTYPE; + +typedef struct classvardec { + CLASSVARTYPE type; + struct vardec* base; + struct classvardec* next; +} CLASSVARDEC; + +typedef enum { + constructor, function, method +} SUBROUTCLASS; + +typedef struct subroutdec { + SUBROUTCLASS subroutclass; + char* type; + TOKENTYPE typeclass; + char* name; + struct parameter* parameters; + struct subroutbody* body; + DEBUGINFO* debug; + struct subroutdec* next; +} SUBROUTDEC; + +typedef struct parameter { + char* type; + char* name; + struct parameter* next; +} PARAMETER; + +typedef struct subroutbody { + struct vardec* vardecs; + struct statement* statements; +} SUBROUTBODY; + +typedef struct vardec { + char* type; + bool primitive; + TOKENTYPE typeclass; + STRINGLIST* names; + struct vardec* next; + DEBUGINFO* debug; +} VARDEC; + +// Statements +typedef enum { + ifstatement, whilestatement, letstatement, dostatement, returnstatement +} STATEMENTTYPE; + +typedef struct statement { + STATEMENTTYPE type; + union { + struct letstatement* letstatement; + struct ifstatement* ifstatement; + struct condstatement* whilestatement; + struct subroutcall* dostatement; + struct term* retstatement; + }; + struct statement* next; +} STATEMENT; + +typedef struct letstatement { + char* varname; + struct term* arrayind; + struct term* expression; +} LETSTATEMENT; + +typedef struct ifstatement { + struct condstatement* base; + struct statement* elsestatements; +} IFSTATEMENT; + +typedef struct condstatement { + struct term* expression; + struct statement* statements; +} CONDSTATEMENT; + +// Expressions + +typedef enum { + varname, intconstant, stringconstant, keywordconstant, arrayitem, subroutcall, innerexpression, unaryopterm +} TERMTYPE; + +typedef struct term { + TERMTYPE type; + union { + char* string; + int integer; + struct subroutcall* call; + struct term* expression; + }; + struct term* arrayexp; + char op; + struct term* next; +} TERM; + +typedef struct subroutcall { + char* parentname; + char* name; + struct expressionlist* parameters; + DEBUGINFO* debug; +} SUBROUTCALL; + +typedef struct expressionlist { + TERM* expression; + struct expressionlist* next; +} EXPRESSIONLIST; + +#endif diff --git a/parser.c b/parser.c index d305c00..10638a7 100644 --- a/parser.c +++ b/parser.c @@ -20,10 +20,10 @@ const char* ops[] = { }; const int opssize = sizeof(ops) / sizeof(char*); -const char* varclasses[] = { +const char* classvartypes[] = { "static", "field" }; -const int varclassessize = sizeof(varclasses) / sizeof(char*); +const int classvartypessize = sizeof(classvartypes) / sizeof(char*); const char* vardectypes[] = { "int", "char", "boolean" @@ -290,29 +290,29 @@ STATEMENT* parsestatement(PARSER* p) { if(!strcmp(p->current->token, "let")) { next(p); st->type = letstatement; - st->letst = parselet(p); + st->letstatement = parselet(p); } else if(!strcmp(p->current->token, "if")) { next(p); st->type = ifstatement; - st->ifst = parseif(p); + st->ifstatement = parseif(p); } else if(!strcmp(p->current->token, "while")) { next(p); st->type = whilestatement; - st->whilest = parsecond(p); + st->whilestatement = parsecond(p); } else if(!strcmp(p->current->token, "do")) { next(p); st->type = dostatement; - st->dost = parsesubroutcall(p); + st->dostatement = parsesubroutcall(p); checkcontent(p, ";"); } else if(!strcmp(p->current->token, "return")) { next(p); st->type = returnstatement; if(strcmp(p->current->token, ";")) { - st->retst = parseexpressionnullified(p); + st->retstatement = parseexpressionnullified(p); checkcontent(p, ";"); } else { - st->retst = NULL; + st->retstatement = NULL; next(p); } } else { @@ -361,8 +361,8 @@ int parsepossibilities(PARSER* p, const char** strings, int sz) { return -1; } -VARCLASS parsevarclass(PARSER* p) { - return parsepossibilities(p, varclasses, varclassessize); +CLASSVARTYPE parseclassvartype(PARSER* p) { + return parsepossibilities(p, classvartypes, classvartypessize); } SUBROUTCLASS parsesubroutclass(PARSER* p) { @@ -400,13 +400,13 @@ void parsevardeccommon(PARSER* p, VARDEC* v) { } CLASSVARDEC* parseclassvardec(PARSER* p) { - VARCLASS varclass = parsevarclass(p); - if(varclass == -1) + CLASSVARTYPE classvartype = parseclassvartype(p); + if(classvartype == -1) return NULL; next(p); CLASSVARDEC* classvardec = (CLASSVARDEC*)malloc(sizeof(CLASSVARDEC)); - classvardec->varclass = varclass; + classvardec->type = classvartype; classvardec->base = (VARDEC*)malloc(sizeof(VARDEC)); @@ -484,44 +484,44 @@ SUBROUTBODY* parsesubroutbody(PARSER* p) { return subroutbody; } -SUBDEC* parsesubroutdec(PARSER* p) { +SUBROUTDEC* parsesubroutdec(PARSER* p) { SUBROUTCLASS subroutclass = parsesubroutclass(p); if(subroutclass == -1) return NULL; next(p); - SUBDEC* subdec = (SUBDEC*)malloc(sizeof(SUBDEC)); - subdec->subroutclass = subroutclass; + SUBROUTDEC* subroutdec = (SUBROUTDEC*)malloc(sizeof(SUBROUTDEC)); + subroutdec->subroutclass = subroutclass; - subdec->typeclass = p->current->type; + subroutdec->typeclass = p->current->type; if(!strcmp(p->current->token, "void")) { - subdec->type = p->current->token; + subroutdec->type = p->current->token; next(p); } else { bool dummy; - subdec->type = parsetype(p, &dummy); + subroutdec->type = parsetype(p, &dummy); } - subdec->debug = getdebug(p); + subroutdec->debug = getdebug(p); - subdec->name = parseidentifier(p); + subroutdec->name = parseidentifier(p); checkcontent(p, "("); - subdec->parameters = parseparameters(p); + subroutdec->parameters = parseparameters(p); checkcontent(p, ")"); checkcontent(p, "{"); - subdec->body = parsesubroutbody(p); + subroutdec->body = parsesubroutbody(p); checkcontent(p, "}"); - return subdec; + return subroutdec; } -SUBDEC* parsesubroutdecs(PARSER* p) { - SUBDEC* head = parsesubroutdec(p); - SUBDEC* current = head; - SUBDEC* next; +SUBROUTDEC* parsesubroutdecs(PARSER* p) { + SUBROUTDEC* head = parsesubroutdec(p); + SUBROUTDEC* current = head; + SUBROUTDEC* next; while(next = parsesubroutdec(p), next != NULL) { current->next = next; current = next; @@ -544,7 +544,7 @@ CLASS* parseclass(PARSER* p) { class->vardecs = parseclassvardecs(p); - class->subdecs = parsesubroutdecs(p); + class->subroutdecs = parsesubroutdecs(p); checkcontent(p, "}"); diff --git a/parser.h b/parser.h index 59d6594..b06a33a 100644 --- a/parser.h +++ b/parser.h @@ -2,130 +2,9 @@ #define PARSER_H #include #include "tokenizer.h" +#include "parser-tree.h" #include "util.h" -struct statement; -struct explist; - -typedef struct { - char* file; - int definedat; -} DEBUGINFO; - -typedef enum { - ifstatement, whilestatement, letstatement, dostatement, returnstatement -} STATEMENTTYPE; - -typedef enum { - varname, intconstant, stringconstant, keywordconstant, arrayitem, subroutcall, innerexpression, unaryopterm -} TERMTYPE; - -typedef struct { - char* parentname; - char* name; - struct explist* parameters; - DEBUGINFO* debug; -} SUBROUTCALL; - -typedef struct term { - TERMTYPE type; - union { - char* string; - int integer; - SUBROUTCALL* call; - struct term* expression; - }; - struct term* arrayexp; - char op; - struct term* next; -} TERM; - -typedef struct explist { - TERM* expression; - struct explist* next; -} EXPRESSIONLIST; - -typedef struct { - TERM* expression; - struct statement* statements; -} CONDSTATEMENT; - -typedef struct { - CONDSTATEMENT* base; - struct statement* elsestatements; -} IFSTATEMENT; - -typedef struct { - char* varname; - TERM* arrayind; - TERM* expression; -} LETSTATEMENT; - -typedef struct statement { - STATEMENTTYPE type; - union { - CONDSTATEMENT* whilest; - IFSTATEMENT* ifst; - LETSTATEMENT* letst; - SUBROUTCALL* dost; - TERM* retst; - }; - struct statement* next; -} STATEMENT; - -typedef enum { - stat, field -} VARCLASS; - -typedef struct vardec { - char* type; - bool primitive; - TOKENTYPE typeclass; - STRINGLIST* names; - struct vardec* next; - DEBUGINFO* debug; -} VARDEC; - -typedef struct classvardec { - VARCLASS varclass; - VARDEC* base; - struct classvardec* next; -} CLASSVARDEC; - -typedef enum { - constructor, function, method -} SUBROUTCLASS; - -typedef struct parameter { - char* type; - char* name; - struct parameter* next; -} PARAMETER; - -typedef struct SUBROUTBODY { - VARDEC* vardecs; - STATEMENT* statements; -} SUBROUTBODY; - -typedef struct subdec { - SUBROUTCLASS subroutclass; - char* type; - TOKENTYPE typeclass; - char* name; - PARAMETER* parameters; - SUBROUTBODY* body; - DEBUGINFO* debug; - struct subdec* next; -} SUBDEC; - -typedef struct cl { - char* name; - CLASSVARDEC* vardecs; - SUBDEC* subdecs; - DEBUGINFO* debug; - struct cl* next; -} CLASS; - typedef struct { TOKEN* tokens; TOKEN* current;