diff --git a/compile.c b/compile.c index ecd03b8..f2c3065 100644 --- a/compile.c +++ b/compile.c @@ -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); } } } diff --git a/environment.c b/environment.c index 1b33fd7..5f3fe76 100644 --- a/environment.c +++ b/environment.c @@ -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))) diff --git a/environment.h b/environment.h index 465ecfa..364fe8c 100644 --- a/environment.h +++ b/environment.h @@ -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; diff --git a/typecheck.c b/typecheck.c index a2530bc..7e63396 100644 --- a/typecheck.c +++ b/typecheck.c @@ -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); } }