diff options
| author | Bruce Hill <bruce@bruce-hill.com> | 2024-03-18 14:11:56 -0400 |
|---|---|---|
| committer | Bruce Hill <bruce@bruce-hill.com> | 2024-03-18 14:11:56 -0400 |
| commit | d94c1057accb197ec3b957fb91ff75597ac54c40 (patch) | |
| tree | c47be271bc392b9169eec84bfb8d27db8334af74 | |
| parent | bff3666d604972f1f38f15c49388cd39d08bee88 (diff) | |
Improve codegen for enums by eliminating unnecessary methods
| -rw-r--r-- | builtins/bool.c | 1 | ||||
| -rw-r--r-- | builtins/integers.c | 5 | ||||
| -rw-r--r-- | builtins/integers.h | 1 | ||||
| -rw-r--r-- | builtins/nums.c | 1 | ||||
| -rw-r--r-- | builtins/types.c | 1 | ||||
| -rw-r--r-- | structs.c | 52 |
6 files changed, 26 insertions, 35 deletions
diff --git a/builtins/bool.c b/builtins/bool.c index 5831845d..7a34073b 100644 --- a/builtins/bool.c +++ b/builtins/bool.c @@ -10,7 +10,6 @@ #include "util.h" #include "bool.h" -#include "halfsiphash.h" #include "types.h" public CORD Bool__as_text(const bool *b, bool colorize, const TypeInfo *type) diff --git a/builtins/integers.c b/builtins/integers.c index 57f678ec..159220a9 100644 --- a/builtins/integers.c +++ b/builtins/integers.c @@ -7,7 +7,6 @@ #include "array.h" #include "datatypes.h" -#include "halfsiphash.h" #include "integers.h" #include "string.h" #include "types.h" @@ -28,6 +27,10 @@ (void)type; \ return (*x > *y) - (*x < *y); \ } \ + public bool KindOfInt ## __equal(const c_type *x, const c_type *y, const TypeInfo *type) { \ + (void)type; \ + return *x == *y; \ + } \ public CORD KindOfInt ## __format(c_type i, int64_t digits) { \ return CORD_asprintf("%0*" fmt, (int)digits, i); \ } \ diff --git a/builtins/integers.h b/builtins/integers.h index 35a579bf..b6b41d6e 100644 --- a/builtins/integers.h +++ b/builtins/integers.h @@ -21,6 +21,7 @@ #define DEFINE_INT_TYPE(c_type, type_name) \ CORD type_name ## __as_text(const c_type *i, bool colorize, const TypeInfo *type); \ int32_t type_name ## __compare(const c_type *x, const c_type *y, const TypeInfo *type); \ + bool type_name ## __equal(const c_type *x, const c_type *y, const TypeInfo *type); \ CORD type_name ## __format(c_type i, int64_t digits); \ CORD type_name ## __hex(c_type i, int64_t digits, bool uppercase, bool prefix); \ CORD type_name ## __octal(c_type i, int64_t digits, bool prefix); \ diff --git a/builtins/nums.c b/builtins/nums.c index f4e5cc99..7d20314a 100644 --- a/builtins/nums.c +++ b/builtins/nums.c @@ -9,7 +9,6 @@ #include <stdlib.h> #include "array.h" -#include "halfsiphash.h" #include "nums.h" #include "string.h" #include "types.h" diff --git a/builtins/types.c b/builtins/types.c index 6850e3d7..cdf58735 100644 --- a/builtins/types.c +++ b/builtins/types.c @@ -7,7 +7,6 @@ #include "util.h" #include "array.h" -#include "halfsiphash.h" #include "pointer.h" #include "table.h" #include "types.h" @@ -11,30 +11,6 @@ #include "typecheck.h" #include "builtins/util.h" -static bool is_plain_data(env_t *env, type_t *t) -{ - switch (t->tag) { - case BoolType: case IntType: case NumType: case PointerType: case FunctionType: - return true; - case StructType: { - for (arg_t *arg = Match(t, StructType)->fields; arg; arg = arg->next) { - if (!is_plain_data(env, get_arg_type(env, arg))) - return false; - } - return true; - } - case EnumType: { - for (tag_t *tag = Match(t, EnumType)->tags; tag; tag = tag->next) { - if (!is_plain_data(env, tag->type)) - return false; - } - return true; - } - default: - return false; - } -} - static CORD compile_str_method(env_t *env, ast_t *ast) { auto def = Match(ast, StructDef); @@ -152,24 +128,38 @@ void compile_struct_def(env_t *env, ast_t *ast) 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 == StructType); + auto struct_ = Match(t, StructType); 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 (t->tag != StructType || Match(t, StructType)->fields) { - typeinfo = CORD_all(typeinfo, ".compare=(void*)", full_name, "$compare, "); - env->code->funcs = CORD_all(env->code->funcs, compile_compare_method(env, ast)); + + if (struct_->fields && !struct_->fields->next) { // Single member, can just use its methods + type_t *member_t = struct_->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 (!t || !is_plain_data(env, t)) { - env->code->funcs = CORD_all( - env->code->funcs, compile_equals_method(env, ast), - compile_hash_method(env, ast)); + if (struct_->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); |
