jack-compiler/parser/parser-structure.c

254 lines
5.6 KiB
C
Raw Permalink Normal View History

2020-12-22 11:18:54 -05:00
#include <stdlib.h>
2020-12-31 18:24:27 -05:00
#include "parser-util.h"
2020-12-22 11:18:54 -05:00
#include "parser-structure.h"
#include "parser-statements.h"
2020-12-31 18:24:27 -05:00
const char* classvartypesarr[] = { "static", "field" };
const char* vartypesarr[] = { "int", "char", "boolean" };
const char* subroutclassesarr[] = { "constructor", "function", "method" };
mkstrlist(classvartypes, classvartypesarr);
mkstrlist(vartypes, vartypesarr);
mkstrlist(subroutclasses, subroutclassesarr);
/* BEGIN FORWARD DECLARATIONS */
// Miscelaneous
bool isprimitive(TOKEN* tk);
char* parsetype(PARSER* p);
2020-12-22 11:18:54 -05:00
int parsepossibilities(PARSER* p, STRINGARRAY* poss);
2020-12-31 18:24:27 -05:00
// Parsing methods
CLASS* parseclass(PARSER* p);
2020-12-22 11:18:54 -05:00
CLASSVARTYPE parseclassvartype(PARSER* p);
CLASSVARDEC* parseclassvardec(PARSER* p);
CLASSVARDEC* parseclassvardecs(PARSER* p);
SUBROUTCLASS parsesubroutclass(PARSER* p);
SUBROUTDEC* parsesubroutdec(PARSER* p, CLASS* c);
SUBROUTDEC* parsesubroutdecs(PARSER* p, CLASS* c);
2020-12-22 11:18:54 -05:00
PARAMETER* parseparameter(PARSER* p);
PARAMETER* parseparameters(PARSER* p);
SUBROUTBODY* parsesubroutbody(PARSER* p);
void parsevardeccommon(PARSER* p, VARDEC* v);
VARDEC* parsevardec(PARSER* p);
VARDEC* parsevardecs(PARSER* p);
2020-12-31 18:24:27 -05:00
/* END FORWARD DECLARATIONS */
// Miscelaneous
bool isprimitive(TOKEN* tk) {
if(tk->type == keyword)
if(existsinarray(&vartypes, tk->token))
return true;
return false;
}
char* parsetype(PARSER* p) {
if(p->current->type != identifier && p->current->type != keyword)
unexpected(p);
char* result = p->current->token;
next(p);
return result;
}
2020-12-22 11:18:54 -05:00
2020-12-31 18:24:27 -05:00
int parsepossibilities(PARSER* p, STRINGARRAY* poss) {
for(int i = 0; i < poss->size; i++)
if(equals(p, poss->items[i]))
return i;
return -1;
}
// Parsing methods
2020-12-22 11:18:54 -05:00
CLASS* parseclass(PARSER* p) {
checkcontent(p, "class");
CLASS* class = (CLASS*)malloc(sizeof(CLASS));
class->debug = getdebug(p);
class->name = parseidentifier(p);
checkcontent(p, "{");
class->vardecs = parseclassvardecs(p);
class->subroutdecs = parsesubroutdecs(p, class);
2020-12-22 11:18:54 -05:00
checkcontent(p, "}");
2020-12-29 19:27:48 -05:00
if(p->current != NULL)
unexpected(p);
return class;
2020-12-22 11:18:54 -05:00
}
CLASSVARTYPE parseclassvartype(PARSER* p) {
return parsepossibilities(p, &classvartypes);
}
CLASSVARDEC* parseclassvardec(PARSER* p) {
CLASSVARTYPE classvartype = parseclassvartype(p);
if(classvartype == -1)
return NULL;
next(p);
CLASSVARDEC* classvardec = (CLASSVARDEC*)malloc(sizeof(CLASSVARDEC));
classvardec->type = classvartype;
classvardec->base = (VARDEC*)malloc(sizeof(VARDEC));
parsevardeccommon(p, classvardec->base);
return classvardec;
}
CLASSVARDEC* parseclassvardecs(PARSER* p) {
CLASSVARDEC* head = parseclassvardec(p);
CLASSVARDEC* curr = head;
2020-12-24 14:22:22 -05:00
CLASSVARDEC* nextc;
while(nextc = parseclassvardec(p), nextc != NULL) {
curr->next = nextc;
curr = nextc;
2020-12-22 11:18:54 -05:00
}
if(curr != NULL)
curr->next = NULL;
return head;
}
SUBROUTCLASS parsesubroutclass(PARSER* p) {
return parsepossibilities(p, &subroutclasses);
}
SUBROUTDEC* parsesubroutdec(PARSER* p, CLASS* c) {
2020-12-22 11:18:54 -05:00
SUBROUTCLASS subroutclass = parsesubroutclass(p);
if(subroutclass == -1)
return NULL;
next(p);
SUBROUTDEC* subroutdec = (SUBROUTDEC*)malloc(sizeof(SUBROUTDEC));
subroutdec->subroutclass = subroutclass;
2020-12-22 14:00:49 -05:00
if(differs(p, "void"))
subroutdec->type = parsetype(p);
else {
subroutdec->type = p->current->token;
next(p);
}
2020-12-22 11:18:54 -05:00
subroutdec->debug = getdebug(p);
subroutdec->name = parseidentifier(p);
checkcontent(p, "(");
subroutdec->parameters = parseparameters(p);
checkcontent(p, ")");
checkcontent(p, "{");
subroutdec->body = parsesubroutbody(p);
checkcontent(p, "}");
subroutdec->class = c;
2020-12-22 11:18:54 -05:00
return subroutdec;
}
SUBROUTDEC* parsesubroutdecs(PARSER* p, CLASS* c) {
SUBROUTDEC* head = parsesubroutdec(p, c);
2020-12-22 11:18:54 -05:00
SUBROUTDEC* curr = head;
2020-12-24 14:22:22 -05:00
SUBROUTDEC* nexts;
while(nexts = parsesubroutdec(p, c), nexts != NULL) {
2020-12-24 14:22:22 -05:00
curr->next = nexts;
curr = nexts;
2020-12-22 11:18:54 -05:00
}
if(curr != NULL)
curr->next = NULL;
return head;
}
PARAMETER* parseparameter(PARSER* p) {
if(equals(p, ")"))
return NULL;
2021-01-03 14:08:54 -05:00
PARAMETER* param = (PARAMETER*)malloc(sizeof(PARAMETER));
2020-12-24 14:22:22 -05:00
param->debug = getdebug(p);
2020-12-27 16:52:28 -05:00
param->primitive = isprimitive(p->current);
2020-12-22 11:18:54 -05:00
param->type = parsetype(p);
param->name = parseidentifier(p);
return param;
}
PARAMETER* parseparameters(PARSER* p) {
PARAMETER* head = parseparameter(p);
PARAMETER* curr = head;
2020-12-24 14:22:22 -05:00
PARAMETER* nextp;
2020-12-22 11:18:54 -05:00
while(equals(p, ",")) {
next(p);
2020-12-24 14:22:22 -05:00
nextp = parseparameter(p);
if(nextp == NULL)
unexpected(p);
curr->next = nextp;
2020-12-22 11:18:54 -05:00
curr = curr->next;
}
if(curr != NULL)
curr->next = NULL;
return head;
}
SUBROUTBODY* parsesubroutbody(PARSER* p) {
SUBROUTBODY* subroutbody = (SUBROUTBODY*)malloc(sizeof(SUBROUTBODY));
subroutbody->vardecs = parsevardecs(p);
subroutbody->statements = parsestatements(p);
return subroutbody;
}
void parsevardeccommon(PARSER* p, VARDEC* v) {
v->typeclass = p->current->type;
v->primitive = isprimitive(p->current);
v->type = parsetype(p);
STRINGLIST* currstr = (STRINGLIST*)malloc(sizeof(STRINGLIST));
v->names = currstr;
v->debug = getdebug(p);
v->names->content = parseidentifier(p);
while(!strcmp(p->current->token, ",")) {
next(p);
STRINGLIST* nextstr = (STRINGLIST*)malloc(sizeof(STRINGLIST));
nextstr->content = parseidentifier(p);
currstr->next = nextstr;
currstr = nextstr;
}
currstr->next = NULL;
checkcontent(p, ";");
}
VARDEC* parsevardec(PARSER* p) {
if(strcmp(p->current->token, "var"))
return NULL;
next(p);
VARDEC* vardec = (VARDEC*)malloc(sizeof(VARDEC));
parsevardeccommon(p, vardec);
return vardec;
}
VARDEC* parsevardecs(PARSER* p) {
VARDEC* head = parsevardec(p);
VARDEC* curr = head;
2020-12-24 14:22:22 -05:00
VARDEC* nextv;
while(nextv = parsevardec(p), nextv != NULL) {
2020-12-27 16:52:28 -05:00
curr->next = nextv;
2020-12-24 14:22:22 -05:00
curr = nextv;
2020-12-22 11:18:54 -05:00
}
if(curr != NULL)
curr->next = NULL;
return head;
}