diff --git a/compile.c b/compile.c index 925bb75..05014ce 100644 --- a/compile.c +++ b/compile.c @@ -47,7 +47,8 @@ CORD expr_as_string(env_t *env, CORD expr, type_t *t, CORD color) case TableType: return CORD_asprintf("Table_as_str(%r, %r, %r)", expr, color, compile_type_info(env, t)); case FunctionType: return CORD_asprintf("Func__as_str(%r, %r, %r)", expr, color, compile_type_info(env, t)); case PointerType: return CORD_asprintf("Pointer__as_str(%r, %r, %r)", expr, color, compile_type_info(env, t)); - case StructType: case EnumType: return CORD_asprintf("%r->as_str(%r, %r, %r)", compile_type_info(env, t), expr, color); + case StructType: case EnumType: return CORD_asprintf("(%r)->CustomInfo.as_str(%r, %r, %r)", + compile_type_info(env, t), expr, color, compile_type_info(env, t)); default: compiler_err(NULL, NULL, NULL, "Stringifying is not supported for %T", t); } } @@ -438,7 +439,12 @@ CORD compile(env_t *env, ast_t *ast) } CORD_appendf(&env->code->typecode, "};\n"); - CORD cord_func = CORD_asprintf("CORD %s__as_str(%s_t *obj, bool use_color) {\n" + // Typeinfo: + CORD_appendf(&env->code->typedefs, "typedef struct { TypeInfo type; } %s_namespace_t;\n", def->name); + CORD_appendf(&env->code->typedefs, "extern %s_namespace_t %s_type;\n", def->name, def->name); + CORD_appendf(&env->code->typeinfos, "public %s_namespace_t %s_type = {.type={.tag=CustomInfo, .CustomInfo={.as_str=(void*)%s__as_str}}};\n", def->name, def->name, def->name); + + CORD cord_func = CORD_asprintf("static CORD %s__as_str(%s_t *obj, bool use_color) {\n" "\tif (!obj) return \"%s\";\n", def->name, def->name, def->name); if (def->secret) { @@ -458,7 +464,7 @@ CORD compile(env_t *env, ast_t *ast) cord_func = CORD_cat(cord_func, ")\""); for (arg_ast_t *field = def->fields; field; field = field->next) { type_t *field_t = parse_type_ast(env, field->type); - CORD_appendf(&cord_func, ", %r", expr_as_string(env, CORD_cat("obj->", field->name), field_t, "use_color")); + CORD_appendf(&cord_func, ", %r", expr_as_string(env, CORD_cat("&obj->", field->name), field_t, "use_color")); } cord_func = CORD_cat(cord_func, ");\n}"); } diff --git a/environment.h b/environment.h index 64b5959..2f5c84d 100644 --- a/environment.h +++ b/environment.h @@ -11,6 +11,7 @@ typedef struct { CORD typecode; CORD staticdefs; CORD funcs; + CORD typeinfos; CORD main; } compilation_unit_t; diff --git a/nextlang.c b/nextlang.c index 65500eb..c260b49 100644 --- a/nextlang.c +++ b/nextlang.c @@ -63,7 +63,8 @@ int main(int argc, char *argv[]) env->code->typedefs, "\n", env->code->typecode, "\n", env->code->staticdefs, "\n", - env->code->funcs, "\n" + env->code->funcs, "\n", + env->code->typeinfos, "\n", "\n" "static void $load(void) {\n", env->code->main, diff --git a/typecheck.c b/typecheck.c index 37a222f..488d910 100644 --- a/typecheck.c +++ b/typecheck.c @@ -104,7 +104,17 @@ void bind_statement(env_t *env, ast_t *statement) } case StructDef: { auto def = Match(statement, StructDef); - type_t *type = Table_str_get(env->types, def->name); + arg_t *fields = NULL; + type_t *type = Type(StructType, .name=def->name, .fields=fields); // placeholder + for (arg_ast_t *field_ast = def->fields; field_ast; field_ast = field_ast->next) { + type_t *field_t = parse_type_ast(env, field_ast->type); + fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->default_val, .next=fields); + } + REVERSE_LIST(fields); + type->__data.StructType.fields = fields; // populate placeholder + Table_str_set(env->types, def->name, type); + + if (!type) code_err(statement, "I couldn't get this type"); type_t *constructor_t = Type(FunctionType, .args=Match(type, StructType)->fields, .ret=type); set_binding(env, def->name, new(binding_t, .type=constructor_t)); break;