diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-05-12 20:13:19 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-05-12 20:13:19 -0400 |
| commit | 02fe49a7646807964d214605a478c90d82d2c8a3 (patch) | |
| tree | f732f3db3b6d7e2eebed68dc4c6f1af57a313279 | |
| parent | 934fd8a173ccad9aa1291c658dbac712eef78b4b (diff) | |
Deprecate interfaces (RIP)
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | ast.c | 1 | ||||
| -rw-r--r-- | ast.h | 7 | ||||
| -rw-r--r-- | compile.c | 77 | ||||
| -rw-r--r-- | environment.c | 4 | ||||
| -rw-r--r-- | interfaces.c | 125 | ||||
| -rw-r--r-- | interfaces.h | 10 | ||||
| -rw-r--r-- | parse.c | 37 | ||||
| -rw-r--r-- | typecheck.c | 73 | ||||
| -rw-r--r-- | types.c | 38 | ||||
| -rw-r--r-- | types.h | 7 |
11 files changed, 12 insertions, 369 deletions
@@ -29,7 +29,7 @@ BUILTIN_OBJS=builtins/array.o builtins/bool.o builtins/nums.o builtins/functions all: libtomo.so tomo -tomo: tomo.c SipHash/halfsiphash.o ast.o parse.o environment.o types.o typecheck.o structs.o enums.o interfaces.o compile.o repl.o +tomo: tomo.c SipHash/halfsiphash.o ast.o parse.o environment.o types.o typecheck.o structs.o enums.o compile.o repl.o libtomo.so: $(BUILTIN_OBJS) SipHash/halfsiphash.o $(CC) $^ $(CFLAGS) $(EXTRA) $(CWARN) $(G) $(O) $(OSFLAGS) -lgc -lcord -lm -lunistring -ldl -Wl,-soname,libtomo.so -shared -o $@ @@ -136,7 +136,6 @@ CORD ast_to_xml(ast_t *ast) T(StructDef, "<StructDef name=\"%s\">%r<namespace>%r</namespace></StructDef>", data.name, arg_list_to_xml(data.fields), ast_to_xml(data.namespace)) T(EnumDef, "<EnumDef name=\"%s\"><tags>%r</tags><namespace>%r</namespace></EnumDef>", data.name, tags_to_xml(data.tags), ast_to_xml(data.namespace)) T(LangDef, "<LangDef name=\"%s\">%r</LangDef>", data.name, ast_to_xml(data.namespace)) - T(InterfaceDef, "<InterfaceDef name=\"%s\">%r</InterfaceDef>", data.name, arg_list_to_xml(data.fields)) T(Index, "<Index>%r%r</Index>", optional_tagged("indexed", data.indexed), optional_tagged("index", data.index)) T(FieldAccess, "<FieldAccess field=\"%s\">%r</FieldAccess>", data.field, ast_to_xml(data.fielded)) T(Optional, "<Optional>%r</Optional>", ast_to_xml(data.value)) @@ -111,7 +111,7 @@ typedef enum { Skip, Stop, Pass, Return, Extern, - StructDef, EnumDef, LangDef, InterfaceDef, + StructDef, EnumDef, LangDef, Index, FieldAccess, Optional, DocTest, Use, @@ -250,11 +250,6 @@ struct ast_s { ast_t *namespace; } LangDef; struct { - const char *name; - arg_ast_t *fields; - ast_t *namespace; - } InterfaceDef; - struct { ast_t *indexed, *index; bool unchecked; } Index; @@ -10,7 +10,6 @@ #include "compile.h" #include "enums.h" #include "structs.h" -#include "interfaces.h" #include "environment.h" #include "typecheck.h" #include "builtins/util.h" @@ -116,10 +115,6 @@ CORD compile_type(env_t *env, type_t *t) auto e = Match(t, EnumType); return CORD_all(e->env->file_prefix, e->name, "_t"); } - case InterfaceType: { - auto s = Match(t, InterfaceType); - return CORD_all(s->env->file_prefix, s->name, "_t"); - } case TypeInfoType: return "TypeInfo"; default: compiler_err(NULL, NULL, NULL, "Not implemented"); } @@ -446,10 +441,6 @@ CORD compile_statement(env_t *env, ast_t *ast) compile_namespace(env, def->name, def->namespace); return CORD_EMPTY; } - case InterfaceDef: { - compile_interface_def(env, ast); - return CORD_EMPTY; - } case FunctionDef: { auto fndef = Match(ast, FunctionDef); bool is_private = Match(fndef->name, Var)->name[0] == '_'; @@ -862,7 +853,7 @@ CORD expr_as_text(env_t *env, CORD expr, type_t *t, CORD color) case TableType: return CORD_asprintf("Table$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(env, t)); case FunctionType: case ClosureType: return CORD_asprintf("Func$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(env, t)); case PointerType: return CORD_asprintf("Pointer$as_text(stack(%r), %r, %r)", expr, color, compile_type_info(env, t)); - case StructType: case EnumType: case InterfaceType: + case StructType: case EnumType: return CORD_asprintf("(%r)->CustomInfo.as_text(stack(%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); @@ -1651,35 +1642,6 @@ CORD compile(env_t *env, ast_t *ast) return CORD_all("Table$clear(", self, ")"); } else code_err(ast, "There is no '%s' method for tables", call->name); } - case InterfaceType: { - auto methodcall = Match(ast, MethodCall); - binding_t *b = get_namespace_binding(env, methodcall->self, methodcall->name); - if (b) { - type_t *fn_t = get_method_type(env, methodcall->self, methodcall->name); - arg_ast_t *args = new(arg_ast_t, .value=methodcall->self, .next=methodcall->args); - return CORD_all(b->code, "(", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, args), ")"); - } else { - auto interface = Match(self_value_t, InterfaceType); - for (arg_t *field = interface->fields; field; field = field->next) { - if (streq(field->name, methodcall->name)) { - env_t tmp_env = *env; - tmp_env.types = new(table_t, .fallback=tmp_env.types); - Table$str_set(tmp_env.types, interface->type_parameter, self_value_t); - type_t *field_t = field->type; - if (field_t->tag == ClosureType) - field_t = Match(field_t, ClosureType)->fn; - - arg_t *type_args = Match(field_t, FunctionType)->args; - CORD args = compile_arguments(env, ast, type_args->next, methodcall->args); - return CORD_all("({ ", compile_type(env, self_value_t), " $self = ", - compile_to_pointer_depth(env, methodcall->self, 0, false), "; ", - "$self.", methodcall->name, "($self.$obj", - args == CORD_EMPTY ? CORD_EMPTY : ", ", args, "); })"); - } - } - code_err(ast, "There is no method called '%s' on the interface type %s", methodcall->name, interface->name); - } - } default: { auto methodcall = Match(ast, MethodCall); type_t *fn_t = get_method_type(env, methodcall->self, methodcall->name); @@ -1703,34 +1665,6 @@ CORD compile(env_t *env, ast_t *ast) fn_t = Type(FunctionType, .args=Match(t, StructType)->fields, .ret=t); CORD fn = compile(env, call->fn); return CORD_all(fn, "(", compile_arguments(env, ast, Match(fn_t, FunctionType)->args, call->args), ")"); - } else if (t->tag == InterfaceType) { - // Interface constructor: - if (!call->args) code_err(ast, "You need to provide an argument to this interface constructor"); - if (call->args->next) code_err(ast, "This interface constructor only takes one argument"); - auto interface = Match(t, InterfaceType); - ast_t *impl = call->args->value; - type_t *impl_t = get_type(env, impl); - if (impl_t->tag != PointerType) { - impl = WrapAST(impl, HeapAllocate, impl); - impl_t = Type(PointerType, .pointed=impl_t); - } - CORD c = CORD_all("({ ", compile_type(env, impl_t), " $impl = ", compile(env, impl), "; (", compile_type(env, t), "){$impl"); - for (arg_t *field = interface->fields->next; field; field = field->next) { - binding_t *b = get_namespace_binding(env, impl, field->name); - if (b) { - // TODO: typecheck implementation! - CORD field_code = b->code; - if (!promote(env, &field_code, b->type, field->type)) - code_err(ast, "I can't promote the method '%s' from %T to %T", field->name, b->type, field->type); - c = CORD_all(c, ", ", field_code); - } else { - type_t *member_t = get_field_type(impl_t, field->name); - if (!member_t) - code_err(ast, "The type %T doesn't have '%s' for the interface %T", impl_t, field->name, t); - c = CORD_all(c, ", &$impl->", field->name); - } - } - return CORD_cat(c, "};})"); } else if (t->tag == IntType || t->tag == NumType) { // Int/Num constructor: if (!call->args || call->args->next) @@ -1901,9 +1835,6 @@ CORD compile(env_t *env, ast_t *ast) } code_err(ast, "There is no '%s' field on tables", f->field); } - case InterfaceType: { - return CORD_all("(*(", compile_to_pointer_depth(env, f->fielded, 0, false), ").", f->field, ")"); - } case ModuleType: { const char *name = Match(value_t, ModuleType)->name; env_t *module_env = Table$str_get(*env->imports, name); @@ -1969,7 +1900,7 @@ CORD compile(env_t *env, ast_t *ast) case Extern: code_err(ast, "Externs are not supported yet"); case TableEntry: code_err(ast, "Table entries should not be compiled directly"); case Declare: case Assign: case UpdateAssign: case For: case While: case StructDef: case LangDef: - case EnumDef: case FunctionDef: case InterfaceDef: case Skip: case Stop: case Pass: case Return: case DocTest: + case EnumDef: case FunctionDef: case Skip: case Stop: case Pass: case Return: case DocTest: code_err(ast, "This is not a valid expression"); case Unknown: code_err(ast, "Unknown AST"); } @@ -2025,10 +1956,6 @@ CORD compile_type_info(env_t *env, type_t *t) auto e = Match(t, EnumType); return CORD_all("(&", e->env->file_prefix, e->name, ")"); } - case InterfaceType: { - auto i = Match(t, InterfaceType); - return CORD_all("(&", i->env->file_prefix, i->name, ")"); - } case ArrayType: { type_t *item_t = Match(t, ArrayType)->item_type; return CORD_asprintf("$ArrayInfo(%r)", compile_type_info(env, item_t)); diff --git a/environment.c b/environment.c index f19b7498..2767340f 100644 --- a/environment.c +++ b/environment.c @@ -324,10 +324,6 @@ binding_t *get_namespace_binding(env_t *env, ast_t *self, const char *name) auto enum_ = Match(cls_type, EnumType); return enum_->env ? get_binding(enum_->env, name) : NULL; } - case InterfaceType: { - auto interface = Match(cls_type, InterfaceType); - return interface->env ? get_binding(interface->env, name) : NULL; - } case TypeInfoType: { auto info = Match(cls_type, TypeInfoType); return info->env ? get_binding(info->env, name) : NULL; diff --git a/interfaces.c b/interfaces.c deleted file mode 100644 index 6406a9ce..00000000 --- a/interfaces.c +++ /dev/null @@ -1,125 +0,0 @@ -// Logic for compiling interfaces -#include <ctype.h> -#include <gc/cord.h> -#include <gc.h> -#include <stdio.h> - -#include "ast.h" -#include "builtins/text.h" -#include "compile.h" -#include "interfaces.h" -#include "environment.h" -#include "typecheck.h" -#include "builtins/util.h" - -static CORD compile_str_method(env_t *env, ast_t *ast) -{ - auto def = Match(ast, InterfaceDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); - const char *name = def->name; - const char *dollar = strrchr(name, '$'); - if (dollar) name = dollar + 1; - CORD str_func = CORD_asprintf("static CORD %r$as_text(%r_t *interface, bool use_color) {\n" - "\tif (!interface) return \"%s\";\n", full_name, full_name, name); - return CORD_all(str_func, "\treturn CORD_asprintf(use_color ? \"\\x1b[0;1m", name, "\\x1b[m<\\x1b[36m%p\\x1b[m>\" : \"", name, "<%p>\", interface->$obj);\n}"); -} - -static CORD compile_compare_method(env_t *env, ast_t *ast) -{ - auto def = Match(ast, InterfaceDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); - return CORD_all("static int ", full_name, "$compare(const ", full_name, "_t *x, const ", full_name, - "_t *y, const TypeInfo *info) {\n" - "(void)info;\n", - "return (x->$obj > y->$obj) - (x->$obj < y->$obj);\n}"); -} - -static CORD compile_equals_method(env_t *env, ast_t *ast) -{ - auto def = Match(ast, InterfaceDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); - return CORD_all("static bool ", full_name, "$equal(const ", full_name, "_t *x, const ", full_name, - "_t *y, const TypeInfo *info) {\n" - "(void)info;\n", - "return (x->$obj == y->$obj);\n}"); -} - -static CORD compile_hash_method(env_t *env, ast_t *ast) -{ - auto def = Match(ast, InterfaceDef); - CORD full_name = CORD_cat(env->file_prefix, def->name); - return CORD_all("static uint32_t ", full_name, "$hash(const ", full_name, "_t *interface, const TypeInfo *info) {\n" - "(void)info;\n" - "uint32_t hash;\n" - "halfsiphash(&interface->$obj, sizeof(void*), TOMO_HASH_VECTOR, (uint8_t*)&hash, sizeof(hash));\n" - "return hash;\n}\n"); -} - -void compile_interface_def(env_t *env, ast_t *ast) -{ - auto def = Match(ast, InterfaceDef); - 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 %r_s {\nvoid *$obj;\n", full_name); - for (arg_ast_t *field = def->fields; field; field = field->next) { - type_t *field_t = parse_type_ast(env, field->type); - if (field_t->tag == ClosureType) { - field_t = Match(field_t, ClosureType)->fn; - // Convert to method: - field_t = Type(FunctionType, .args=new(arg_t, .name="$obj", .type=Type(PointerType, .pointed=Type(MemoryType)), - .next=Match(field_t, FunctionType)->args), - .ret=Match(field_t, FunctionType)->ret); - } else { - field_t = Type(PointerType, .pointed=field_t); - } - CORD decl = compile_declaration(env, field_t, field->name); - CORD_appendf(&env->code->typecode, "%r%s;\n", decl, - field_t->tag == BoolType ? ":1" : ""); - } - CORD_appendf(&env->code->typecode, "};\n"); - - // Typeinfo: - CORD_appendf(&env->code->typedefs, "extern const TypeInfo %r;\n", full_name); - - type_t *t = Table$str_get(*env->types, def->name); - assert(t && t->tag == InterfaceType); - auto interface = Match(t, InterfaceType); - 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*)", full_name, "$as_text, "); - env->code->funcs = CORD_all(env->code->funcs, compile_str_method(env, ast)); - - if (interface->fields && !interface->fields->next) { // Single member, can just use its methods - type_t *member_t = interface->fields->type; - switch (member_t->tag) { - case TextType: - typeinfo = CORD_all(typeinfo, ".hash=(void*)", type_to_cord(member_t), "$hash", ", "); - // fallthrough - case IntType: case NumType: - typeinfo = CORD_all(typeinfo, ".compare=(void*)", type_to_cord(member_t), "$compare, " - ".equal=(void*)", type_to_cord(member_t), "$equal, "); - // fallthrough - case BoolType: goto got_methods; - default: break; - } - } - if (interface->fields) { - env->code->funcs = CORD_all(env->code->funcs, compile_compare_method(env, ast), - compile_equals_method(env, ast), compile_hash_method(env, ast)); - typeinfo = CORD_all( - typeinfo, - ".compare=(void*)", full_name, "$compare, " - ".equal=(void*)", full_name, "$equal, " - ".hash=(void*)", full_name, "$hash"); - } - got_methods:; - typeinfo = CORD_cat(typeinfo, "}}};\n"); - env->code->typeinfos = CORD_all(env->code->typeinfos, typeinfo); - - compile_namespace(env, def->name, def->namespace); -} - -// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 diff --git a/interfaces.h b/interfaces.h deleted file mode 100644 index 47dc4790..00000000 --- a/interfaces.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -// Compilation of user-defined interfaces - -#include "ast.h" -#include "environment.h" - -void compile_interface_def(env_t *env, ast_t *ast); - -// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0 @@ -91,7 +91,6 @@ static PARSER(parse_var); static PARSER(parse_enum_def); static PARSER(parse_struct_def); static PARSER(parse_lang_def); -static PARSER(parse_interface_def); static PARSER(parse_text); static PARSER(parse_func_def); static PARSER(parse_extern); @@ -1598,7 +1597,6 @@ PARSER(parse_namespace) { if ((stmt=optional(ctx, &pos, parse_struct_def)) ||(stmt=optional(ctx, &pos, parse_enum_def)) ||(stmt=optional(ctx, &pos, parse_lang_def)) - ||(stmt=optional(ctx, &pos, parse_interface_def)) ||(stmt=optional(ctx, &pos, parse_func_def)) ||(stmt=optional(ctx, &pos, parse_use)) ||(stmt=optional(ctx, &pos, parse_linker)) @@ -1634,7 +1632,6 @@ PARSER(parse_file_body) { if ((stmt=optional(ctx, &pos, parse_struct_def)) ||(stmt=optional(ctx, &pos, parse_enum_def)) ||(stmt=optional(ctx, &pos, parse_lang_def)) - ||(stmt=optional(ctx, &pos, parse_interface_def)) ||(stmt=optional(ctx, &pos, parse_func_def)) ||(stmt=optional(ctx, &pos, parse_use)) ||(stmt=optional(ctx, &pos, parse_linker)) @@ -1812,40 +1809,6 @@ PARSER(parse_lang_def) { return NewAST(ctx->file, start, pos, LangDef, .name=name, .namespace=namespace); } -PARSER(parse_interface_def) { - // interface Name(T; field:type, ...): namespace... - const char *start = pos; - if (!match_word(&pos, "interface")) return NULL; - int64_t starting_indent = get_indent(ctx, pos); - spaces(&pos); - const char *name = get_id(&pos); - if (!name) - parser_err(ctx, start, pos, "I expected a name for this interface"); - spaces(&pos); - - if (!match(&pos, "(")) - parser_err(ctx, pos, pos, "I expected a '(' and a list of fields here"); - whitespace(&pos); - arg_ast_t *fields = parse_args(ctx, &pos, false); - whitespace(&pos); - expect_closing(ctx, &pos, ")", "I wasn't able to parse the rest of this interface definition"); - - ast_t *namespace = NULL; - if (match(&pos, ":")) { - const char *ns_pos = pos; - whitespace(&ns_pos); - int64_t ns_indent = get_indent(ctx, ns_pos); - if (ns_indent > starting_indent) { - pos = ns_pos; - namespace = optional(ctx, &pos, parse_namespace); - } - } - if (!namespace) - namespace = NewAST(ctx->file, pos, pos, Block, .statements=NULL); - - return NewAST(ctx->file, start, pos, InterfaceDef, .name=name, .fields=fields, .namespace=namespace); -} - arg_ast_t *parse_args(parse_ctx_t *ctx, const char **pos, bool allow_unnamed) { arg_ast_t *args = NULL; diff --git a/typecheck.c b/typecheck.c index 3b70e26e..87f7544c 100644 --- a/typecheck.c +++ b/typecheck.c @@ -263,46 +263,6 @@ void bind_statement(env_t *env, ast_t *statement) bind_statement(ns_env, stmt->ast); break; } - case InterfaceDef: { - auto def = Match(statement, InterfaceDef); - if (get_binding(env, def->name)) - code_err(statement, "A %T called '%s' has already been defined", get_binding(env, def->name)->type, def->name); - - env_t *ns_env = namespace_env(env, def->name); - - arg_t *fields = new(arg_t, .name="$obj", .type=Type(PointerType, .pointed=Type(MemoryType))); // interface implementor - type_t *type = Type(InterfaceType, .name=def->name, .fields=fields, .opaque=true, .env=ns_env); // placeholder - Table$str_set(env->types, def->name, type); - for (arg_ast_t *field_ast = def->fields; field_ast; field_ast = field_ast->next) { - if (!field_ast->type) - code_err(field_ast->value, "Interface fields must have defined types, not default values"); - type_t *field_t = parse_type_ast(env, field_ast->type); - if (field_t->tag == ClosureType) { - field_t = Match(field_t, ClosureType)->fn; - // Convert to method: - field_t = Type(FunctionType, .args=new(arg_t, .name="$obj", .type=Type(PointerType, .pointed=Type(MemoryType)), - .next=Match(field_t, FunctionType)->args), - .ret=Match(field_t, FunctionType)->ret); - } else if ((field_t->tag == InterfaceType && Match(field_t, InterfaceType)->opaque) - || (field_t->tag == EnumType && Match(field_t, EnumType)->opaque)) { - code_err(field_ast->type, "This type is recursive and would create an infinitely sized interface. Try using a pointer."); - } else { - field_t = Type(PointerType, .pointed=field_t); - } - fields = new(arg_t, .name=field_ast->name, .type=field_t, .default_val=field_ast->value, .next=fields); - } - REVERSE_LIST(fields); - type->__data.InterfaceType.fields = fields; // populate placeholder - type->__data.InterfaceType.opaque = false; - - type_t *typeinfo_type = Type(TypeInfoType, .name=def->name, .type=type, .env=ns_env); - Table$str_set(env->locals, def->name, new(binding_t, .type=typeinfo_type, .code=CORD_all(env->file_prefix, def->name))); - - for (ast_list_t *stmt = def->namespace ? Match(def->namespace, Block)->statements : NULL; stmt; stmt = stmt->next) { - bind_statement(ns_env, stmt->ast); - } - break; - } case Use: { env_t *module_env = load_module(env, statement); for (table_t *bindings = module_env->locals; bindings != module_env->globals; bindings = bindings->fallback) { @@ -593,7 +553,7 @@ type_t *get_type(env_t *env, ast_t *ast) if (fn_type_t->tag == TypeInfoType) { type_t *t = Match(fn_type_t, TypeInfoType)->type; - if (t->tag == StructType || t->tag == InterfaceType || t->tag == IntType || t->tag == NumType) + if (t->tag == StructType || t->tag == IntType || t->tag == NumType) return t; // Constructor code_err(call->fn, "This is not a type that has a constructor"); } @@ -634,31 +594,6 @@ type_t *get_type(env_t *env, ast_t *ast) else if (streq(call->name, "clear")) return Type(VoidType); else code_err(ast, "There is no '%s' method for tables", call->name); } - case InterfaceType: { - auto methodcall = Match(ast, MethodCall); - binding_t *b = get_namespace_binding(env, methodcall->self, methodcall->name); - if (b) { - if (b->type->tag != FunctionType) - code_err(ast, "'%s' is not a function, it's a %T", methodcall->name, b->type); - return Match(b->type, FunctionType)->ret; - } else { - auto interface = Match(self_value_t, InterfaceType); - for (arg_t *field = interface->fields; field; field = field->next) { - if (streq(field->name, methodcall->name)) { - env_t tmp_env = *env; - tmp_env.types = new(table_t, .fallback=tmp_env.types); - Table$str_set(tmp_env.types, interface->type_parameter, self_value_t); - type_t *field_t = field->type; - if (field_t->tag == ClosureType) - field_t = Match(field_t, ClosureType)->fn; - if (field_t->tag != FunctionType) - code_err(ast, "'%s' is not a function, it's a %T", methodcall->name, b->type); - return Match(field_t, FunctionType)->ret; - } - } - code_err(ast, "There is no method called '%s' on the interface type %s", methodcall->name, interface->name); - } - } default: { type_t *fn_type_t = get_method_type(env, call->self, call->name); if (!fn_type_t) @@ -680,7 +615,7 @@ type_t *get_type(env_t *env, ast_t *ast) // Early out if the type is knowable without any context from the block: switch (last->ast->tag) { - case UpdateAssign: case Assign: case Declare: case FunctionDef: case StructDef: case EnumDef: case LangDef: case InterfaceDef: + case UpdateAssign: case Assign: case Declare: case FunctionDef: case StructDef: case EnumDef: case LangDef: return Type(VoidType); default: break; } @@ -857,7 +792,7 @@ type_t *get_type(env_t *env, ast_t *ast) return Type(ClosureType, Type(FunctionType, .args=args, .ret=ret)); } - case FunctionDef: case StructDef: case EnumDef: case LangDef: case InterfaceDef: { + case FunctionDef: case StructDef: case EnumDef: case LangDef: { return Type(VoidType); } @@ -996,7 +931,7 @@ type_t *get_type(env_t *env, ast_t *ast) bool is_discardable(env_t *env, ast_t *ast) { switch (ast->tag) { - case UpdateAssign: case Assign: case Declare: case FunctionDef: case StructDef: case EnumDef: case LangDef: case InterfaceDef: case Use: + case UpdateAssign: case Assign: case Declare: case FunctionDef: case StructDef: case EnumDef: case LangDef: case Use: return true; default: break; } @@ -45,9 +45,6 @@ CORD type_to_cord(type_t *t) { auto struct_ = Match(t, StructType); return struct_->name; } - case InterfaceType: { - return Match(t, InterfaceType)->name; - } case PointerType: { auto ptr = Match(t, PointerType); CORD sigil = ptr->is_stack ? "&" : "@"; @@ -216,7 +213,6 @@ bool has_heap_memory(type_t *t) } return false; } - case InterfaceType: return true; default: return false; } } @@ -309,7 +305,6 @@ bool can_leave_uninitialized(type_t *t) } return true; } - case InterfaceType: return false; default: return false; } } @@ -337,13 +332,6 @@ static bool _can_have_cycles(type_t *t, table_t *seen) } return false; } - case InterfaceType: { - for (arg_t *field = Match(t, InterfaceType)->fields; field; field = field->next) { - if (_can_have_cycles(field->type, seen)) - return true; - } - return false; - } default: return false; } } @@ -390,13 +378,6 @@ type_t *replace_type(type_t *t, type_t *target, type_t *replacement) Match((struct type_s*)t, EnumType)->tags = tags; return t; } - case InterfaceType: { - auto interface = Match(t, InterfaceType); - arg_t *fields = LIST_MAP(interface->fields, field, .type=replace_type(field->type, target, replacement)); - t = COPY(t); - Match((struct type_s*)t, InterfaceType)->fields = fields; - return t; - } default: return t; } #undef COPY @@ -417,8 +398,8 @@ size_t type_size(type_t *t) case FunctionType: return sizeof(void*); case ClosureType: return sizeof(struct {void *fn, *userdata;}); case PointerType: return sizeof(void*); - case StructType: case InterfaceType: { - arg_t *fields = t->tag == StructType ? Match(t, StructType)->fields : Match(t, InterfaceType)->fields; + case StructType: { + arg_t *fields = Match(t, StructType)->fields; size_t size = t->tag == StructType ? 0 : sizeof(void*); for (arg_t *field = fields; field; field = field->next) { type_t *field_type = field->type; @@ -468,8 +449,8 @@ size_t type_align(type_t *t) case FunctionType: return __alignof__(void*); case ClosureType: return __alignof__(struct {void *fn, *userdata;}); case PointerType: return __alignof__(void*); - case StructType: case InterfaceType: { - arg_t *fields = t->tag == StructType ? Match(t, StructType)->fields : Match(t, InterfaceType)->fields; + case StructType: { + arg_t *fields = Match(t, StructType)->fields; size_t align = t->tag == StructType ? 0 : sizeof(void*); for (arg_t *field = fields; field; field = field->next) { size_t field_align = type_align(field->type); @@ -505,17 +486,6 @@ type_t *get_field_type(type_t *t, const char *field_name) } return NULL; } - case InterfaceType: { - auto interface = Match(t, InterfaceType); - for (arg_t *field = interface->fields; field; field = field->next) { - if (streq(field->name, field_name)) { - if (field->type->tag == PointerType) - return Match(field->type, PointerType)->pointed; - return field->type; - } - } - return NULL; - } case EnumType: { auto e = Match(t, EnumType); for (tag_t *tag = e->tags; tag; tag = tag->next) { @@ -52,7 +52,6 @@ struct type_s { PointerType, StructType, EnumType, - InterfaceType, TypeInfoType, ModuleType, } tag; @@ -100,12 +99,6 @@ struct type_s { struct env_s *env; } EnumType; struct { - const char *name, *type_parameter; - arg_t *fields; - bool opaque; - struct env_s *env; - } InterfaceType; - struct { const char *name; type_t *type; struct env_s *env; |
