#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, "%"PRId64, 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; } /* static struct node *node_new(enum ntype ntype) */ /* { */ /* struct node *n; */ /* n = calloc(1, sizeof(*n)); */ /* assert(n); */ /* n->ntype = N_IDENT; */ /* n->ident.name = name; */ /* return n; */ /* } */ /* struct node *node_string(char *data) */ /* { */ /* struct node *n = node_new(N_STRING); */ /* n->string.data = data; */ /* return n; */ /* } */ /* struct node *node_num(int64_t num) */ /* { */ /* struct node *n = node_new(N_NUM); */ /* n->num.num = num; */ /* return n; */ /* } */ /* struct node *node_ident(char *name) */ /* { */ /* struct node *n = node_new(N_IDENT); */ /* n->ident.name = name; */ /* return n; */ /* } */ /* struct node *node_append(struct node *n, struct node *arg) */ /* { */ /* struct node *last; */ /* assert(n->ntype == N_EXPR); */ /* arg->up = n; */ /* if (!n->expr.args) { */ /* n->expr.args = arg; */ /* return n; */ /* } */ /* for (last = n->expr.args; last->next; last = last->next); */ /* last->next = arg; */ /* arg->prev = last; */ /* return n; */ /* } */ /* struct node *node_expr(char *func, ...) */ /* { */ /* va_list ap; */ /* struct node *n, *arg; */ /* n = node_new(N_EXPR); */ /* n->expr.func = func; */ /* va_start(ap, func); */ /* while ((arg = va_arg(ap, struct node *))) */ /* append(n, arg); */ /* va_end(ap); */ /* return n; */ /* } */