diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-23 20:51:17 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-23 20:51:17 +0200 |
commit | c46596607e8ea5b37ac1bc145902b5c59dbce4e9 (patch) | |
tree | bc57522170fcaf4fe80285235b7e2b9e79653f16 | |
parent | a52097738e663f8bfea9b771c6f839f3dea9d901 (diff) | |
download | bdl-c46596607e8ea5b37ac1bc145902b5c59dbce4e9.tar.gz bdl-c46596607e8ea5b37ac1bc145902b5c59dbce4e9.zip |
Add while typechecking
-rw-r--r-- | src/main.c | 22 | ||||
-rw-r--r-- | tests/semantics.bad | 4 |
2 files changed, 22 insertions, 4 deletions
@@ -254,8 +254,8 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
254 | return node->type; | 254 | return node->type; |
255 | } break; | 255 | } break; |
256 | case NODE_IF: { | 256 | case NODE_IF: { |
257 | Type type = type_inference(a, node->cond_if, scope); | 257 | Type cond_type = type_inference(a, node->cond_if, scope); |
258 | if (!str_eq(type, cstr("bool"))) { | 258 | if (!str_eq(cond_type, cstr("bool"))) { |
259 | emit_semantic_error( | 259 | emit_semantic_error( |
260 | a, node->cond_if, | 260 | a, node->cond_if, |
261 | cstr("non boolean expression on if condition")); | 261 | cstr("non boolean expression on if condition")); |
@@ -277,12 +277,26 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
277 | } | 277 | } |
278 | if (!str_eq(node->type, else_type)) { | 278 | if (!str_eq(node->type, else_type)) { |
279 | emit_semantic_error( | 279 | emit_semantic_error( |
280 | a, node, | 280 | a, node, cstr("mismatch types for if/else branches")); |
281 | cstr("mismatch types for if/else branches")); | ||
282 | return cstr(""); | 281 | return cstr(""); |
283 | } | 282 | } |
284 | } | 283 | } |
285 | } break; | 284 | } break; |
285 | case NODE_WHILE: { | ||
286 | Type cond_type = type_inference(a, node->while_cond, scope); | ||
287 | if (!str_eq(cond_type, cstr("bool"))) { | ||
288 | emit_semantic_error( | ||
289 | a, node->cond_if, | ||
290 | cstr("non boolean expression on while condition")); | ||
291 | return cstr(""); | ||
292 | } | ||
293 | if (node->while_expr->kind != NODE_BLOCK) { | ||
294 | scope = typescope_alloc(a, scope); | ||
295 | } | ||
296 | type_inference(a, node->while_expr, scope); | ||
297 | node->type = cstr("nil"); | ||
298 | return node->type; | ||
299 | } break; | ||
286 | case NODE_TRUE: | 300 | case NODE_TRUE: |
287 | case NODE_FALSE: { | 301 | case NODE_FALSE: { |
288 | node->type = cstr("bool"); | 302 | node->type = cstr("bool"); |
diff --git a/tests/semantics.bad b/tests/semantics.bad index c316a3c..a66c8ba 100644 --- a/tests/semantics.bad +++ b/tests/semantics.bad | |||
@@ -22,6 +22,10 @@ let single = if (true) { | |||
22 | 123 | 22 | 123 |
23 | } | 23 | } |
24 | 24 | ||
25 | while (!true) { | ||
26 | "asjdflasdjf" | ||
27 | } | ||
28 | |||
25 | ; enum test { | 29 | ; enum test { |
26 | ; a = 1 | 30 | ; a = 1 |
27 | ; b | 31 | ; b |