#include #include #include "node.h" #include "printxf.h" #include "sym.h" #include "type.h" struct ast_fprint_info { FILE *fp; int indent; }; static int __ast_fprint_pre(struct node *n, void *_info) { struct ast_fprint_info *info = _info; struct node *arg; if (n->prev) fputc(' ', info->fp); if (node_is(n->up, ":block")) { info->indent += 4; fprintf(info->fp, "\n%*s", info->indent, ""); } if (n->ntype == N_EXPR) fputc('(', info->fp); fprintxf(NULL, info->fp, "%N%T", n, n->sym ? n->sym->type : NULL); if ((n->ntype == N_EXPR) && n->expr.args) fputc(' ', info->fp); return 0; } static int __ast_fprint_post(struct node *n, void *_info) { struct ast_fprint_info *info = _info; struct node *c; if (node_is(n, ":block")) fprintf(info->fp, "\n%*s", info->indent, ""); if (n->ntype == N_EXPR) fputc(')', info->fp); if (node_is(n->up, ":block")) info->indent -= 4; return 0; } void ast_fprint(FILE *fp, struct node *root) { struct ast_fprint_info info = { .fp = fp, }; node_walk(root, __ast_fprint_pre, __ast_fprint_post, &info); fputc('\n', fp); } int order_vfprintxf(struct printxf *pxf, FILE *fp, const char *fmt, va_list ap) { int arg = va_arg(ap, int); switch (arg) { case 1: fputs("1st", fp); return 3; case 2: fputs("2nd", fp); return 3; case 3: fputs("3rd", fp); return 3; } return fprintf(fp, "%dth", arg); } __attribute__((constructor)) static void utils_init(void) { printxf_default.vfprintxf['O'] = order_vfprintxf; }