aboutsummaryrefslogtreecommitdiff
path: root/typecheck.c
diff options
context:
space:
mode:
authorBruce Hill <bruce@bruce-hill.com>2024-11-07 13:27:09 -0500
committerBruce Hill <bruce@bruce-hill.com>2024-11-07 13:27:09 -0500
commitbd3df661656adecae089045a5afa51a46b94666b (patch)
tree86c2a33b5295619513153b9dd80bd874c04a9a9c /typecheck.c
parent3d9e562e2cc6141ea8c5c66477c036404a868ecd (diff)
Fix up some stuff with boolean operators and reductions
Diffstat (limited to 'typecheck.c')
-rw-r--r--typecheck.c35
1 files changed, 7 insertions, 28 deletions
diff --git a/typecheck.c b/typecheck.c
index 2dcfda42..49eba2ca 100644
--- a/typecheck.c
+++ b/typecheck.c
@@ -950,8 +950,7 @@ type_t *get_type(env_t *env, ast_t *ast)
|| (lhs_t->tag == ByteType && rhs_t->tag == ByteType)) {
return get_math_type(env, ast, lhs_t, rhs_t);
}
- code_err(ast, "I can't figure out the type of this `and` expression because the left side is a %T, but the right side is a %T",
- lhs_t, rhs_t);
+ code_err(ast, "I can't figure out the type of this `and` expression between a %T and a %T", lhs_t, rhs_t);
}
case BINOP_OR: {
if (lhs_t->tag == BoolType && rhs_t->tag == BoolType) {
@@ -976,8 +975,7 @@ type_t *get_type(env_t *env, ast_t *ast)
return Type(PointerType, .pointed=lhs_ptr->pointed);
}
}
- code_err(ast, "I can't figure out the type of this `or` expression because the left side is a %T, but the right side is a %T",
- lhs_t, rhs_t);
+ code_err(ast, "I can't figure out the type of this `or` expression between a %T and a %T", lhs_t, rhs_t);
}
case BINOP_XOR: {
if (lhs_t->tag == BoolType && rhs_t->tag == BoolType) {
@@ -987,8 +985,7 @@ type_t *get_type(env_t *env, ast_t *ast)
return get_math_type(env, ast, lhs_t, rhs_t);
}
- code_err(ast, "I can't figure out the type of this `xor` expression because the left side is a %T, but the right side is a %T",
- lhs_t, rhs_t);
+ code_err(ast, "I can't figure out the type of this `xor` expression between a %T and a %T", lhs_t, rhs_t);
}
case BINOP_CONCAT: {
if (!type_eq(lhs_t, rhs_t))
@@ -1028,28 +1025,10 @@ type_t *get_type(env_t *env, ast_t *ast)
return Type(OptionalType, .type=Type(BoolType));
}
- type_t *value_t;
- type_t *iter_value_t = value_type(iter_t);
- switch (iter_value_t->tag) {
- case BigIntType: case IntType: value_t = iter_value_t; break;
- case ArrayType: value_t = Match(iter_value_t, ArrayType)->item_type; break;
- case SetType: value_t = Match(iter_value_t, SetType)->item_type; break;
- case TableType: code_err(reduction->iter, "To do a reduction over a table, please specify either .keys or .values");
- case FunctionType: case ClosureType: {
- // Iterator function
- auto fn = iter_value_t->tag == ClosureType ?
- Match(Match(iter_value_t, ClosureType)->fn, FunctionType) : Match(iter_value_t, FunctionType);
- if (fn->args)
- code_err(reduction->iter, "I expected this iterator function to not take any arguments, but it's %T", iter_value_t);
- if (fn->ret->tag != OptionalType)
- code_err(reduction->iter, "I expected this iterator function to return an optional value, but it's %T", iter_value_t);
- value_t = Match(fn->ret, OptionalType)->type;
- break;
- }
- default: code_err(reduction->iter, "I don't know how to do a reduction over %T values", iter_t);
- }
-
- return Type(OptionalType, .type=value_t);
+ type_t *iterated = get_iterated_type(iter_t);
+ if (!iterated)
+ code_err(reduction->iter, "I don't know how to do a reduction over %T values", iter_t);
+ return iterated->tag == OptionalType ? iterated : Type(OptionalType, .type=iterated);
}
case UpdateAssign: