use b_plain export cz/namespace struct macrospace namespace ns hashtable vague struct macro_key cstr name int n_args # -1 means no parens macrospace_init(macrospace *ms, macrospace *parent) init(&ms->vague, hashtable, namespace_buckets) init(&ms->ns, namespace, &parent->ns, macro_keymap) struct macro_def cstr name vec *params vec *lines flag ldef:1 flag block:1 flag raw:2 struct macro_arg cstr val int tok_count macro_def_init(macro_def *m, cstr name, vec *params, vec *lines, boolean block, boolean ldef, int raw) m->name = name ; m->params = params ; m->lines = lines m->block = block ; m->ldef = ldef ; m->raw = raw def macrospace_lookup_vague(ms, name) macrospace_lookup_vague(ms, name, 0) boolean macrospace_lookup_vague(macrospace *ms, cstr name, int depth) if ++depth > lookup_max_depth error("macrospace_lookup_vague is caught in a loop while looking up %s", name) return get(&ms->vague, name, 0) || (ms->ns.parent && macrospace_lookup_vague((macrospace *)ms->ns.parent, name, depth)) # I thought I was meant to use let not set??? macrospace_set(macrospace *ms, macro_key *key, void *value) if value set(&ms->vague, key->name, 1) namespace_set(&ms->ns, key, value) # XXX this uses a static buffer char *macro_keymap(void *key) static buffer *b = NULL if !b NEW(b, buffer, 64) macro_key *mk = key if mk->n_args == -1 return mk->name bufclr(b) buffer_cat_cstr(b, mk->name) buffer_cat_char(b, '(') if mk->n_args >= 1 buffer_cat_char(b, '_') repeat(mk->n_args - 1) buffer_cat_cstr(b, ", _") buffer_cat_char(b, ')') return buffer_add_nul(b) macrospace_dump(macrospace *ms) new(ks, vec, cstr, 64) keys(ks, &ms->ns.hash) for_vec(k, ks, cstr) cstr name = *k warn("lookup macro by key: %s", name) macro_def *m = Get(&ms->ns.hash, name) int n_args = m->params ? veclen(m->params) : -1 warn("name: %s", name) warn("n_args: %d", n_args) if n_args >= 0 Fprint(stderr, "args: ") for_vec(a, m->params, cstr) Fprintf(stderr, "%s ", *a) nl(stderr) warn("lines:") for_vec(l, m->lines, cstr) Fsayf(stderr, " %s", *l) warn("opts: l %d b %d raw %d", m->ldef, m->block, m->raw) nl(stderr) if ms->ns.parent macrospace_dump((macrospace *)ms->ns.parent)