Organize parse tree

This commit is contained in:
Augusto Gunsch 2020-12-21 20:35:41 -03:00
parent c629a01b59
commit bf61fcdd30
No known key found for this signature in database
GPG Key ID: F7EEFE29825C72DC
6 changed files with 222 additions and 199 deletions

View File

@ -26,7 +26,7 @@ OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, char** retname);
// Scope adding // Scope adding
void addclassvardec(SCOPE* s, CLASSVARDEC* v); void addclassvardec(SCOPE* s, CLASSVARDEC* v);
void addvardec(SCOPE* s, VARDEC* 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); void addclass(SCOPE* s, CLASS* c);
// DEFINITIONS // DEFINITIONS
@ -59,8 +59,8 @@ DEBUGINFO* getdebugvardec(OBJ* obj) {
return obj->vardec->debug; return obj->vardec->debug;
} }
DEBUGINFO* getdebugsubdec(OBJ* obj) { DEBUGINFO* getdebugsubroutdec(OBJ* obj) {
return obj->subdec->debug; return obj->subroutdec->debug;
} }
DEBUGINFO* getdebugclass(OBJ* obj) { DEBUGINFO* getdebugclass(OBJ* obj) {
@ -150,15 +150,15 @@ CLASSVARDEC* getclassvardec(SCOPE* s, char* name) {
return NULL; return NULL;
} }
SUBDEC* getsubdec(SCOPE* s, char* name) { SUBROUTDEC* getsubroutdec(SCOPE* s, char* name) {
SUBDEC* curr = s->subroutines; SUBROUTDEC* curr = s->subroutines;
while(curr != NULL) { while(curr != NULL) {
if(!strcmp(curr->name, name)) if(!strcmp(curr->name, name))
return curr; return curr;
curr = curr->next; curr = curr->next;
} }
if(s->previous != NULL) if(s->previous != NULL)
return getsubdec(s->previous, name); return getsubroutdec(s->previous, name);
return NULL; return NULL;
} }
@ -174,8 +174,8 @@ CLASS* getclass(SCOPE* s, char* name) {
return NULL; return NULL;
} }
SUBDEC* getsubdecfromclass(CLASS* c, char* name) { SUBROUTDEC* getsubroutdecfromclass(CLASS* c, char* name) {
SUBDEC* curr = c->subdecs; SUBROUTDEC* curr = c->subroutdecs;
while(curr != NULL) { while(curr != NULL) {
if(!strcmp(curr->name, name)) if(!strcmp(curr->name, name))
return curr; return curr;
@ -184,34 +184,34 @@ SUBDEC* getsubdecfromclass(CLASS* c, char* name) {
return NULL; return NULL;
} }
SUBDEC* getsubdecfromvar(SCOPE* s, OBJ* var, SUBROUTCALL* call) { SUBROUTDEC* getsubroutdecfromvar(SCOPE* s, OBJ* var, SUBROUTCALL* call) {
VARDEC* vd = tovardec(var); VARDEC* vd = tovardec(var);
if(vd == NULL || vd->primitive) if(vd == NULL || vd->primitive)
invalidparent(call); invalidparent(call);
CLASS* c = getclass(s, vd->type); CLASS* c = getclass(s, vd->type);
return getsubdecfromclass(c, call->name); return getsubroutdecfromclass(c, call->name);
} }
SUBDEC* getsubdecfromparent(SCOPE* s, SUBROUTCALL* call) { SUBROUTDEC* getsubroutdecfromparent(SCOPE* s, SUBROUTCALL* call) {
SUBDEC* sd; SUBROUTDEC* sd;
OBJ* parent = getbyname(s, call->parentname); OBJ* parent = getbyname(s, call->parentname);
if(parent == NULL) if(parent == NULL)
notdeclared(call->parentname, call->debug); notdeclared(call->parentname, call->debug);
if(parent->type == class) if(parent->type == class)
sd = getsubdecfromclass(parent->class, call->name); sd = getsubroutdecfromclass(parent->class, call->name);
else else
sd = getsubdecfromvar(s, parent, call); sd = getsubroutdecfromvar(s, parent, call);
return sd; return sd;
} }
SUBDEC* getsubdecfromcall(SCOPE* s, SUBROUTCALL* call) { SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call) {
SUBDEC* sd; SUBROUTDEC* sd;
if(call->parentname != NULL) if(call->parentname != NULL)
sd = getsubdecfromparent(s, call); sd = getsubroutdecfromparent(s, call);
else else
sd = getsubdec(s, call->name); sd = getsubroutdec(s, call->name);
if(sd == NULL) if(sd == NULL)
notdeclared(call->name, call->debug); notdeclared(call->name, call->debug);
return sd; return sd;
@ -233,14 +233,14 @@ OBJ* getbyname(SCOPE* s, char* name) {
if(vd != NULL) { if(vd != NULL) {
o->vardec = vd; o->vardec = vd;
o->type = vardec; o->type = vardec;
o->getdebug = getdebugsubdec; o->getdebug = getdebugsubroutdec;
return o; return o;
} }
SUBDEC* sd = getsubdec(s, name); SUBROUTDEC* sd = getsubroutdec(s, name);
if(sd != NULL) { if(sd != NULL) {
o->subdec = sd; o->subroutdec = sd;
o->type = subdec; o->type = subroutdec;
o->getdebug = getdebugclassvardec; o->getdebug = getdebugclassvardec;
return o; return o;
} }
@ -286,9 +286,9 @@ void addvardec(SCOPE* s, VARDEC* v) {
s->vardecs = new; s->vardecs = new;
} }
void addsubdec(SCOPE* s, SUBDEC* sd) { void addsubroutdec(SCOPE* s, SUBROUTDEC* sd) {
ensurenoduplicate(s, sd->name, sd->debug); ensurenoduplicate(s, sd->name, sd->debug);
SUBDEC* new = copy(sd, sizeof(SUBDEC)); SUBROUTDEC* new = copy(sd, sizeof(SUBROUTDEC));
new->next = s->subroutines; new->next = s->subroutines;
s->subroutines = new; s->subroutines = new;
} }
@ -319,11 +319,11 @@ void addvardecs(SCOPE* s, VARDEC* vs) {
} }
} }
void addsubdecs(SCOPE* s, SUBDEC* ss) { void addsubroutdecs(SCOPE* s, SUBROUTDEC* ss) {
SUBDEC* next; SUBROUTDEC* next;
while(ss != NULL) { while(ss != NULL) {
next = ss->next; next = ss->next;
addsubdec(s, ss); addsubroutdec(s, ss);
ss = next; ss = next;
} }
} }

View File

@ -10,7 +10,7 @@
// Data types // Data types
typedef struct scope { typedef struct scope {
SUBDEC* subroutines; SUBROUTDEC* subroutines;
CLASSVARDEC* classvardecs; CLASSVARDEC* classvardecs;
VARDEC* vardecs; VARDEC* vardecs;
CLASS* classes; CLASS* classes;
@ -18,13 +18,13 @@ typedef struct scope {
} SCOPE; } SCOPE;
typedef enum { typedef enum {
subdec, classvardec, vardec, class subroutdec, classvardec, vardec, class
} OBJTYPE; } OBJTYPE;
typedef struct object { typedef struct object {
OBJTYPE type; OBJTYPE type;
union { union {
SUBDEC* subdec; SUBROUTDEC* subroutdec;
CLASSVARDEC* classvardec; CLASSVARDEC* classvardec;
VARDEC* vardec; VARDEC* vardec;
CLASS* class; CLASS* class;
@ -35,15 +35,15 @@ typedef struct object {
// Group adding // Group adding
void addclassvardecs(SCOPE* s, CLASSVARDEC* vs); void addclassvardecs(SCOPE* s, CLASSVARDEC* vs);
void addvardecs(SCOPE* s, VARDEC* 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); void addclasses(SCOPE* s, CLASS* c);
// Scope handling // Scope handling
SCOPE* mkscope(SCOPE* prev); SCOPE* mkscope(SCOPE* prev);
// Single type getters // Single type getters
SUBDEC* getsubdec(SCOPE* s, char* name); SUBROUTDEC* getsubroutdec(SCOPE* s, char* name);
SUBDEC* getsubdecfromcall(SCOPE* s, SUBROUTCALL* call); SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call);
CLASS* getclass(SCOPE* s, char* name); CLASS* getclass(SCOPE* s, char* name);
// Generic getters // Generic getters

View File

@ -27,7 +27,7 @@ char* dotlabel(char* n1, char* n2) {
return result; return result;
} }
char* subdecname(CLASS* c, SUBDEC* sd) { char* subroutdecname(CLASS* c, SUBROUTDEC* sd) {
return dotlabel(c->name, sd->name); return dotlabel(c->name, sd->name);
} }
@ -126,10 +126,10 @@ LINEBLOCK* compilecallln(CLASS* c, SUBROUTCALL* call) {
} }
// temporary ignore list for OS functions // temporary ignore list for OS functions
char* ignoresubdecs[] = { char* ignoresubroutdecs[] = {
"printInt", "void", "peek", "int" "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* compilesubroutcall(SCOPE* s, CLASS* c, SUBROUTCALL* call) {
LINEBLOCK* block = compilecallln(c, call); LINEBLOCK* block = compilecallln(c, call);
@ -143,13 +143,13 @@ LINEBLOCK* compilesubroutcall(SCOPE* s, CLASS* c, SUBROUTCALL* call) {
// gambiarra // gambiarra
char* type = NULL; char* type = NULL;
for(int i = 0; i < ignorecount; i += 2) { for(int i = 0; i < ignorecount; i += 2) {
if(!strcmp(call->name, ignoresubdecs[i])) { if(!strcmp(call->name, ignoresubroutdecs[i])) {
type = ignoresubdecs[i+1]; type = ignoresubroutdecs[i+1];
break; break;
} }
} }
if(type == NULL) if(type == NULL)
type = getsubdecfromcall(s, call)->type; type = getsubroutdecfromcall(s, call)->type;
if(!strcmp(type, "void")) { if(!strcmp(type, "void")) {
char* tokens[] = { "pop", "temp", "0" }; char* tokens[] = { "pop", "temp", "0" };
appendln(block, mksimpleln(tokens, sizeof(tokens) / sizeof(char*))); appendln(block, mksimpleln(tokens, sizeof(tokens) / sizeof(char*)));
@ -162,7 +162,7 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) {
LINE* ret = onetoken("return"); LINE* ret = onetoken("return");
LINEBLOCK* block = mklnblk(ret); LINEBLOCK* block = mklnblk(ret);
// void subdecs 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, sizeof(tokens) / sizeof(char*)));
@ -174,9 +174,9 @@ LINEBLOCK* compileret(SCOPE* s, TERM* e) {
LINEBLOCK* compilestatement(SCOPE* s, CLASS* c, STATEMENT* st) { LINEBLOCK* compilestatement(SCOPE* s, CLASS* c, STATEMENT* st) {
if(st->type == dostatement) if(st->type == dostatement)
return compilesubroutcall(s, c, st->dost); return compilesubroutcall(s, c, st->dostatement);
else if(st->type == returnstatement) else if(st->type == returnstatement)
return compileret(s, st->retst); return compileret(s, st->retstatement);
else { else {
eprintf("UNSUPPORTED\n"); eprintf("UNSUPPORTED\n");
exit(1); exit(1);
@ -198,10 +198,10 @@ LINEBLOCK* compilefunbody(SCOPE* s, CLASS* c, SUBROUTBODY* b) {
return head; return head;
} }
LINEBLOCK* compilefundec(SCOPE* s, CLASS* c, SUBDEC* 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, subdecname(c, f)); addtoken(label, subroutdecname(c, f));
addtoken(label, itoa(countlocalvars(f->body->vardecs))); addtoken(label, itoa(countlocalvars(f->body->vardecs)));
label->next = NULL; label->next = NULL;
@ -214,7 +214,7 @@ LINEBLOCK* compilefundec(SCOPE* s, CLASS* c, SUBDEC* f) {
return mklnblk(label); 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 // 'this' and arguments are pushed by caller
// Must have a 'return' at the end // Must have a 'return' at the end
// Label names must have class name too (see mapping) // 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) { LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
SCOPE* topscope = mkscope(c->globalscope); SCOPE* topscope = mkscope(c->globalscope);
addclassvardecs(topscope, class->vardecs); addclassvardecs(topscope, class->vardecs);
addsubdecs(topscope, class->subdecs); addsubroutdecs(topscope, class->subroutdecs);
LINEBLOCK* output = NULL; LINEBLOCK* output = NULL;
SUBDEC* curr = class->subdecs; SUBROUTDEC* curr = class->subroutdecs;
while(curr != NULL) { while(curr != NULL) {
output = mergelnblks(output, compilesubdec(topscope, class, curr)); output = mergelnblks(output, compilesubroutdec(topscope, class, curr));
curr = curr->next; curr = curr->next;
} }
return output; return output;

144
parser-tree.h Normal file
View File

@ -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

View File

@ -20,10 +20,10 @@ const char* ops[] = {
}; };
const int opssize = sizeof(ops) / sizeof(char*); const int opssize = sizeof(ops) / sizeof(char*);
const char* varclasses[] = { const char* classvartypes[] = {
"static", "field" "static", "field"
}; };
const int varclassessize = sizeof(varclasses) / sizeof(char*); const int classvartypessize = sizeof(classvartypes) / sizeof(char*);
const char* vardectypes[] = { const char* vardectypes[] = {
"int", "char", "boolean" "int", "char", "boolean"
@ -290,29 +290,29 @@ STATEMENT* parsestatement(PARSER* p) {
if(!strcmp(p->current->token, "let")) { if(!strcmp(p->current->token, "let")) {
next(p); next(p);
st->type = letstatement; st->type = letstatement;
st->letst = parselet(p); st->letstatement = parselet(p);
} else if(!strcmp(p->current->token, "if")) { } else if(!strcmp(p->current->token, "if")) {
next(p); next(p);
st->type = ifstatement; st->type = ifstatement;
st->ifst = parseif(p); st->ifstatement = parseif(p);
} else if(!strcmp(p->current->token, "while")) { } else if(!strcmp(p->current->token, "while")) {
next(p); next(p);
st->type = whilestatement; st->type = whilestatement;
st->whilest = parsecond(p); st->whilestatement = parsecond(p);
} else if(!strcmp(p->current->token, "do")) { } else if(!strcmp(p->current->token, "do")) {
next(p); next(p);
st->type = dostatement; st->type = dostatement;
st->dost = parsesubroutcall(p); st->dostatement = parsesubroutcall(p);
checkcontent(p, ";"); checkcontent(p, ";");
} else if(!strcmp(p->current->token, "return")) { } else if(!strcmp(p->current->token, "return")) {
next(p); next(p);
st->type = returnstatement; st->type = returnstatement;
if(strcmp(p->current->token, ";")) { if(strcmp(p->current->token, ";")) {
st->retst = parseexpressionnullified(p); st->retstatement = parseexpressionnullified(p);
checkcontent(p, ";"); checkcontent(p, ";");
} }
else { else {
st->retst = NULL; st->retstatement = NULL;
next(p); next(p);
} }
} else { } else {
@ -361,8 +361,8 @@ int parsepossibilities(PARSER* p, const char** strings, int sz) {
return -1; return -1;
} }
VARCLASS parsevarclass(PARSER* p) { CLASSVARTYPE parseclassvartype(PARSER* p) {
return parsepossibilities(p, varclasses, varclassessize); return parsepossibilities(p, classvartypes, classvartypessize);
} }
SUBROUTCLASS parsesubroutclass(PARSER* p) { SUBROUTCLASS parsesubroutclass(PARSER* p) {
@ -400,13 +400,13 @@ void parsevardeccommon(PARSER* p, VARDEC* v) {
} }
CLASSVARDEC* parseclassvardec(PARSER* p) { CLASSVARDEC* parseclassvardec(PARSER* p) {
VARCLASS varclass = parsevarclass(p); CLASSVARTYPE classvartype = parseclassvartype(p);
if(varclass == -1) if(classvartype == -1)
return NULL; return NULL;
next(p); next(p);
CLASSVARDEC* classvardec = (CLASSVARDEC*)malloc(sizeof(CLASSVARDEC)); CLASSVARDEC* classvardec = (CLASSVARDEC*)malloc(sizeof(CLASSVARDEC));
classvardec->varclass = varclass; classvardec->type = classvartype;
classvardec->base = (VARDEC*)malloc(sizeof(VARDEC)); classvardec->base = (VARDEC*)malloc(sizeof(VARDEC));
@ -484,44 +484,44 @@ SUBROUTBODY* parsesubroutbody(PARSER* p) {
return subroutbody; return subroutbody;
} }
SUBDEC* parsesubroutdec(PARSER* p) { SUBROUTDEC* parsesubroutdec(PARSER* p) {
SUBROUTCLASS subroutclass = parsesubroutclass(p); SUBROUTCLASS subroutclass = parsesubroutclass(p);
if(subroutclass == -1) if(subroutclass == -1)
return NULL; return NULL;
next(p); next(p);
SUBDEC* subdec = (SUBDEC*)malloc(sizeof(SUBDEC)); SUBROUTDEC* subroutdec = (SUBROUTDEC*)malloc(sizeof(SUBROUTDEC));
subdec->subroutclass = subroutclass; subroutdec->subroutclass = subroutclass;
subdec->typeclass = p->current->type; subroutdec->typeclass = p->current->type;
if(!strcmp(p->current->token, "void")) { if(!strcmp(p->current->token, "void")) {
subdec->type = p->current->token; subroutdec->type = p->current->token;
next(p); next(p);
} }
else { else {
bool dummy; 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, "("); checkcontent(p, "(");
subdec->parameters = parseparameters(p); subroutdec->parameters = parseparameters(p);
checkcontent(p, ")"); checkcontent(p, ")");
checkcontent(p, "{"); checkcontent(p, "{");
subdec->body = parsesubroutbody(p); subroutdec->body = parsesubroutbody(p);
checkcontent(p, "}"); checkcontent(p, "}");
return subdec; return subroutdec;
} }
SUBDEC* parsesubroutdecs(PARSER* p) { SUBROUTDEC* parsesubroutdecs(PARSER* p) {
SUBDEC* head = parsesubroutdec(p); SUBROUTDEC* head = parsesubroutdec(p);
SUBDEC* current = head; SUBROUTDEC* current = head;
SUBDEC* next; SUBROUTDEC* next;
while(next = parsesubroutdec(p), next != NULL) { while(next = parsesubroutdec(p), next != NULL) {
current->next = next; current->next = next;
current = next; current = next;
@ -544,7 +544,7 @@ CLASS* parseclass(PARSER* p) {
class->vardecs = parseclassvardecs(p); class->vardecs = parseclassvardecs(p);
class->subdecs = parsesubroutdecs(p); class->subroutdecs = parsesubroutdecs(p);
checkcontent(p, "}"); checkcontent(p, "}");

123
parser.h
View File

@ -2,130 +2,9 @@
#define PARSER_H #define PARSER_H
#include <stdbool.h> #include <stdbool.h>
#include "tokenizer.h" #include "tokenizer.h"
#include "parser-tree.h"
#include "util.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 { typedef struct {
TOKEN* tokens; TOKEN* tokens;
TOKEN* current; TOKEN* current;