#include #include #include #include #include #include "node.h" void node_print_atom(node_t *n, FILE *fp) { switch (n->atom.atype) { case A_IDENT: fputs(n->atom.ident, fp); break; case A_NUM: fprintf(fp, "%#"PRIx64, n->atom.num); break; case A_STRING: fprintf(fp, "\"%s\"", n->atom.string); break; default: fputs("INVALID_ATOM", fp); } } void node_print_expr(node_t *n, FILE *fp) { if (!isprint(n->expr.etype)) { fputs("INVALID_EXPR", fp); return; } fputc(n->expr.etype, fp); } void node_print(node_t *n, FILE *fp) { switch (n->ntype) { case N_ATOM: node_print_atom(n, fp); break; case N_EXPR: node_print_expr(n, fp); break; default: fputs("INVALID_NODE", fp); } } int __node_dump_pre(node_t *n, void *_info) { node_dump_info_t *info = _info; fprintf(info->fp, "%*s", info->indent, ""); node_print(n, info->fp); fputc('\n', info->fp); if (n->ntype == N_EXPR) { info->indent += 2; } return 0; } int __node_dump_post(node_t *n, void *_info) { node_dump_info_t *info = _info; node_t *next; if (n->ntype == N_EXPR) info->indent -= 2; if (n->up && n->up->ntype == N_EXPR && n->up->expr.arg == n) { for (next = n->next; next; next = next->next) { node_dump(next, info); } } return 0; } void node_dump(node_t *n, node_dump_info_t *info) { node_walk(n, __node_dump_pre, __node_dump_post, info); } int node_walk(node_t *n, int (*pre)(node_t *, void *), int (*post)(node_t *, void *), void *ctx) { int err = 0; if (pre && (err = pre(n, ctx))) return err; if (n->ntype == N_EXPR) { err = node_walk(n->expr.arg, pre, post, ctx); if (err) return err; } if (post && (err = post(n, ctx))) return err; return 0; } static node_t *__node(ntype_t ntype) { node_t *n = calloc(1, sizeof(*n)); assert(n); n->ntype = ntype; return n; } node_t *node_ident(char *name) { node_t *n = __node(N_ATOM); n->atom.atype = A_IDENT; n->atom.ident = name; return n; } node_t *node_num(int64_t num) { node_t *n = __node(N_ATOM); n->atom.atype = A_NUM; n->atom.num = num; return n; } node_t *node_string(char *string) { node_t *n = __node(N_ATOM); n->atom.atype = A_STRING; n->atom.string = string; return n; } node_t *node_expr(etype_t etype, node_t *arg) { node_t *n = __node(N_EXPR); node_t *next; n->expr.etype = etype; n->expr.arg = arg; for (next = arg; next; next = next->next) next->up = n; return n; } node_t *node_cons(node_t *head, node_t *tail) { node_t *next; assert(!head->next); head->next = tail; for (next = tail; next; next = next->next) next->up = head->up; return head; }