| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- #include <assert.h>
- #include <ctype.h>
- #include <inttypes.h>
- #include <stdio.h>
- #include <stdlib.h>
- #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;
- }
|