From 655b6778955c8da782365d86326d3afceccc9a6b Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 17 Mar 2024 20:40:40 -0400 Subject: Preface symbols with file prefix --- compile.c | 113 +++++++++++++++++++++++++++++++--------------------------- compile.h | 6 ++-- enums.c | 57 +++++++++++++++-------------- environment.c | 2 +- environment.h | 2 +- structs.c | 35 ++++++++++-------- typecheck.c | 6 ++-- 7 files changed, 119 insertions(+), 102 deletions(-) diff --git a/compile.c b/compile.c index 178a7794..00abe891 100644 --- a/compile.c +++ b/compile.c @@ -14,11 +14,11 @@ #include "typecheck.h" #include "builtins/util.h" -CORD compile_type_ast(type_ast_t *t) +CORD compile_type_ast(env_t *env, type_ast_t *t) { switch (t->tag) { - case VarTypeAST: return CORD_cat(Match(t, VarTypeAST)->name, "_t"); - case PointerTypeAST: return CORD_cat(compile_type_ast(Match(t, PointerTypeAST)->pointed), "*"); + case VarTypeAST: return CORD_all(env->file_prefix, 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"; case FunctionTypeAST: return "const void*"; @@ -57,22 +57,22 @@ static bool promote(env_t *env, CORD *code, type_t *actual, type_t *needed) } -CORD compile_declaration(type_t *t, const char *name) +CORD compile_declaration(env_t *env, type_t *t, const char *name) { if (t->tag == FunctionType) { auto fn = Match(t, FunctionType); - CORD code = CORD_all(compile_type(fn->ret), " (*", name, ")("); + CORD code = CORD_all(compile_type(env, fn->ret), " (*", name, ")("); for (arg_t *arg = fn->args; arg; arg = arg->next) { - code = CORD_all(code, compile_type(arg->type)); + code = CORD_all(code, compile_type(env, arg->type)); if (arg->next) code = CORD_cat(code, ", "); } return CORD_all(code, ")"); } else { - return CORD_all(compile_type(t), " ", name); + return CORD_all(compile_type(env, t), " ", name); } } -CORD compile_type(type_t *t) +CORD compile_type(env_t *env, type_t *t) { switch (t->tag) { case AbortType: return "void"; @@ -83,23 +83,23 @@ CORD compile_type(type_t *t) case NumType: return Match(t, NumType)->bits == 64 ? "Num_t" : CORD_asprintf("Num%ld_t", Match(t, NumType)->bits); case TextType: { const char *dsl = Match(t, TextType)->lang; - return dsl ? CORD_cat(dsl, "_t") : "Text_t"; + return dsl ? CORD_all(env->file_prefix, dsl, "_t") : "Text_t"; } case ArrayType: return "array_t"; case TableType: return "table_t"; case FunctionType: { auto fn = Match(t, FunctionType); - CORD code = CORD_all(compile_type(fn->ret), " (*)("); + CORD code = CORD_all(compile_type(env, fn->ret), " (*)("); for (arg_t *arg = fn->args; arg; arg = arg->next) { - code = CORD_all(code, compile_type(arg->type)); + code = CORD_all(code, compile_type(env, arg->type)); if (arg->next) code = CORD_cat(code, ", "); } return CORD_all(code, ")"); } case ClosureType: return "closure_t"; - case PointerType: return CORD_cat(compile_type(Match(t, PointerType)->pointed), "*"); - case StructType: return CORD_cat(Match(t, StructType)->name, "_t"); - case EnumType: return CORD_cat(Match(t, EnumType)->name, "_t"); + case PointerType: return CORD_cat(compile_type(env, Match(t, PointerType)->pointed), "*"); + case StructType: return CORD_all(env->file_prefix, Match(t, StructType)->name, "_t"); + case EnumType: return CORD_all(env->file_prefix, Match(t, EnumType)->name, "_t"); case TypeInfoType: return "TypeInfo"; default: compiler_err(NULL, NULL, NULL, "Not implemented"); } @@ -124,7 +124,7 @@ CORD compile_statement(env_t *env, ast_t *ast) auto when = Match(ast, When); type_t *subject_t = get_type(env, when->subject); auto enum_t = Match(subject_t, EnumType); - CORD code = CORD_all("{ ", compile_type(subject_t), " $subject = ", compile(env, when->subject), ";\n" + CORD code = CORD_all("{ ", compile_type(env, subject_t), " $subject = ", compile(env, when->subject), ";\n" "switch ($subject.$tag) {"); type_t *result_t = get_type(env, ast); (void)result_t; @@ -141,7 +141,7 @@ CORD compile_statement(env_t *env, ast_t *ast) assert(tag_type); env_t *scope = env; if (clause->var) { - code = CORD_all(code, compile_type(tag_type), " ", compile(env, clause->var), " = $subject.", clause_tag_name, ";\n"); + code = CORD_all(code, compile_type(env, tag_type), " ", compile(env, clause->var), " = $subject.", clause_tag_name, ";\n"); scope = fresh_scope(env); set_binding(scope, Match(clause->var, Var)->name, new(binding_t, .type=tag_type)); } @@ -204,7 +204,7 @@ CORD compile_statement(env_t *env, ast_t *ast) CORD code = "{ // Assignment\n"; int64_t i = 1; for (ast_list_t *value = assign->values; value; value = value->next) - CORD_appendf(&code, "%r $%ld = %r;\n", compile_type(get_type(env, value->ast)), i++, compile(env, value->ast)); + CORD_appendf(&code, "%r $%ld = %r;\n", compile_type(env, get_type(env, value->ast)), i++, compile(env, value->ast)); i = 1; for (ast_list_t *target = assign->targets; target; target = target->next) { check_assignable(env, target->ast); @@ -232,7 +232,7 @@ CORD compile_statement(env_t *env, ast_t *ast) "{ // Test:\n%r $expr = %r;\n" "$test(&$expr, %r, %r, %r, %ld, %ld);\n" "}", - compile_type(expr_t), + compile_type(env, expr_t), compile(env, test->expr), compile_type_info(env, expr_t), compile(env, WrapAST(test->expr, TextLiteral, .cord=output)), @@ -246,7 +246,7 @@ CORD compile_statement(env_t *env, ast_t *ast) type_t *t = get_type(env, decl->value); if (t->tag == AbortType || t->tag == VoidType) code_err(ast, "You can't declare a variable with a %T value", t); - return CORD_all(compile_declaration(t, Match(decl->var, Var)->name), " = ", compile(env, decl->value), ";"); + return CORD_all(compile_declaration(env, t, Match(decl->var, Var)->name), " = ", compile(env, decl->value), ";"); } case Assign: { auto assign = Match(ast, Assign); @@ -257,7 +257,7 @@ CORD compile_statement(env_t *env, ast_t *ast) CORD code = "{ // Assignment\n"; int64_t i = 1; for (ast_list_t *value = assign->values; value; value = value->next) - CORD_appendf(&code, "%r $%ld = %r;\n", compile_type(get_type(env, value->ast)), i++, compile(env, value->ast)); + CORD_appendf(&code, "%r $%ld = %r;\n", compile_type(env, get_type(env, value->ast)), i++, compile(env, value->ast)); i = 1; for (ast_list_t *target = assign->targets; target; target = target->next) { check_assignable(env, target->ast); @@ -352,10 +352,10 @@ CORD compile_statement(env_t *env, ast_t *ast) case LangDef: { // TODO: implement auto def = Match(ast, LangDef); - CORD_appendf(&env->code->typedefs, "typedef CORD %s_t;\n", def->name); - CORD_appendf(&env->code->typedefs, "extern const TypeInfo %s;\n", def->name); - CORD_appendf(&env->code->typeinfos, "public const TypeInfo %s = {%zu, %zu, {.tag=TextInfo, .TextInfo={%s}}};\n", - def->name, sizeof(CORD), __alignof__(CORD), + CORD_appendf(&env->code->typedefs, "typedef CORD %r%s_t;\n", env->file_prefix, def->name); + CORD_appendf(&env->code->typedefs, "extern const TypeInfo %r%s;\n", env->file_prefix, def->name); + CORD_appendf(&env->code->typeinfos, "public const TypeInfo %r%s = {%zu, %zu, {.tag=TextInfo, .TextInfo={%s}}};\n", + env->file_prefix, def->name, sizeof(CORD), __alignof__(CORD), Text__quoted(def->name, false)); compile_namespace(env, def->name, def->namespace); return CORD_EMPTY; @@ -368,12 +368,12 @@ CORD compile_statement(env_t *env, ast_t *ast) CORD arg_signature = "("; for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - arg_signature = CORD_cat(arg_signature, compile_declaration(arg_type, arg->name)); + arg_signature = CORD_cat(arg_signature, compile_declaration(env, arg_type, arg->name)); if (arg->next) arg_signature = CORD_cat(arg_signature, ", "); } arg_signature = CORD_cat(arg_signature, ")"); - CORD ret_type_code = compile_type(ret_t); + CORD ret_type_code = compile_type(env, ret_t); if (fndef->is_private) env->code->staticdefs = CORD_all(env->code->staticdefs, "static ", ret_type_code, " ", name, arg_signature, ";\n"); @@ -430,7 +430,7 @@ CORD compile_statement(env_t *env, ast_t *ast) CORD wrapper = CORD_all( fndef->is_private ? CORD_EMPTY : "public ", ret_type_code, " ", name, arg_signature, "{\n" "static table_t $cache = {};\n", - compile_type(args_t), " $args = {", all_args, "};\n" + compile_type(env, args_t), " $args = {", all_args, "};\n" "static const TypeInfo *$table_type = $TableInfo(", compile_type_info(env, args_t), ", ", compile_type_info(env, ret_t), ");\n", ret_type_code, "*$cached = Table_get_raw($cache, &$args, $table_type);\n" "if ($cached) return *$cached;\n", @@ -541,7 +541,7 @@ CORD compile_statement(env_t *env, ast_t *ast) type_t *item_t = Match(iter_t, ArrayType)->item_type; CORD index = for_->index ? compile(env, for_->index) : "$i"; CORD value = compile(env, for_->value); - return CORD_all("$ARRAY_FOREACH(", compile(env, for_->iter), ", ", index, ", ", compile_type(item_t), ", ", value, ", ", + return CORD_all("$ARRAY_FOREACH(", compile(env, for_->iter), ", ", index, ", ", compile_type(env, item_t), ", ", value, ", ", body, ", ", for_->empty ? compile_statement(env, for_->empty) : "{}", ")", stop); } case TableType: { @@ -554,12 +554,12 @@ CORD compile_statement(env_t *env, ast_t *ast) size_t value_offset = type_size(key_t); if (type_align(value_t) > 1 && value_offset % type_align(value_t)) value_offset += type_align(value_t) - (value_offset % type_align(value_t)); // padding - return CORD_all("$TABLE_FOREACH(", compile(env, for_->iter), ", ", compile_type(key_t), ", ", key, ", ", - compile_type(value_t), ", ", value, ", ", heap_strf("%zu", value_offset), + return CORD_all("$TABLE_FOREACH(", compile(env, for_->iter), ", ", compile_type(env, key_t), ", ", key, ", ", + compile_type(env, value_t), ", ", value, ", ", heap_strf("%zu", value_offset), ", ", body, ", ", for_->empty ? compile_statement(env, for_->empty) : "{}", ")", stop); } else { CORD key = compile(env, for_->value); - return CORD_all("$ARRAY_FOREACH((", compile(env, for_->iter), ").entries, $i, ", compile_type(key_t), ", ", key, ", ", + return CORD_all("$ARRAY_FOREACH((", compile(env, for_->iter), ").entries, $i, ", compile_type(env, key_t), ", ", key, ", ", body, ", ", for_->empty ? compile_statement(env, for_->empty) : "{}", ")", stop); } } @@ -624,7 +624,7 @@ CORD compile_statement(env_t *env, ast_t *ast) } set_binding(true_scope, name, new(binding_t, .type=var_t, .code=var_code)); CORD code = CORD_all("{\n", - compile_type(var_t), " ", var_code, " = ", compile(env, decl->value), ";\n" + compile_type(env, var_t), " ", var_code, " = ", compile(env, decl->value), ";\n" "if (", var_code, ") ", compile_statement(true_scope, if_->body)); if (if_->else_body) code = CORD_all(code, "\nelse ", compile_statement(env, if_->else_body)); @@ -827,7 +827,7 @@ static CORD compile_arguments(env_t *env, ast_t *call_ast, arg_t *spec_args, arg CORD compile(env_t *env, ast_t *ast) { switch (ast->tag) { - case Nil: return CORD_asprintf("$Null(%r)", compile_type_ast(Match(ast, Nil)->type)); + case Nil: return CORD_asprintf("$Null(%r)", compile_type_ast(env, Match(ast, Nil)->type)); case Bool: return Match(ast, Bool)->b ? "yes" : "no"; case Var: { binding_t *b = get_binding(env, Match(ast, Var)->name); @@ -1165,7 +1165,7 @@ CORD compile(env_t *env, ast_t *ast) return CORD_all( "({\n", - compile_type(t), " $ternary$lhs = ", compile(env, lhs), ", $ternary$rhs = ", compile(env, rhs), ";\n", + compile_type(env, t), " $ternary$lhs = ", compile(env, lhs), ", $ternary$rhs = ", compile(env, rhs), ";\n", comparison, " ? $ternary$lhs : $ternary$rhs;\n" "})"); } @@ -1185,7 +1185,7 @@ CORD compile(env_t *env, ast_t *ast) { type_t *item_type = Match(array_type, ArrayType)->item_type; - CORD code = CORD_all("$TypedArrayN(", compile_type(item_type), CORD_asprintf(", %ld", n)); + CORD code = CORD_all("$TypedArrayN(", compile_type(env, item_type), CORD_asprintf(", %ld", n)); for (ast_list_t *item = array->items; item; item = item->next) code = CORD_all(code, ", ", compile(env, item->ast)); return CORD_cat(code, ")"); @@ -1234,8 +1234,8 @@ CORD compile(env_t *env, ast_t *ast) { // No comprehension: CORD code = CORD_all("$Table(", - compile_type(key_t), ", ", - compile_type(value_t), ", ", + compile_type(env, key_t), ", ", + compile_type(env, value_t), ", ", compile_type_info(env, key_t), ", ", compile_type_info(env, value_t)); if (table->fallback) @@ -1321,10 +1321,10 @@ CORD compile(env_t *env, ast_t *ast) body_scope->fn_ctx = &fn_ctx; body_scope->locals->fallback = env->globals; - CORD code = CORD_all("static ", compile_type(ret_t), " ", name, "("); + CORD code = CORD_all("static ", compile_type(env, ret_t), " ", name, "("); for (arg_ast_t *arg = lambda->args; arg; arg = arg->next) { type_t *arg_type = get_arg_ast_type(env, arg); - code = CORD_all(code, compile_type(arg_type), " ", arg->name, ", "); + code = CORD_all(code, compile_type(env, arg_type), " ", arg->name, ", "); } for (ast_list_t *stmt = Match(lambda->body, Block)->statements; stmt; stmt = stmt->next) @@ -1339,7 +1339,7 @@ CORD compile(env_t *env, ast_t *ast) userdata = CORD_all("new(", name, "$userdata_t"); for (int64_t i = 1; i <= Table_length(*fn_ctx.closed_vars); i++) { struct { const char *name; binding_t *b; } *entry = Table_entry(*fn_ctx.closed_vars, i); - def = CORD_all(def, compile_declaration(entry->b->type, entry->name), "; "); + def = CORD_all(def, compile_declaration(env, entry->b->type, entry->name), "; "); userdata = CORD_all(userdata, ", ", entry->b->code); } userdata = CORD_all(userdata, ")"); @@ -1460,7 +1460,7 @@ CORD compile(env_t *env, ast_t *ast) closure_fn_args = new(arg_t, .name=arg->name, .type=arg->type, .default_val=arg->default_val, .next=closure_fn_args); closure_fn_args = new(arg_t, .name="$userdata", .type=Type(PointerType, .pointed=Type(MemoryType)), .next=closure_fn_args); REVERSE_LIST(closure_fn_args); - CORD fn_type_code = compile_type(Type(FunctionType, .args=closure_fn_args, .ret=Match(fn_t, FunctionType)->ret)); + CORD fn_type_code = compile_type(env, Type(FunctionType, .args=closure_fn_args, .ret=Match(fn_t, FunctionType)->ret)); CORD closure = compile(env, call->fn); CORD arg_code = compile_arguments(env, ast, type_args, call->args); @@ -1524,7 +1524,7 @@ CORD compile(env_t *env, ast_t *ast) type_t *t = get_type(env, ast); CORD code = CORD_all( "({ // Reduction:\n", - compile_declaration(t, "$reduction"), ";\n" + compile_declaration(env, t, "$reduction"), ";\n" ); env_t *scope = fresh_scope(env); ast_t *result = FakeAST(Var, "$reduction"); @@ -1585,7 +1585,7 @@ CORD compile(env_t *env, ast_t *ast) for (tag_t *tag = enum_->tags; tag; tag = tag->next) { if (streq(tag->name, f->field)) { CORD fielded = compile_to_pointer_depth(env, f->fielded, 0, false); - return CORD_asprintf("$tagged(%r, %s, %s)", fielded, enum_->name, f->field); + return CORD_asprintf("$tagged(%r, %r%s, %s)", fielded, env->file_prefix, enum_->name, f->field); } } code_err(ast, "The field '%s' is not a valid field name of %T", f->field, value_t); @@ -1642,9 +1642,9 @@ CORD compile(env_t *env, ast_t *ast) CORD index = compile(env, indexing->index); file_t *f = indexing->index->file; if (indexing->unchecked) - return CORD_all("$Array_get_unchecked", compile_type(item_type), ", ", arr, ", ", index, ")"); + return CORD_all("$Array_get_unchecked", compile_type(env, item_type), ", ", arr, ", ", index, ")"); else - return CORD_all("$Array_get(", compile_type(item_type), ", ", arr, ", ", index, ", ", + return CORD_all("$Array_get(", compile_type(env, item_type), ", ", arr, ", ", index, ", ", Text__quoted(f->filename, false), ", ", CORD_asprintf("%ld", (int64_t)(indexing->index->start - f->text)), ", ", CORD_asprintf("%ld", (int64_t)(indexing->index->end - f->text)), ")"); @@ -1657,7 +1657,7 @@ CORD compile(env_t *env, ast_t *ast) if (!promote(env, &key, index_t, key_t)) code_err(indexing->index, "This value has type %T, but this table can only be index with keys of type %T", index_t, key_t); file_t *f = indexing->index->file; - return CORD_all("$Table_get(", table, ", ", compile_type(key_t), ", ", compile_type(value_t), ", ", + return CORD_all("$Table_get(", table, ", ", compile_type(env, key_t), ", ", compile_type(env, value_t), ", ", key, ", ", compile_type_info(env, container_t), ", ", Text__quoted(f->filename, false), ", ", CORD_asprintf("%ld", (int64_t)(indexing->index->start - f->text)), ", ", CORD_asprintf("%ld", (int64_t)(indexing->index->end - f->text)), @@ -1695,13 +1695,13 @@ void compile_namespace(env_t *env, const char *ns_name, ast_t *block) auto decl = Match(ast, Declare); type_t *t = get_type(ns_env, decl->value); - CORD var_decl = CORD_all(compile_type(t), " ", compile(ns_env, decl->var), ";\n"); + CORD var_decl = CORD_all(compile_type(env, t), " ", compile(ns_env, decl->var), ";\n"); env->code->staticdefs = CORD_cat(env->code->staticdefs, var_decl); CORD init = CORD_all(compile(ns_env, decl->var), " = ", compile(ns_env, decl->value), ";\n"); env->code->main = CORD_cat(env->code->main, init); - env->code->fndefs = CORD_all(env->code->fndefs, "extern ", compile_type(t), " ", compile(ns_env, decl->var), ";\n"); + env->code->fndefs = CORD_all(env->code->fndefs, "extern ", compile_type(env, t), " ", compile(ns_env, decl->var), ";\n"); break; } default: { @@ -1717,9 +1717,9 @@ CORD compile_type_info(env_t *env, type_t *t) { switch (t->tag) { case BoolType: case IntType: case NumType: return CORD_asprintf("&%r", type_to_cord(t)); - case TextType: return CORD_all("(&", Match(t, TextType)->lang ? Match(t, TextType)->lang : "Text", ")"); - case StructType: return CORD_all("(&", Match(t, StructType)->name, ")"); - case EnumType: return CORD_all("(&", Match(t, EnumType)->name, ")"); + case TextType: return Match(t, TextType)->lang ? CORD_all("(&", env->file_prefix, Match(t, TextType)->lang, ")") : "&Text"; + case StructType: return CORD_all("(&", env->file_prefix, Match(t, StructType)->name, ")"); + case EnumType: return CORD_all("(&", env->file_prefix, Match(t, EnumType)->name, ")"); case ArrayType: { type_t *item_t = Match(t, ArrayType)->item_type; return CORD_asprintf("$ArrayInfo(%r)", compile_type_info(env, item_t)); @@ -1750,6 +1750,13 @@ CORD compile_type_info(env_t *env, type_t *t) module_code_t compile_file(ast_t *ast) { env_t *env = new_compilation_unit(); + + const char *prefix = strrchr(ast->file->filename, '/'); + if (prefix) ++prefix; + else prefix = ast->file->filename; + prefix = heap_strf("%.*s$", strspn(prefix, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789"), prefix); + env->file_prefix = prefix; + CORD_appendf(&env->code->imports, "#include \n"); for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) { @@ -1776,7 +1783,7 @@ module_code_t compile_file(ast_t *ast) env->code->typedefs, "\n", env->code->typecode, "\n", env->code->fndefs, "\n", - "public void use(void);\n" + "public void ", env->file_prefix, "use(void);\n" ), .c_file=CORD_all( // CORD_asprintf("#line 0 %r\n", Text__quoted(ast->file->filename, false)), @@ -1784,7 +1791,7 @@ module_code_t compile_file(ast_t *ast) env->code->funcs, "\n", env->code->typeinfos, "\n", "\n" - "public void use(void) {\n", + "public void ", env->file_prefix, "use(void) {\n", env->code->main, "}\n" ), diff --git a/compile.h b/compile.h index b8bdbc36..e5c2809a 100644 --- a/compile.h +++ b/compile.h @@ -14,9 +14,9 @@ typedef struct { CORD expr_as_text(env_t *env, CORD expr, type_t *t, CORD color); module_code_t compile_file(ast_t *ast); -CORD compile_type_ast(type_ast_t *t); -CORD compile_declaration(type_t *t, const char *name); -CORD compile_type(type_t *t); +CORD compile_type_ast(env_t *env, type_ast_t *t); +CORD compile_declaration(env_t *env, type_t *t, const char *name); +CORD compile_type(env_t *env, type_t *t); CORD compile(env_t *env, ast_t *ast); void compile_namespace(env_t *env, const char *ns_name, ast_t *block); CORD compile_statement(env_t *env, ast_t *ast); diff --git a/enums.c b/enums.c index ff0c09fc..9917d2ca 100644 --- a/enums.c +++ b/enums.c @@ -15,11 +15,12 @@ static CORD compile_str_method(env_t *env, ast_t *ast) { auto def = Match(ast, EnumDef); - CORD str_func = CORD_all("static CORD ", def->name, "$as_text(", def->name, "_t *obj, bool use_color) {\n" + CORD full_name = CORD_cat(env->file_prefix, 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"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - str_func = CORD_all(str_func, "\tcase $tag$", def->name, "$", tag->name, ": return CORD_all(use_color ? \"\\x1b[36;1m", + str_func = CORD_all(str_func, "\tcase $tag$", full_name, "$", tag->name, ": return CORD_all(use_color ? \"\\x1b[36;1m", def->name, ".", tag->name, "\\x1b[m(\" : \"", def->name, ".", tag->name, "(\""); if (tag->secret) { @@ -42,15 +43,16 @@ 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 cmp_func = CORD_all("static int ", def->name, "$compare(const ", def->name, "_t *x, const ", def->name, + CORD full_name = CORD_cat(env->file_prefix, 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" "int diff = x->$tag - y->$tag;\n" "if (diff) return diff;\n" "switch (x->$tag) {\n"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - type_t *tag_type = Table_str_get(*env->types, heap_strf("%s$%s", def->name, tag->name)); - cmp_func = CORD_all(cmp_func, "\tcase $tag$", def->name, "$", tag->name, ": " + type_t *tag_type = Table_str_get(*env->types, CORD_to_const_char_star(CORD_all(def->name, "$", tag->name))); + cmp_func = CORD_all(cmp_func, "\tcase $tag$", full_name, "$", tag->name, ": " "return generic_compare(&x->", tag->name, ", &y->", tag->name, ", ", compile_type_info(env, tag_type), ");\n"); } cmp_func = CORD_all(cmp_func, "default: return 0;\n}\n}\n"); @@ -60,14 +62,15 @@ 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 eq_func = CORD_all("static bool ", def->name, "$equal(const ", def->name, "_t *x, const ", def->name, + CORD full_name = CORD_cat(env->file_prefix, 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" "if (x->$tag != y->$tag) return no;\n" "switch (x->$tag) {\n"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - type_t *tag_type = Table_str_get(*env->types, heap_strf("%s$%s", def->name, tag->name)); - eq_func = CORD_all(eq_func, "\tcase $tag$", def->name, "$", tag->name, ": " + type_t *tag_type = Table_str_get(*env->types, CORD_to_const_char_star(CORD_all(def->name, "$", tag->name))); + eq_func = CORD_all(eq_func, "\tcase $tag$", full_name, "$", tag->name, ": " "return generic_equal(&x->", tag->name, ", &y->", tag->name, ", ", compile_type_info(env, tag_type), ");\n"); } eq_func = CORD_all(eq_func, "default: return 0;\n}\n}\n"); @@ -77,13 +80,14 @@ 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 hash_func = CORD_all("static uint32_t ", def->name, "$hash(const ", def->name, "_t *obj, const TypeInfo *info) {\n" + CORD full_name = CORD_cat(env->file_prefix, 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 hashes[2] = {(uint32_t)obj->$tag};\n" "switch (obj->$tag) {\n"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - type_t *tag_type = Table_str_get(*env->types, heap_strf("%s$%s", def->name, tag->name)); - hash_func = CORD_all(hash_func, "\tcase $tag$", def->name, "$", tag->name, ": " + type_t *tag_type = Table_str_get(*env->types, CORD_to_const_char_star(CORD_all(def->name, "$", tag->name))); + hash_func = CORD_all(hash_func, "\tcase $tag$", full_name, "$", tag->name, ": " "hashes[1] = generic_hash(&obj->", tag->name, ", ", compile_type_info(env, tag_type), ");\n" "break;\n"); } @@ -97,32 +101,33 @@ 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_appendf(&env->code->typedefs, "typedef struct %s_s %s_t;\n", def->name, def->name); - CORD_appendf(&env->code->typedefs, "extern const TypeInfo %s;\n", def->name); - CORD enum_def = CORD_all("struct ", def->name, "_s {\n" + CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD_appendf(&env->code->typedefs, "typedef struct %r_s %r_t;\n", full_name, full_name); + CORD_appendf(&env->code->typedefs, "extern const TypeInfo %r;\n", full_name); + CORD enum_def = CORD_all("struct ", full_name, "_s {\n" "\tenum {"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - CORD_appendf(&enum_def, "$tag$%s$%s = %ld", def->name, tag->name, tag->value); + CORD_appendf(&enum_def, "$tag$%r$%s = %ld", full_name, tag->name, tag->value); if (tag->next) enum_def = CORD_cat(enum_def, ", "); } enum_def = CORD_cat(enum_def, "} $tag;\n" "union {\n"); for (tag_ast_t *tag = def->tags; tag; tag = tag->next) { - compile_struct_def(env, WrapAST(ast, StructDef, .name=heap_strf("%s$%s", def->name, tag->name), .fields=tag->fields)); - enum_def = CORD_all(enum_def, def->name, "$", tag->name, "_t ", tag->name, ";\n"); + compile_struct_def(env, WrapAST(ast, StructDef, .name=CORD_to_const_char_star(CORD_all(def->name, "$", tag->name)), .fields=tag->fields)); + enum_def = CORD_all(enum_def, full_name, "$", tag->name, "_t ", tag->name, ";\n"); // Constructor: CORD arg_sig = CORD_EMPTY; for (arg_ast_t *field = tag->fields; field; field = field->next) { type_t *field_t = get_arg_ast_type(env, field); - arg_sig = CORD_all(arg_sig, compile_declaration(field_t, field->name)); + arg_sig = CORD_all(arg_sig, compile_declaration(env, field_t, field->name)); if (field->next) arg_sig = CORD_cat(arg_sig, ", "); } if (arg_sig == CORD_EMPTY) arg_sig = "void"; - CORD constructor_def = CORD_all(def->name, "_t ", def->name, "$tagged$", tag->name, "(", arg_sig, ");\n"); + CORD constructor_def = CORD_all(full_name, "_t ", full_name, "$tagged$", tag->name, "(", arg_sig, ");\n"); env->code->fndefs = CORD_cat(env->code->fndefs, constructor_def); - CORD constructor_impl = CORD_all("public inline ", def->name, "_t ", def->name, "$tagged$", tag->name, "(", arg_sig, ") { return (", - def->name, "_t){.$tag=$tag$", def->name, "$", tag->name, ", .", tag->name, "={"); + CORD constructor_impl = CORD_all("public inline ", full_name, "_t ", full_name, "$tagged$", tag->name, "(", arg_sig, ") { return (", + full_name, "_t){.$tag=$tag$", full_name, "$", tag->name, ", .", tag->name, "={"); for (arg_ast_t *field = tag->fields; field; field = field->next) { constructor_impl = CORD_all(constructor_impl, field->name); if (field->next) constructor_impl = CORD_cat(constructor_impl, ", "); @@ -135,7 +140,7 @@ void compile_enum_def(env_t *env, ast_t *ast) type_t *t = Table_str_get(*env->types, def->name); CORD typeinfo = CORD_asprintf("public const TypeInfo %s = {%zu, %zu, {.tag=CustomInfo, .CustomInfo={", - def->name, type_size(t), type_align(t)); + full_name, type_size(t), type_align(t)); env->code->funcs = CORD_all( env->code->funcs, @@ -144,10 +149,10 @@ void compile_enum_def(env_t *env, ast_t *ast) compile_hash_method(env, ast)); typeinfo = CORD_all( typeinfo, - ".as_text=(void*)", def->name, "$as_text, " - ".equal=(void*)", def->name, "$equal, " - ".hash=(void*)", def->name, "$hash, " - ".compare=(void*)", def->name, "$compare"); + ".as_text=(void*)", full_name, "$as_text, " + ".equal=(void*)", full_name, "$equal, " + ".hash=(void*)", full_name, "$hash, " + ".compare=(void*)", full_name, "$compare"); typeinfo = CORD_cat(typeinfo, "}}};\n"); env->code->typeinfos = CORD_all(env->code->typeinfos, typeinfo); diff --git a/environment.c b/environment.c index a50d4e32..1786be50 100644 --- a/environment.c +++ b/environment.c @@ -255,7 +255,7 @@ env_t *namespace_env(env_t *env, const char *namespace_name) ns_env->locals = new(table_t, .fallback=env->globals); Table_str_set(env->type_namespaces, namespace_name, ns_env->locals); } - ns_env->scope_prefix = CORD_cat(namespace_name, "$"); + ns_env->scope_prefix = CORD_all(env->file_prefix, namespace_name, "$"); return ns_env; } diff --git a/environment.h b/environment.h index 49d15a19..c5acb57d 100644 --- a/environment.h +++ b/environment.h @@ -34,7 +34,7 @@ typedef struct { compilation_unit_t *code; fn_ctx_t *fn_ctx; loop_ctx_t *loop_ctx; - CORD scope_prefix; + CORD file_prefix, scope_prefix; const char *comprehension_var; } env_t; diff --git a/structs.c b/structs.c index b5ea5638..725eaac5 100644 --- a/structs.c +++ b/structs.c @@ -38,8 +38,9 @@ static bool is_plain_data(env_t *env, type_t *t) static CORD compile_str_method(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); - CORD str_func = CORD_asprintf("static CORD %s$as_text(%s_t *obj, bool use_color) {\n" - "\tif (!obj) return \"%s\";\n", def->name, def->name, def->name); + CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD str_func = CORD_asprintf("static CORD %r$as_text(%r_t *obj, bool use_color) {\n" + "\tif (!obj) return \"%s\";\n", full_name, full_name, def->name); if (def->secret) { CORD_appendf(&str_func, "\treturn use_color ? \"\\x1b[0;1m%s\\x1b[m(\\x1b[2m...\\x1b[m)\" : \"%s(...)\";\n}", def->name, def->name); @@ -59,7 +60,8 @@ 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 cmp_func = CORD_all("static int ", def->name, "$compare(const ", def->name, "_t *x, const ", def->name, + CORD full_name = CORD_cat(env->file_prefix, 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", "int diff;\n"); @@ -86,7 +88,8 @@ 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 eq_func = CORD_all("static bool ", def->name, "$equal(const ", def->name, "_t *x, const ", def->name, + CORD full_name = CORD_cat(env->file_prefix, 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"); for (arg_ast_t *field = def->fields; field; field = field->next) { @@ -111,7 +114,8 @@ 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 hash_func = CORD_all("static uint32_t ", def->name, "$hash(const ", def->name, "_t *obj, const TypeInfo *info) {\n" + CORD full_name = CORD_cat(env->file_prefix, 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[] = {"); for (arg_ast_t *field = def->fields; field; field = field->next) { @@ -128,26 +132,27 @@ 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_appendf(&env->code->typedefs, "typedef struct %s_s %s_t;\n", def->name, def->name); - CORD_appendf(&env->code->typedefs, "#define %s(...) ((%s_t){__VA_ARGS__})\n", def->name, def->name); + CORD full_name = CORD_cat(env->file_prefix, def->name); + CORD_appendf(&env->code->typedefs, "typedef struct %r_s %r_t;\n", full_name, full_name); + CORD_appendf(&env->code->typedefs, "#define %r(...) ((%r_t){__VA_ARGS__})\n", full_name, full_name); - CORD_appendf(&env->code->typecode, "struct %s_s {\n", def->name); + CORD_appendf(&env->code->typecode, "struct %r_s {\n", full_name); for (arg_ast_t *field = def->fields; field; field = field->next) { type_t *field_t = get_arg_ast_type(env, field); - CORD type_code = compile_type(field_t); + CORD type_code = compile_type(env, field_t); CORD_appendf(&env->code->typecode, "%r %s%s;\n", type_code, field->name, CORD_cmp(type_code, "Bool_t") ? "" : ":1"); } CORD_appendf(&env->code->typecode, "};\n"); // Typeinfo: - CORD_appendf(&env->code->typedefs, "extern const TypeInfo %s;\n", def->name); + CORD_appendf(&env->code->typedefs, "extern const TypeInfo %r;\n", full_name); type_t *t = Table_str_get(*env->types, def->name); - CORD typeinfo = CORD_asprintf("public const TypeInfo %s = {%zu, %zu, {.tag=CustomInfo, .CustomInfo={", - def->name, type_size(t), type_align(t)); + CORD typeinfo = CORD_asprintf("public const TypeInfo %r = {%zu, %zu, {.tag=CustomInfo, .CustomInfo={", + full_name, type_size(t), type_align(t)); - typeinfo = CORD_all(typeinfo, ".as_text=(void*)", def->name, "$as_text, .compare=(void*)", def->name, "$compare, "); + typeinfo = CORD_all(typeinfo, ".as_text=(void*)", full_name, "$as_text, .compare=(void*)", full_name, "$compare, "); env->code->funcs = CORD_all(env->code->funcs, compile_str_method(env, ast), compile_compare_method(env, ast)); if (!t || !is_plain_data(env, t)) { env->code->funcs = CORD_all( @@ -155,8 +160,8 @@ void compile_struct_def(env_t *env, ast_t *ast) compile_hash_method(env, ast)); typeinfo = CORD_all( typeinfo, - ".equal=(void*)", def->name, "$equal, " - ".hash=(void*)", def->name, "$hash"); + ".equal=(void*)", full_name, "$equal, " + ".hash=(void*)", full_name, "$hash"); } typeinfo = CORD_cat(typeinfo, "}}};\n"); env->code->typeinfos = CORD_all(env->code->typeinfos, typeinfo); diff --git a/typecheck.c b/typecheck.c index ced1f028..74c53fbf 100644 --- a/typecheck.c +++ b/typecheck.c @@ -136,7 +136,7 @@ void bind_statement(env_t *env, ast_t *statement) } type_t *typeinfo_type = Type(TypeInfoType, .name=def->name, .type=type); - Table_str_set(env->globals, def->name, new(binding_t, .type=typeinfo_type)); + Table_str_set(env->globals, def->name, new(binding_t, .type=typeinfo_type, .code=CORD_all(env->file_prefix, def->name))); break; } case EnumDef: { @@ -166,7 +166,7 @@ void bind_statement(env_t *env, ast_t *statement) for (tag_t *tag = tags; tag; tag = tag->next) { 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(def->name, "$tagged$", tag->name))); + set_binding(ns_env, tag->name, new(binding_t, .type=constructor_t, .code=CORD_all(env->file_prefix, def->name, "$tagged$", tag->name))); Table_str_set(env->types, heap_strf("%s$%s", def->name, tag->name), tag->type); } @@ -188,7 +188,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=Type(TextType)), .ret=type), - .code=CORD_all("(", def->name, "_t)"))); + .code=CORD_all("(", env->file_prefix, def->name, "_t)"))); set_binding(ns_env, "text_content", new(binding_t, .type=Type(FunctionType, .args=new(arg_t, .name="text", .type=Type(TextType)), .ret=type), .code="(Text_t)")); -- cgit v1.2.3