diff --git a/compile.c b/compile.c index edeb505..edcd00a 100644 --- a/compile.c +++ b/compile.c @@ -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(namespace_prefix(env->namespace), Match(t, VarTypeAST)->name, "_t"); + case VarTypeAST: return CORD_all(namespace_prefix(env->libname, 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(namespace_prefix(text->env->namespace->parent), text->lang, "_t") : "Text_t"; + return text->lang ? CORD_all(namespace_prefix(env->libname, 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 ", namespace_prefix(s->env->namespace->parent), s->name, "_s"); + return CORD_all("struct ", namespace_prefix(env->libname, s->env->namespace->parent), s->name, "_s"); } case EnumType: { auto e = Match(t, EnumType); - return CORD_all(namespace_prefix(e->env->namespace->parent), e->name, "_t"); + return CORD_all(namespace_prefix(env->libname, 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 ", namespace_prefix(enum_t->env->namespace), enum_t->name, "$tag$", clause_tag_name, ": {\n"); + code = CORD_all(code, "case ", namespace_prefix(env->libname, 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", - namespace_prefix(env->namespace), def->name, sizeof(CORD), __alignof__(CORD), + namespace_prefix(env->libname, env->namespace), def->name, sizeof(CORD), __alignof__(CORD), Text$quoted(def->name, false)); compile_namespace(env, def->name, def->namespace); return CORD_EMPTY; @@ -523,7 +523,7 @@ CORD compile_statement(env_t *env, ast_t *ast) case FunctionDef: { auto fndef = Match(ast, FunctionDef); bool is_private = Match(fndef->name, Var)->name[0] == '_'; - CORD name = is_private ? CORD_cat("$", Match(fndef->name, Var)->name) : compile(env, fndef->name); + CORD name = compile(env, fndef->name); type_t *ret_t = fndef->ret_type ? parse_type_ast(env, fndef->ret_type) : Type(VoidType); CORD arg_signature = "("; @@ -1497,7 +1497,7 @@ CORD compile(env_t *env, ast_t *ast) } case Lambda: { auto lambda = Match(ast, Lambda); - CORD name = CORD_asprintf("%rlambda$%ld", namespace_prefix(env->namespace), lambda->id); + CORD name = CORD_asprintf("%rlambda$%ld", namespace_prefix(env->libname, 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("(&", namespace_prefix(text->env->namespace->parent), text->lang, ")") : "&$Text"; + return text->lang ? CORD_all("(&", namespace_prefix(env->libname, text->env->namespace->parent), text->lang, ")") : "&$Text"; } case StructType: { auto s = Match(t, StructType); - return CORD_all("(&", namespace_prefix(s->env->namespace->parent), s->name, ")"); + return CORD_all("(&", namespace_prefix(env->libname, s->env->namespace->parent), s->name, ")"); } case EnumType: { auto e = Match(t, EnumType); - return CORD_all("(&", namespace_prefix(e->env->namespace->parent), e->name, ")"); + return CORD_all("(&", namespace_prefix(env->libname, 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), " ", namespace_prefix(env->namespace), decl_name, " = ", + "static ", compile_type(env, t), " ", namespace_prefix(env->libname, env->namespace), decl_name, " = ", compile(env, decl->value), ";\n"); } else { env->code->staticdefs = CORD_all( env->code->staticdefs, - compile_type(env, t), " ", namespace_prefix(env->namespace), decl_name, " = ", + compile_type(env, t), " ", namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), decl_name)), ";\n"); + code, "\n" "extern ", compile_declaration(env, t, CORD_cat(namespace_prefix(env->libname, 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 ", namespace_prefix(env->namespace), def->name, "_t;\n", - "extern const TypeInfo ", namespace_prefix(env->namespace), def->name, ";\n"); + "typedef CORD ", namespace_prefix(env->libname, env->namespace), def->name, "_t;\n", + "extern const TypeInfo ", namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), decl_name), arg_signature, ";\n"); + CORD header = CORD_all(ret_type_code, " ", CORD_cat(namespace_prefix(env->libname, env->namespace), decl_name), arg_signature, ";\n"); return header; } case Lambda: { auto lambda = Match(ast, Lambda); - CORD name = CORD_asprintf("%rlambda$%ld", namespace_prefix(env->namespace), lambda->id); + CORD name = CORD_asprintf("%rlambda$%ld", namespace_prefix(env->libname, env->namespace), lambda->id); table_t *closed_vars = get_closed_vars(env, ast); if (Table$length(*closed_vars) == 0) { return CORD_EMPTY; diff --git a/enums.c b/enums.c index b9e6754..3d11d7f 100644 --- a/enums.c +++ b/enums.c @@ -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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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 1ba4bf0..aca60d2 100644 --- a/environment.c +++ b/environment.c @@ -11,7 +11,7 @@ type_t *TEXT_TYPE = NULL; -env_t *new_compilation_unit(void) +env_t *new_compilation_unit(CORD *libname) { env_t *env = new(env_t); env->code = new(compilation_unit_t); @@ -19,6 +19,7 @@ env_t *new_compilation_unit(void) env->globals = new(table_t); env->locals = new(table_t, .fallback=env->globals); env->imports = new(table_t); + env->libname = libname; if (!TEXT_TYPE) TEXT_TYPE = Type(TextType, .env=namespace_env(env, "Text")); @@ -235,11 +236,13 @@ env_t *new_compilation_unit(void) return env; } -CORD namespace_prefix(namespace_t *ns) +CORD namespace_prefix(CORD *libname, namespace_t *ns) { CORD prefix = CORD_EMPTY; for (; ns; ns = ns->parent) prefix = CORD_all(ns->name, "$", prefix); + if (libname && *libname) + prefix = CORD_all(*libname, "$", prefix); return prefix; } @@ -250,7 +253,7 @@ env_t *load_module_env(env_t *env, ast_t *ast) if (cached) return cached; 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), + module_env->namespace = new(namespace_t, .name=name); Table$str_set(module_env->imports, name, module_env); for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) diff --git a/environment.h b/environment.h index ff41164..7ecedd6 100644 --- a/environment.h +++ b/environment.h @@ -37,6 +37,7 @@ typedef struct env_s { compilation_unit_t *code; fn_ctx_t *fn_ctx; loop_ctx_t *loop_ctx; + CORD *libname; // Pointer to currently compiling library name (if any) namespace_t *namespace; const char *comprehension_var; } env_t; @@ -49,9 +50,9 @@ typedef struct { }; } binding_t; -env_t *new_compilation_unit(void); +env_t *new_compilation_unit(CORD *libname); env_t *load_module_env(env_t *env, ast_t *ast); -CORD namespace_prefix(namespace_t *ns); +CORD namespace_prefix(CORD *libname, 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); diff --git a/repl.c b/repl.c index c687f37..d3d433d 100644 --- a/repl.c +++ b/repl.c @@ -28,7 +28,7 @@ static void eval(env_t *env, ast_t *ast, void *dest); void repl(void) { - env_t *env = new_compilation_unit(); + env_t *env = new_compilation_unit(NULL); void *dl = dlopen("libtomo.so", RTLD_LAZY); if (!dl) errx(1, "I couldn't find libtomo.so in your library paths"); diff --git a/structs.c b/structs.c index 10b9465..ff98dfa 100644 --- a/structs.c +++ b/structs.c @@ -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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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(namespace_prefix(env->namespace), def->name); + CORD full_name = CORD_cat(namespace_prefix(env->libname, 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"); diff --git a/tomo.c b/tomo.c index 392df94..78f665a 100644 --- a/tomo.c +++ b/tomo.c @@ -120,7 +120,8 @@ int main(int argc, char *argv[]) cc = ENV_CORD("CC"); if (!cc) cc = "cc"; - env_t *env = new_compilation_unit(); + CORD compilation_library_name = CORD_EMPTY; + env_t *env = new_compilation_unit(&compilation_library_name); table_t dependency_files = {}; table_t to_link = {}; @@ -187,34 +188,7 @@ int main(int argc, char *argv[]) if (!isalnum(*p) && *p != '_' && *p != '$') *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; - } - } - } - } + compilation_library_name = libname_id; // Build a "libwhatever.h" header that loads all the headers: const char *h_filename = heap_strf("lib%s.h", libname); @@ -226,7 +200,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->namespace = new(namespace_t, .name=file_base_name(filename), .parent=lib_ns); + env->namespace = new(namespace_t, .name=file_base_name(filename)); 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; diff --git a/typecheck.c b/typecheck.c index 8e4bfd7..4b4f103 100644 --- a/typecheck.c +++ b/typecheck.c @@ -137,7 +137,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) if (!isalnum(*c) && *c != '_') *c = '_'; } - module_env->namespace = new(namespace_t, .name=libname_id); + module_env->libname = (const char**)&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")); @@ -156,7 +156,7 @@ static env_t *load_module(env_t *env, ast_t *module_ast) if (!isalnum(*p) && *p != '_' && *p != '$') *p = '_'; } - module_file_env->namespace = new(namespace_t, .name=file_prefix, .parent=module_env->namespace); + module_file_env->namespace = new(namespace_t, .name=file_prefix); 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++) { @@ -188,7 +188,7 @@ void prebind_statement(env_t *env, ast_t *statement) 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->namespace), def->name))); + .code=CORD_all(namespace_prefix(env->libname, 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; @@ -201,7 +201,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->namespace), 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->libname, 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; @@ -214,7 +215,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->namespace), 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->libname, 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; @@ -240,7 +242,7 @@ void bind_statement(env_t *env, ast_t *statement) else bind_statement(env, decl->value); type_t *type = get_type(env, decl->value); - CORD prefix = namespace_prefix(env->namespace); + CORD prefix = namespace_prefix(env->libname, env->namespace); CORD code = CORD_cat(prefix ? prefix : "$", name); set_binding(env, name, new(binding_t, .type=type, .code=code)); break; @@ -251,8 +253,7 @@ void bind_statement(env_t *env, ast_t *statement) if (get_binding(env, name)) 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(namespace_prefix(env->namespace), name); + CORD code = CORD_all(namespace_prefix(env->libname, env->namespace), name); set_binding(env, name, new(binding_t, .type=type, .code=code)); break; } @@ -318,9 +319,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(namespace_prefix(env->namespace), def->name, "$tagged$", tag->name))); + set_binding(ns_env, tag->name, new(binding_t, .type=constructor_t, .code=CORD_all(namespace_prefix(env->libname, env->namespace), def->name, "$tagged$", tag->name))); } else { // Empty singleton value: - CORD code = CORD_all("(", namespace_prefix(env->namespace), def->name, "_t){", namespace_prefix(env->namespace), def->name, "$tag$", tag->name, "}"); + CORD code = CORD_all("(", namespace_prefix(env->libname, env->namespace), def->name, "_t){", namespace_prefix(env->libname, 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); @@ -339,7 +340,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("(", namespace_prefix(env->namespace), def->name, "_t)"))); + .code=CORD_all("(", namespace_prefix(env->libname, 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)"));