aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-23 21:59:35 +0200
committerBad Diode <bd@badd10de.dev>2024-06-23 21:59:35 +0200
commit55849f31e9ad0d2faadd7488ca25669737d74b8d (patch)
tree175187d3bf70eb9a50dd8b335460ffb52c5cfc98 /src
parent25444d18759bb7dde28dc6cb7a1554a08a125e34 (diff)
downloadbdl-55849f31e9ad0d2faadd7488ca25669737d74b8d.tar.gz
bdl-55849f31e9ad0d2faadd7488ca25669737d74b8d.zip
Add wip function typechecking
Diffstat (limited to 'src')
-rw-r--r--src/main.c73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/main.c b/src/main.c
index d442b98..4cde055 100644
--- a/src/main.c
+++ b/src/main.c
@@ -448,6 +448,15 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
448 node->type = cstr("str"); 448 node->type = cstr("str");
449 return node->type; 449 return node->type;
450 } break; 450 } break;
451 case NODE_TYPE: {
452 TypeMap *type = find_type(scope, node->value.str);
453 if (!type) {
454 emit_semantic_error(a, node, cstr("unknown type"));
455 return cstr("");
456 }
457 node->type = type->val;
458 return node->type;
459 } break;
451 case NODE_SYMBOL: { 460 case NODE_SYMBOL: {
452 TypeMap *type = find_type(scope, node->value.str); 461 TypeMap *type = find_type(scope, node->value.str);
453 if (type) { 462 if (type) {
@@ -481,6 +490,70 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
481 node->type = type; 490 node->type = type;
482 return node->type; 491 return node->type;
483 } break; 492 } break;
493 case NODE_RETURN: {
494 Type type;
495 for (sz i = 0; i < array_size(node->elements); i++) {
496 Node *expr = node->elements[i];
497 type = type_inference(a, expr, scope);
498 }
499 // TODO: this is incorrect, must return the inferred type, but what
500 // to do if we have multiple? This only considers single return
501 // values for now...
502 node->type = type;
503 return type;
504 } break;
505 case NODE_FUN: {
506 // TODO: we may want to do this and register a special table with
507 // function and formals...
508 // if (scope->parent != NULL) {
509 // // Str symbol = node->func_name->value.str;
510 // // if (symmap_lookup(&scope->symbols, symbol) != NULL) {
511 // // eprintln(
512 // // "%s:%d:%d: error: symbol '%s' already exists in "
513 // // "current "
514 // // "scope",
515 // // a->file_name, node->func_name->line,
516 // // node->func_name->col, symbol);
517 // // return;
518 // // }
519 // // symmap_insert(&scope->symbols, symbol,
520 // // (Symbol){.kind = SYM_FUN, .name = symbol},
521 // // a->storage);
522 // }
523
524 node->type = cstr("nil");
525 scope = typescope_alloc(a, scope);
526 for (sz i = 0; i < array_size(node->func_params); i++) {
527 Node *param = node->func_params[i];
528 Str symbol = param->param_name->value.str;
529 Type type = param->param_type->value.str;
530 param->param_name->type =
531 type_inference(a, param->param_type, scope);
532 param->type = param->param_name->type;
533 typemap_insert(&scope->types, symbol, type, a->storage);
534 }
535
536 for (sz i = 0; i < array_size(node->func_ret); i++) {
537 Node *ret = node->func_ret[i];
538 ret->type = type_inference(a, ret, scope);
539 }
540
541 node->type = cstr("nil");
542 if (node->func_body->kind == NODE_BLOCK) {
543 node = node->func_body;
544 Type type;
545 for (sz i = 0; i < array_size(node->elements); i++) {
546 Node *expr = node->elements[i];
547 type = type_inference(a, expr, scope);
548 }
549 node->type = type;
550 // TODO: ensure ALL return statements match the function
551 // prototype.
552 } else {
553 type_inference(a, node->func_body, scope);
554 }
555 return cstr("nil");
556 } break;
484 default: { 557 default: {
485 emit_semantic_error(a, node, 558 emit_semantic_error(a, node,
486 cstr("type inference not implemented for this " 559 cstr("type inference not implemented for this "