Tweak set_binding() API

This commit is contained in:
Bruce Hill 2025-02-10 13:13:45 -05:00
parent be87d8169d
commit 66eca49d18
4 changed files with 81 additions and 82 deletions

View File

@ -292,7 +292,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
auto lambda = Match(ast, Lambda);
env_t *lambda_scope = fresh_scope(env);
for (arg_ast_t *arg = lambda->args; arg; arg = arg->next)
set_binding(lambda_scope, arg->name, new(binding_t, .type=get_arg_ast_type(env, arg)));
set_binding(lambda_scope, arg->name, get_arg_ast_type(env, arg), CORD_all("_$", arg->name));
add_closed_vars(closed_vars, enclosing_scope, lambda_scope, lambda->body);
break;
}
@ -339,7 +339,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
type_t *cond_t = get_type(truthy_scope, var);
if (cond_t->tag == OptionalType) {
set_binding(truthy_scope, Match(var, Var)->name,
new(binding_t, .type=Match(cond_t, OptionalType)->type));
Match(cond_t, OptionalType)->type, CORD_EMPTY);
}
add_closed_vars(closed_vars, enclosing_scope, truthy_scope, if_->body);
add_closed_vars(closed_vars, enclosing_scope, env, if_->else_body);
@ -349,7 +349,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
if (condition->tag == Var && cond_t->tag == OptionalType) {
truthy_scope = fresh_scope(env);
set_binding(truthy_scope, Match(condition, Var)->name,
new(binding_t, .type=Match(cond_t, OptionalType)->type));
Match(cond_t, OptionalType)->type, CORD_EMPTY);
}
add_closed_vars(closed_vars, enclosing_scope, truthy_scope, if_->body);
add_closed_vars(closed_vars, enclosing_scope, env, if_->else_body);
@ -377,7 +377,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
auto tag_struct = Match(tag_type, StructType);
if (clause->args && !clause->args->next && tag_struct->fields && tag_struct->fields->next) {
scope = fresh_scope(scope);
set_binding(scope, Match(clause->args->ast, Var)->name, new(binding_t, .type=tag_type));
set_binding(scope, Match(clause->args->ast, Var)->name, tag_type, CORD_EMPTY);
} else if (clause->args) {
scope = fresh_scope(scope);
ast_list_t *var = clause->args;
@ -387,7 +387,7 @@ static void add_closed_vars(Table_t *closed_vars, env_t *enclosing_scope, env_t
code_err(clause->tag_name, "The field %T.%s.%s wasn't accounted for", subject_t, clause_tag_name, field->name);
if (!field)
code_err(var->ast, "This is one more field than %T has", subject_t);
set_binding(scope, Match(var->ast, Var)->name, new(binding_t, .type=field->type));
set_binding(scope, Match(var->ast, Var)->name, field->type, CORD_EMPTY);
var = var->next;
field = field->next;
}
@ -458,7 +458,7 @@ static Table_t get_closed_vars(env_t *env, arg_ast_t *args, ast_t *block)
env_t *body_scope = fresh_scope(env);
for (arg_ast_t *arg = args; arg; arg = arg->next) {
type_t *arg_type = get_arg_ast_type(env, arg);
set_binding(body_scope, arg->name, new(binding_t, .type=arg_type, .code=CORD_cat("_$", arg->name)));
set_binding(body_scope, arg->name, arg_type, CORD_cat("_$", arg->name));
}
Table_t closed_vars = {};
@ -774,7 +774,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
if (clause->args && !clause->args->next && tag_struct->fields && tag_struct->fields->next) {
code = CORD_all(code, compile_declaration(tag_type, compile(env, clause->args->ast)), " = subject.$", clause_tag_name, ";\n");
scope = fresh_scope(scope);
set_binding(scope, Match(clause->args->ast, Var)->name, new(binding_t, .type=tag_type));
set_binding(scope, Match(clause->args->ast, Var)->name, tag_type, CORD_EMPTY);
} else if (clause->args) {
scope = fresh_scope(scope);
ast_list_t *var = clause->args;
@ -785,7 +785,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
if (!field)
code_err(var->ast, "This is one more field than %T has", subject_t);
code = CORD_all(code, compile_declaration(field->type, compile(env, var->ast)), " = subject.$", clause_tag_name, ".$", field->name, ";\n");
set_binding(scope, Match(var->ast, Var)->name, new(binding_t, .type=field->type));
set_binding(scope, Match(var->ast, Var)->name, field->type, CORD_EMPTY);
var = var->next;
field = field->next;
}
@ -1201,7 +1201,7 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
body_scope->namespace = NULL;
for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
type_t *arg_type = get_arg_ast_type(env, arg);
set_binding(body_scope, arg->name, new(binding_t, .type=arg_type, .code=CORD_cat("_$", arg->name)));
set_binding(body_scope, arg->name, arg_type, CORD_cat("_$", arg->name));
}
body_scope->fn_ret = ret_t;
@ -1387,12 +1387,12 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
if (entry->b->type->tag == ModuleType)
continue;
if (CORD_ncmp(entry->b->code, 0, "userdata->", 0, strlen("userdata->")) == 0) {
set_binding(defer_env, entry->name, entry->b);
Table$str_set(defer_env->locals, entry->name, entry->b);
} else {
CORD defer_name = CORD_asprintf("defer$%d$%s", ++defer_id, entry->name);
code = CORD_all(
code, compile_declaration(entry->b->type, defer_name), " = ", entry->b->code, ";\n");
set_binding(defer_env, entry->name, new(binding_t, .type=entry->b->type, .code=defer_name));
set_binding(defer_env, entry->name, entry->b->type, defer_name);
}
}
env->deferred = new(deferral_t, .defer_env=defer_env, .block=body, .next=env->deferred);
@ -1493,8 +1493,8 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
.next=body_scope->deferred);
if (held->tag == Var) {
CORD held_var = CORD_all(Match(held, Var)->name, "$held");
set_binding(body_scope, Match(held, Var)->name, new(binding_t, .type=Type(PointerType, .pointed=Match(held_type, MutexedType)->type, .is_stack=true),
.code=held_var));
set_binding(body_scope, Match(held, Var)->name,
Type(PointerType, .pointed=Match(held_type, MutexedType)->type, .is_stack=true), held_var);
code = CORD_all(code, compile_declaration(Type(PointerType, .pointed=Match(held_type, MutexedType)->type), held_var),
" = (", compile_type(Type(PointerType, .pointed=Match(held_type, MutexedType)->type)), ")mutexed->data;\n");
}
@ -1795,8 +1795,8 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
type_t *cond_t = get_type(truthy_scope, var);
if (cond_t->tag == OptionalType) {
set_binding(truthy_scope, Match(var, Var)->name,
new(binding_t, .type=Match(cond_t, OptionalType)->type,
.code=optional_into_nonnone(cond_t, compile(truthy_scope, var))));
Match(cond_t, OptionalType)->type,
optional_into_nonnone(cond_t, compile(truthy_scope, var)));
}
code = CORD_all(code, compile_statement(truthy_scope, if_->body), ")");
if (if_->else_body)
@ -1809,8 +1809,8 @@ static CORD _compile_statement(env_t *env, ast_t *ast)
if (condition->tag == Var && cond_t->tag == OptionalType) {
truthy_scope = fresh_scope(env);
set_binding(truthy_scope, Match(condition, Var)->name,
new(binding_t, .type=Match(cond_t, OptionalType)->type,
.code=optional_into_nonnone(cond_t, compile(truthy_scope, condition))));
Match(cond_t, OptionalType)->type,
optional_into_nonnone(cond_t, compile(truthy_scope, condition)));
}
code = CORD_all(code, compile_statement(truthy_scope, if_->body));
if (if_->else_body)
@ -1988,7 +1988,7 @@ env_t *with_enum_scope(env_t *env, type_t *t)
continue;
binding_t *b = get_binding(ns_env, tag->name);
assert(b);
set_binding(env, tag->name, b);
Table$str_set(env->locals, tag->name, b);
}
return env;
}
@ -2465,8 +2465,8 @@ CORD compile(env_t *env, ast_t *ast)
.next=body_scope->deferred);
if (held->tag == Var) {
CORD held_var = CORD_all(Match(held, Var)->name, "$held");
set_binding(body_scope, Match(held, Var)->name, new(binding_t, .type=Type(PointerType, .pointed=Match(held_type, MutexedType)->type, .is_stack=true),
.code=held_var));
set_binding(body_scope, Match(held, Var)->name,
Type(PointerType, .pointed=Match(held_type, MutexedType)->type, .is_stack=true), held_var);
code = CORD_all(code, compile_declaration(Type(PointerType, .pointed=Match(held_type, MutexedType)->type), held_var),
" = (", compile_type(Type(PointerType, .pointed=Match(held_type, MutexedType)->type)), ")mutexed->data;\n");
}
@ -2856,10 +2856,10 @@ CORD compile(env_t *env, ast_t *ast)
if (key == NULL) key = FakeAST(Var, key_name);
env_t *expr_env = fresh_scope(env);
set_binding(expr_env, key_name, new(binding_t, .type=t, .code="ternary$lhs"));
set_binding(expr_env, key_name, t, "ternary$lhs");
CORD lhs_key = compile(expr_env, key);
set_binding(expr_env, key_name, new(binding_t, .type=t, .code="ternary$rhs"));
set_binding(expr_env, key_name, t, "ternary$rhs");
CORD rhs_key = compile(expr_env, key);
type_t *key_t = get_type(expr_env, key);
@ -2915,7 +2915,7 @@ CORD compile(env_t *env, ast_t *ast)
Closure_t comp_action = {.fn=add_to_array_comprehension, .userdata=comprehension_var};
scope->comprehension_action = &comp_action;
CORD code = CORD_all("({ Array_t ", comprehension_name, " = {};");
// set_binding(scope, comprehension_name, new(binding_t, .type=array_type, .code=comprehension_name));
// set_binding(scope, comprehension_name, array_type, comprehension_name);
for (ast_list_t *item = array->items; item; item = item->next) {
if (item->ast->tag == Comprehension)
code = CORD_all(code, "\n", compile_statement(scope, item->ast));
@ -3070,7 +3070,7 @@ CORD compile(env_t *env, ast_t *ast)
body_scope->deferred = NULL;
for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) {
type_t *arg_type = get_arg_ast_type(env, arg);
set_binding(body_scope, arg->name, new(binding_t, .type=arg_type, .code=CORD_all("_$", arg->name)));
set_binding(body_scope, arg->name, arg_type, CORD_all("_$", arg->name));
}
type_t *ret_t = get_type(body_scope, lambda->body);
@ -3098,7 +3098,7 @@ CORD compile(env_t *env, ast_t *ast)
entry->b->type, entry->name);
if (entry->b->type->tag == ModuleType)
continue;
set_binding(body_scope, entry->name, new(binding_t, .type=entry->b->type, .code=CORD_cat("userdata->", entry->name)));
set_binding(body_scope, entry->name, entry->b->type, CORD_cat("userdata->", entry->name));
def = CORD_all(def, compile_declaration(entry->b->type, entry->name), "; ");
}
def = CORD_all(def, "} ", name, "$userdata_t;");
@ -3644,7 +3644,7 @@ CORD compile(env_t *env, ast_t *ast)
type_t *t = get_type(env, ast);
env_t *when_env = fresh_scope(env);
set_binding(when_env, "when", new(binding_t, .type=t, .code="when"));
set_binding(when_env, "when", t, "when");
return CORD_all(
"({ ", compile_declaration(t, "when"), ";\n",
compile_statement(when_env, WrapAST(ast, When, .subject=original->subject, .clauses=new_clauses, .else_body=else_body)),
@ -3668,16 +3668,16 @@ CORD compile(env_t *env, ast_t *ast)
bind_statement(truthy_scope, condition);
condition_code = compile_condition(truthy_scope, var);
set_binding(truthy_scope, Match(var, Var)->name,
new(binding_t, .type=Match(condition_type, OptionalType)->type,
.code=optional_into_nonnone(condition_type, compile(truthy_scope, var))));
Match(condition_type, OptionalType)->type,
optional_into_nonnone(condition_type, compile(truthy_scope, var)));
} else if (condition->tag == Var) {
type_t *condition_type = get_type(env, condition);
condition_code = compile_condition(env, condition);
if (condition_type->tag == OptionalType) {
truthy_scope = fresh_scope(env);
set_binding(truthy_scope, Match(condition, Var)->name,
new(binding_t, .type=Match(condition_type, OptionalType)->type,
.code=optional_into_nonnone(condition_type, compile(truthy_scope, condition))));
Match(condition_type, OptionalType)->type,
optional_into_nonnone(condition_type, compile(truthy_scope, condition)));
}
} else {
condition_code = compile_condition(env, condition);
@ -3747,7 +3747,7 @@ CORD compile(env_t *env, ast_t *ast)
binop_e cmp_op = op == BINOP_MIN ? BINOP_LT : BINOP_GT;
if (reduction->key) {
env_t *key_scope = fresh_scope(env);
set_binding(key_scope, "$", new(binding_t, .type=item_t, .code=item_code));
set_binding(key_scope, "$", item_t, item_code);
type_t *key_type = get_type(key_scope, reduction->key);
const char *superlative_key = op == BINOP_MIN ? "min_key" : "max_key";
code = CORD_all(code, compile_declaration(key_type, superlative_key), ";\n");
@ -4031,7 +4031,7 @@ void compile_namespace(env_t *env, const char *ns_name, ast_t *block)
name_code, "$initialized = true;\n")));
CORD checked_access = CORD_all("check_initialized(", name_code, ", \"", Match(decl->var, Var)->name, "\")");
set_binding(ns_env, Match(decl->var, Var)->name, new(binding_t, .type=t, .code=checked_access));
set_binding(ns_env, Match(decl->var, Var)->name, t, checked_access);
}
}
}
@ -4293,7 +4293,7 @@ CORD compile_file(env_t *env, ast_t *ast)
full_name, "$initialized = true;\n")));
CORD checked_access = CORD_all("check_initialized(", full_name, ", \"", decl_name, "\")");
set_binding(env, decl_name, new(binding_t, .type=t, .code=checked_access));
set_binding(env, decl_name, t, checked_access);
}
}
}

View File

@ -468,26 +468,25 @@ env_t *new_compilation_unit(CORD libname)
type_t *type = parse_type_string(ns_env, entry->type_str);
if (!type) compiler_err(NULL, NULL, NULL, "Couldn't parse type string: %s", entry->type_str);
if (type->tag == ClosureType) type = Match(type, ClosureType)->fn;
binding_t *b = new(binding_t, .code=entry->code, .type=type);
set_binding(ns_env, entry->name, b);
set_binding(ns_env, entry->name, type, entry->code);
}
}
set_binding(namespace_env(env, "Shell"), "without_escaping",
new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE),
.ret=Type(TextType, .lang="Shell", .env=namespace_env(env, "Shell"))),
.code="(Shell_t)"));
Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE),
.ret=Type(TextType, .lang="Shell", .env=namespace_env(env, "Shell"))),
"(Shell_t)");
set_binding(namespace_env(env, "Path"), "without_escaping",
new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE),
.ret=Type(TextType, .lang="Path", .env=namespace_env(env, "Path"))),
.code="Path$cleanup"));
Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE),
.ret=Type(TextType, .lang="Path", .env=namespace_env(env, "Path"))),
"Path$cleanup");
set_binding(namespace_env(env, "Pattern"), "without_escaping",
new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE),
.ret=Type(TextType, .lang="Pattern", .env=namespace_env(env, "Pattern"))),
.code="(Pattern_t)"));
Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE),
.ret=Type(TextType, .lang="Pattern", .env=namespace_env(env, "Pattern"))),
"(Pattern_t)");
Table$str_set(env->globals, "random", new(binding_t, .type=RNG_TYPE, .code="default_rng"));
@ -553,7 +552,7 @@ env_t *for_scope(env_t *env, ast_t *ast)
if (for_->vars->next)
code_err(for_->vars->next->ast, "This is too many variables for this loop");
const char *var = Match(for_->vars->ast, Var)->name;
set_binding(scope, var, new(binding_t, .type=INT_TYPE, .code=CORD_cat("_$", var)));
set_binding(scope, var, INT_TYPE, CORD_cat("_$", var));
}
return scope;
}
@ -569,10 +568,10 @@ env_t *for_scope(env_t *env, ast_t *ast)
vars[num_vars++] = Match(var->ast, Var)->name;
}
if (num_vars == 1) {
set_binding(scope, vars[0], new(binding_t, .type=item_t, .code=CORD_cat("_$", vars[0])));
set_binding(scope, vars[0], item_t, CORD_cat("_$", vars[0]));
} else if (num_vars == 2) {
set_binding(scope, vars[0], new(binding_t, .type=INT_TYPE, .code=CORD_cat("_$", vars[0])));
set_binding(scope, vars[1], new(binding_t, .type=item_t, .code=CORD_cat("_$", vars[1])));
set_binding(scope, vars[0], INT_TYPE, CORD_cat("_$", vars[0]));
set_binding(scope, vars[1], item_t, CORD_cat("_$", vars[1]));
}
return scope;
}
@ -582,7 +581,7 @@ env_t *for_scope(env_t *env, ast_t *ast)
code_err(for_->vars->next->ast, "This is too many variables for this loop");
type_t *item_type = Match(iter_t, SetType)->item_type;
const char *name = Match(for_->vars->ast, Var)->name;
set_binding(scope, name, new(binding_t, .type=item_type, .code=CORD_cat("_$", name)));
set_binding(scope, name, item_type, CORD_cat("_$", name));
}
return scope;
}
@ -597,11 +596,11 @@ env_t *for_scope(env_t *env, ast_t *ast)
type_t *key_t = Match(iter_t, TableType)->key_type;
if (num_vars == 1) {
set_binding(scope, vars[0], new(binding_t, .type=key_t, .code=CORD_cat("_$", vars[0])));
set_binding(scope, vars[0], key_t, CORD_cat("_$", vars[0]));
} else if (num_vars == 2) {
set_binding(scope, vars[0], new(binding_t, .type=key_t, .code=CORD_cat("_$", vars[0])));
set_binding(scope, vars[0], key_t, CORD_cat("_$", vars[0]));
type_t *value_t = Match(iter_t, TableType)->value_type;
set_binding(scope, vars[1], new(binding_t, .type=value_t, .code=CORD_cat("_$", vars[1])));
set_binding(scope, vars[1], value_t, CORD_cat("_$", vars[1]));
}
return scope;
}
@ -610,7 +609,7 @@ env_t *for_scope(env_t *env, ast_t *ast)
if (for_->vars->next)
code_err(for_->vars->next->ast, "This is too many variables for this loop");
const char *var = Match(for_->vars->ast, Var)->name;
set_binding(scope, var, new(binding_t, .type=INT_TYPE, .code=CORD_cat("_$", var)));
set_binding(scope, var, INT_TYPE, CORD_cat("_$", var));
}
return scope;
}
@ -624,7 +623,7 @@ env_t *for_scope(env_t *env, ast_t *ast)
code_err(for_->vars->next->ast, "This is too many variables for this loop");
const char *var = Match(for_->vars->ast, Var)->name;
type_t *non_opt_type = fn->ret->tag == OptionalType ? Match(fn->ret, OptionalType)->type : fn->ret;
set_binding(scope, var, new(binding_t, .type=non_opt_type, .code=CORD_cat("_$", var)));
set_binding(scope, var, non_opt_type, CORD_cat("_$", var));
}
return scope;
}
@ -711,10 +710,10 @@ PUREFUNC binding_t *get_lang_escape_function(env_t *env, const char *lang_name,
return NULL;
}
void set_binding(env_t *env, const char *name, binding_t *binding)
void set_binding(env_t *env, const char *name, type_t *type, CORD code)
{
if (name && binding)
Table$str_set(env->locals, name, binding);
assert(name);
Table$str_set(env->locals, name, new(binding_t, .type=type, .code=code));
}
__attribute__((format(printf, 4, 5)))

View File

@ -66,7 +66,7 @@ __attribute__((format(printf, 4, 5)))
_Noreturn void compiler_err(file_t *f, const char *start, const char *end, const char *fmt, ...);
binding_t *get_binding(env_t *env, const char *name);
binding_t *get_lang_escape_function(env_t *env, const char *lang_name, type_t *type_to_escape);
void set_binding(env_t *env, const char *name, binding_t *binding);
void set_binding(env_t *env, const char *name, type_t *type, CORD code);
binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name);
#define code_err(ast, ...) compiler_err((ast)->file, (ast)->start, (ast)->end, __VA_ARGS__)
extern type_t *TEXT_TYPE;

View File

@ -207,7 +207,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast)
struct {
const char *name; binding_t *binding;
} *entry = subenv->locals->entries.data + j*subenv->locals->entries.stride;
set_binding(module_env, entry->name, entry->binding);
Table$str_set(module_env->locals, entry->name, entry->binding);
}
}
globfree(&tm_files);
@ -232,8 +232,8 @@ void prebind_statement(env_t *env, ast_t *statement)
env_t *ns_env = namespace_env(env, def->name);
type_t *type = Type(StructType, .name=def->name, .opaque=true, .env=ns_env); // placeholder
Table$str_set(env->types, def->name, type);
set_binding(env, def->name, new(binding_t, .type=Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env),
.code=CORD_all(namespace_prefix(env, env->namespace), def->name)));
set_binding(env, def->name, Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env),
CORD_all(namespace_prefix(env, env->namespace), def->name));
for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next)
prebind_statement(ns_env, stmt->ast);
break;
@ -246,8 +246,8 @@ void prebind_statement(env_t *env, ast_t *statement)
env_t *ns_env = namespace_env(env, def->name);
type_t *type = Type(EnumType, .name=def->name, .opaque=true, .env=ns_env); // placeholder
Table$str_set(env->types, def->name, type);
set_binding(env, def->name, new(binding_t, .type=Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env),
.code=CORD_all(namespace_prefix(env, env->namespace), def->name)));
set_binding(env, def->name, Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env),
CORD_all(namespace_prefix(env, env->namespace), def->name));
for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next)
prebind_statement(ns_env, stmt->ast);
break;
@ -260,8 +260,8 @@ void prebind_statement(env_t *env, ast_t *statement)
env_t *ns_env = namespace_env(env, def->name);
type_t *type = Type(TextType, .lang=def->name, .env=ns_env);
Table$str_set(env->types, def->name, type);
set_binding(env, def->name, new(binding_t, .type=Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env),
.code=CORD_all(namespace_prefix(env, env->namespace), def->name)));
set_binding(env, def->name, Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env),
CORD_all(namespace_prefix(env, env->namespace), def->name));
for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next)
prebind_statement(ns_env, stmt->ast);
break;
@ -292,7 +292,7 @@ void bind_statement(env_t *env, ast_t *statement)
type = Type(ClosureType, type);
CORD prefix = namespace_prefix(env, env->namespace);
CORD code = CORD_cat(prefix ? prefix : "$", name);
set_binding(env, name, new(binding_t, .type=type, .code=code));
set_binding(env, name, type, code);
break;
}
case FunctionDef: {
@ -302,7 +302,7 @@ void bind_statement(env_t *env, ast_t *statement)
code_err(def->name, "A %T called '%s' has already been defined", get_binding(env, name)->type, name);
type_t *type = get_function_def_type(env, statement);
CORD code = CORD_all(namespace_prefix(env, env->namespace), name);
set_binding(env, name, new(binding_t, .type=type, .code=code));
set_binding(env, name, type, code);
break;
}
case StructDef: {
@ -370,10 +370,10 @@ void bind_statement(env_t *env, ast_t *statement)
for (tag_t *tag = tags; tag; tag = tag->next) {
if (Match(tag->type, StructType)->fields) { // Constructor:
type_t *constructor_t = Type(FunctionType, .args=Match(tag->type, StructType)->fields, .ret=type);
set_binding(ns_env, tag->name, new(binding_t, .type=constructor_t, .code=CORD_all(namespace_prefix(env, env->namespace), def->name, "$tagged$", tag->name)));
set_binding(ns_env, tag->name, constructor_t, CORD_all(namespace_prefix(env, env->namespace), def->name, "$tagged$", tag->name));
} else { // Empty singleton value:
CORD code = CORD_all("(", namespace_prefix(env, env->namespace), def->name, "_t){", namespace_prefix(env, env->namespace), def->name, "$tag$", tag->name, "}");
set_binding(ns_env, tag->name, new(binding_t, .type=type, .code=code));
set_binding(ns_env, tag->name, type, code);
}
Table$str_set(env->types, heap_strf("%s$%s", def->name, tag->name), tag->type);
}
@ -390,8 +390,8 @@ void bind_statement(env_t *env, ast_t *statement)
Table$str_set(env->types, def->name, type);
set_binding(ns_env, "without_escaping",
new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE), .ret=type),
.code=CORD_all("(", namespace_prefix(env, env->namespace), def->name, "_t)")));
Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE), .ret=type),
CORD_all("(", namespace_prefix(env, env->namespace), def->name, "_t)"));
for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next)
bind_statement(ns_env, stmt->ast);
@ -426,7 +426,7 @@ void bind_statement(env_t *env, ast_t *statement)
if (var) {
type_t *type = get_type(env, statement);
assert(type);
set_binding(env, Match(var, Var)->name, new(binding_t, .type=type));
set_binding(env, Match(var, Var)->name, type, CORD_EMPTY);
}
break;
}
@ -435,7 +435,7 @@ void bind_statement(env_t *env, ast_t *statement)
type_t *t = parse_type_ast(env, ext->type);
if (t->tag == ClosureType)
t = Match(t, ClosureType)->fn;
set_binding(env, ext->name, new(binding_t, .type=t, .code=ext->name));
set_binding(env, ext->name, t, ext->name);
break;
}
default: break;
@ -450,7 +450,7 @@ type_t *get_function_def_type(env_t *env, ast_t *ast)
for (arg_ast_t *arg = fn->args; arg; arg = arg->next) {
type_t *t = arg->type ? parse_type_ast(env, arg->type) : get_type(env, arg->value);
args = new(arg_t, .name=arg->name, .type=t, .default_val=arg->value, .next=args);
set_binding(scope, arg->name, new(binding_t, .type=t));
set_binding(scope, arg->name, t, CORD_EMPTY);
}
REVERSE_LIST(args);
@ -492,7 +492,7 @@ type_t *get_clause_type(env_t *env, type_t *subject_t, when_clause_t *clause)
env_t *scope = fresh_scope(env);
auto tag_struct = Match(tag_type, StructType);
if (!clause->args->next && tag_struct->fields && tag_struct->fields->next) {
set_binding(scope, Match(clause->args->ast, Var)->name, new(binding_t, .type=tag_type));
set_binding(scope, Match(clause->args->ast, Var)->name, tag_type, CORD_EMPTY);
} else {
ast_list_t *var = clause->args;
arg_t *field = tag_struct->fields;
@ -501,7 +501,7 @@ type_t *get_clause_type(env_t *env, type_t *subject_t, when_clause_t *clause)
code_err(clause->tag_name, "The field %T.%s.%s wasn't accounted for", subject_t, tag_name, field->name);
if (!field)
code_err(var->ast, "This is one more field than %T has", subject_t);
set_binding(scope, Match(var->ast, Var)->name, new(binding_t, .type=field->type));
set_binding(scope, Match(var->ast, Var)->name, field->type, CORD_EMPTY);
var = var->next;
field = field->next;
}
@ -917,7 +917,7 @@ type_t *get_type(env_t *env, ast_t *ast)
continue;
binding_t *b = get_binding(ns_env, tag->name);
assert(b);
set_binding(env, tag->name, b);
Table$str_set(env->locals, tag->name, b);
}
}
return Type(ReturnType, .ret=(val ? get_type(env, val) : Type(VoidType)));
@ -968,7 +968,7 @@ type_t *get_type(env_t *env, ast_t *ast)
code_err(held, "This is a %t, not a mutexed value", held_type);
if (held->tag == Var) {
env = fresh_scope(env);
set_binding(env, Match(held, Var)->name, new(binding_t, .type=Type(PointerType, .pointed=Match(held_type, MutexedType)->type, .is_stack=true)));
set_binding(env, Match(held, Var)->name, Type(PointerType, .pointed=Match(held_type, MutexedType)->type, .is_stack=true), CORD_EMPTY);
}
return get_type(env, Match(ast, Holding)->body);
}
@ -1165,7 +1165,7 @@ type_t *get_type(env_t *env, ast_t *ast)
for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) {
type_t *t = get_arg_ast_type(env, arg);
args = new(arg_t, .name=arg->name, .type=t, .next=args);
set_binding(scope, arg->name, new(binding_t, .type=t));
set_binding(scope, arg->name, t, CORD_EMPTY);
}
REVERSE_LIST(args);
@ -1212,16 +1212,16 @@ type_t *get_type(env_t *env, ast_t *ast)
truthy_scope = fresh_scope(env);
if (condition_type->tag == OptionalType)
set_binding(truthy_scope, varname,
new(binding_t, .type=Match(condition_type, OptionalType)->type));
Match(condition_type, OptionalType)->type, CORD_EMPTY);
else
set_binding(truthy_scope, varname, new(binding_t, .type=condition_type));
set_binding(truthy_scope, varname, condition_type, CORD_EMPTY);
} else if (if_->condition->tag == Var) {
type_t *condition_type = get_type(env, if_->condition);
if (condition_type->tag == OptionalType) {
truthy_scope = fresh_scope(env);
const char *varname = Match(if_->condition, Var)->name;
set_binding(truthy_scope, varname,
new(binding_t, .type=Match(condition_type, OptionalType)->type));
Match(condition_type, OptionalType)->type, CORD_EMPTY);
}
}