| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include <assert.h>
- #include <ctype.h>
- #include <inttypes.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include "node.h"
- void nprint(node_t *n, FILE *fp)
- {
- switch (n->ntype) {
- case N_CONS:
- fputs("<CONS>", 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("<INVALID>", 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;
- }
|