diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-23 20:46:51 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-23 20:46:51 +0200 |
commit | a52097738e663f8bfea9b771c6f839f3dea9d901 (patch) | |
tree | 15bca360082a1aef2f85166096d26716e4f7eb93 | |
parent | caf4d4c7dd0fff6cdf69bf8cb27f3bbb6d02a366 (diff) | |
download | bdl-a52097738e663f8bfea9b771c6f839f3dea9d901.tar.gz bdl-a52097738e663f8bfea9b771c6f839f3dea9d901.zip |
Add typechecking for if expressions
-rw-r--r-- | src/main.c | 30 | ||||
-rw-r--r-- | tests/semantics.bad | 30 |
2 files changed, 50 insertions, 10 deletions
@@ -253,6 +253,36 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
253 | } | 253 | } |
254 | return node->type; | 254 | return node->type; |
255 | } break; | 255 | } break; |
256 | case NODE_IF: { | ||
257 | Type type = type_inference(a, node->cond_if, scope); | ||
258 | if (!str_eq(type, cstr("bool"))) { | ||
259 | emit_semantic_error( | ||
260 | a, node->cond_if, | ||
261 | cstr("non boolean expression on if condition")); | ||
262 | return cstr(""); | ||
263 | } | ||
264 | if (node->cond_expr->kind == NODE_BLOCK) { | ||
265 | node->type = type_inference(a, node->cond_expr, scope); | ||
266 | } else { | ||
267 | TypeScope *next = typescope_alloc(a, scope); | ||
268 | node->type = type_inference(a, node->cond_expr, next); | ||
269 | } | ||
270 | if (node->cond_else) { | ||
271 | Type else_type; | ||
272 | if (node->cond_else->kind == NODE_BLOCK) { | ||
273 | else_type = type_inference(a, node->cond_else, scope); | ||
274 | } else { | ||
275 | TypeScope *next = typescope_alloc(a, scope); | ||
276 | else_type = type_inference(a, node->cond_else, next); | ||
277 | } | ||
278 | if (!str_eq(node->type, else_type)) { | ||
279 | emit_semantic_error( | ||
280 | a, node, | ||
281 | cstr("mismatch types for if/else branches")); | ||
282 | return cstr(""); | ||
283 | } | ||
284 | } | ||
285 | } break; | ||
256 | case NODE_TRUE: | 286 | case NODE_TRUE: |
257 | case NODE_FALSE: { | 287 | case NODE_FALSE: { |
258 | node->type = cstr("bool"); | 288 | node->type = cstr("bool"); |
diff --git a/tests/semantics.bad b/tests/semantics.bad index 158cec6..c316a3c 100644 --- a/tests/semantics.bad +++ b/tests/semantics.bad | |||
@@ -1,15 +1,25 @@ | |||
1 | ; let a:f32 = (1.0 + 2.0 * 2.0) / 2.0 | 1 | ; let a:f32 = (1.0 + 2.0 * 2.0) / 2.0 |
2 | 2 | ||
3 | let annotated:int = (1 + 2 * 2) / 2 | 3 | ; let annotated:int = (1 + 2 * 2) / 2 |
4 | let numbers = 1 | 4 | ; let numbers = 1 |
5 | let symbols = numbers | 5 | ; let symbols = numbers |
6 | let arith = 1 + 2 * 4 | 6 | ; let arith = 1 + 2 * 4 |
7 | let cmp = 1 <= 2 | 7 | ; let cmp = 1 <= 2 |
8 | let logic = !true && false || (1 <= 2) | 8 | ; let logic = !true && false || (1 <= 2) |
9 | let bits = 0xff & 0b00001111 | 9 | ; let bits = 0xff & 0b00001111 |
10 | let block = { | 10 | ; let block = { |
11 | let a = 1 + 2 | 11 | ; let a = 1 + 2 |
12 | a + 3 | 12 | ; a + 3 |
13 | ; } | ||
14 | |||
15 | let maybe = if (1 == 2) { | ||
16 | 32 | ||
17 | } else { | ||
18 | 44 | ||
19 | } | ||
20 | |||
21 | let single = if (true) { | ||
22 | 123 | ||
13 | } | 23 | } |
14 | 24 | ||
15 | ; enum test { | 25 | ; enum test { |