#include #include #include #include #include #include #include #include "ply.h" void __type_dump(type_t *t, FILE *fp) { if (!t) return; fputs(" \e[2m<", fp); type_dump(t, fp); fputs(">\e[0m", fp); } void node_print(node_t *n, FILE *fp) { switch (n->ntype) { case N_LIST: fputs("()", fp); break; case N_KEYWORD: fputs("\e[31m", fp); fputc(n->keyword.class, fp); if (n->keyword.op) fputc(n->keyword.op, fp); fputs("\e[0m", 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); } __type_dump(n->type, fp); } struct node_dump_info { FILE *fp; int indent; }; int __node_dump_pre(node_t *n, void *_info) { struct node_dump_info *info = _info; switch (n->ntype) { case N_LIST: fprintf(info->fp, "%s%*s(", info->indent? "\n" : "", info->indent, ""); info->indent += 2; break; default: if (n->prev) { node_t *c; for (c = n->next; c; c = c->next) { if (c->ntype == N_LIST) { fprintf(info->fp, "\n%*s", info->indent, ""); break; } } if (!c) fputc(' ', info->fp); } node_print(n, info->fp); } return 0; } int __node_dump_post(node_t *n, void *_info) { struct node_dump_info *info = _info; node_t *c; if (n->ntype != N_LIST) return 0; info->indent -= 2; for (c = n->list; c; c = c->next) { if (c->ntype == N_LIST) { fprintf(info->fp, "\n%*s)", info->indent, ""); __type_dump(n->type, info->fp); return 0; } } fputc(')', info->fp); __type_dump(n->type, info->fp); return 0; } void node_dump(node_t *n, FILE *fp) { struct node_dump_info info = { .fp = fp, }; 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_LIST) { node_t *c; for (c = n->list; c; c = c->next) { err = node_walk(c, pre, post, ctx); if (err) return err; } } if (post && (err = post(n, ctx))) return err; return 0; } int node_replace(node_t *n, node_t *new) { new->up = n->up; if (n->prev) { new->prev = n->prev; n->prev->next = new; } if (n->next) { new->next = n->next; n->next->prev = new; } /* TODO: don't leak memory */ return 0; } /* constructors */ static node_t *__node(ntype_t ntype) { node_t *n = calloc(1, sizeof(*n)); assert(n); n->ntype = ntype; return n; } node_t *node_list(node_t *head) { node_t *n = __node(N_LIST); n->list = head; head->up = n; return n; } node_t *node_vlist(node_t *head, ...) { va_list ap; node_t *n, *next; n = node_list(head); va_start(ap, head); while ((next = va_arg(ap, node_t *))) { insque(next, head); next->up = n; head = next; } va_end(ap); return n; } node_t *node_keyword(kwclass_t class, int op) { node_t *n = __node(N_KEYWORD); n->keyword.class = class; n->keyword.op = op; return n; } node_t *node_ident(const char *name) { node_t *n = __node(N_IDENT); n->ident = name; return n; } node_t *node_num(int64_t num) { node_t *n = __node(N_NUM); n->num = num; /* TODO: handle L UL ULL and such nonsense */ n->type = &t_s64; return n; } node_t *node_string(const char *string) { node_t *n = __node(N_STRING); n->string = string; /* TODO: string type like dtrace? */ n->type = type_ptr_of(&t_char); return n; }