#include #include #include #include #include #include "node.h" void nprint(node_t *n, FILE *fp) { switch (n->ntype) { case N_CONS: fputs("", fp); break; case N_OP: fputc(n->op, fp); break; case N_IDENT: fputs(n->ident, fp); break; case N_NUM: fprintf(fp, "%#"PRIx64, n->num); break; case N_STRING: fprintf(fp, "\"%s\"", n->string); break; default: fputs("", fp); } } int __node_dump_pre(node_t *n, void *_info) { ndump_info_t *info = _info; switch (n->ntype) { case N_CONS: info->indent += 2; break; default: fprintf(info->fp, "%*s", info->indent, ""); nprint(n, info->fp); fputc('\n', info->fp); } return 0; } int __node_dump_post(node_t *n, void *_info) { ndump_info_t *info = _info; node_t *next; if (n->ntype == N_CONS) info->indent -= 2; return 0; } void ndump(node_t *n, ndump_info_t *info) { nwalk(n, __node_dump_pre, __node_dump_post, info); } int nwalk(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_CONS) { err = ncar(n) ? nwalk(ncar(n), pre, post, ctx) : 0; if (err) return err; err = ncdr(n) ? nwalk(ncdr(n), pre, post, ctx) : 0; if (err) return err; } if (post && (err = post(n, ctx))) return err; return 0; } /* high-level constructors */ node_t *ncall(char *name, node_t *args) { return ncons(nop('('), ncons(nident(name), args)); } node_t *nmap(char *name, node_t *key) { return ncons(nop('{'), ncons(nident(name), key)); } /* basic constructors */ static node_t *__node(ntype_t ntype) { node_t *n = calloc(1, sizeof(*n)); assert(n); n->ntype = ntype; return n; } node_t *ncons(node_t *car, node_t *cdr) { node_t *n = __node(N_CONS); assert(car); car->up = n; if (cdr) cdr->up = n; n->cons.car = car; n->cons.cdr = cdr; return n; } node_t *nop(op_t op) { node_t *n = __node(N_OP); n->op = op; return n; } node_t *nident(char *name) { node_t *n = __node(N_IDENT); n->ident = name; return n; } node_t *nnum(int64_t num) { node_t *n = __node(N_NUM); n->num = num; return n; } node_t *nstring(char *string) { node_t *n = __node(N_STRING); n->string = string; return n; }