diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-24 12:48:05 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-24 12:48:05 +0200 |
commit | 6fbe06eda046bd3b261e2ba84e1f728ecdf55a47 (patch) | |
tree | 6042e3ac8fa645c2a944277e3ba9a37da0caebe8 | |
parent | 9c73b54a747e5489b2d6f27947cd8216f5311d5e (diff) | |
download | bdl-6fbe06eda046bd3b261e2ba84e1f728ecdf55a47.tar.gz bdl-6fbe06eda046bd3b261e2ba84e1f728ecdf55a47.zip |
Change typecheck returns to emit err on site
-rw-r--r-- | src/main.c | 45 |
1 files changed, 16 insertions, 29 deletions
@@ -201,10 +201,10 @@ emit_semantic_error(Analyzer *a, Node *n, Str msg) { | |||
201 | eprintln("%s:%d:%d: error: %s", a->file_name, n->line, n->col, msg); | 201 | eprintln("%s:%d:%d: error: %s", a->file_name, n->line, n->col, msg); |
202 | } | 202 | } |
203 | 203 | ||
204 | bool | 204 | void |
205 | typecheck_returns(Node *node, Str expected) { | 205 | typecheck_returns(Analyzer *a, Node *node, Str expected) { |
206 | if (!node) { | 206 | if (!node) { |
207 | return true; | 207 | return; |
208 | } | 208 | } |
209 | 209 | ||
210 | // Traverse the tree again. | 210 | // Traverse the tree again. |
@@ -213,56 +213,44 @@ typecheck_returns(Node *node, Str expected) { | |||
213 | case NODE_MATCH: { | 213 | case NODE_MATCH: { |
214 | for (sz i = 0; i < array_size(node->match_cases); i++) { | 214 | for (sz i = 0; i < array_size(node->match_cases); i++) { |
215 | Node *next = node->match_cases[i]; | 215 | Node *next = node->match_cases[i]; |
216 | if (!typecheck_returns(next, expected)) { | 216 | typecheck_returns(a, next, expected); |
217 | return false; | ||
218 | } | ||
219 | } | 217 | } |
220 | } break; | 218 | } break; |
221 | case NODE_RETURN: { | 219 | case NODE_RETURN: { |
222 | return str_eq(node->type, expected); | 220 | bool err = !str_eq(node->type, expected); |
221 | if (err) { | ||
222 | emit_semantic_error(a, node, cstr("mismatched return types")); | ||
223 | } | ||
223 | } break; | 224 | } break; |
224 | case NODE_BLOCK: { | 225 | case NODE_BLOCK: { |
225 | for (sz i = 0; i < array_size(node->elements); i++) { | 226 | for (sz i = 0; i < array_size(node->elements); i++) { |
226 | Node *next = node->elements[i]; | 227 | Node *next = node->elements[i]; |
227 | if (!typecheck_returns(next, expected)) { | 228 | typecheck_returns(a, next, expected); |
228 | return false; | ||
229 | } | ||
230 | } | 229 | } |
231 | } break; | 230 | } break; |
232 | case NODE_IF: { | 231 | case NODE_IF: { |
233 | if (node->cond_expr) { | 232 | if (node->cond_expr) { |
234 | if (!typecheck_returns(node->cond_expr, expected)) { | 233 | typecheck_returns(a, node->cond_expr, expected); |
235 | return false; | ||
236 | } | ||
237 | } | 234 | } |
238 | if (node->cond_else) { | 235 | if (node->cond_else) { |
239 | if (!typecheck_returns(node->cond_else, expected)) { | 236 | typecheck_returns(a, node->cond_else, expected); |
240 | return false; | ||
241 | } | ||
242 | } | 237 | } |
243 | } break; | 238 | } break; |
244 | case NODE_SET: | 239 | case NODE_SET: |
245 | case NODE_LET: { | 240 | case NODE_LET: { |
246 | if (node->var_val) { | 241 | if (node->var_val) { |
247 | if (!typecheck_returns(node->var_val, expected)) { | 242 | typecheck_returns(a, node->var_val, expected); |
248 | return false; | ||
249 | } | ||
250 | } | 243 | } |
251 | } break; | 244 | } break; |
252 | default: { | 245 | default: { |
253 | if (node->left) { | 246 | if (node->left) { |
254 | if (!typecheck_returns(node->left, expected)) { | 247 | typecheck_returns(a, node->left, expected); |
255 | return false; | ||
256 | } | ||
257 | } | 248 | } |
258 | if (node->right) { | 249 | if (node->right) { |
259 | if (!typecheck_returns(node->right, expected)) { | 250 | typecheck_returns(a, node->right, expected); |
260 | return false; | ||
261 | } | ||
262 | } | 251 | } |
263 | } break; | 252 | } break; |
264 | } | 253 | } |
265 | return true; | ||
266 | } | 254 | } |
267 | 255 | ||
268 | Type | 256 | Type |
@@ -635,10 +623,9 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) { | |||
635 | } | 623 | } |
636 | 624 | ||
637 | // Ensure ALL return statements match the function prototype. | 625 | // Ensure ALL return statements match the function prototype. |
638 | if (!typecheck_returns(node->func_body, ret_type)) { | 626 | typecheck_returns(a, node->func_body, ret_type); |
639 | emit_semantic_error(a, node, cstr("mismatched return types")); | ||
640 | } | ||
641 | 627 | ||
628 | // TODO: should return statements be allowed on let blocks? | ||
642 | // TODO: insert this into a functions map in the current scope? need | 629 | // TODO: insert this into a functions map in the current scope? need |
643 | // the arity and return parameters for funcalls. | 630 | // the arity and return parameters for funcalls. |
644 | return node->type; | 631 | return node->type; |