aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-24 12:48:05 +0200
committerBad Diode <bd@badd10de.dev>2024-06-24 12:48:05 +0200
commit6fbe06eda046bd3b261e2ba84e1f728ecdf55a47 (patch)
tree6042e3ac8fa645c2a944277e3ba9a37da0caebe8
parent9c73b54a747e5489b2d6f27947cd8216f5311d5e (diff)
downloadbdl-6fbe06eda046bd3b261e2ba84e1f728ecdf55a47.tar.gz
bdl-6fbe06eda046bd3b261e2ba84e1f728ecdf55a47.zip
Change typecheck returns to emit err on site
-rw-r--r--src/main.c45
1 files changed, 16 insertions, 29 deletions
diff --git a/src/main.c b/src/main.c
index acc2b46..33ab4ed 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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
204bool 204void
205typecheck_returns(Node *node, Str expected) { 205typecheck_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
268Type 256Type
@@ -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;