aboutsummaryrefslogtreecommitdiffstats
path: root/src/semantic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/semantic.c')
-rw-r--r--src/semantic.c538
1 files changed, 383 insertions, 155 deletions
diff --git a/src/semantic.c b/src/semantic.c
index 1b40723..7c44671 100644
--- a/src/semantic.c
+++ b/src/semantic.c
@@ -82,6 +82,9 @@ Scope *
82typescope_alloc(Analyzer *a, Scope *parent) { 82typescope_alloc(Analyzer *a, Scope *parent) {
83 Scope *scope = arena_calloc(sizeof(Scope), a->storage); 83 Scope *scope = arena_calloc(sizeof(Scope), a->storage);
84 scope->parent = parent; 84 scope->parent = parent;
85 if (parent != NULL) {
86 scope->name = parent->name;
87 }
85 scope->id = a->typescope_gen++; 88 scope->id = a->typescope_gen++;
86 scope->depth = parent == NULL ? 0 : parent->depth + 1; 89 scope->depth = parent == NULL ? 0 : parent->depth + 1;
87 array_push(a->scopes, scope, a->storage); 90 array_push(a->scopes, scope, a->storage);
@@ -146,6 +149,23 @@ find_struct(Scope *scope, Str type) {
146 return (FindStructResult){0}; 149 return (FindStructResult){0};
147} 150}
148 151
152typedef struct FindSymbolResult {
153 SymbolMap *map;
154 Scope *scope;
155} FindSymbolResult;
156
157FindSymbolResult
158find_symbol(Scope *scope, Str type) {
159 while (scope != NULL) {
160 SymbolMap *val = symmap_lookup(&scope->symbols, type);
161 if (val != NULL) {
162 return (FindSymbolResult){.map = val, .scope = scope};
163 }
164 scope = scope->parent;
165 }
166 return (FindSymbolResult){0};
167}
168
149void 169void
150graph_typescope(Scope *scope, Arena a) { 170graph_typescope(Scope *scope, Arena a) {
151 if (!scope->symbols) { 171 if (!scope->symbols) {
@@ -259,7 +279,7 @@ Str type_inference(Analyzer *a, Node *node, Scope *scope);
259 279
260void 280void
261typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { 281typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
262 if (node->field_type->kind == NODE_COMPOUND_TYPE) { 282 if (node->field.type->kind == NODE_COMPOUND_TYPE) {
263 Str field_name = str_concat(symbol, cstr("."), a->storage); 283 Str field_name = str_concat(symbol, cstr("."), a->storage);
264 field_name = str_concat(field_name, node->value.str, a->storage); 284 field_name = str_concat(field_name, node->value.str, a->storage);
265 if (structmap_lookup(&scope->structs, field_name)) { 285 if (structmap_lookup(&scope->structs, field_name)) {
@@ -268,8 +288,8 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
268 a->err = true; 288 a->err = true;
269 } 289 }
270 Str type = cstr("\\{ "); 290 Str type = cstr("\\{ ");
271 for (sz i = 0; i < array_size(node->field_type->elements); i++) { 291 for (sz i = 0; i < array_size(node->field.type->elements); i++) {
272 Node *field = node->field_type->elements[i]; 292 Node *field = node->field.type->elements[i];
273 typecheck_field(a, field, scope, field_name); 293 typecheck_field(a, field, scope, field_name);
274 type = str_concat(type, field->type, a->storage); 294 type = str_concat(type, field->type, a->storage);
275 type = str_concat(type, cstr(" "), a->storage); 295 type = str_concat(type, cstr(" "), a->storage);
@@ -279,16 +299,16 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
279 } else { 299 } else {
280 Str field_name = str_concat(symbol, cstr("."), a->storage); 300 Str field_name = str_concat(symbol, cstr("."), a->storage);
281 field_name = str_concat(field_name, node->value.str, a->storage); 301 field_name = str_concat(field_name, node->value.str, a->storage);
282 Str field_type = node->field_type->value.str; 302 Str field_type = node->field.type->value.str;
283 if (!find_type(scope, field_type)) { 303 if (!find_type(scope, field_type)) {
284 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, 304 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
285 node->field_type->line, node->field_type->col, field_type); 305 node->field.type->line, node->field.type->col, field_type);
286 a->err = true; 306 a->err = true;
287 } 307 }
288 if (node->field_type->is_ptr) { 308 if (node->field.type->is_ptr) {
289 field_type = str_concat(cstr("@"), field_type, a->storage); 309 field_type = str_concat(cstr("@"), field_type, a->storage);
290 } 310 }
291 if (node->field_type->kind == NODE_ARR_TYPE) { 311 if (node->field.type->kind == NODE_ARR_TYPE) {
292 field_type = str_concat(cstr("@"), field_type, a->storage); 312 field_type = str_concat(cstr("@"), field_type, a->storage);
293 } 313 }
294 if (structmap_lookup(&scope->structs, field_name)) { 314 if (structmap_lookup(&scope->structs, field_name)) {
@@ -296,8 +316,8 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
296 a->file_name, node->line, node->col, field_name); 316 a->file_name, node->line, node->col, field_name);
297 a->err = true; 317 a->err = true;
298 } 318 }
299 if (node->field_val) { 319 if (node->field.val) {
300 Str type = type_inference(a, node->field_val, scope); 320 Str type = type_inference(a, node->field.val, scope);
301 if (!str_eq(type, field_type)) { 321 if (!str_eq(type, field_type)) {
302 eprintln( 322 eprintln(
303 "%s:%d:%d: error: mismatched types in struct " 323 "%s:%d:%d: error: mismatched types in struct "
@@ -312,7 +332,7 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
312 (Struct){ 332 (Struct){
313 .name = field_name, 333 .name = field_name,
314 .type = field_type, 334 .type = field_type,
315 .val = node->field_val, 335 .val = node->field.val,
316 }, 336 },
317 a->storage); 337 a->storage);
318 symmap_insert(&scope->symbols, field_name, 338 symmap_insert(&scope->symbols, field_name,
@@ -324,10 +344,10 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
324 344
325void 345void
326typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { 346typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
327 if (node->field_val->kind == NODE_COMPOUND_TYPE) { 347 if (node->field.val->kind == NODE_COMPOUND_TYPE) {
328 Str type = cstr("\\{ "); 348 Str type = cstr("\\{ ");
329 for (sz i = 0; i < array_size(node->field_val->elements); i++) { 349 for (sz i = 0; i < array_size(node->field.val->elements); i++) {
330 Node *field = node->field_val->elements[i]; 350 Node *field = node->field.val->elements[i];
331 Str field_name = str_concat(symbol, cstr("."), a->storage); 351 Str field_name = str_concat(symbol, cstr("."), a->storage);
332 field_name = str_concat(field_name, field->value.str, a->storage); 352 field_name = str_concat(field_name, field->value.str, a->storage);
333 typecheck_lit_field(a, field, scope, field_name); 353 typecheck_lit_field(a, field, scope, field_name);
@@ -345,7 +365,7 @@ typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
345 return; 365 return;
346 } 366 }
347 Str field_type = s->val.type; 367 Str field_type = s->val.type;
348 Str type = type_inference(a, node->field_val, scope); 368 Str type = type_inference(a, node->field.val, scope);
349 if (!str_eq(type, field_type)) { 369 if (!str_eq(type, field_type)) {
350 eprintln( 370 eprintln(
351 "%s:%d:%d: error: mismatched types in struct " 371 "%s:%d:%d: error: mismatched types in struct "
@@ -367,17 +387,18 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
367 switch (node->kind) { 387 switch (node->kind) {
368 case NODE_COND: 388 case NODE_COND:
369 case NODE_MATCH: { 389 case NODE_MATCH: {
370 for (sz i = 0; i < array_size(node->match_cases); i++) { 390 for (sz i = 0; i < array_size(node->match.cases); i++) {
371 Node *next = node->match_cases[i]; 391 Node *next = node->match.cases[i];
372 typecheck_returns(a, next, expected); 392 typecheck_returns(a, next, expected);
373 } 393 }
374 } break; 394 } break;
375 case NODE_RETURN: { 395 case NODE_RETURN: {
376 bool err = !str_eq(node->type, expected); 396 Str type = str_remove_prefix(node->type, cstr("ret:"));
397 bool err = !str_eq(type, expected);
377 if (err) { 398 if (err) {
378 eprintln( 399 eprintln(
379 "%s:%d:%d: error: mismatched return type %s, expected %s", 400 "%s:%d:%d: error: mismatched return type %s, expected %s",
380 a->file_name, node->line, node->col, node->type, expected); 401 a->file_name, node->line, node->col, type, expected);
381 a->err = true; 402 a->err = true;
382 } 403 }
383 } break; 404 } break;
@@ -388,17 +409,17 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
388 } 409 }
389 } break; 410 } break;
390 case NODE_IF: { 411 case NODE_IF: {
391 if (node->cond_expr) { 412 if (node->ifelse.expr_true) {
392 typecheck_returns(a, node->cond_expr, expected); 413 typecheck_returns(a, node->ifelse.expr_true, expected);
393 } 414 }
394 if (node->cond_else) { 415 if (node->ifelse.expr_else) {
395 typecheck_returns(a, node->cond_else, expected); 416 typecheck_returns(a, node->ifelse.expr_else, expected);
396 } 417 }
397 } break; 418 } break;
398 case NODE_SET: 419 case NODE_SET:
399 case NODE_LET: { 420 case NODE_LET: {
400 if (node->var_val) { 421 if (node->var.val) {
401 typecheck_returns(a, node->var_val, expected); 422 typecheck_returns(a, node->var.val, expected);
402 } 423 }
403 } break; 424 } break;
404 case NODE_ADD: 425 case NODE_ADD:
@@ -418,13 +439,14 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
418 case NODE_BITNOT: 439 case NODE_BITNOT:
419 case NODE_BITAND: 440 case NODE_BITAND:
420 case NODE_BITOR: 441 case NODE_BITOR:
442 case NODE_BITXOR:
421 case NODE_BITLSHIFT: 443 case NODE_BITLSHIFT:
422 case NODE_BITRSHIFT: { 444 case NODE_BITRSHIFT: {
423 if (node->left) { 445 if (node->binary.left) {
424 typecheck_returns(a, node->left, expected); 446 typecheck_returns(a, node->binary.left, expected);
425 } 447 }
426 if (node->right) { 448 if (node->binary.right) {
427 typecheck_returns(a, node->right, expected); 449 typecheck_returns(a, node->binary.right, expected);
428 } 450 }
429 } break; 451 } break;
430 default: break; 452 default: break;
@@ -435,66 +457,79 @@ Str
435type_inference(Analyzer *a, Node *node, Scope *scope) { 457type_inference(Analyzer *a, Node *node, Scope *scope) {
436 assert(a); 458 assert(a);
437 assert(scope); 459 assert(scope);
438 if (!node) { 460 if (!node || a->err) {
439 return cstr(""); 461 return cstr("");
440 } 462 }
441 // NOTE: For now we are not going to do implicit numeric conversions. 463 // NOTE: For now we are not going to do implicit numeric conversions.
442 switch (node->kind) { 464 switch (node->kind) {
443 case NODE_LET: { 465 case NODE_LET: {
444 node->type = cstr("nil"); 466 node->type = cstr("nil");
445 Str symbol = node->var_name->value.str; 467 node->var.name->parent = node;
468 Str symbol = node->var.name->value.str;
446 if (symmap_lookup(&scope->symbols, symbol)) { 469 if (symmap_lookup(&scope->symbols, symbol)) {
447 eprintln( 470 eprintln(
448 "%s:%d:%d: error: symbol '%s' already exists in current " 471 "%s:%d:%d: error: symbol '%s' already exists in current "
449 "scope ", 472 "scope ",
450 a->file_name, node->var_name->line, node->var_name->col, 473 a->file_name, node->var.name->line, node->var.name->col,
451 symbol); 474 symbol);
452 a->err = true; 475 a->err = true;
453 return cstr(""); 476 return cstr("");
454 } 477 }
455 if (node->var_type) { 478 if (node->var.type) {
456 Str type_name = node->var_type->value.str; 479 node->var.type->parent = node;
480 Str type_name = node->var.type->value.str;
457 SymbolMap *type = find_type(scope, type_name); 481 SymbolMap *type = find_type(scope, type_name);
458 if (type == NULL) { 482 if (type == NULL) {
459 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, 483 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
460 node->var_type->line, node->var_type->col, 484 node->var.type->line, node->var.type->col,
461 type_name); 485 type_name);
462 a->err = true; 486 a->err = true;
463 return cstr(""); 487 return cstr("");
464 } 488 }
465 if (node->var_type->is_ptr) { 489 if (node->var.type->is_ptr) {
466 type_name = str_concat(cstr("@"), type_name, a->storage); 490 type_name = str_concat(cstr("@"), type_name, a->storage);
467 } 491 }
468 if (node->var_type->kind == NODE_ARR_TYPE) { 492 if (node->var.type->kind == NODE_ARR_TYPE) {
469 type_name = str_concat(cstr("@"), type_name, a->storage); 493 type_name = str_concat(cstr("@"), type_name, a->storage);
470 // TODO: typecheck size 494 if (node->var.type->sym.arr_size->value.i == 0) {
495 eprintln("%s:%d:%d: error: zero sized array '%s'",
496 a->file_name, node->var.type->line,
497 node->var.type->col, symbol);
498 a->err = true;
499 return cstr("");
500 }
471 // TODO: register array in scope 501 // TODO: register array in scope
472 } 502 }
473 if (node->var_val) { 503 if (node->var.val) {
474 Str type = type_inference(a, node->var_val, scope); 504 node->var.val->parent = node;
505 Str type = type_inference(a, node->var.val, scope);
475 if (!type.size) { 506 if (!type.size) {
476 eprintln( 507 eprintln(
477 "%s:%d:%d: error: can't bind `nil` to variable " 508 "%s:%d:%d: error: can't bind `nil` to variable "
478 "'%s'", 509 "'%s'",
479 a->file_name, node->var_type->line, 510 a->file_name, node->var.type->line,
480 node->var_type->col, symbol); 511 node->var.type->col, symbol);
481 a->err = true; 512 a->err = true;
482 return cstr(""); 513 return cstr("");
483 } 514 }
484 // TODO: Consider compatible types.
485 if (!str_eq(type, type_name)) { 515 if (!str_eq(type, type_name)) {
486 // Special case, enums can be treated as ints. 516 if (!(strset_lookup(&a->integer_types, type) &&
487 FindEnumResult res = find_enum(scope, type_name); 517 strset_lookup(&a->integer_types, type_name)) &&
488 if (!(res.map && str_eq(type, cstr("int")))) { 518 !(strset_lookup(&a->numeric_types, type) &&
489 eprintln( 519 strset_lookup(&a->numeric_types, type_name))) {
490 "%s:%d:%d: error: type mismatch, trying to " 520 // Special case, enums can be treated as ints.
491 "assing " 521 FindEnumResult res = find_enum(scope, type_name);
492 "%s" 522 if (!(res.map && str_eq(type, cstr("int")))) {
493 " to a variable of type %s", 523 eprintln(
494 a->file_name, node->var_type->line, 524 "%s:%d:%d: error: type mismatch, trying to "
495 node->var_type->col, type, type_name); 525 "assing "
496 a->err = true; 526 "%s"
497 return cstr(""); 527 " to a variable of type %s",
528 a->file_name, node->var.type->line,
529 node->var.type->col, type, type_name);
530 a->err = true;
531 return cstr("");
532 }
498 } 533 }
499 } 534 }
500 } 535 }
@@ -504,17 +539,29 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
504 .kind = SYM_VAR, 539 .kind = SYM_VAR,
505 }, 540 },
506 a->storage); 541 a->storage);
542 node->var.name->type = type_name;
543 symbol = str_concat(cstr("."), symbol, a->storage);
544 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
545 a->storage);
546 node->unique_name = symbol;
507 return node->type; 547 return node->type;
508 } 548 }
509 549
510 // We don't know the type for this symbol, perform inference. 550 // We don't know the type for this symbol, perform inference.
511 Str type = type_inference(a, node->var_val, scope); 551 node->var.val->parent = node;
512 if (type.size) { 552 Str type = type_inference(a, node->var.val, scope);
513 symmap_insert(&scope->symbols, symbol, 553 if (!type.size || str_eq(type, cstr("nil")) ||
514 (Symbol){.name = type, .kind = SYM_VAR}, 554 str_has_prefix(type, cstr("ret:"))) {
515 a->storage); 555 eprintln(
516 node->var_name->type = type; 556 "%s:%d:%d: error: can't bind `nil` to variable "
557 "'%s'",
558 a->file_name, node->line, node->col, symbol);
559 a->err = true;
560 return cstr("");
517 } 561 }
562 symmap_insert(&scope->symbols, symbol,
563 (Symbol){.name = type, .kind = SYM_VAR}, a->storage);
564 node->var.name->type = type;
518 symbol = str_concat(cstr("."), symbol, a->storage); 565 symbol = str_concat(cstr("."), symbol, a->storage);
519 symbol = str_concat(symbol, str_from_int(scope->id, a->storage), 566 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
520 a->storage); 567 a->storage);
@@ -522,8 +569,10 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
522 return node->type; 569 return node->type;
523 } break; 570 } break;
524 case NODE_SET: { 571 case NODE_SET: {
525 Str name = type_inference(a, node->var_name, scope); 572 node->var.name->parent = node;
526 Str val = type_inference(a, node->var_val, scope); 573 node->var.val->parent = node;
574 Str name = type_inference(a, node->var.name, scope);
575 Str val = type_inference(a, node->var.val, scope);
527 if (!str_eq(name, val)) { 576 if (!str_eq(name, val)) {
528 eprintln( 577 eprintln(
529 "%s:%d:%d: error: type mismatch, trying to assing " 578 "%s:%d:%d: error: type mismatch, trying to assing "
@@ -533,6 +582,12 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
533 a->err = true; 582 a->err = true;
534 return cstr(""); 583 return cstr("");
535 } 584 }
585 Str symbol = node->var.name->value.str;
586 FindSymbolResult sym = find_symbol(scope, symbol);
587 node->unique_name = str_concat(cstr("."), symbol, a->storage);
588 node->unique_name =
589 str_concat(node->unique_name,
590 str_from_int(sym.scope->id, a->storage), a->storage);
536 node->type = cstr("nil"); 591 node->type = cstr("nil");
537 return node->type; 592 return node->type;
538 } break; 593 } break;
@@ -551,6 +606,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
551 a->storage); 606 a->storage);
552 for (sz i = 0; i < array_size(node->struct_field); i++) { 607 for (sz i = 0; i < array_size(node->struct_field); i++) {
553 Node *field = node->struct_field[i]; 608 Node *field = node->struct_field[i];
609 field->parent = node;
554 typecheck_field(a, field, scope, symbol); 610 typecheck_field(a, field, scope, symbol);
555 } 611 }
556 symmap_insert(&scope->symbols, symbol, 612 symmap_insert(&scope->symbols, symbol,
@@ -572,11 +628,12 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
572 enummap_insert(&scope->enums, symbol, 628 enummap_insert(&scope->enums, symbol,
573 (Enum){ 629 (Enum){
574 .name = symbol, 630 .name = symbol,
575 .val = node->field_val, 631 .val = node->field.val,
576 }, 632 },
577 a->storage); 633 a->storage);
578 for (sz i = 0; i < array_size(node->struct_field); i++) { 634 for (sz i = 0; i < array_size(node->struct_field); i++) {
579 Node *field = node->struct_field[i]; 635 Node *field = node->struct_field[i];
636 field->parent = node;
580 Str field_name = str_concat(symbol, cstr("."), a->storage); 637 Str field_name = str_concat(symbol, cstr("."), a->storage);
581 field_name = 638 field_name =
582 str_concat(field_name, field->value.str, a->storage); 639 str_concat(field_name, field->value.str, a->storage);
@@ -585,8 +642,8 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
585 a->file_name, field->line, field->col, field_name); 642 a->file_name, field->line, field->col, field_name);
586 a->err = true; 643 a->err = true;
587 } 644 }
588 if (field->field_val) { 645 if (field->field.val) {
589 Str type = type_inference(a, field->field_val, scope); 646 Str type = type_inference(a, field->field.val, scope);
590 if (!str_eq(type, cstr("int"))) { 647 if (!str_eq(type, cstr("int"))) {
591 eprintln( 648 eprintln(
592 "%s:%d:%d: error: non int enum value for '%s.%s'", 649 "%s:%d:%d: error: non int enum value for '%s.%s'",
@@ -609,26 +666,34 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
609 return node->type; 666 return node->type;
610 } break; 667 } break;
611 case NODE_IF: { 668 case NODE_IF: {
612 Str cond_type = type_inference(a, node->cond_if, scope); 669 node->ifelse.cond->parent = node;
670 node->ifelse.expr_true->parent = node;
671 Str cond_type = type_inference(a, node->ifelse.cond, scope);
613 if (!str_eq(cond_type, cstr("bool"))) { 672 if (!str_eq(cond_type, cstr("bool"))) {
614 emit_semantic_error( 673 emit_semantic_error(
615 a, node->cond_if, 674 a, node->ifelse.cond,
616 cstr("non boolean expression on if condition")); 675 cstr("non boolean expression on if condition"));
617 return cstr(""); 676 return cstr("");
618 } 677 }
619 if (node->cond_expr->kind == NODE_BLOCK) { 678 if (node->ifelse.expr_true->kind == NODE_BLOCK) {
620 node->type = type_inference(a, node->cond_expr, scope); 679 node->type = type_inference(a, node->ifelse.expr_true, scope);
621 } else { 680 } else {
622 Scope *next = typescope_alloc(a, scope); 681 Scope *next = typescope_alloc(a, scope);
623 node->type = type_inference(a, node->cond_expr, next); 682 node->type = type_inference(a, node->ifelse.expr_true, next);
624 } 683 }
625 if (node->cond_else) { 684 if (str_has_prefix(node->type, cstr("ret:")) ||
685 str_has_prefix(node->type, cstr("flow:"))) {
686 node->type = cstr("nil");
687 }
688 if (node->ifelse.expr_else) {
689 node->ifelse.expr_else->parent = node;
626 Str else_type; 690 Str else_type;
627 if (node->cond_else->kind == NODE_BLOCK) { 691 if (node->ifelse.expr_else->kind == NODE_BLOCK) {
628 else_type = type_inference(a, node->cond_else, scope); 692 else_type =
693 type_inference(a, node->ifelse.expr_else, scope);
629 } else { 694 } else {
630 Scope *next = typescope_alloc(a, scope); 695 Scope *next = typescope_alloc(a, scope);
631 else_type = type_inference(a, node->cond_else, next); 696 else_type = type_inference(a, node->ifelse.expr_else, next);
632 } 697 }
633 if (!str_eq(node->type, else_type)) { 698 if (!str_eq(node->type, else_type)) {
634 emit_semantic_error( 699 emit_semantic_error(
@@ -636,27 +701,41 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
636 return cstr(""); 701 return cstr("");
637 } 702 }
638 } 703 }
704
705 // If it returns a value, verify it contains an `else` statement.
706 if (!str_eq(node->type, cstr("nil"))) {
707 if (!node->ifelse.expr_else) {
708 emit_semantic_error(
709 a, node,
710 cstr("missing else statement in if expression"));
711 return cstr("");
712 }
713 }
639 return node->type; 714 return node->type;
640 } break; 715 } break;
641 case NODE_WHILE: { 716 case NODE_WHILE: {
642 Str cond_type = type_inference(a, node->while_cond, scope); 717 node->loop.cond->parent = node;
718 node->loop.expr->parent = node;
719 Str cond_type = type_inference(a, node->loop.cond, scope);
643 if (!str_eq(cond_type, cstr("bool"))) { 720 if (!str_eq(cond_type, cstr("bool"))) {
644 emit_semantic_error( 721 emit_semantic_error(
645 a, node->cond_if, 722 a, node->loop.cond,
646 cstr("non boolean expression on while condition")); 723 cstr("non boolean expression on while condition"));
647 return cstr(""); 724 return cstr("");
648 } 725 }
649 if (node->while_expr->kind != NODE_BLOCK) { 726 if (node->loop.expr->kind != NODE_BLOCK) {
650 scope = typescope_alloc(a, scope); 727 scope = typescope_alloc(a, scope);
651 } 728 }
652 type_inference(a, node->while_expr, scope); 729 type_inference(a, node->loop.expr, scope);
653 node->type = cstr("nil"); 730 node->type = cstr("nil");
654 return node->type; 731 return node->type;
655 } break; 732 } break;
656 case NODE_COND: { 733 case NODE_COND: {
657 Str previous = cstr(""); 734 Str previous = cstr("");
658 for (sz i = 0; i < array_size(node->match_cases); i++) { 735 bool has_else = false;
659 Node *expr = node->match_cases[i]; 736 for (sz i = 0; i < array_size(node->match.cases); i++) {
737 Node *expr = node->match.cases[i];
738 expr->parent = node;
660 Str next = type_inference(a, expr, scope); 739 Str next = type_inference(a, expr, scope);
661 if (i != 0 && !str_eq(next, previous)) { 740 if (i != 0 && !str_eq(next, previous)) {
662 emit_semantic_error( 741 emit_semantic_error(
@@ -664,22 +743,38 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
664 cstr("non-matching types for cond expressions")); 743 cstr("non-matching types for cond expressions"));
665 return cstr(""); 744 return cstr("");
666 } 745 }
746 if (!expr->case_entry.cond) {
747 has_else = true;
748 }
667 previous = next; 749 previous = next;
668 } 750 }
751 // If it returns a value, verify it contains an `else` statement.
752 if (!str_eq(node->type, cstr("nil")) &&
753 !str_has_prefix(node->type, cstr("ret:")) &&
754 !str_has_prefix(node->type, cstr("flow:"))) {
755 if (!has_else) {
756 emit_semantic_error(
757 a, node,
758 cstr("missing else statement in cond expression"));
759 return cstr("");
760 }
761 }
669 node->type = previous; 762 node->type = previous;
670 return node->type; 763 return node->type;
671 } break; 764 } break;
672 case NODE_MATCH: { 765 case NODE_MATCH: {
673 Str e = type_inference(a, node->match_expr, scope); 766 node->match.expr->parent = node;
767 Str e = type_inference(a, node->match.expr, scope);
674 if (str_eq(e, cstr("int"))) { 768 if (str_eq(e, cstr("int"))) {
675 // Integer matching. 769 // Integer matching.
676 for (sz i = 0; i < array_size(node->match_cases); i++) { 770 for (sz i = 0; i < array_size(node->match.cases); i++) {
677 Node *field = node->match_cases[i]; 771 Node *field = node->match.cases[i];
678 if (field->case_value) { 772 field->parent = node;
679 if (field->case_value->kind != NODE_NUM_INT && 773 if (field->case_entry.cond) {
680 field->case_value->kind != NODE_NUM_UINT) { 774 if (field->case_entry.cond->kind != NODE_NUM_INT &&
775 field->case_entry.cond->kind != NODE_NUM_UINT) {
681 emit_semantic_error( 776 emit_semantic_error(
682 a, field->case_value, 777 a, field->case_entry.cond,
683 cstr( 778 cstr(
684 "non-integer or enum types on match case")); 779 "non-integer or enum types on match case"));
685 } 780 }
@@ -690,24 +785,26 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
690 FindEnumResult res = find_enum(scope, e); 785 FindEnumResult res = find_enum(scope, e);
691 Str enum_prefix = 786 Str enum_prefix =
692 str_concat(res.map->val.name, cstr("."), a->storage); 787 str_concat(res.map->val.name, cstr("."), a->storage);
693 for (sz i = 0; i < array_size(node->match_cases); i++) { 788 for (sz i = 0; i < array_size(node->match.cases); i++) {
694 Node *field = node->match_cases[i]; 789 Node *field = node->match.cases[i];
695 if (field->case_value) { 790 field->parent = node;
791 if (field->case_entry.cond) {
696 Str field_name = str_concat( 792 Str field_name = str_concat(
697 enum_prefix, field->case_value->value.str, 793 enum_prefix, field->case_entry.cond->value.str,
698 a->storage); 794 a->storage);
699 if (!enummap_lookup(&res.scope->enums, field_name)) { 795 if (!enummap_lookup(&res.scope->enums, field_name)) {
700 eprintln("%s:%d:%d: error: unknown enum field '%s'", 796 eprintln("%s:%d:%d: error: unknown enum field '%s'",
701 a->file_name, field->case_value->line, 797 a->file_name, field->case_entry.cond->line,
702 field->case_value->col, field_name); 798 field->case_entry.cond->col, field_name);
703 a->err = true; 799 a->err = true;
704 } 800 }
705 } 801 }
706 } 802 }
707 } 803 }
708 Str previous = cstr(""); 804 Str previous = cstr("");
709 for (sz i = 0; i < array_size(node->match_cases); i++) { 805 for (sz i = 0; i < array_size(node->match.cases); i++) {
710 Node *expr = node->match_cases[i]; 806 Node *expr = node->match.cases[i];
807 expr->parent = node;
711 Str next = type_inference(a, expr, scope); 808 Str next = type_inference(a, expr, scope);
712 if (i != 0 && !str_eq(next, previous)) { 809 if (i != 0 && !str_eq(next, previous)) {
713 emit_semantic_error( 810 emit_semantic_error(
@@ -721,24 +818,27 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
721 return node->type; 818 return node->type;
722 } break; 819 } break;
723 case NODE_CASE_MATCH: { 820 case NODE_CASE_MATCH: {
724 if (node->case_expr->kind != NODE_BLOCK) { 821 if (node->case_entry.expr->kind != NODE_BLOCK) {
725 scope = typescope_alloc(a, scope); 822 scope = typescope_alloc(a, scope);
726 } 823 }
727 node->type = type_inference(a, node->case_expr, scope); 824 node->case_entry.expr->parent = node;
825 node->type = type_inference(a, node->case_entry.expr, scope);
728 return node->type; 826 return node->type;
729 } break; 827 } break;
730 case NODE_CASE_COND: { 828 case NODE_CASE_COND: {
731 if (node->case_value) { 829 node->case_entry.expr->parent = node;
732 Str cond = type_inference(a, node->case_value, scope); 830 if (node->case_entry.cond) {
831 node->case_entry.cond->parent = node;
832 Str cond = type_inference(a, node->case_entry.cond, scope);
733 if (!str_eq(cond, cstr("bool"))) { 833 if (!str_eq(cond, cstr("bool"))) {
734 emit_semantic_error(a, node, 834 emit_semantic_error(a, node,
735 cstr("non-boolean case condition")); 835 cstr("non-boolean case condition"));
736 } 836 }
737 } 837 }
738 if (node->case_expr->kind != NODE_BLOCK) { 838 if (node->case_entry.expr->kind != NODE_BLOCK) {
739 scope = typescope_alloc(a, scope); 839 scope = typescope_alloc(a, scope);
740 } 840 }
741 node->type = type_inference(a, node->case_expr, scope); 841 node->type = type_inference(a, node->case_entry.expr, scope);
742 return node->type; 842 return node->type;
743 } break; 843 } break;
744 case NODE_TRUE: 844 case NODE_TRUE:
@@ -753,14 +853,16 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
753 case NODE_NOT: 853 case NODE_NOT:
754 case NODE_AND: 854 case NODE_AND:
755 case NODE_OR: { 855 case NODE_OR: {
756 Str left = type_inference(a, node->left, scope); 856 node->binary.left->parent = node;
857 Str left = type_inference(a, node->binary.left, scope);
757 if (!str_eq(left, cstr("bool"))) { 858 if (!str_eq(left, cstr("bool"))) {
758 emit_semantic_error(a, node, 859 emit_semantic_error(a, node,
759 cstr("expected bool on logic expression")); 860 cstr("expected bool on logic expression"));
760 return cstr(""); 861 return cstr("");
761 } 862 }
762 if (node->right) { 863 if (node->binary.right) {
763 Str right = type_inference(a, node->right, scope); 864 node->binary.right->parent = node;
865 Str right = type_inference(a, node->binary.right, scope);
764 if (!str_eq(right, cstr("bool"))) { 866 if (!str_eq(right, cstr("bool"))) {
765 emit_semantic_error( 867 emit_semantic_error(
766 a, node, cstr("expected bool on logic expression")); 868 a, node, cstr("expected bool on logic expression"));
@@ -776,8 +878,10 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
776 case NODE_GT: 878 case NODE_GT:
777 case NODE_LE: 879 case NODE_LE:
778 case NODE_GE: { 880 case NODE_GE: {
779 Str left = type_inference(a, node->left, scope); 881 node->binary.left->parent = node;
780 Str right = type_inference(a, node->right, scope); 882 node->binary.right->parent = node;
883 Str left = type_inference(a, node->binary.left, scope);
884 Str right = type_inference(a, node->binary.right, scope);
781 if (!str_eq(left, right)) { 885 if (!str_eq(left, right)) {
782 emit_semantic_error( 886 emit_semantic_error(
783 a, node, cstr("mismatched types on binary expression")); 887 a, node, cstr("mismatched types on binary expression"));
@@ -787,7 +891,8 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
787 return node->type; 891 return node->type;
788 } break; 892 } break;
789 case NODE_BITNOT: { 893 case NODE_BITNOT: {
790 Str left = type_inference(a, node->left, scope); 894 node->binary.left->parent = node;
895 Str left = type_inference(a, node->binary.left, scope);
791 if (!strset_lookup(&a->integer_types, left)) { 896 if (!strset_lookup(&a->integer_types, left)) {
792 emit_semantic_error( 897 emit_semantic_error(
793 a, node, cstr("non integer type on bit twiddling expr")); 898 a, node, cstr("non integer type on bit twiddling expr"));
@@ -798,10 +903,13 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
798 } break; 903 } break;
799 case NODE_BITAND: 904 case NODE_BITAND:
800 case NODE_BITOR: 905 case NODE_BITOR:
906 case NODE_BITXOR:
801 case NODE_BITLSHIFT: 907 case NODE_BITLSHIFT:
802 case NODE_BITRSHIFT: { 908 case NODE_BITRSHIFT: {
803 Str left = type_inference(a, node->left, scope); 909 node->binary.left->parent = node;
804 Str right = type_inference(a, node->right, scope); 910 node->binary.right->parent = node;
911 Str left = type_inference(a, node->binary.left, scope);
912 Str right = type_inference(a, node->binary.right, scope);
805 if (!strset_lookup(&a->integer_types, left) || 913 if (!strset_lookup(&a->integer_types, left) ||
806 !strset_lookup(&a->integer_types, right)) { 914 !strset_lookup(&a->integer_types, right)) {
807 emit_semantic_error( 915 emit_semantic_error(
@@ -816,8 +924,10 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
816 case NODE_DIV: 924 case NODE_DIV:
817 case NODE_MUL: 925 case NODE_MUL:
818 case NODE_MOD: { 926 case NODE_MOD: {
819 Str left = type_inference(a, node->left, scope); 927 node->binary.left->parent = node;
820 Str right = type_inference(a, node->right, scope); 928 node->binary.right->parent = node;
929 Str left = type_inference(a, node->binary.left, scope);
930 Str right = type_inference(a, node->binary.right, scope);
821 if (!strset_lookup(&a->numeric_types, left) || 931 if (!strset_lookup(&a->numeric_types, left) ||
822 !strset_lookup(&a->numeric_types, right)) { 932 !strset_lookup(&a->numeric_types, right)) {
823 emit_semantic_error( 933 emit_semantic_error(
@@ -833,7 +943,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
833 return node->type; 943 return node->type;
834 } break; 944 } break;
835 case NODE_NUM_UINT: { 945 case NODE_NUM_UINT: {
836 node->type = cstr("uint"); 946 node->type = cstr("int");
837 return node->type; 947 return node->type;
838 } break; 948 } break;
839 case NODE_NUM_INT: { 949 case NODE_NUM_INT: {
@@ -868,9 +978,24 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
868 a->err = true; 978 a->err = true;
869 return cstr(""); 979 return cstr("");
870 } 980 }
981
982 FindSymbolResult sym = find_symbol(scope, symbol);
983 if (!str_eq(sym.scope->name, scope->name) && sym.scope->name.size) {
984 eprintln(
985 "%s:%d:%d: error: can't capture external local symbol '%s'",
986 a->file_name, node->line, node->col, symbol);
987 a->err = true;
988 return cstr("");
989 }
990 node->unique_name = str_concat(cstr("."), symbol, a->storage);
991 node->unique_name =
992 str_concat(node->unique_name,
993 str_from_int(sym.scope->id, a->storage), a->storage);
994
871 Str type_name = type->val.name; 995 Str type_name = type->val.name;
872 if (node->kind == NODE_SYMBOL_IDX) { 996 if (node->kind == NODE_SYMBOL_IDX) {
873 Str idx_type = type_inference(a, node->arr_size, scope); 997 node->sym.arr_size->parent = node;
998 Str idx_type = type_inference(a, node->sym.arr_size, scope);
874 if (!strset_lookup(&a->integer_types, idx_type)) { 999 if (!strset_lookup(&a->integer_types, idx_type)) {
875 emit_semantic_error( 1000 emit_semantic_error(
876 a, node, cstr("can't resolve non integer index")); 1001 a, node, cstr("can't resolve non integer index"));
@@ -884,7 +1009,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
884 1009
885 FindEnumResult e = find_enum(scope, type_name); 1010 FindEnumResult e = find_enum(scope, type_name);
886 if (e.map && str_eq(symbol, type_name)) { 1011 if (e.map && str_eq(symbol, type_name)) {
887 if (!node->next) { 1012 if (!node->sym.next) {
888 eprintln( 1013 eprintln(
889 "%s:%d:%d: error: unspecified enum field for symbol " 1014 "%s:%d:%d: error: unspecified enum field for symbol "
890 "'%s'", 1015 "'%s'",
@@ -894,19 +1019,21 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
894 } 1019 }
895 // Check if there is a next and it matches the enum field. 1020 // Check if there is a next and it matches the enum field.
896 Str field = str_concat(type_name, cstr("."), a->storage); 1021 Str field = str_concat(type_name, cstr("."), a->storage);
897 field = str_concat(field, node->next->value.str, a->storage); 1022 field =
1023 str_concat(field, node->sym.next->value.str, a->storage);
898 if (!enummap_lookup(&e.scope->enums, field)) { 1024 if (!enummap_lookup(&e.scope->enums, field)) {
899 eprintln( 1025 eprintln(
900 "%s:%d:%d: error: unknown enum field for " 1026 "%s:%d:%d: error: unknown enum field for "
901 "'%s': %s", 1027 "'%s': %s",
902 a->file_name, node->line, node->col, symbol, 1028 a->file_name, node->line, node->col, symbol,
903 node->next->value.str); 1029 node->sym.next->value.str);
904 a->err = true; 1030 a->err = true;
905 return cstr(""); 1031 return cstr("");
906 } 1032 }
907 node->next->type = type_name; 1033
1034 node->sym.next->type = type_name;
908 node->type = type_name; 1035 node->type = type_name;
909 return node->next->type; 1036 return node->sym.next->type;
910 } 1037 }
911 1038
912 FindStructResult s = find_struct(scope, type_name); 1039 FindStructResult s = find_struct(scope, type_name);
@@ -919,11 +1046,11 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
919 a->err = true; 1046 a->err = true;
920 return cstr(""); 1047 return cstr("");
921 } else { 1048 } else {
922 if (node->next) { 1049 if (node->sym.next) {
923 Str chain = type_name; 1050 Str chain = type_name;
924 Node *next = node; 1051 Node *next = node;
925 while (next->next) { 1052 while (next->sym.next) {
926 next = next->next; 1053 next = next->sym.next;
927 chain = str_concat(chain, cstr("."), a->storage); 1054 chain = str_concat(chain, cstr("."), a->storage);
928 chain = 1055 chain =
929 str_concat(chain, next->value.str, a->storage); 1056 str_concat(chain, next->value.str, a->storage);
@@ -939,8 +1066,9 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
939 } 1066 }
940 Str field_type = field->val.type; 1067 Str field_type = field->val.type;
941 if (next->kind == NODE_SYMBOL_IDX) { 1068 if (next->kind == NODE_SYMBOL_IDX) {
1069 node->sym.arr_size->parent = node;
942 Str idx_type = 1070 Str idx_type =
943 type_inference(a, next->arr_size, scope); 1071 type_inference(a, next->sym.arr_size, scope);
944 if (!strset_lookup(&a->integer_types, idx_type)) { 1072 if (!strset_lookup(&a->integer_types, idx_type)) {
945 emit_semantic_error( 1073 emit_semantic_error(
946 a, next, 1074 a, next,
@@ -971,6 +1099,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
971 StrSet *set = NULL; 1099 StrSet *set = NULL;
972 for (sz i = 0; i < array_size(node->elements); i++) { 1100 for (sz i = 0; i < array_size(node->elements); i++) {
973 Node *next = node->elements[i]; 1101 Node *next = node->elements[i];
1102 next->parent = node;
974 Str field_name = str_concat(name, cstr("."), a->storage); 1103 Str field_name = str_concat(name, cstr("."), a->storage);
975 field_name = 1104 field_name =
976 str_concat(field_name, next->value.str, a->storage); 1105 str_concat(field_name, next->value.str, a->storage);
@@ -1000,10 +1129,17 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1000 a->err = true; 1129 a->err = true;
1001 return cstr(""); 1130 return cstr("");
1002 } 1131 }
1132 FindSymbolResult sym = find_symbol(scope, symbol);
1133 node->unique_name = str_concat(cstr("."), symbol, a->storage);
1134 node->unique_name =
1135 str_concat(node->unique_name,
1136 str_from_int(sym.scope->id, a->storage), a->storage);
1137
1003 // Check that actual parameters typecheck 1138 // Check that actual parameters typecheck
1004 Str args = cstr(""); 1139 Str args = cstr("");
1005 for (sz i = 0; i < array_size(node->elements); i++) { 1140 for (sz i = 0; i < array_size(node->elements); i++) {
1006 Node *expr = node->elements[i]; 1141 Node *expr = node->elements[i];
1142 expr->parent = node;
1007 Str type = type_inference(a, expr, scope); 1143 Str type = type_inference(a, expr, scope);
1008 args = str_concat(args, type, a->storage); 1144 args = str_concat(args, type, a->storage);
1009 if (i != array_size(node->elements) - 1) { 1145 if (i != array_size(node->elements) - 1) {
@@ -1029,15 +1165,27 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1029 Str type; 1165 Str type;
1030 for (sz i = 0; i < array_size(node->elements); i++) { 1166 for (sz i = 0; i < array_size(node->elements); i++) {
1031 Node *expr = node->elements[i]; 1167 Node *expr = node->elements[i];
1168 expr->parent = node;
1032 type = type_inference(a, expr, scope); 1169 type = type_inference(a, expr, scope);
1170 if (str_has_prefix(type, cstr("ret:")) ||
1171 str_has_prefix(type, cstr("flow:"))) {
1172 break;
1173 }
1033 } 1174 }
1034 node->type = type; 1175 node->type = type;
1035 return node->type; 1176 return node->type;
1036 } break; 1177 } break;
1037 case NODE_RETURN: { 1178 case NODE_RETURN: {
1038 Str ret_type = cstr(""); 1179 if (!scope->name.size) {
1180 emit_semantic_error(
1181 a, node, cstr("return statement outside a function"));
1182 a->err = true;
1183 return cstr("");
1184 }
1185 Str ret_type = cstr("ret:");
1039 for (sz i = 0; i < array_size(node->elements); i++) { 1186 for (sz i = 0; i < array_size(node->elements); i++) {
1040 Node *expr = node->elements[i]; 1187 Node *expr = node->elements[i];
1188 expr->parent = node;
1041 Str type = type_inference(a, expr, scope); 1189 Str type = type_inference(a, expr, scope);
1042 ret_type = str_concat(ret_type, type, a->storage); 1190 ret_type = str_concat(ret_type, type, a->storage);
1043 if (i != array_size(node->elements) - 1) { 1191 if (i != array_size(node->elements) - 1) {
@@ -1050,40 +1198,68 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1050 node->type = ret_type; 1198 node->type = ret_type;
1051 return node->type; 1199 return node->type;
1052 } break; 1200 } break;
1201 case NODE_CONTINUE:
1202 case NODE_BREAK: {
1203 // Check if we are inside a loop.
1204 Node *parent = node->parent;
1205 bool inside_loop = false;
1206 while (parent != NULL) {
1207 if (parent->kind == NODE_WHILE) {
1208 inside_loop = true;
1209 break;
1210 }
1211 parent = parent->parent;
1212 }
1213 if (!inside_loop) {
1214 eprintln(
1215 "%s:%d:%d: error: control flow statement outside a loop",
1216 a->file_name, node->line, node->col);
1217 a->err = true;
1218 return cstr("");
1219 }
1220 node->type = cstr("flow:");
1221 return node->type;
1222 } break;
1053 case NODE_FUN: { 1223 case NODE_FUN: {
1054 node->type = cstr("nil"); 1224 node->type = cstr("nil");
1055 Scope *prev_scope = scope; 1225 Scope *prev_scope = scope;
1056 scope = typescope_alloc(a, scope); 1226 scope = typescope_alloc(a, scope);
1057 Str param_type = cstr(""); 1227 Str param_type = cstr("");
1058 for (sz i = 0; i < array_size(node->func_params); i++) { 1228 for (sz i = 0; i < array_size(node->func.params); i++) {
1059 Node *param = node->func_params[i]; 1229 Node *param = node->func.params[i];
1060 Str symbol = param->param_name->value.str; 1230 param->parent = node;
1061 Str type = param->param_type->value.str; 1231 Str symbol = param->param.name->value.str;
1062 if (param->param_type->is_ptr) { 1232 Str type = param->param.type->value.str;
1233 if (param->param.type->is_ptr) {
1063 type = str_concat(cstr("@"), type, a->storage); 1234 type = str_concat(cstr("@"), type, a->storage);
1064 } 1235 }
1065 if (param->param_type->kind == NODE_ARR_TYPE) { 1236 if (param->param.type->kind == NODE_ARR_TYPE) {
1066 type = str_concat(cstr("@"), type, a->storage); 1237 type = str_concat(cstr("@"), type, a->storage);
1067 } 1238 }
1068 param->param_name->type = 1239 param->param.name->type =
1069 type_inference(a, param->param_type, scope); 1240 type_inference(a, param->param.type, scope);
1070 param->type = type; 1241 param->type = type;
1071 symmap_insert(&scope->symbols, symbol, 1242 symmap_insert(&scope->symbols, symbol,
1072 (Symbol){.name = type, .kind = SYM_PARAM}, 1243 (Symbol){.name = type, .kind = SYM_PARAM},
1073 a->storage); 1244 a->storage);
1074 param_type = str_concat(param_type, type, a->storage); 1245 param_type = str_concat(param_type, type, a->storage);
1075 if (i != array_size(node->func_params) - 1) { 1246 if (i != array_size(node->func.params) - 1) {
1076 param_type = str_concat(param_type, cstr(","), a->storage); 1247 param_type = str_concat(param_type, cstr(","), a->storage);
1077 } 1248 }
1249 symbol = str_concat(cstr("."), symbol, a->storage);
1250 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
1251 a->storage);
1252 param->unique_name = symbol;
1078 } 1253 }
1079 if (!param_type.size) { 1254 if (!param_type.size) {
1080 param_type = cstr("nil"); 1255 param_type = cstr("nil");
1081 } 1256 }
1082 node->fun_params = param_type; 1257 node->type_params = param_type;
1083 1258
1084 Str ret_type = cstr(""); 1259 Str ret_type = cstr("");
1085 for (sz i = 0; i < array_size(node->func_ret); i++) { 1260 for (sz i = 0; i < array_size(node->func.ret); i++) {
1086 Node *expr = node->func_ret[i]; 1261 Node *expr = node->func.ret[i];
1262 expr->parent = node;
1087 Str type = type_inference(a, expr, scope); 1263 Str type = type_inference(a, expr, scope);
1088 if (expr->is_ptr) { 1264 if (expr->is_ptr) {
1089 type = str_concat(cstr("@"), type, a->storage); 1265 type = str_concat(cstr("@"), type, a->storage);
@@ -1092,28 +1268,28 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1092 type = str_concat(cstr("@"), type, a->storage); 1268 type = str_concat(cstr("@"), type, a->storage);
1093 } 1269 }
1094 ret_type = str_concat(ret_type, type, a->storage); 1270 ret_type = str_concat(ret_type, type, a->storage);
1095 if (i != array_size(node->func_ret) - 1) { 1271 if (i != array_size(node->func.ret) - 1) {
1096 ret_type = str_concat(ret_type, cstr(","), a->storage); 1272 ret_type = str_concat(ret_type, cstr(","), a->storage);
1097 } 1273 }
1098 } 1274 }
1099 if (!ret_type.size) { 1275 if (!ret_type.size) {
1100 ret_type = cstr("nil"); 1276 ret_type = cstr("nil");
1101 } 1277 }
1102 node->fun_return = ret_type; 1278 node->type_returns = ret_type;
1103 1279
1104 Str symbol = node->func_name->value.str; 1280 Str symbol = node->func.name->value.str;
1105 if (prev_scope->parent != NULL) { 1281 if (prev_scope->parent != NULL) {
1106 if (symmap_lookup(&prev_scope->symbols, symbol)) { 1282 if (symmap_lookup(&prev_scope->symbols, symbol)) {
1107 eprintln( 1283 eprintln(
1108 "%s:%d:%d: error: function '%s' already defined in " 1284 "%s:%d:%d: error: function '%s' already defined in "
1109 "current " 1285 "current "
1110 "scope ", 1286 "scope ",
1111 a->file_name, node->var_name->line, node->var_name->col, 1287 a->file_name, node->var.name->line, node->var.name->col,
1112 symbol); 1288 symbol);
1113 a->err = true; 1289 a->err = true;
1114 return cstr(""); 1290 return cstr("");
1115 } 1291 }
1116 symmap_insert(&scope->symbols, symbol, 1292 symmap_insert(&prev_scope->symbols, symbol,
1117 (Symbol){.name = symbol, .kind = SYM_FUN}, 1293 (Symbol){.name = symbol, .kind = SYM_FUN},
1118 a->storage); 1294 a->storage);
1119 } 1295 }
@@ -1123,41 +1299,50 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1123 .param_type = param_type, 1299 .param_type = param_type,
1124 .return_type = ret_type}, 1300 .return_type = ret_type},
1125 a->storage); 1301 a->storage);
1302 symbol = str_concat(cstr("."), symbol, a->storage);
1303 symbol = str_concat(
1304 symbol, str_from_int(prev_scope->id, a->storage), a->storage);
1305 node->unique_name = symbol;
1126 1306
1127 if (node->func_body->kind == NODE_BLOCK) { 1307 if (node->func.body->kind == NODE_BLOCK) {
1128 Str type; 1308 Str type;
1129 for (sz i = 0; i < array_size(node->func_body->elements); i++) { 1309 for (sz i = 0; i < array_size(node->func.body->elements); i++) {
1130 Node *expr = node->func_body->elements[i]; 1310 Node *expr = node->func.body->elements[i];
1311 expr->parent = node;
1312 // TODO: block early return.
1131 type = type_inference(a, expr, scope); 1313 type = type_inference(a, expr, scope);
1132 } 1314 }
1133 if (!type.size) { 1315 if (!type.size) {
1134 type = cstr("nil"); 1316 type = cstr("nil");
1135 } 1317 }
1136 node->func_body->type = type; 1318 node->func.body->type = type;
1137 } else { 1319 } else {
1138 type_inference(a, node->func_body, scope); 1320 node->func.body->parent = node;
1321 type_inference(a, node->func.body, scope);
1139 } 1322 }
1140 1323
1141 // Ensure main body return matches the prototype. 1324 // Ensure main body return matches the prototype.
1142 if (!str_eq(node->func_body->type, ret_type)) { 1325 Str type = str_remove_prefix(node->func.body->type, cstr("ret:"));
1326 node->func.body->type = type;
1327 if (!str_eq(type, ret_type)) {
1143 eprintln( 1328 eprintln(
1144 "%s:%d:%d: error: mismatched return type %s, expected %s", 1329 "%s:%d:%d: error: mismatched return type %s, expected %s",
1145 a->file_name, node->line, node->col, node->func_body->type, 1330 a->file_name, node->line, node->col, type, ret_type);
1146 ret_type);
1147 a->err = true; 1331 a->err = true;
1148 } 1332 }
1149 1333
1150 // Ensure ALL return statements match the function prototype. 1334 // Ensure ALL return statements match the function prototype.
1151 typecheck_returns(a, node->func_body, ret_type); 1335 typecheck_returns(a, node->func.body, ret_type);
1152 1336
1153 // TODO: should return statements be allowed on let blocks? 1337 // TODO: should return statements be allowed on let blocks?
1154 return node->type; 1338 return node->type;
1155 } break; 1339 } break;
1156 default: { 1340 default: {
1157 emit_semantic_error(a, node, 1341 eprintln(
1158 cstr("type inference not implemented for this " 1342 "%s:%d:%d: error: type inference not implemented for node "
1159 "kind of expression")); 1343 "type: %s",
1160 println("KIND: %s", node_str[node->kind]); 1344 a->file_name, node->line, node->col, node_str[node->kind]);
1345 a->err = true;
1161 } break; 1346 } break;
1162 } 1347 }
1163 return cstr(""); 1348 return cstr("");
@@ -1218,16 +1403,59 @@ symbolic_analysis(Analyzer *a, Parser *parser) {
1218 for (sz i = 0; i < array_size(parser->nodes); i++) { 1403 for (sz i = 0; i < array_size(parser->nodes); i++) {
1219 Node *root = parser->nodes[i]; 1404 Node *root = parser->nodes[i];
1220 if (root->kind == NODE_FUN) { 1405 if (root->kind == NODE_FUN) {
1221 Str symbol = root->func_name->value.str; 1406 Str symbol = root->func.name->value.str;
1222 if (symmap_lookup(&scope->symbols, symbol)) { 1407 if (symmap_lookup(&scope->symbols, symbol)) {
1223 eprintln( 1408 eprintln(
1224 "%s:%d:%d: error: function '%s' already defined in " 1409 "%s:%d:%d: error: function '%s' already defined in "
1225 "current " 1410 "current "
1226 "scope ", 1411 "scope ",
1227 a->file_name, root->var_name->line, root->var_name->col, 1412 a->file_name, root->var.name->line, root->var.name->col,
1228 symbol); 1413 symbol);
1229 a->err = true; 1414 a->err = true;
1230 } 1415 }
1416 Str param_type = cstr("");
1417 for (sz i = 0; i < array_size(root->func.params); i++) {
1418 Node *param = root->func.params[i];
1419 Str type = param->param.type->value.str;
1420 if (param->param.type->is_ptr) {
1421 type = str_concat(cstr("@"), type, a->storage);
1422 }
1423 if (param->param.type->kind == NODE_ARR_TYPE) {
1424 type = str_concat(cstr("@"), type, a->storage);
1425 }
1426 param_type = str_concat(param_type, type, a->storage);
1427 if (i != array_size(root->func.params) - 1) {
1428 param_type = str_concat(param_type, cstr(","), a->storage);
1429 }
1430 }
1431 if (!param_type.size) {
1432 param_type = cstr("nil");
1433 }
1434 root->type_params = param_type;
1435
1436 Str ret_type = cstr("");
1437 for (sz i = 0; i < array_size(root->func.ret); i++) {
1438 Node *expr = root->func.ret[i];
1439 Str type = expr->value.str;
1440 if (expr->is_ptr) {
1441 type = str_concat(cstr("@"), type, a->storage);
1442 }
1443 if (expr->kind == NODE_ARR_TYPE) {
1444 type = str_concat(cstr("@"), type, a->storage);
1445 }
1446 ret_type = str_concat(ret_type, type, a->storage);
1447 if (i != array_size(root->func.ret) - 1) {
1448 ret_type = str_concat(ret_type, cstr(","), a->storage);
1449 }
1450 }
1451 if (!ret_type.size) {
1452 ret_type = cstr("nil");
1453 }
1454 funmap_insert(&scope->funcs, symbol,
1455 (Fun){.name = symbol,
1456 .param_type = param_type,
1457 .return_type = ret_type},
1458 a->storage);
1231 symmap_insert(&scope->symbols, symbol, 1459 symmap_insert(&scope->symbols, symbol,
1232 (Symbol){.name = symbol, .kind = SYM_FUN}, 1460 (Symbol){.name = symbol, .kind = SYM_FUN},
1233 a->storage); 1461 a->storage);