aboutsummaryrefslogtreecommitdiff
path: root/typecheck.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-03-01 16:04:14 -0500
committerBruce Hill <bruce@bruce-hill.com>2025-03-01 16:04:14 -0500
commitfab0083129c134a49c77a4f7e3b333f1e0f14d55 (patch)
treef4d493712a7b9ebad9ab4136bd1fa25ec4e933d6 /typecheck.c
parent90548ebb33ea69c6c9e0962d8bab6d3ec72ac90f (diff)
Support post-hoc definitions of escaping rules for DSLs
Diffstat (limited to 'typecheck.c')
-rw-r--r--typecheck.c12
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