diff options
| author | 2022-08-03 20:24:47 +0200 | |
|---|---|---|
| committer | 2022-08-03 20:24:47 +0200 | |
| commit | 1625c50f0c0e4b1c7ba01a5df5713efaf6dce606 (patch) | |
| tree | bc5f24811413749b776964c1bbdec13a46dd9768 /bootstrap/env.c | |
initial
Diffstat (limited to 'bootstrap/env.c')
| -rw-r--r-- | bootstrap/env.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/bootstrap/env.c b/bootstrap/env.c new file mode 100644 index 0000000..513b4d9 --- /dev/null +++ b/bootstrap/env.c @@ -0,0 +1,48 @@ +#include "all.h" + + +struct decl * +envfind(const struct env *env, const char *name) { + if (!env) + return NULL; + for (struct decls *decls = env->decls; decls; decls = decls->next) { + if (!strcmp(decls->decl.name, name)) + return &decls->decl; + } + return envfind(env->parent, name); +} + +static bool +declsshadowable(const struct decl *a, const struct decl *b) { + return b->t == Dvar; +} + +static bool +declscompatible(const struct decl *a, const struct decl *b) { + if (a->t != b->t) + return 0; + if (a->t == Dfn && a->fn.selfty == b->fn.selfty && !a->fn.body) + return 1; + if (a->t == Dtype && a->ty == b->ty) + return 1; + return 0; +} + +bool +envput(struct env *env, const struct decl *decl) { + struct decls *decls; + struct env env_noparent = { + .decls = env->decls + }; + struct decl *decl0; + if ((decl0 = envfind(&env_noparent, decl->name))) { + if (!declsshadowable(decl0, decl) && !declscompatible(decl0, decl)) + return 0; + } + + decls = xcalloc(1, sizeof *decls); + decls->next = env->decls; + decls->decl = *decl; + env->decls = decls; + return 1; +} |