#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 \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 \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); }