aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c113
-rw-r--r--compile.h6
-rw-r--r--enums.c57
-rw-r--r--environment.c2
-rw-r--r--environment.h2
-rw-r--r--structs.c35
-rw-r--r--typecheck.c6
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 <tomo/tomo.h>\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)"));