aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2025-04-05 02:13:24 -0400
committerBruce Hill <bruce@bruce-hill.com>2025-04-05 02:13:24 -0400
commit486f2153e84f2b82ddffc601de75289cddb9c942 (patch)
tree6852412958366d52d9b5b40b5748434f44079ef8 /src
parent81316e0d9704834a0a648cf84401b968933b7581 (diff)
Misc fixes
Diffstat (limited to 'src')
-rw-r--r--src/compile.c12
-rw-r--r--src/typecheck.c15
2 files changed, 22 insertions, 5 deletions
diff --git a/src/compile.c b/src/compile.c
index 21091489..c7e02b3f 100644
--- a/src/compile.c
+++ b/src/compile.c
@@ -619,6 +619,12 @@ static CORD compile_binary_op(env_t *env, ast_t *ast)
}
if (ast->tag == Or && lhs_t->tag == OptionalType) {
+ if (rhs_t->tag == AbortType || rhs_t->tag == ReturnType) {
+ return CORD_all("({ ", compile_declaration(lhs_t, "lhs"), " = ", compile(env, binop.lhs), "; ",
+ "if (", check_none(lhs_t, "lhs"), ") ", compile_statement(env, binop.rhs), " ",
+ optional_into_nonnone(lhs_t, "lhs"), "; })");
+ }
+
if (is_incomplete_type(rhs_t)) {
type_t *complete = most_complete_type(rhs_t, Match(lhs_t, OptionalType)->type);
if (complete == NULL)
@@ -626,11 +632,7 @@ static CORD compile_binary_op(env_t *env, ast_t *ast)
rhs_t = complete;
}
- if (rhs_t->tag == AbortType || rhs_t->tag == ReturnType) {
- return CORD_all("({ ", compile_declaration(lhs_t, "lhs"), " = ", compile(env, binop.lhs), "; ",
- "if (", check_none(lhs_t, "lhs"), ") ", compile_statement(env, binop.rhs), " ",
- optional_into_nonnone(lhs_t, "lhs"), "; })");
- } else if (rhs_t->tag == OptionalType && type_eq(lhs_t, rhs_t)) {
+ if (rhs_t->tag == OptionalType && type_eq(lhs_t, rhs_t)) {
return CORD_all("({ ", compile_declaration(lhs_t, "lhs"), " = ", compile(env, binop.lhs), "; ",
check_none(lhs_t, "lhs"), " ? ", compile(env, binop.rhs), " : lhs; })");
} else if (rhs_t->tag != OptionalType && type_eq(Match(lhs_t, OptionalType)->type, rhs_t)) {
diff --git a/src/typecheck.c b/src/typecheck.c
index 1bef98c8..7b86ec63 100644
--- a/src/typecheck.c
+++ b/src/typecheck.c
@@ -1055,6 +1055,11 @@ type_t *get_type(env_t *env, ast_t *ast)
type_t *lhs_t = get_type(env, binop.lhs);
type_t *rhs_t = get_type(env, binop.rhs);
+ if (binop.lhs->tag == Int && (is_int_type(rhs_t) || rhs_t->tag == ByteType))
+ return rhs_t;
+ else if (binop.rhs->tag == Int && (is_int_type(lhs_t) || lhs_t->tag == ByteType))
+ return lhs_t;
+
// `opt? or (x == y)` / `(x == y) or opt?` is a boolean conditional:
if ((lhs_t->tag == OptionalType && rhs_t->tag == BoolType)
|| (lhs_t->tag == BoolType && rhs_t->tag == OptionalType)) {
@@ -1096,6 +1101,11 @@ type_t *get_type(env_t *env, ast_t *ast)
type_t *lhs_t = get_type(env, binop.lhs);
type_t *rhs_t = get_type(env, binop.rhs);
+ if (binop.lhs->tag == Int && (is_int_type(rhs_t) || rhs_t->tag == ByteType))
+ return rhs_t;
+ else if (binop.rhs->tag == Int && (is_int_type(lhs_t) || lhs_t->tag == ByteType))
+ return lhs_t;
+
// `and` between optionals/bools is a boolean expression like `if opt? and opt?:` or `if x > 0 and opt?:`
if ((lhs_t->tag == OptionalType || lhs_t->tag == BoolType)
&& (rhs_t->tag == OptionalType || rhs_t->tag == BoolType)) {
@@ -1125,6 +1135,11 @@ type_t *get_type(env_t *env, ast_t *ast)
type_t *lhs_t = get_type(env, binop.lhs);
type_t *rhs_t = get_type(env, binop.rhs);
+ if (binop.lhs->tag == Int && (is_int_type(rhs_t) || rhs_t->tag == ByteType))
+ return rhs_t;
+ else if (binop.rhs->tag == Int && (is_int_type(lhs_t) || lhs_t->tag == ByteType))
+ return lhs_t;
+
// `xor` between optionals/bools is a boolean expression like `if opt? xor opt?:` or `if x > 0 xor opt?:`
if ((lhs_t->tag == OptionalType || lhs_t->tag == BoolType)
&& (rhs_t->tag == OptionalType || rhs_t->tag == BoolType)) {