diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-23 21:59:35 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-23 21:59:35 +0200 |
commit | 55849f31e9ad0d2faadd7488ca25669737d74b8d (patch) | |
tree | 175187d3bf70eb9a50dd8b335460ffb52c5cfc98 /src/main.c | |
parent | 25444d18759bb7dde28dc6cb7a1554a08a125e34 (diff) | |
download | bdl-55849f31e9ad0d2faadd7488ca25669737d74b8d.tar.gz bdl-55849f31e9ad0d2faadd7488ca25669737d74b8d.zip |
Add wip function typechecking
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 73 |
1 files changed, 73 insertions, 0 deletions
@@ -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 " |