diff options
-rw-r--r-- | src/analyzer.c | 32 | ||||
-rw-r--r-- | src/primitives.gperf | 2 |
2 files changed, 17 insertions, 17 deletions
diff --git a/src/analyzer.c b/src/analyzer.c index 1b9e9cb..4d41a33 100644 --- a/src/analyzer.c +++ b/src/analyzer.c @@ -278,20 +278,20 @@ typechkblk(struct typechkctx ctx, struct evstack evs, struct type *types, bool typecompat(struct type lhs, struct type rhs) { - switch (lhs.kind) { - case TYPE_FN: - return lhs.ret == rhs.ret; - case TYPE_NUM: - if (rhs.size == 0) - return true; - return lhs.issigned == rhs.issigned && lhs.size >= rhs.size; - case TYPE_F16: - case TYPE_F32: - case TYPE_F64: - return lhs.size >= rhs.size; - case TYPE_RUNE: - return rhs.size == 0 || lhs.kind == rhs.kind; - } - - __builtin_unreachable(); + /* Function types are compatible if they have the same parameter- and + return types */ + if (lhs.kind == TYPE_FN && rhs.kind == TYPE_FN) + return lhs.paramcnt == rhs.paramcnt && lhs.ret == rhs.ret; + if (lhs.kind == TYPE_FN || rhs.kind == TYPE_FN) + return false; + + /* At this point we only have numeric types left */ + + /* Untyped numeric types are compatible with all numeric types */ + if (lhs.size == 0 || rhs.size == 0) + return true; + + /* Two typed numeric types are only compatible if they have the same size + and sign */ + return lhs.issigned == rhs.issigned && lhs.size == rhs.size; } diff --git a/src/primitives.gperf b/src/primitives.gperf index ea7543b..4391565 100644 --- a/src/primitives.gperf +++ b/src/primitives.gperf @@ -28,7 +28,7 @@ u32, { TYPE_NUM, 4, false } u64, { TYPE_NUM, 8, false } u128, { TYPE_NUM, 16, false } uint, { TYPE_NUM, 8, false } -rune, { TYPE_RUNE, 4, true } +rune, { TYPE_NUM , 4, true } %% const struct type * typelookup(const uchar *p, size_t len) |