diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2025-03-01 16:04:14 -0500 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2025-03-01 16:04:14 -0500 |
| commit | fab0083129c134a49c77a4f7e3b333f1e0f14d55 (patch) | |
| tree | f4d493712a7b9ebad9ab4136bd1fa25ec4e933d6 /typecheck.c | |
| parent | 90548ebb33ea69c6c9e0962d8bab6d3ec72ac90f (diff) | |
Support post-hoc definitions of escaping rules for DSLs
Diffstat (limited to 'typecheck.c')
| -rw-r--r-- | typecheck.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/typecheck.c b/typecheck.c index 26a8ff9f..91343179 100644 --- a/typecheck.c +++ b/typecheck.c @@ -299,15 +299,17 @@ void bind_statement(env_t *env, ast_t *statement) auto def = Match(statement, FunctionDef); const char *name = Match(def->name, Var)->name; type_t *type = get_function_def_type(env, statement); - if (env->namespace && env->namespace->parent && env->namespace->name && streq(name, env->namespace->name)) { - CORD code = CORD_asprintf("%r%ld", namespace_prefix(env, env->namespace), get_line_number(statement->file, statement->start)); + binding_t *clobber = get_binding(env, name); + if (clobber && clobber->type->tag == TypeInfoType && type_eq(Match(clobber->type, TypeInfoType)->type, Match(type, FunctionType)->ret)) { + CORD code = CORD_asprintf("%r%r$%ld", namespace_prefix(env, env->namespace), name, + get_line_number(statement->file, statement->start)); binding_t binding = {.type=type, .code=code}; Array$insert(&env->namespace->constructors, &binding, I(0), sizeof(binding)); break; } - if (get_binding(env, name)) - code_err(def->name, "A %T called '%s' has already been defined", get_binding(env, name)->type, name); + if (clobber) + code_err(def->name, "A %T called '%s' has already been defined", clobber->type, name); CORD code = CORD_all(namespace_prefix(env, env->namespace), name); set_binding(env, name, type, code); break; @@ -792,7 +794,7 @@ type_t *get_type(env_t *env, ast_t *ast) if (fn_type_t->tag == TypeInfoType) { type_t *t = Match(fn_type_t, TypeInfoType)->type; - binding_t *constructor = get_constructor(env, t, call->args); + binding_t *constructor = get_constructor(env, t, call->args, t); if (constructor) return t; else if (t->tag == StructType || t->tag == IntType || t->tag == BigIntType || t->tag == NumType |
