#include "printer.h"
void printexpression(TERM* e, FILE* output, int depth);
void printstatements(STATEMENT* st, FILE* output, int depth);
const char* tmpvarclasses[] = {
"static", "field"
};
const int tmpvarclassessize = sizeof(tmpvarclasses) / sizeof(char*);
const char* tmpsubroutclasses[] = {
"constructor", "function", "method"
};
const int tmpsubroutclassessize = sizeof(tmpsubroutclasses) / sizeof(char*);
const char* tmptokentypes[] = {
"keyword", "identifier"
};
void printident(FILE* output, int depth) {
for(int i = 0; i < depth; i++)
fprintf(output, " ");
}
void printstringlist(FILE* output, int depth, STRINGLIST* ls) {
printident(output, depth);
fprintf(output, " %s \r\n", ls->content);
if(ls->next != NULL) {
printident(output, depth);
fprintf(output, " , \r\n");
printstringlist(output, depth, ls->next);
}
}
void printvardec(VARDEC* vd, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "<%s> %s %s>\r\n", tmptokentypes[vd->typeclass], vd->type, tmptokentypes[vd->typeclass]);
printstringlist(output, depth, vd->names);
printident(output, depth);
fprintf(output, " ; \r\n");
}
void printvardecs(VARDEC* vd, FILE* output, int depth) {
VARDEC* current = vd;
while(current != NULL) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " var \r\n");
printvardec(current, output, depth+1);
current = current->next;
printident(output, depth);
fprintf(output, "\r\n");
}
}
void printclassvardec(CLASSVARDEC* vd, FILE* output, int depth) {
printident(output, depth);
fprintf(output, " %s \r\n", tmpvarclasses[vd->varclass]);
printvardec(vd->base, output, depth);
}
void printclassvardecs(CLASSVARDEC* vd, FILE* output, int depth) {
CLASSVARDEC* current = vd;
while(current != NULL) {
printident(output, depth);
fprintf(output, "\r\n");
printclassvardec(current, output, depth+1);
current = current->next;
printident(output, depth);
fprintf(output, "\r\n");
}
}
void printparameter(PARAMETER* p, FILE* output, int depth) {
printident(output, depth);
fprintf(output, " %s \r\n", p->type);
printident(output, depth);
fprintf(output, " %s \r\n", p->name);
if(p->next != NULL) {
printident(output, depth);
fprintf(output, " , \r\n");
}
}
void printparameters(PARAMETER* p, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
PARAMETER* current = p;
while(current != NULL) {
printparameter(current, output, depth+1);
current = current->next;
}
printident(output, depth);
fprintf(output, "\r\n");
}
void printexpressionlist(EXPRESSIONLIST* list, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
if(list != NULL) {
EXPRESSIONLIST* current = list;
while(current != NULL) {
printexpression(current->expression, output, depth+1);
current = current->next;
if(current != NULL) {
printident(output, depth+1);
fprintf(output, " , \r\n");
}
}
}
printident(output, depth);
fprintf(output, "\r\n");
}
void printsubroutcall(SUBROUTCALL* c, FILE* output, int depth) {
if(c->parentname != NULL) {
printident(output, depth);
fprintf(output, " %s \r\n", c->parentname);
printident(output, depth);
fprintf(output, " . \r\n");
}
printident(output, depth);
fprintf(output, " %s \r\n", c->name);
printident(output, depth);
fprintf(output, " ( \r\n");
printexpressionlist(c->parameters, output, depth);
printident(output, depth);
fprintf(output, " ) \r\n");
}
void printterm(TERM* e, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
if(e->type == varname) {
printident(output, depth+1);
fprintf(output, " %s \r\n", e->string);
} else if(e->type == subroutcall) {
printsubroutcall(e->call, output, depth+1);
} else if(e->type == stringconstant) {
printident(output, depth+1);
fprintf(output, " %s \r\n", e->string);
} else if(e->type == keywordconstant) {
printident(output, depth+1);
fprintf(output, " %s \r\n", e->string);
} else if(e->type == intconstant) {
printident(output, depth+1);
fprintf(output, " %i \r\n", e->integer);
} else if(e->type == arrayitem) {
printident(output, depth+1);
fprintf(output, " %s \r\n", e->string);
printident(output, depth+1);
fprintf(output, " [ \r\n");
printexpression(e->arrayexp, output, depth+1);
printident(output, depth+1);
fprintf(output, " ] \r\n");
} else if(e->type == innerexpression) {
printident(output, depth+1);
fprintf(output, " ( \r\n");
printexpression(e->expression, output, depth+1);
printident(output, depth+1);
fprintf(output, " ) \r\n");
} else {
printident(output, depth+1);
fprintf(output, " %c \r\n", e->unaryop);
printterm(e->expression, output, depth+1);
}
printident(output, depth);
fprintf(output, "\r\n");
if(e->next != NULL) {
printident(output, depth);
fprintf(output, " %c \r\n", e->op);
}
}
void printexpression(TERM* e, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
TERM* current = e;
while(current != NULL) {
printterm(current, output, depth+1);
current = current->next;
}
printident(output, depth);
fprintf(output, "\r\n");
}
void printcond(CONDSTATEMENT* st, FILE* output, int depth) {
printident(output, depth);
fprintf(output, " ( \r\n");
printexpression(st->expression, output, depth);
printident(output, depth);
fprintf(output, " ) \r\n");
printident(output, depth);
fprintf(output, " { \r\n");
printstatements(st->statements, output, depth);
printident(output, depth);
fprintf(output, " } \r\n");
}
void printif(IFSTATEMENT* st, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " if \r\n");
printcond(st->base, output, depth+1);
if(st->elsestatements != NULL) {
printident(output, depth+1);
fprintf(output, " else \r\n");
printident(output, depth+1);
fprintf(output, " { \r\n");
printstatements(st->elsestatements, output, depth+1);
printident(output, depth+1);
fprintf(output, " } \r\n");
}
printident(output, depth);
fprintf(output, "\r\n");
}
void printwhile(CONDSTATEMENT* st, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " while \r\n");
printcond(st, output, depth+1);
printident(output, depth);
fprintf(output, "\r\n");
}
void printlet(LETSTATEMENT* st, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " let \r\n");
printident(output, depth+1);
fprintf(output, " %s \r\n", st->varname);
if(st->arrayind != NULL) {
printident(output, depth+1);
fprintf(output, " [ \r\n");
printexpression(st->arrayind, output, depth+1);
printident(output, depth+1);
fprintf(output, " ] \r\n");
}
printident(output, depth+1);
fprintf(output, " = \r\n");
printexpression(st->expression, output, depth+1);
printident(output, depth+1);
fprintf(output, " ; \r\n");
printident(output, depth);
fprintf(output, "\r\n");
}
void printdo(SUBROUTCALL* st, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " do \r\n");
printsubroutcall(st, output, depth+1);
printident(output, depth+1);
fprintf(output, " ; \r\n");
printident(output, depth);
fprintf(output, "\r\n");
}
void printreturn(TERM* st, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " return \r\n");
if(st != NULL)
printexpression(st, output, depth+1);
printident(output, depth+1);
fprintf(output, " ; \r\n");
printident(output, depth);
fprintf(output, "\r\n");
}
void printstatement(STATEMENT* st, FILE* output, int depth) {
if(st->type == ifstatement)
printif(st->ifst, output, depth);
else if(st->type == letstatement)
printlet(st->letst, output, depth);
else if(st->type == whilestatement)
printwhile(st->whilest, output, depth);
else if(st->type == dostatement)
printdo(st->dost, output, depth);
else
printreturn(st->retst, output, depth);
}
void printstatements(STATEMENT* st, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
STATEMENT* current = st;
while(current != NULL) {
printstatement(current, output, depth+1);
current = current->next;
}
printident(output, depth);
fprintf(output, "\r\n");
}
void printsubroutbody(SUBROUTBODY* bd, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " { \r\n");
printvardecs(bd->vardecs, output, depth+1);
printstatements(bd->statements, output, depth+1);
printident(output, depth+1);
fprintf(output, " } \r\n");
printident(output, depth);
fprintf(output, "\r\n");
}
void printsubroutdec(SUBDEC* sd, FILE* output, int depth) {
printident(output, depth);
fprintf(output, " %s \r\n", tmpsubroutclasses[sd->subroutclass]);
printident(output, depth);
fprintf(output, "<%s> %s %s>\r\n", tmptokentypes[sd->typeclass], sd->type, tmptokentypes[sd->typeclass]);
printident(output, depth);
fprintf(output, " %s \r\n", sd->name);
printident(output, depth);
fprintf(output, " ( \r\n");
printparameters(sd->parameters, output, depth);
printident(output, depth);
fprintf(output, " ) \r\n");
printsubroutbody(sd->body, output, depth);
}
void printsubroutdecs(SUBDEC* sd, FILE* output, int depth) {
SUBDEC* current = sd;
while(current != NULL) {
printident(output, depth);
fprintf(output, "\r\n");
printsubroutdec(current, output, depth+1);
current = current->next;
printident(output, depth);
fprintf(output, "\r\n");
}
}
void printclass(CLASS* c, FILE* output, int depth) {
printident(output, depth);
fprintf(output, "\r\n");
printident(output, depth+1);
fprintf(output, " class \r\n");
printident(output, depth+1);
fprintf(output, " %s \r\n", c->name);
printident(output, depth+1);
fprintf(output, " { \r\n");
printclassvardecs(c->vardecs, output, depth+1);
printsubroutdecs(c->subdecs, output, depth+1);
printident(output, depth+1);
fprintf(output, " } \r\n");
printident(output, depth);
fprintf(output, "\r\n");
}
void printparser(FILE* output, PARSER* p) {
printclass(p->output, output, 0);
}