diff options
| -rw-r--r-- | compile.c | 36 | ||||
| -rw-r--r-- | enums.c | 12 | ||||
| -rw-r--r-- | environment.c | 36 | ||||
| -rw-r--r-- | environment.h | 10 | ||||
| -rw-r--r-- | structs.c | 12 | ||||
| -rw-r--r-- | tomo.c | 35 | ||||
| -rw-r--r-- | typecheck.c | 44 |
7 files changed, 115 insertions, 70 deletions
@@ -20,7 +20,7 @@ static env_t *with_enum_scope(env_t *env, type_t *t); CORD compile_type_ast(env_t *env, type_ast_t *t) { switch (t->tag) { - case VarTypeAST: return CORD_all(env->file_prefix, Match(t, VarTypeAST)->name, "_t"); + case VarTypeAST: return CORD_all(namespace_prefix(env->namespace), Match(t, VarTypeAST)->name, "_t"); case PointerTypeAST: return CORD_cat(compile_type_ast(env, Match(t, PointerTypeAST)->pointed), "*"); case TableTypeAST: return "table_t"; case ArrayTypeAST: return "array_t"; @@ -126,7 +126,7 @@ CORD compile_type(env_t *env, type_t *t) case NumType: return Match(t, NumType)->bits == 64 ? "Num_t" : CORD_asprintf("Num%ld_t", Match(t, NumType)->bits); case TextType: { auto text = Match(t, TextType); - return text->lang ? CORD_all(text->env->file_prefix, text->lang, "_t") : "Text_t"; + return text->lang ? CORD_all(namespace_prefix(text->env->namespace->parent), text->lang, "_t") : "Text_t"; } case ArrayType: return "array_t"; case TableType: return "table_t"; @@ -143,11 +143,11 @@ CORD compile_type(env_t *env, type_t *t) case PointerType: return CORD_cat(compile_type(env, Match(t, PointerType)->pointed), "*"); case StructType: { auto s = Match(t, StructType); - return CORD_all("struct ", s->env->file_prefix, s->name, "_s"); + return CORD_all("struct ", namespace_prefix(s->env->namespace->parent), s->name, "_s"); } case EnumType: { auto e = Match(t, EnumType); - return CORD_all(e->env->file_prefix, e->name, "_t"); + return CORD_all(namespace_prefix(e->env->namespace->parent), e->name, "_t"); } case TypeInfoType: return "TypeInfo"; default: compiler_err(NULL, NULL, NULL, "Compiling type is not implemented for type with tag %d", t->tag); @@ -232,7 +232,7 @@ CORD compile_statement(env_t *env, ast_t *ast) "switch (subject.$tag) {"); for (when_clause_t *clause = when->clauses; clause; clause = clause->next) { const char *clause_tag_name = Match(clause->tag_name, Var)->name; - code = CORD_all(code, "case ", enum_t->env->file_prefix, enum_t->name, "$tag$", clause_tag_name, ": {\n"); + code = CORD_all(code, "case ", namespace_prefix(enum_t->env->namespace), enum_t->name, "$tag$", clause_tag_name, ": {\n"); type_t *tag_type = NULL; for (tag_t *tag = enum_t->tags; tag; tag = tag->next) { if (streq(tag->name, clause_tag_name)) { @@ -515,7 +515,7 @@ CORD compile_statement(env_t *env, ast_t *ast) case LangDef: { auto def = Match(ast, LangDef); CORD_appendf(&env->code->typeinfos, "public const TypeInfo %r%s = {%zu, %zu, {.tag=TextInfo, .TextInfo={%r}}};\n", - env->file_prefix, def->name, sizeof(CORD), __alignof__(CORD), + namespace_prefix(env->namespace), def->name, sizeof(CORD), __alignof__(CORD), Text$quoted(def->name, false)); compile_namespace(env, def->name, def->namespace); return CORD_EMPTY; @@ -551,7 +551,7 @@ CORD compile_statement(env_t *env, ast_t *ast) } env_t *body_scope = fresh_scope(env); - body_scope->scope_prefix = CORD_EMPTY; + 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))); @@ -1497,7 +1497,7 @@ CORD compile(env_t *env, ast_t *ast) } case Lambda: { auto lambda = Match(ast, Lambda); - CORD name = CORD_asprintf("%slambda$%ld", env->file_prefix, lambda->id); + CORD name = CORD_asprintf("%rlambda$%ld", namespace_prefix(env->namespace), lambda->id); env_t *body_scope = fresh_scope(env); for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) { @@ -1976,15 +1976,15 @@ CORD compile_type_info(env_t *env, type_t *t) return CORD_asprintf("&$%r", type_to_cord(t)); case TextType: { auto text = Match(t, TextType); - return text->lang ? CORD_all("(&", text->env->file_prefix, text->lang, ")") : "&$Text"; + return text->lang ? CORD_all("(&", namespace_prefix(text->env->namespace->parent), text->lang, ")") : "&$Text"; } case StructType: { auto s = Match(t, StructType); - return CORD_all("(&", s->env->file_prefix, s->name, ")"); + return CORD_all("(&", namespace_prefix(s->env->namespace->parent), s->name, ")"); } case EnumType: { auto e = Match(t, EnumType); - return CORD_all("(&", e->env->file_prefix, e->name, ")"); + return CORD_all("(&", namespace_prefix(e->env->namespace->parent), e->name, ")"); } case ArrayType: { type_t *item_t = Match(t, ArrayType)->item_type; @@ -2201,12 +2201,12 @@ CORD compile_file(env_t *env, ast_t *ast) } else if (is_private) { env->code->staticdefs = CORD_all( env->code->staticdefs, - "static ", compile_type(env, t), " $", decl_name, " = ", + "static ", compile_type(env, t), " ", namespace_prefix(env->namespace), decl_name, " = ", compile(env, decl->value), ";\n"); } else { env->code->staticdefs = CORD_all( env->code->staticdefs, - compile_type(env, t), " ", env->file_prefix, decl_name, " = ", + compile_type(env, t), " ", namespace_prefix(env->namespace), decl_name, " = ", compile(env, decl->value), ";\n"); } } else if (stmt->ast->tag == InlineCCode) { @@ -2256,7 +2256,7 @@ CORD compile_statement_header(env_t *env, ast_t *ast) return code; } else { return CORD_all( - code, "\n" "extern ", compile_declaration(env, t, CORD_cat(env->file_prefix, decl_name)), ";\n"); + code, "\n" "extern ", compile_declaration(env, t, CORD_cat(namespace_prefix(env->namespace), decl_name)), ";\n"); } } case StructDef: { @@ -2268,8 +2268,8 @@ CORD compile_statement_header(env_t *env, ast_t *ast) case LangDef: { auto def = Match(ast, LangDef); return CORD_all( - "typedef CORD ", env->file_prefix, def->name, "_t;\n", - "extern const TypeInfo ", env->file_prefix, def->name, ";\n"); + "typedef CORD ", namespace_prefix(env->namespace), def->name, "_t;\n", + "extern const TypeInfo ", namespace_prefix(env->namespace), def->name, ";\n"); compile_namespace(env, def->name, def->namespace); return CORD_EMPTY; } @@ -2288,12 +2288,12 @@ CORD compile_statement_header(env_t *env, ast_t *ast) type_t *ret_t = fndef->ret_type ? parse_type_ast(env, fndef->ret_type) : Type(VoidType); CORD ret_type_code = compile_type(env, ret_t); - CORD header = CORD_all(ret_type_code, " ", CORD_cat(env->file_prefix, decl_name), arg_signature, ";\n"); + CORD header = CORD_all(ret_type_code, " ", CORD_cat(namespace_prefix(env->namespace), decl_name), arg_signature, ";\n"); return header; } case Lambda: { auto lambda = Match(ast, Lambda); - CORD name = CORD_asprintf("%slambda$%ld", env->file_prefix, lambda->id); + CORD name = CORD_asprintf("%rlambda$%ld", namespace_prefix(env->namespace), lambda->id); table_t *closed_vars = get_closed_vars(env, ast); if (Table$length(*closed_vars) == 0) { return CORD_EMPTY; @@ -23,7 +23,7 @@ static bool has_extra_data(tag_ast_t *tags) static CORD compile_str_method(env_t *env, ast_t *ast) { auto def = Match(ast, EnumDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); CORD str_func = CORD_all("static CORD ", full_name, "$as_text(", full_name, "_t *obj, bool use_color) {\n" "\tif (!obj) return \"", def->name, "\";\n" "switch (obj->$tag) {\n"); @@ -57,7 +57,7 @@ static CORD compile_str_method(env_t *env, ast_t *ast) static CORD compile_compare_method(env_t *env, ast_t *ast) { auto def = Match(ast, EnumDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); if (!has_extra_data(def->tags)) { // Comparisons are simpler if there is only a tag, no tagged data: return CORD_all("static int ", full_name, "$compare(const ", full_name, "_t *x, const ", full_name, @@ -88,7 +88,7 @@ static CORD compile_compare_method(env_t *env, ast_t *ast) static CORD compile_equals_method(env_t *env, ast_t *ast) { auto def = Match(ast, EnumDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); if (!has_extra_data(def->tags)) { // Equality is simpler if there is only a tag, no tagged data: return CORD_all("static bool ", full_name, "$equal(const ", full_name, "_t *x, const ", full_name, @@ -118,7 +118,7 @@ static CORD compile_equals_method(env_t *env, ast_t *ast) static CORD compile_hash_method(env_t *env, ast_t *ast) { auto def = Match(ast, EnumDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); if (!has_extra_data(def->tags)) { // Hashing is simpler if there is only a tag, no tagged data: return CORD_all("static uint32_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo *info) {\n" @@ -152,7 +152,7 @@ static CORD compile_hash_method(env_t *env, ast_t *ast) void compile_enum_def(env_t *env, ast_t *ast) { auto def = Match(ast, EnumDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { compile_struct_def(env, WrapAST(ast, StructDef, .name=CORD_to_const_char_star(CORD_all(def->name, "$", tag->name)), .fields=tag->fields)); if (tag->fields) { // Constructor macros: @@ -203,7 +203,7 @@ void compile_enum_def(env_t *env, ast_t *ast) CORD compile_enum_header(env_t *env, ast_t *ast) { auto def = Match(ast, EnumDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); CORD header = CORD_all("typedef struct ", full_name, "_s ", full_name, "_t;\n", "extern const TypeInfo ", full_name, ";\n"); CORD enum_def = CORD_all("struct ", full_name, "_s {\n" diff --git a/environment.c b/environment.c index c71699e1..1ba4bf05 100644 --- a/environment.c +++ b/environment.c @@ -235,28 +235,32 @@ env_t *new_compilation_unit(void) return env; } -env_t *load_module_env(env_t *env, const char *prefix, ast_t *ast) +CORD namespace_prefix(namespace_t *ns) +{ + CORD prefix = CORD_EMPTY; + for (; ns; ns = ns->parent) + prefix = CORD_all(ns->name, "$", prefix); + return prefix; +} + +env_t *load_module_env(env_t *env, ast_t *ast) { const char *name = file_base_name(ast->file->filename); env_t *cached = Table$str_get(*env->imports, name); if (cached) return cached; - env = fresh_scope(env); - env->code = new(compilation_unit_t); - env->file_prefix = prefix; - Table$str_set(env->imports, name, env); + env_t *module_env = fresh_scope(env); + module_env->code = new(compilation_unit_t); + module_env->namespace = new(namespace_t, .name=name, .parent=env->namespace), + Table$str_set(module_env->imports, name, module_env); for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) - prebind_statement(env, stmt->ast); + prebind_statement(module_env, stmt->ast); - for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { - // Hack: make sure global variables are bound as foo$var: - if (stmt->ast->tag == Declare && Match(Match(stmt->ast, Declare)->var, Var)->name[0] != '_') - env->scope_prefix = prefix; - bind_statement(env, stmt->ast); - env->scope_prefix = NULL; - } - Table$str_set(env->imports, name, env); - return env; + for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) + bind_statement(module_env, stmt->ast); + + Table$str_set(env->imports, name, module_env); + return module_env; } env_t *global_scope(env_t *env) @@ -334,7 +338,7 @@ env_t *namespace_env(env_t *env, const char *namespace_name) env_t *ns_env = new(env_t); *ns_env = *env; ns_env->locals = new(table_t, .fallback=env->locals); - ns_env->scope_prefix = CORD_all(namespace_name, "$"); + ns_env->namespace = new(namespace_t, .name=namespace_name, .parent=env->namespace); return ns_env; } diff --git a/environment.h b/environment.h index 6cc083ef..ff411649 100644 --- a/environment.h +++ b/environment.h @@ -26,13 +26,18 @@ typedef struct loop_ctx_s { CORD skip_label, stop_label; } loop_ctx_t; +typedef struct namespace_s { + const char *name; + struct namespace_s *parent; +} namespace_t; + typedef struct env_s { table_t *types, *globals, *locals; table_t *imports; // Map of 'use' name -> env_t* compilation_unit_t *code; fn_ctx_t *fn_ctx; loop_ctx_t *loop_ctx; - CORD file_prefix, scope_prefix; + namespace_t *namespace; const char *comprehension_var; } env_t; @@ -45,7 +50,8 @@ typedef struct { } binding_t; env_t *new_compilation_unit(void); -env_t *load_module_env(env_t *env, const char *prefix, ast_t *ast); +env_t *load_module_env(env_t *env, ast_t *ast); +CORD namespace_prefix(namespace_t *ns); env_t *global_scope(env_t *env); env_t *fresh_scope(env_t *env); env_t *for_scope(env_t *env, ast_t *ast); @@ -14,7 +14,7 @@ static CORD compile_str_method(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); const char *name = def->name; const char *dollar = strrchr(name, '$'); if (dollar) name = dollar + 1; @@ -39,7 +39,7 @@ static CORD compile_str_method(env_t *env, ast_t *ast) static CORD compile_compare_method(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); CORD cmp_func = CORD_all("static int ", full_name, "$compare(const ", full_name, "_t *x, const ", full_name, "_t *y, const TypeInfo *info) {\n" "(void)info;\n", @@ -67,7 +67,7 @@ static CORD compile_compare_method(env_t *env, ast_t *ast) static CORD compile_equals_method(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); CORD eq_func = CORD_all("static bool ", full_name, "$equal(const ", full_name, "_t *x, const ", full_name, "_t *y, const TypeInfo *info) {\n" "(void)info;\n"); @@ -96,7 +96,7 @@ static CORD compile_equals_method(env_t *env, ast_t *ast) static CORD compile_hash_method(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); CORD hash_func = CORD_all("static uint32_t ", full_name, "$hash(const ", full_name, "_t *obj, const TypeInfo *info) {\n" "(void)info;\n" "uint32_t field_hashes[] = {"); @@ -114,7 +114,7 @@ static CORD compile_hash_method(env_t *env, ast_t *ast) void compile_struct_def(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); type_t *t = Table$str_get(*env->types, def->name); assert(t && t->tag == StructType); @@ -165,7 +165,7 @@ void compile_struct_def(env_t *env, ast_t *ast) CORD compile_struct_header(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD full_name = CORD_cat(namespace_prefix(env->namespace), def->name); CORD header = CORD_all("typedef struct ", full_name, "_s ", full_name, "_t;\n"); CORD struct_code = CORD_all("struct ", full_name, "_s {\n"); @@ -188,6 +188,34 @@ int main(int argc, char *argv[]) *p = '_'; } + // Each type's namespace now exists within the library's namespace, on top of whatever + // other namespace it was already in: + namespace_t *lib_ns = new(namespace_t, .name=libname_id); + for (int64_t i = 1; i <= Table$length(*env->types); i++) { + struct {const char *name; type_t *type; } *entry = Table$entry(*env->types, i); + env_t *type_env = NULL; + switch (entry->type->tag) { + case TextType: type_env = Match(entry->type, TextType)->env; break; + case StructType: type_env = Match(entry->type, StructType)->env; break; + case EnumType: type_env = Match(entry->type, EnumType)->env; break; + case TypeInfoType: type_env = Match(entry->type, TypeInfoType)->env; break; + default: break; + } + + if (type_env) { + // Find the topmost namespace, and if it's not already `lib_ns`, then + // set it to that: + for (namespace_t **ns = &type_env->namespace; ; ns = &((*ns)->parent)) { + if (*ns == lib_ns) { + break; + } else if (*ns == NULL) { + *ns = lib_ns; + break; + } + } + } + } + // Build a "libwhatever.h" header that loads all the headers: const char *h_filename = heap_strf("lib%s.h", libname); FILE *header_prog = CORD_RUN(autofmt ? autofmt : "cat", " 2>/dev/null >", h_filename); @@ -198,8 +226,7 @@ int main(int argc, char *argv[]) if (!f) errx(1, "No such file: %s", filename); ast_t *ast = parse_file(f, NULL); if (!ast) errx(1, "Could not parse %s", f); - env->file_prefix = heap_strf("%s$%s$", libname_id, file_base_name(filename)); - + env->namespace = new(namespace_t, .name=file_base_name(filename), .parent=lib_ns); for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { if (stmt->ast->tag == Import || (stmt->ast->tag == Declare && Match(stmt->ast, Declare)->value->tag == Import)) continue; @@ -352,7 +379,7 @@ int transpile_header(env_t *base_env, const char *filename, bool force_retranspi if (!ast) errx(1, "Could not parse %s", f); - env_t *module_env = load_module_env(base_env, heap_strf("%s$", file_base_name(filename)), ast); + env_t *module_env = load_module_env(base_env, ast); CORD h_code = compile_header(module_env, ast); @@ -396,7 +423,7 @@ int transpile_code(env_t *base_env, const char *filename, bool force_retranspile if (!ast) errx(1, "Could not parse %s", f); - env_t *module_env = load_module_env(base_env, heap_strf("%s$", file_base_name(filename)), ast); + env_t *module_env = load_module_env(base_env, ast); CORD c_code = compile_file(module_env, ast); diff --git a/typecheck.c b/typecheck.c index 31fdfc77..8e4bfd7d 100644 --- a/typecheck.c +++ b/typecheck.c @@ -121,7 +121,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) ast_t *ast = parse_file(f, NULL); if (!ast) errx(1, "Could not compile!"); - return load_module_env(env, heap_strf("%s$", name), ast); + return load_module_env(env, ast); } else if (module_ast->tag == Use) { const char *libname = Match(module_ast, Use)->name; const char *files_filename = heap_strf("%s/lib%s.files", libname, libname); @@ -131,7 +131,13 @@ static env_t *load_module(env_t *env, ast_t *module_ast) file_t *files_f = load_file(resolved_path); if (!files_f) errx(1, "Couldn't open file: %s", resolved_path); - env_t *ret_env = fresh_scope(env); + env_t *module_env = fresh_scope(env); + char *libname_id = heap_str(libname); + for (char *c = libname_id; *c; c++) { + if (!isalnum(*c) && *c != '_') + *c = '_'; + } + module_env->namespace = new(namespace_t, .name=libname_id); for (int64_t i = 1; i <= files_f->num_lines; i++) { const char *line = get_line(files_f, i); line = heap_strn(line, strcspn(line, "\r\n")); @@ -144,23 +150,23 @@ static env_t *load_module(env_t *env, ast_t *module_ast) ast_t *ast = parse_file(tm_f, NULL); if (!ast) errx(1, "Could not compile!"); - env_t *tmp_env = fresh_scope(env); - char *prefix = heap_strf("%s$%s$", libname, file_base_name(line)); - for (char *p = prefix; *p; p++) { + env_t *module_file_env = fresh_scope(env); + char *file_prefix = heap_str(file_base_name(line)); + for (char *p = file_prefix; *p; p++) { if (!isalnum(*p) && *p != '_' && *p != '$') *p = '_'; } - tmp_env->file_prefix = prefix; - tmp_env->imports = new(table_t); - env_t *subenv = load_module_env(tmp_env, prefix, ast); + module_file_env->namespace = new(namespace_t, .name=file_prefix, .parent=module_env->namespace); + module_file_env->imports = new(table_t); + env_t *subenv = load_module_env(module_file_env, ast); for (int64_t j = 0; j < subenv->locals->entries.length; j++) { struct { const char *name; binding_t *binding; } *entry = subenv->locals->entries.data + j*subenv->locals->entries.stride; - set_binding(ret_env, entry->name, entry->binding); + set_binding(module_env, entry->name, entry->binding); } } - return ret_env; + return module_env; } else { code_err(module_ast, "This is not a module import"); } @@ -181,7 +187,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(env->file_prefix, def->name))); + 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->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; @@ -194,7 +201,7 @@ 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(env->file_prefix, def->name))); + 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->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; @@ -207,7 +214,7 @@ 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(env->file_prefix, def->name))); + 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->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; @@ -233,7 +240,8 @@ void bind_statement(env_t *env, ast_t *statement) else bind_statement(env, decl->value); type_t *type = get_type(env, decl->value); - CORD code = CORD_cat(env->scope_prefix ? env->scope_prefix : "$", name); + CORD prefix = namespace_prefix(env->namespace); + CORD code = CORD_cat(prefix ? prefix : "$", name); set_binding(env, name, new(binding_t, .type=type, .code=code)); break; } @@ -244,7 +252,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); bool is_private = (name[0] == '_'); - CORD code = is_private ? CORD_cat("$", name) : CORD_all(env->file_prefix, env->scope_prefix, name); + CORD code = is_private ? CORD_cat("$", name) : CORD_all(namespace_prefix(env->namespace), name); set_binding(env, name, new(binding_t, .type=type, .code=code)); break; } @@ -310,9 +318,9 @@ 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(env->file_prefix, def->name, "$tagged$", tag->name))); + set_binding(ns_env, tag->name, new(binding_t, .type=constructor_t, .code=CORD_all(namespace_prefix(env->namespace), def->name, "$tagged$", tag->name))); } else { // Empty singleton value: - CORD code = CORD_all("(", env->file_prefix, def->name, "_t){", env->file_prefix, def->name, "$tag$", tag->name, "}"); + CORD code = CORD_all("(", namespace_prefix(env->namespace), def->name, "_t){", namespace_prefix(env->namespace), def->name, "$tag$", tag->name, "}"); set_binding(ns_env, tag->name, new(binding_t, .type=type, .code=code)); } Table$str_set(env->types, heap_strf("%s$%s", def->name, tag->name), tag->type); @@ -331,7 +339,7 @@ void bind_statement(env_t *env, ast_t *statement) set_binding(ns_env, "from_unsafe_text", new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE), .ret=type), - .code=CORD_all("(", env->file_prefix, def->name, "_t)"))); + .code=CORD_all("(", namespace_prefix(env->namespace), def->name, "_t)"))); set_binding(ns_env, "text_content", new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=TEXT_TYPE), .ret=type), .code="(Text_t)")); |
