aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compile/assertions.c4
-rw-r--r--src/compile/comparisons.c8
-rw-r--r--src/compile/lists.c2
-rw-r--r--src/typecheck.c13
4 files changed, 19 insertions, 8 deletions
diff --git a/src/compile/assertions.c b/src/compile/assertions.c
index 5746b21e..34055998 100644
--- a/src/compile/assertions.c
+++ b/src/compile/assertions.c
@@ -33,7 +33,9 @@ Text_t compile_assertion(env_t *env, ast_t *ast) {
type_t *lhs_t = get_type(env, cmp.lhs);
type_t *rhs_t = get_type(with_enum_scope(env, lhs_t), cmp.rhs);
type_t *operand_t;
- if (cmp.lhs->tag == Int && is_numeric_type(rhs_t)) {
+ if (type_eq(lhs_t, rhs_t)) {
+ operand_t = lhs_t;
+ } else if (cmp.lhs->tag == Int && is_numeric_type(rhs_t)) {
operand_t = rhs_t;
} else if (cmp.rhs->tag == Int && is_numeric_type(lhs_t)) {
operand_t = lhs_t;
diff --git a/src/compile/comparisons.c b/src/compile/comparisons.c
index ffa04b9d..62196cdf 100644
--- a/src/compile/comparisons.c
+++ b/src/compile/comparisons.c
@@ -28,7 +28,9 @@ Text_t compile_comparison(env_t *env, ast_t *ast) {
type_t *lhs_t = get_type(env, binop.lhs);
type_t *rhs_t = get_type(with_enum_scope(env, lhs_t), binop.rhs);
type_t *operand_t;
- if (binop.lhs->tag == Int && is_numeric_type(rhs_t)) {
+ if (type_eq(lhs_t, rhs_t)) {
+ operand_t = lhs_t;
+ } else if (binop.lhs->tag == Int && is_numeric_type(rhs_t)) {
operand_t = rhs_t;
} else if (binop.rhs->tag == Int && is_numeric_type(lhs_t)) {
operand_t = lhs_t;
@@ -68,7 +70,9 @@ Text_t compile_comparison(env_t *env, ast_t *ast) {
type_t *lhs_t = get_type(env, cmp.lhs);
type_t *rhs_t = get_type(env, cmp.rhs);
type_t *operand_t;
- if (cmp.lhs->tag == Int && is_numeric_type(rhs_t)) {
+ if (type_eq(lhs_t, rhs_t)) {
+ operand_t = lhs_t;
+ } else if (cmp.lhs->tag == Int && is_numeric_type(rhs_t)) {
operand_t = rhs_t;
} else if (cmp.rhs->tag == Int && is_numeric_type(lhs_t)) {
operand_t = lhs_t;
diff --git a/src/compile/lists.c b/src/compile/lists.c
index 54ad6e7f..97b0b85d 100644
--- a/src/compile/lists.c
+++ b/src/compile/lists.c
@@ -53,7 +53,7 @@ list_comprehension: {
// set_binding(scope, comprehension_name, list_type, comprehension_name);
for (ast_list_t *item = list->items; item; item = item->next) {
if (item->ast->tag == Comprehension) code = Texts(code, "\n", compile_statement(scope, item->ast));
- else code = Texts(code, compile_statement(env, add_to_list_comprehension(item->ast, comprehension_var)));
+ else code = Texts(code, compile_statement(scope, add_to_list_comprehension(item->ast, comprehension_var)));
}
code = Texts(code, " ", comprehension_name, "; })");
return code;
diff --git a/src/typecheck.c b/src/typecheck.c
index a0e55a88..27bb62c6 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -1218,6 +1218,7 @@ type_t *get_type(env_t *env, ast_t *ast) {
binary_operands_t binop = BINARY_OPERANDS(ast);
type_t *lhs_t = get_type(env, binop.lhs);
type_t *rhs_t = get_type(env, binop.rhs);
+ if (type_eq(lhs_t, rhs_t)) return ast->tag == Compare ? Type(IntType, .bits = TYPE_IBITS32) : Type(BoolType);
if ((binop.lhs->tag == Int && is_numeric_type(rhs_t)) || (binop.rhs->tag == Int && is_numeric_type(lhs_t))
|| can_compile_to_type(env, binop.rhs, lhs_t) || can_compile_to_type(env, binop.lhs, rhs_t))
@@ -1696,9 +1697,7 @@ PUREFUNC bool can_compile_to_type(env_t *env, ast_t *ast, type_t *needed) {
if (needed->tag == OptionalType && ast->tag == None) return true;
- type_t *actual = get_type(env, ast);
- if (actual->tag == OptionalType && needed->tag == OptionalType) return can_promote(actual, needed);
-
+ env = with_enum_scope(env, needed);
if (is_numeric_type(needed) && ast->tag == Int) return true;
if (needed->tag == NumType && ast->tag == Num) return true;
@@ -1720,7 +1719,13 @@ PUREFUNC bool can_compile_to_type(env_t *env, ast_t *ast, type_t *needed) {
return false;
}
return true;
- } else if (needed->tag == PointerType) {
+ }
+
+ type_t *actual = get_type(env, ast);
+ if (type_eq(actual, needed)) return true;
+ if (actual->tag == OptionalType && needed->tag == OptionalType) return can_promote(actual, needed);
+
+ if (needed->tag == PointerType) {
DeclareMatch(ptr, needed, PointerType);
if (ast->tag == HeapAllocate)
return !ptr->is_stack && can_compile_to_type(env, Match(ast, HeapAllocate)->value, ptr->pointed);