import "cffc.hff"; import "map.hff"; import "util.hff"; import "common.hff"; struct StringKeyTraits { fn hash(s *const u8) u32 { return fnv1a_s(FNV1A_INI, s); } fn eq(a *const u8, b *const u8) bool { return streq(a, b); } } struct Env { parent *Env, alloc *Allocator, decls Map<*const u8, *DeclList, StringKeyTraits>, } extern fn mkenv(parent *Env, alloc *Allocator) *Env { let env *Env = xmalloc(sizeof Env); *env = { parent, alloc }; return env; } extern fn envput(env *Env, decl Decl, old **const Decl) *Decl { let l **DeclList = env.decls->get_slot(decl.name); let n *DeclList = anew(env.alloc, DeclList); if *l { // decl with this name exists *old = &(*l).decl; return #null; } n.link = *l; n.decl = decl; *l = n; return &n.decl; } extern fn envfind(env *Env, name *const u8) *Decl { let l **DeclList = env.decls->get(name); if l == #null { return #null; } let l = *l; assert(l != #null, "l?"); return &l.decl; } extern fn envfree(env *Env) void { env.decls->clear(); free(env); }