Organize parse tree
This commit is contained in:
parent
c629a01b59
commit
bf61fcdd30
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
30
compiler.c
30
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;
|
||||
|
|
|
@ -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
|
58
parser.c
58
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, "}");
|
||||
|
||||
|
|
123
parser.h
123
parser.h
|
@ -2,130 +2,9 @@
|
|||
#define PARSER_H
|
||||
#include <stdbool.h>
|
||||
#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;
|
||||
|
|
Loading…
Reference in New Issue