aboutsummaryrefslogtreecommitdiffstats
path: root/src/semantic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/semantic.c')
-rw-r--r--src/semantic.c868
1 files changed, 578 insertions, 290 deletions
diff --git a/src/semantic.c b/src/semantic.c
index 9b119df..2e2735f 100644
--- a/src/semantic.c
+++ b/src/semantic.c
@@ -39,6 +39,10 @@ typedef struct Fun {
39 Str name; 39 Str name;
40 Str param_type; 40 Str param_type;
41 Str return_type; 41 Str return_type;
42 Str *param_types;
43 Str *return_types;
44 sz param_arity;
45 sz return_arity;
42} Fun; 46} Fun;
43 47
44typedef struct Enum { 48typedef struct Enum {
@@ -62,6 +66,7 @@ typedef struct Scope {
62 sz depth; 66 sz depth;
63 Str name; 67 Str name;
64 SymbolMap *symbols; 68 SymbolMap *symbols;
69 StrSet *types;
65 FunMap *funcs; 70 FunMap *funcs;
66 EnumMap *enums; 71 EnumMap *enums;
67 StructMap *structs; 72 StructMap *structs;
@@ -75,6 +80,7 @@ typedef struct Analyzer {
75 Scope **scopes; 80 Scope **scopes;
76 StrSet *numeric_types; 81 StrSet *numeric_types;
77 StrSet *integer_types; 82 StrSet *integer_types;
83 StrSet *float_types;
78 bool err; 84 bool err;
79} Analyzer; 85} Analyzer;
80 86
@@ -82,16 +88,19 @@ Scope *
82typescope_alloc(Analyzer *a, Scope *parent) { 88typescope_alloc(Analyzer *a, Scope *parent) {
83 Scope *scope = arena_calloc(sizeof(Scope), a->storage); 89 Scope *scope = arena_calloc(sizeof(Scope), a->storage);
84 scope->parent = parent; 90 scope->parent = parent;
91 if (parent != NULL) {
92 scope->name = parent->name;
93 }
85 scope->id = a->typescope_gen++; 94 scope->id = a->typescope_gen++;
86 scope->depth = parent == NULL ? 0 : parent->depth + 1; 95 scope->depth = parent == NULL ? 0 : parent->depth + 1;
87 array_push(a->scopes, scope, a->storage); 96 array_push(a->scopes, scope, a->storage);
88 return scope; 97 return scope;
89} 98}
90 99
91SymbolMap * 100StrSet *
92find_type(Scope *scope, Str type) { 101find_type(Scope *scope, Str type) {
93 while (scope != NULL) { 102 while (scope != NULL) {
94 SymbolMap *val = symmap_lookup(&scope->symbols, type); 103 StrSet *val = strset_lookup(&scope->types, type);
95 if (val != NULL) { 104 if (val != NULL) {
96 return val; 105 return val;
97 } 106 }
@@ -276,7 +285,7 @@ Str type_inference(Analyzer *a, Node *node, Scope *scope);
276 285
277void 286void
278typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { 287typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
279 if (node->field_type->kind == NODE_COMPOUND_TYPE) { 288 if (node->field.type->kind == NODE_COMPOUND_TYPE) {
280 Str field_name = str_concat(symbol, cstr("."), a->storage); 289 Str field_name = str_concat(symbol, cstr("."), a->storage);
281 field_name = str_concat(field_name, node->value.str, a->storage); 290 field_name = str_concat(field_name, node->value.str, a->storage);
282 if (structmap_lookup(&scope->structs, field_name)) { 291 if (structmap_lookup(&scope->structs, field_name)) {
@@ -285,8 +294,8 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
285 a->err = true; 294 a->err = true;
286 } 295 }
287 Str type = cstr("\\{ "); 296 Str type = cstr("\\{ ");
288 for (sz i = 0; i < array_size(node->field_type->elements); i++) { 297 for (sz i = 0; i < array_size(node->field.type->elements); i++) {
289 Node *field = node->field_type->elements[i]; 298 Node *field = node->field.type->elements[i];
290 typecheck_field(a, field, scope, field_name); 299 typecheck_field(a, field, scope, field_name);
291 type = str_concat(type, field->type, a->storage); 300 type = str_concat(type, field->type, a->storage);
292 type = str_concat(type, cstr(" "), a->storage); 301 type = str_concat(type, cstr(" "), a->storage);
@@ -296,25 +305,19 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
296 } else { 305 } else {
297 Str field_name = str_concat(symbol, cstr("."), a->storage); 306 Str field_name = str_concat(symbol, cstr("."), a->storage);
298 field_name = str_concat(field_name, node->value.str, a->storage); 307 field_name = str_concat(field_name, node->value.str, a->storage);
299 Str field_type = node->field_type->value.str; 308 Str field_type = node->field.type->value.str;
300 if (!find_type(scope, field_type)) { 309 if (!find_type(scope, field_type)) {
301 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name, 310 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
302 node->field_type->line, node->field_type->col, field_type); 311 node->field.type->line, node->field.type->col, field_type);
303 a->err = true; 312 a->err = true;
304 } 313 }
305 if (node->field_type->is_ptr) {
306 field_type = str_concat(cstr("@"), field_type, a->storage);
307 }
308 if (node->field_type->kind == NODE_ARR_TYPE) {
309 field_type = str_concat(cstr("@"), field_type, a->storage);
310 }
311 if (structmap_lookup(&scope->structs, field_name)) { 314 if (structmap_lookup(&scope->structs, field_name)) {
312 eprintln("%s:%d:%d: error: struct field '%s' already exists", 315 eprintln("%s:%d:%d: error: struct field '%s' already exists",
313 a->file_name, node->line, node->col, field_name); 316 a->file_name, node->line, node->col, field_name);
314 a->err = true; 317 a->err = true;
315 } 318 }
316 if (node->field_val) { 319 if (node->field.val) {
317 Str type = type_inference(a, node->field_val, scope); 320 Str type = type_inference(a, node->field.val, scope);
318 if (!str_eq(type, field_type)) { 321 if (!str_eq(type, field_type)) {
319 eprintln( 322 eprintln(
320 "%s:%d:%d: error: mismatched types in struct " 323 "%s:%d:%d: error: mismatched types in struct "
@@ -329,7 +332,7 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
329 (Struct){ 332 (Struct){
330 .name = field_name, 333 .name = field_name,
331 .type = field_type, 334 .type = field_type,
332 .val = node->field_val, 335 .val = node->field.val,
333 }, 336 },
334 a->storage); 337 a->storage);
335 symmap_insert(&scope->symbols, field_name, 338 symmap_insert(&scope->symbols, field_name,
@@ -341,10 +344,10 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
341 344
342void 345void
343typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { 346typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
344 if (node->field_val->kind == NODE_COMPOUND_TYPE) { 347 if (node->field.val->kind == NODE_COMPOUND_TYPE) {
345 Str type = cstr("\\{ "); 348 Str type = cstr("\\{ ");
346 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++) {
347 Node *field = node->field_val->elements[i]; 350 Node *field = node->field.val->elements[i];
348 Str field_name = str_concat(symbol, cstr("."), a->storage); 351 Str field_name = str_concat(symbol, cstr("."), a->storage);
349 field_name = str_concat(field_name, field->value.str, a->storage); 352 field_name = str_concat(field_name, field->value.str, a->storage);
350 typecheck_lit_field(a, field, scope, field_name); 353 typecheck_lit_field(a, field, scope, field_name);
@@ -362,7 +365,7 @@ typecheck_lit_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
362 return; 365 return;
363 } 366 }
364 Str field_type = s->val.type; 367 Str field_type = s->val.type;
365 Str type = type_inference(a, node->field_val, scope); 368 Str type = type_inference(a, node->field.val, scope);
366 if (!str_eq(type, field_type)) { 369 if (!str_eq(type, field_type)) {
367 eprintln( 370 eprintln(
368 "%s:%d:%d: error: mismatched types in struct " 371 "%s:%d:%d: error: mismatched types in struct "
@@ -384,17 +387,18 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
384 switch (node->kind) { 387 switch (node->kind) {
385 case NODE_COND: 388 case NODE_COND:
386 case NODE_MATCH: { 389 case NODE_MATCH: {
387 for (sz i = 0; i < array_size(node->match_cases); i++) { 390 for (sz i = 0; i < array_size(node->match.cases); i++) {
388 Node *next = node->match_cases[i]; 391 Node *next = node->match.cases[i];
389 typecheck_returns(a, next, expected); 392 typecheck_returns(a, next, expected);
390 } 393 }
391 } break; 394 } break;
392 case NODE_RETURN: { 395 case NODE_RETURN: {
393 bool err = !str_eq(node->type, expected); 396 Str type = str_remove_prefix(node->type, cstr("ret:"));
397 bool err = !str_eq(type, expected);
394 if (err) { 398 if (err) {
395 eprintln( 399 eprintln(
396 "%s:%d:%d: error: mismatched return type %s, expected %s", 400 "%s:%d:%d: error: mismatched return type %s, expected %s",
397 a->file_name, node->line, node->col, node->type, expected); 401 a->file_name, node->line, node->col, type, expected);
398 a->err = true; 402 a->err = true;
399 } 403 }
400 } break; 404 } break;
@@ -405,17 +409,17 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
405 } 409 }
406 } break; 410 } break;
407 case NODE_IF: { 411 case NODE_IF: {
408 if (node->cond_expr) { 412 if (node->ifelse.expr_true) {
409 typecheck_returns(a, node->cond_expr, expected); 413 typecheck_returns(a, node->ifelse.expr_true, expected);
410 } 414 }
411 if (node->cond_else) { 415 if (node->ifelse.expr_else) {
412 typecheck_returns(a, node->cond_else, expected); 416 typecheck_returns(a, node->ifelse.expr_else, expected);
413 } 417 }
414 } break; 418 } break;
415 case NODE_SET: 419 case NODE_SET:
416 case NODE_LET: { 420 case NODE_LET: {
417 if (node->var_val) { 421 if (node->var.val) {
418 typecheck_returns(a, node->var_val, expected); 422 typecheck_returns(a, node->var.val, expected);
419 } 423 }
420 } break; 424 } break;
421 case NODE_ADD: 425 case NODE_ADD:
@@ -435,13 +439,14 @@ typecheck_returns(Analyzer *a, Node *node, Str expected) {
435 case NODE_BITNOT: 439 case NODE_BITNOT:
436 case NODE_BITAND: 440 case NODE_BITAND:
437 case NODE_BITOR: 441 case NODE_BITOR:
442 case NODE_BITXOR:
438 case NODE_BITLSHIFT: 443 case NODE_BITLSHIFT:
439 case NODE_BITRSHIFT: { 444 case NODE_BITRSHIFT: {
440 if (node->left) { 445 if (node->binary.left) {
441 typecheck_returns(a, node->left, expected); 446 typecheck_returns(a, node->binary.left, expected);
442 } 447 }
443 if (node->right) { 448 if (node->binary.right) {
444 typecheck_returns(a, node->right, expected); 449 typecheck_returns(a, node->binary.right, expected);
445 } 450 }
446 } break; 451 } break;
447 default: break; 452 default: break;
@@ -452,66 +457,65 @@ Str
452type_inference(Analyzer *a, Node *node, Scope *scope) { 457type_inference(Analyzer *a, Node *node, Scope *scope) {
453 assert(a); 458 assert(a);
454 assert(scope); 459 assert(scope);
455 if (!node) { 460 if (!node || a->err) {
456 return cstr(""); 461 return cstr("");
457 } 462 }
458 // NOTE: For now we are not going to do implicit numeric conversions.
459 switch (node->kind) { 463 switch (node->kind) {
460 case NODE_LET: { 464 case NODE_LET: {
461 node->type = cstr("nil"); 465 node->type = cstr("nil");
462 Str symbol = node->var_name->value.str; 466 Str symbol = node->var.name->value.str;
463 if (symmap_lookup(&scope->symbols, symbol)) { 467 if (symmap_lookup(&scope->symbols, symbol)) {
464 eprintln( 468 eprintln(
465 "%s:%d:%d: error: symbol '%s' already exists in current " 469 "%s:%d:%d: error: symbol '%s' already exists in current "
466 "scope ", 470 "scope ",
467 a->file_name, node->var_name->line, node->var_name->col, 471 a->file_name, node->var.name->line, node->var.name->col,
468 symbol); 472 symbol);
469 a->err = true; 473 a->err = true;
470 return cstr(""); 474 return cstr("");
471 } 475 }
472 if (node->var_type) { 476 if (node->var.type) {
473 Str type_name = node->var_type->value.str; 477 Str type_name = type_inference(a, node->var.type, scope);
474 SymbolMap *type = find_type(scope, type_name); 478 if (node->var.val) {
475 if (type == NULL) { 479 Str type = type_inference(a, node->var.val, scope);
476 eprintln("%s:%d:%d: error: unknown type '%s'", a->file_name,
477 node->var_type->line, node->var_type->col,
478 type_name);
479 a->err = true;
480 return cstr("");
481 }
482 if (node->var_type->is_ptr) {
483 type_name = str_concat(cstr("@"), type_name, a->storage);
484 }
485 if (node->var_type->kind == NODE_ARR_TYPE) {
486 type_name = str_concat(cstr("@"), type_name, a->storage);
487 // TODO: typecheck size
488 // TODO: register array in scope
489 }
490 if (node->var_val) {
491 Str type = type_inference(a, node->var_val, scope);
492 if (!type.size) { 480 if (!type.size) {
493 eprintln( 481 eprintln(
494 "%s:%d:%d: error: can't bind `nil` to variable " 482 "%s:%d:%d: error: can't bind `nil` to variable "
495 "'%s'", 483 "'%s'",
496 a->file_name, node->var_type->line, 484 a->file_name, node->var.type->line,
497 node->var_type->col, symbol); 485 node->var.type->col, symbol);
498 a->err = true; 486 a->err = true;
499 return cstr(""); 487 return cstr("");
500 } 488 }
501 // TODO: Consider compatible types.
502 if (!str_eq(type, type_name)) { 489 if (!str_eq(type, type_name)) {
503 // Special case, enums can be treated as ints. 490 // TODO: ensure that we only assign compatible arrays,
504 FindEnumResult res = find_enum(scope, type_name); 491 // for pointers this was ok but not anymore.
505 if (!(res.map && str_eq(type, cstr("int")))) { 492 Str type_a = type;
506 eprintln( 493 Str type_b = type_name;
507 "%s:%d:%d: error: type mismatch, trying to " 494 if (str_has_prefix(type_a, cstr("@")) ||
508 "assing " 495 str_has_prefix(type_a, cstr("["))) {
509 "%s" 496 type_a = cstr("Ptr");
510 " to a variable of type %s", 497 }
511 a->file_name, node->var_type->line, 498 if (str_has_prefix(type_b, cstr("@")) ||
512 node->var_type->col, type, type_name); 499 str_has_prefix(type_b, cstr("["))) {
513 a->err = true; 500 type_b = cstr("Ptr");
514 return cstr(""); 501 }
502 if (!(strset_lookup(&a->integer_types, type_a) &&
503 strset_lookup(&a->integer_types, type_b)) ||
504 !(strset_lookup(&a->numeric_types, type_a) &&
505 strset_lookup(&a->numeric_types, type_b))) {
506 // Special case, enums can be treated as ints.
507 FindEnumResult res = find_enum(scope, type_name);
508 if (!(res.map && str_eq(type, cstr("Int")))) {
509 eprintln(
510 "%s:%d:%d: error: type mismatch, trying to "
511 "assing "
512 "%s"
513 " to a variable of type %s",
514 a->file_name, node->var.type->line,
515 node->var.type->col, type, type_name);
516 a->err = true;
517 return cstr("");
518 }
515 } 519 }
516 } 520 }
517 } 521 }
@@ -521,17 +525,28 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
521 .kind = SYM_VAR, 525 .kind = SYM_VAR,
522 }, 526 },
523 a->storage); 527 a->storage);
528 node->var.name->type = type_name;
529 symbol = str_concat(cstr("."), symbol, a->storage);
530 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
531 a->storage);
532 node->unique_name = symbol;
524 return node->type; 533 return node->type;
525 } 534 }
526 535
527 // We don't know the type for this symbol, perform inference. 536 // We don't know the type for this symbol, perform inference.
528 Str type = type_inference(a, node->var_val, scope); 537 Str type = type_inference(a, node->var.val, scope);
529 if (type.size) { 538 if (!type.size || str_eq(type, cstr("nil")) ||
530 symmap_insert(&scope->symbols, symbol, 539 str_has_prefix(type, cstr("ret:"))) {
531 (Symbol){.name = type, .kind = SYM_VAR}, 540 eprintln(
532 a->storage); 541 "%s:%d:%d: error: can't bind `nil` to variable "
533 node->var_name->type = type; 542 "'%s'",
543 a->file_name, node->line, node->col, symbol);
544 a->err = true;
545 return cstr("");
534 } 546 }
547 symmap_insert(&scope->symbols, symbol,
548 (Symbol){.name = type, .kind = SYM_VAR}, a->storage);
549 node->var.name->type = type;
535 symbol = str_concat(cstr("."), symbol, a->storage); 550 symbol = str_concat(cstr("."), symbol, a->storage);
536 symbol = str_concat(symbol, str_from_int(scope->id, a->storage), 551 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
537 a->storage); 552 a->storage);
@@ -539,23 +554,38 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
539 return node->type; 554 return node->type;
540 } break; 555 } break;
541 case NODE_SET: { 556 case NODE_SET: {
542 Str name = type_inference(a, node->var_name, scope); 557 Str name = type_inference(a, node->var.name, scope);
543 Str val = type_inference(a, node->var_val, scope); 558 Str val = type_inference(a, node->var.val, scope);
559 if (str_has_prefix(name, cstr("@")) ||
560 str_has_prefix(name, cstr("["))) {
561 name = cstr("Ptr");
562 }
563 if (str_has_prefix(val, cstr("@")) ||
564 str_has_prefix(val, cstr("["))) {
565 val = cstr("Ptr");
566 }
544 if (!str_eq(name, val)) { 567 if (!str_eq(name, val)) {
545 eprintln( 568 if (!(strset_lookup(&a->integer_types, name) &&
546 "%s:%d:%d: error: type mismatch, trying to assing " 569 strset_lookup(&a->integer_types, val)) ||
547 "%s" 570 !(strset_lookup(&a->numeric_types, name) &&
548 " to a variable of type %s", 571 strset_lookup(&a->numeric_types, val))) {
549 a->file_name, node->line, node->col, val, name); 572 eprintln(
550 a->err = true; 573 "%s:%d:%d: error: type mismatch, trying to assing "
551 return cstr(""); 574 "%s"
575 " to a variable of type %s",
576 a->file_name, node->line, node->col, val, name);
577 a->err = true;
578 return cstr("");
579 }
552 } 580 }
553 Str symbol = node->var_name->value.str; 581 Str symbol = node->var.name->value.str;
554 FindSymbolResult sym = find_symbol(scope, symbol); 582 FindSymbolResult sym = find_symbol(scope, symbol);
555 node->unique_name = str_concat(cstr("."), symbol, a->storage); 583 if (sym.map) {
556 node->unique_name = 584 node->unique_name = str_concat(cstr("."), symbol, a->storage);
557 str_concat(node->unique_name, 585 node->unique_name = str_concat(
558 str_from_int(sym.scope->id, a->storage), a->storage); 586 node->unique_name, str_from_int(sym.scope->id, a->storage),
587 a->storage);
588 }
559 node->type = cstr("nil"); 589 node->type = cstr("nil");
560 return node->type; 590 return node->type;
561 } break; 591 } break;
@@ -595,7 +625,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
595 enummap_insert(&scope->enums, symbol, 625 enummap_insert(&scope->enums, symbol,
596 (Enum){ 626 (Enum){
597 .name = symbol, 627 .name = symbol,
598 .val = node->field_val, 628 .val = node->field.val,
599 }, 629 },
600 a->storage); 630 a->storage);
601 for (sz i = 0; i < array_size(node->struct_field); i++) { 631 for (sz i = 0; i < array_size(node->struct_field); i++) {
@@ -608,9 +638,9 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
608 a->file_name, field->line, field->col, field_name); 638 a->file_name, field->line, field->col, field_name);
609 a->err = true; 639 a->err = true;
610 } 640 }
611 if (field->field_val) { 641 if (field->field.val) {
612 Str type = type_inference(a, field->field_val, scope); 642 Str type = type_inference(a, field->field.val, scope);
613 if (!str_eq(type, cstr("int"))) { 643 if (!str_eq(type, cstr("Int"))) {
614 eprintln( 644 eprintln(
615 "%s:%d:%d: error: non int enum value for '%s.%s'", 645 "%s:%d:%d: error: non int enum value for '%s.%s'",
616 a->file_name, field->line, field->col, symbol, 646 a->file_name, field->line, field->col, symbol,
@@ -632,26 +662,31 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
632 return node->type; 662 return node->type;
633 } break; 663 } break;
634 case NODE_IF: { 664 case NODE_IF: {
635 Str cond_type = type_inference(a, node->cond_if, scope); 665 Str cond_type = type_inference(a, node->ifelse.cond, scope);
636 if (!str_eq(cond_type, cstr("bool"))) { 666 if (!str_eq(cond_type, cstr("Bool"))) {
637 emit_semantic_error( 667 emit_semantic_error(
638 a, node->cond_if, 668 a, node->ifelse.cond,
639 cstr("non boolean expression on if condition")); 669 cstr("non boolean expression on if condition"));
640 return cstr(""); 670 return cstr("");
641 } 671 }
642 if (node->cond_expr->kind == NODE_BLOCK) { 672 if (node->ifelse.expr_true->kind == NODE_BLOCK) {
643 node->type = type_inference(a, node->cond_expr, scope); 673 node->type = type_inference(a, node->ifelse.expr_true, scope);
644 } else { 674 } else {
645 Scope *next = typescope_alloc(a, scope); 675 Scope *next = typescope_alloc(a, scope);
646 node->type = type_inference(a, node->cond_expr, next); 676 node->type = type_inference(a, node->ifelse.expr_true, next);
677 }
678 if (str_has_prefix(node->type, cstr("ret:")) ||
679 str_has_prefix(node->type, cstr("flow:"))) {
680 node->type = cstr("nil");
647 } 681 }
648 if (node->cond_else) { 682 if (node->ifelse.expr_else) {
649 Str else_type; 683 Str else_type;
650 if (node->cond_else->kind == NODE_BLOCK) { 684 if (node->ifelse.expr_else->kind == NODE_BLOCK) {
651 else_type = type_inference(a, node->cond_else, scope); 685 else_type =
686 type_inference(a, node->ifelse.expr_else, scope);
652 } else { 687 } else {
653 Scope *next = typescope_alloc(a, scope); 688 Scope *next = typescope_alloc(a, scope);
654 else_type = type_inference(a, node->cond_else, next); 689 else_type = type_inference(a, node->ifelse.expr_else, next);
655 } 690 }
656 if (!str_eq(node->type, else_type)) { 691 if (!str_eq(node->type, else_type)) {
657 emit_semantic_error( 692 emit_semantic_error(
@@ -659,27 +694,38 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
659 return cstr(""); 694 return cstr("");
660 } 695 }
661 } 696 }
697
698 // If it returns a value, verify it contains an `else` statement.
699 if (!str_eq(node->type, cstr("nil"))) {
700 if (!node->ifelse.expr_else) {
701 emit_semantic_error(
702 a, node,
703 cstr("missing else statement in if expression"));
704 return cstr("");
705 }
706 }
662 return node->type; 707 return node->type;
663 } break; 708 } break;
664 case NODE_WHILE: { 709 case NODE_WHILE: {
665 Str cond_type = type_inference(a, node->while_cond, scope); 710 Str cond_type = type_inference(a, node->loop.cond, scope);
666 if (!str_eq(cond_type, cstr("bool"))) { 711 if (!str_eq(cond_type, cstr("Bool"))) {
667 emit_semantic_error( 712 emit_semantic_error(
668 a, node->cond_if, 713 a, node->loop.cond,
669 cstr("non boolean expression on while condition")); 714 cstr("non boolean expression on while condition"));
670 return cstr(""); 715 return cstr("");
671 } 716 }
672 if (node->while_expr->kind != NODE_BLOCK) { 717 if (node->loop.expr->kind != NODE_BLOCK) {
673 scope = typescope_alloc(a, scope); 718 scope = typescope_alloc(a, scope);
674 } 719 }
675 type_inference(a, node->while_expr, scope); 720 type_inference(a, node->loop.expr, scope);
676 node->type = cstr("nil"); 721 node->type = cstr("nil");
677 return node->type; 722 return node->type;
678 } break; 723 } break;
679 case NODE_COND: { 724 case NODE_COND: {
680 Str previous = cstr(""); 725 Str previous = cstr("");
681 for (sz i = 0; i < array_size(node->match_cases); i++) { 726 bool has_else = false;
682 Node *expr = node->match_cases[i]; 727 for (sz i = 0; i < array_size(node->match.cases); i++) {
728 Node *expr = node->match.cases[i];
683 Str next = type_inference(a, expr, scope); 729 Str next = type_inference(a, expr, scope);
684 if (i != 0 && !str_eq(next, previous)) { 730 if (i != 0 && !str_eq(next, previous)) {
685 emit_semantic_error( 731 emit_semantic_error(
@@ -687,22 +733,36 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
687 cstr("non-matching types for cond expressions")); 733 cstr("non-matching types for cond expressions"));
688 return cstr(""); 734 return cstr("");
689 } 735 }
736 if (!expr->case_entry.cond) {
737 has_else = true;
738 }
690 previous = next; 739 previous = next;
691 } 740 }
741 // If it returns a value, verify it contains an `else` statement.
742 if (!str_eq(node->type, cstr("nil")) &&
743 !str_has_prefix(node->type, cstr("ret:")) &&
744 !str_has_prefix(node->type, cstr("flow:"))) {
745 if (!has_else) {
746 emit_semantic_error(
747 a, node,
748 cstr("missing else statement in cond expression"));
749 return cstr("");
750 }
751 }
692 node->type = previous; 752 node->type = previous;
693 return node->type; 753 return node->type;
694 } break; 754 } break;
695 case NODE_MATCH: { 755 case NODE_MATCH: {
696 Str e = type_inference(a, node->match_expr, scope); 756 Str e = type_inference(a, node->match.expr, scope);
697 if (str_eq(e, cstr("int"))) { 757 if (str_eq(e, cstr("Int"))) {
698 // Integer matching. 758 // Integer matching.
699 for (sz i = 0; i < array_size(node->match_cases); i++) { 759 for (sz i = 0; i < array_size(node->match.cases); i++) {
700 Node *field = node->match_cases[i]; 760 Node *field = node->match.cases[i];
701 if (field->case_value) { 761 if (field->case_entry.cond) {
702 if (field->case_value->kind != NODE_NUM_INT && 762 if (field->case_entry.cond->kind != NODE_NUM_INT &&
703 field->case_value->kind != NODE_NUM_UINT) { 763 field->case_entry.cond->kind != NODE_NUM_UINT) {
704 emit_semantic_error( 764 emit_semantic_error(
705 a, field->case_value, 765 a, field->case_entry.cond,
706 cstr( 766 cstr(
707 "non-integer or enum types on match case")); 767 "non-integer or enum types on match case"));
708 } 768 }
@@ -713,24 +773,24 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
713 FindEnumResult res = find_enum(scope, e); 773 FindEnumResult res = find_enum(scope, e);
714 Str enum_prefix = 774 Str enum_prefix =
715 str_concat(res.map->val.name, cstr("."), a->storage); 775 str_concat(res.map->val.name, cstr("."), a->storage);
716 for (sz i = 0; i < array_size(node->match_cases); i++) { 776 for (sz i = 0; i < array_size(node->match.cases); i++) {
717 Node *field = node->match_cases[i]; 777 Node *field = node->match.cases[i];
718 if (field->case_value) { 778 if (field->case_entry.cond) {
719 Str field_name = str_concat( 779 Str field_name = str_concat(
720 enum_prefix, field->case_value->value.str, 780 enum_prefix, field->case_entry.cond->value.str,
721 a->storage); 781 a->storage);
722 if (!enummap_lookup(&res.scope->enums, field_name)) { 782 if (!enummap_lookup(&res.scope->enums, field_name)) {
723 eprintln("%s:%d:%d: error: unknown enum field '%s'", 783 eprintln("%s:%d:%d: error: unknown enum field '%s'",
724 a->file_name, field->case_value->line, 784 a->file_name, field->case_entry.cond->line,
725 field->case_value->col, field_name); 785 field->case_entry.cond->col, field_name);
726 a->err = true; 786 a->err = true;
727 } 787 }
728 } 788 }
729 } 789 }
730 } 790 }
731 Str previous = cstr(""); 791 Str previous = cstr("");
732 for (sz i = 0; i < array_size(node->match_cases); i++) { 792 for (sz i = 0; i < array_size(node->match.cases); i++) {
733 Node *expr = node->match_cases[i]; 793 Node *expr = node->match.cases[i];
734 Str next = type_inference(a, expr, scope); 794 Str next = type_inference(a, expr, scope);
735 if (i != 0 && !str_eq(next, previous)) { 795 if (i != 0 && !str_eq(next, previous)) {
736 emit_semantic_error( 796 emit_semantic_error(
@@ -744,29 +804,29 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
744 return node->type; 804 return node->type;
745 } break; 805 } break;
746 case NODE_CASE_MATCH: { 806 case NODE_CASE_MATCH: {
747 if (node->case_expr->kind != NODE_BLOCK) { 807 if (node->case_entry.expr->kind != NODE_BLOCK) {
748 scope = typescope_alloc(a, scope); 808 scope = typescope_alloc(a, scope);
749 } 809 }
750 node->type = type_inference(a, node->case_expr, scope); 810 node->type = type_inference(a, node->case_entry.expr, scope);
751 return node->type; 811 return node->type;
752 } break; 812 } break;
753 case NODE_CASE_COND: { 813 case NODE_CASE_COND: {
754 if (node->case_value) { 814 if (node->case_entry.cond) {
755 Str cond = type_inference(a, node->case_value, scope); 815 Str cond = type_inference(a, node->case_entry.cond, scope);
756 if (!str_eq(cond, cstr("bool"))) { 816 if (!str_eq(cond, cstr("Bool"))) {
757 emit_semantic_error(a, node, 817 emit_semantic_error(a, node,
758 cstr("non-boolean case condition")); 818 cstr("non-boolean case condition"));
759 } 819 }
760 } 820 }
761 if (node->case_expr->kind != NODE_BLOCK) { 821 if (node->case_entry.expr->kind != NODE_BLOCK) {
762 scope = typescope_alloc(a, scope); 822 scope = typescope_alloc(a, scope);
763 } 823 }
764 node->type = type_inference(a, node->case_expr, scope); 824 node->type = type_inference(a, node->case_entry.expr, scope);
765 return node->type; 825 return node->type;
766 } break; 826 } break;
767 case NODE_TRUE: 827 case NODE_TRUE:
768 case NODE_FALSE: { 828 case NODE_FALSE: {
769 node->type = cstr("bool"); 829 node->type = cstr("Bool");
770 return node->type; 830 return node->type;
771 } break; 831 } break;
772 case NODE_NIL: { 832 case NODE_NIL: {
@@ -776,21 +836,21 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
776 case NODE_NOT: 836 case NODE_NOT:
777 case NODE_AND: 837 case NODE_AND:
778 case NODE_OR: { 838 case NODE_OR: {
779 Str left = type_inference(a, node->left, scope); 839 Str left = type_inference(a, node->binary.left, scope);
780 if (!str_eq(left, cstr("bool"))) { 840 if (!str_eq(left, cstr("Bool"))) {
781 emit_semantic_error(a, node, 841 emit_semantic_error(a, node,
782 cstr("expected bool on logic expression")); 842 cstr("expected bool on logic expression"));
783 return cstr(""); 843 return cstr("");
784 } 844 }
785 if (node->right) { 845 if (node->binary.right) {
786 Str right = type_inference(a, node->right, scope); 846 Str right = type_inference(a, node->binary.right, scope);
787 if (!str_eq(right, cstr("bool"))) { 847 if (!str_eq(right, cstr("Bool"))) {
788 emit_semantic_error( 848 emit_semantic_error(
789 a, node, cstr("expected bool on logic expression")); 849 a, node, cstr("expected bool on logic expression"));
790 return cstr(""); 850 return cstr("");
791 } 851 }
792 } 852 }
793 node->type = cstr("bool"); 853 node->type = cstr("Bool");
794 return node->type; 854 return node->type;
795 } break; 855 } break;
796 case NODE_EQ: 856 case NODE_EQ:
@@ -799,18 +859,23 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
799 case NODE_GT: 859 case NODE_GT:
800 case NODE_LE: 860 case NODE_LE:
801 case NODE_GE: { 861 case NODE_GE: {
802 Str left = type_inference(a, node->left, scope); 862 Str left = type_inference(a, node->binary.left, scope);
803 Str right = type_inference(a, node->right, scope); 863 Str right = type_inference(a, node->binary.right, scope);
804 if (!str_eq(left, right)) { 864 if (!str_eq(left, right)) {
805 emit_semantic_error( 865 if (!(strset_lookup(&a->integer_types, left) &&
806 a, node, cstr("mismatched types on binary expression")); 866 strset_lookup(&a->integer_types, right)) ||
807 return cstr(""); 867 !(strset_lookup(&a->numeric_types, left) &&
868 strset_lookup(&a->numeric_types, right))) {
869 emit_semantic_error(
870 a, node, cstr("mismatched types on binary expression"));
871 return cstr("");
872 }
808 } 873 }
809 node->type = cstr("bool"); 874 node->type = cstr("Bool");
810 return node->type; 875 return node->type;
811 } break; 876 } break;
812 case NODE_BITNOT: { 877 case NODE_BITNOT: {
813 Str left = type_inference(a, node->left, scope); 878 Str left = type_inference(a, node->binary.left, scope);
814 if (!strset_lookup(&a->integer_types, left)) { 879 if (!strset_lookup(&a->integer_types, left)) {
815 emit_semantic_error( 880 emit_semantic_error(
816 a, node, cstr("non integer type on bit twiddling expr")); 881 a, node, cstr("non integer type on bit twiddling expr"));
@@ -821,10 +886,11 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
821 } break; 886 } break;
822 case NODE_BITAND: 887 case NODE_BITAND:
823 case NODE_BITOR: 888 case NODE_BITOR:
889 case NODE_BITXOR:
824 case NODE_BITLSHIFT: 890 case NODE_BITLSHIFT:
825 case NODE_BITRSHIFT: { 891 case NODE_BITRSHIFT: {
826 Str left = type_inference(a, node->left, scope); 892 Str left = type_inference(a, node->binary.left, scope);
827 Str right = type_inference(a, node->right, scope); 893 Str right = type_inference(a, node->binary.right, scope);
828 if (!strset_lookup(&a->integer_types, left) || 894 if (!strset_lookup(&a->integer_types, left) ||
829 !strset_lookup(&a->integer_types, right)) { 895 !strset_lookup(&a->integer_types, right)) {
830 emit_semantic_error( 896 emit_semantic_error(
@@ -839,8 +905,15 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
839 case NODE_DIV: 905 case NODE_DIV:
840 case NODE_MUL: 906 case NODE_MUL:
841 case NODE_MOD: { 907 case NODE_MOD: {
842 Str left = type_inference(a, node->left, scope); 908 Str left = type_inference(a, node->binary.left, scope);
843 Str right = type_inference(a, node->right, scope); 909 Str right = type_inference(a, node->binary.right, scope);
910 // Enable pointer arithmetic.
911 if (str_has_prefix(left, cstr("@"))) {
912 left = cstr("Ptr");
913 }
914 if (str_has_prefix(right, cstr("@"))) {
915 right = cstr("Ptr");
916 }
844 if (!strset_lookup(&a->numeric_types, left) || 917 if (!strset_lookup(&a->numeric_types, left) ||
845 !strset_lookup(&a->numeric_types, right)) { 918 !strset_lookup(&a->numeric_types, right)) {
846 emit_semantic_error( 919 emit_semantic_error(
@@ -848,73 +921,149 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
848 return cstr(""); 921 return cstr("");
849 } 922 }
850 if (!str_eq(left, right)) { 923 if (!str_eq(left, right)) {
851 emit_semantic_error( 924 if (!((strset_lookup(&a->integer_types, left) &&
852 a, node, cstr("mismatched types on binary expression")); 925 strset_lookup(&a->integer_types, right)) ||
853 return cstr(""); 926 (strset_lookup(&a->float_types, left) &&
927 strset_lookup(&a->float_types, right)))) {
928 emit_semantic_error(
929 a, node, cstr("mismatched types on binary expression"));
930 return cstr("");
931 }
854 } 932 }
855 node->type = left; 933 node->type = left;
856 return node->type; 934 return node->type;
857 } break; 935 } break;
858 case NODE_NUM_UINT: { 936 case NODE_NUM_UINT: {
859 node->type = cstr("uint"); 937 node->type = cstr("UInt");
860 return node->type; 938 return node->type;
861 } break; 939 } break;
862 case NODE_NUM_INT: { 940 case NODE_NUM_INT: {
863 node->type = cstr("int"); 941 node->type = cstr("Int");
864 return node->type; 942 return node->type;
865 } break; 943 } break;
866 case NODE_NUM_FLOAT: { 944 case NODE_NUM_FLOAT: {
867 node->type = cstr("f64"); 945 node->type = cstr("F64");
868 return node->type; 946 return node->type;
869 } break; 947 } break;
870 case NODE_STRING: { 948 case NODE_STRING: {
871 node->type = cstr("str"); 949 node->type = cstr("Str");
872 return node->type; 950 return node->type;
873 } break; 951 } break;
874 case NODE_ARR_TYPE:
875 case NODE_TYPE: { 952 case NODE_TYPE: {
876 SymbolMap *type = find_type(scope, node->value.str); 953 Str base_type = node->value.str;
877 if (!type) { 954 StrSet *set = find_type(scope, node->value.str);
955 if (!set) {
878 emit_semantic_error(a, node, cstr("unknown type")); 956 emit_semantic_error(a, node, cstr("unknown type"));
879 return cstr(""); 957 return cstr("");
880 } 958 }
881 node->type = type->val.name; 959 Node *next = node->t.next;
960 Str type = cstr("");
961 while (next) {
962 switch (next->kind) {
963 case NODE_PTR: {
964 Str suffix = cstr("@");
965 type = str_concat(type, suffix, a->storage);
966 } break;
967 case NODE_ARR: {
968 Str suffix = cstr("[");
969 switch (next->array.kind) {
970 case NODE_ARR_STATIC: {
971 suffix = str_concat(
972 suffix,
973 str_from_int(next->array.size->value.i,
974 a->storage),
975 a->storage);
976 suffix =
977 str_concat(suffix, cstr("]"), a->storage);
978 } break;
979 default: {
980 emit_semantic_error(a, node,
981 cstr("unimplemented"));
982 return cstr("");
983 } break;
984 }
985 type = str_concat(type, suffix, a->storage);
986 } break;
987 default: break;
988 }
989 next = next->t.next;
990 }
991 type = str_concat(type, base_type, a->storage);
992 node->type = type;
993 return node->type;
994 } break;
995 case NODE_DEREF: {
996 Node *next = node->deref.next;
997 Str amount = cstr("@");
998 while (next) {
999 if (next->kind == NODE_SYMBOL) {
1000 break;
1001 }
1002 next = next->deref.next;
1003 amount = str_concat(cstr("@"), amount, a->storage);
1004 }
1005 Str symbol = next->value.str;
1006 Str type = type_inference(a, next, scope);
1007 if (str_has_prefix(type, cstr("["))) {
1008 str_split(&type, cstr("]"));
1009 type = str_concat(cstr("@"), type, a->storage);
1010 }
1011 if (!str_has_prefix(type, amount)) {
1012 eprintln(
1013 "%s:%d:%d: error: invalid type dereference %s from type %s",
1014 a->file_name, node->line, node->col,
1015 str_concat(symbol, amount, a->storage), type);
1016 a->err = true;
1017 return cstr("");
1018 }
1019 type = str_remove_prefix(type, amount);
1020 node->value.str = next->value.str;
1021 node->unique_name = next->unique_name;
1022 node->type = type;
882 return node->type; 1023 return node->type;
883 } break; 1024 } break;
884 case NODE_SYMBOL_IDX:
885 case NODE_SYMBOL: { 1025 case NODE_SYMBOL: {
886 Str symbol = node->value.str; 1026 Str symbol = node->value.str;
887 SymbolMap *type = find_type(scope, symbol); 1027
888 if (!type) { 1028 FindSymbolResult sym = find_symbol(scope, symbol);
1029 if (!sym.map) {
889 eprintln("%s:%d:%d: error: couldn't resolve symbol '%s'", 1030 eprintln("%s:%d:%d: error: couldn't resolve symbol '%s'",
890 a->file_name, node->line, node->col, symbol); 1031 a->file_name, node->line, node->col, symbol);
891 a->err = true; 1032 a->err = true;
892 return cstr(""); 1033 return cstr("");
893 } 1034 }
894 1035
895 FindSymbolResult sym = find_symbol(scope, symbol); 1036 if (!str_eq(sym.scope->name, scope->name) && sym.scope->name.size) {
1037 eprintln(
1038 "%s:%d:%d: error: can't capture external local symbol '%s'",
1039 a->file_name, node->line, node->col, symbol);
1040 a->err = true;
1041 return cstr("");
1042 }
896 node->unique_name = str_concat(cstr("."), symbol, a->storage); 1043 node->unique_name = str_concat(cstr("."), symbol, a->storage);
897 node->unique_name = 1044 node->unique_name =
898 str_concat(node->unique_name, 1045 str_concat(node->unique_name,
899 str_from_int(sym.scope->id, a->storage), a->storage); 1046 str_from_int(sym.scope->id, a->storage), a->storage);
900 1047
901 Str type_name = type->val.name; 1048 Str type_name = sym.map->val.name;
902 if (node->kind == NODE_SYMBOL_IDX) { 1049 // if (node->kind == NODE_SYMBOL_IDX) {
903 Str idx_type = type_inference(a, node->arr_size, scope); 1050 // // TODO: get rid of NODE_SYMBOL_IDX, use deref instead
904 if (!strset_lookup(&a->integer_types, idx_type)) { 1051 // Str idx_type = type_inference(a, node->sym.arr_size, scope);
905 emit_semantic_error( 1052 // if (!strset_lookup(&a->integer_types, idx_type)) {
906 a, node, cstr("can't resolve non integer index")); 1053 // emit_semantic_error(
907 return cstr(""); 1054 // a, node, cstr("can't resolve non integer index"));
908 } 1055 // return cstr("");
909 type_name = str_remove_prefix(type_name, cstr("@")); 1056 // }
910 } 1057 // if (str_has_prefix(type_name, cstr("@"))) {
911 if (node->is_ptr) { 1058 // type_name = str_remove_prefix(type_name, cstr("@"));
912 type_name = str_concat(cstr("@"), type_name, a->storage); 1059 // } else if (str_has_prefix(type_name, cstr("["))) {
913 } 1060 // str_split(&type_name, cstr("]"));
1061 // }
1062 // }
914 1063
915 FindEnumResult e = find_enum(scope, type_name); 1064 FindEnumResult e = find_enum(scope, type_name);
916 if (e.map && str_eq(symbol, type_name)) { 1065 if (e.map && str_eq(symbol, type_name)) {
917 if (!node->next) { 1066 if (!node->sym.next) {
918 eprintln( 1067 eprintln(
919 "%s:%d:%d: error: unspecified enum field for symbol " 1068 "%s:%d:%d: error: unspecified enum field for symbol "
920 "'%s'", 1069 "'%s'",
@@ -924,20 +1073,21 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
924 } 1073 }
925 // Check if there is a next and it matches the enum field. 1074 // Check if there is a next and it matches the enum field.
926 Str field = str_concat(type_name, cstr("."), a->storage); 1075 Str field = str_concat(type_name, cstr("."), a->storage);
927 field = str_concat(field, node->next->value.str, a->storage); 1076 field =
1077 str_concat(field, node->sym.next->value.str, a->storage);
928 if (!enummap_lookup(&e.scope->enums, field)) { 1078 if (!enummap_lookup(&e.scope->enums, field)) {
929 eprintln( 1079 eprintln(
930 "%s:%d:%d: error: unknown enum field for " 1080 "%s:%d:%d: error: unknown enum field for "
931 "'%s': %s", 1081 "'%s': %s",
932 a->file_name, node->line, node->col, symbol, 1082 a->file_name, node->line, node->col, symbol,
933 node->next->value.str); 1083 node->sym.next->value.str);
934 a->err = true; 1084 a->err = true;
935 return cstr(""); 1085 return cstr("");
936 } 1086 }
937 1087
938 node->next->type = type_name; 1088 node->sym.next->type = type_name;
939 node->type = type_name; 1089 node->type = type_name;
940 return node->next->type; 1090 return node->sym.next->type;
941 } 1091 }
942 1092
943 FindStructResult s = find_struct(scope, type_name); 1093 FindStructResult s = find_struct(scope, type_name);
@@ -950,11 +1100,11 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
950 a->err = true; 1100 a->err = true;
951 return cstr(""); 1101 return cstr("");
952 } else { 1102 } else {
953 if (node->next) { 1103 if (node->sym.next) {
954 Str chain = type_name; 1104 Str chain = type_name;
955 Node *next = node; 1105 Node *next = node;
956 while (next->next) { 1106 while (next->sym.next) {
957 next = next->next; 1107 next = next->sym.next;
958 chain = str_concat(chain, cstr("."), a->storage); 1108 chain = str_concat(chain, cstr("."), a->storage);
959 chain = 1109 chain =
960 str_concat(chain, next->value.str, a->storage); 1110 str_concat(chain, next->value.str, a->storage);
@@ -969,18 +1119,18 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
969 return cstr(""); 1119 return cstr("");
970 } 1120 }
971 Str field_type = field->val.type; 1121 Str field_type = field->val.type;
972 if (next->kind == NODE_SYMBOL_IDX) { 1122 // if (next->kind == NODE_SYMBOL_IDX) {
973 Str idx_type = 1123 // Str idx_type =
974 type_inference(a, next->arr_size, scope); 1124 // type_inference(a, next->sym.arr_size, scope);
975 if (!strset_lookup(&a->integer_types, idx_type)) { 1125 // if (!strset_lookup(&a->integer_types, idx_type)) {
976 emit_semantic_error( 1126 // emit_semantic_error(
977 a, next, 1127 // a, next,
978 cstr("can't resolve non integer index")); 1128 // cstr("can't resolve non integer index"));
979 return cstr(""); 1129 // return cstr("");
980 } 1130 // }
981 field_type = 1131 // field_type =
982 str_remove_prefix(field_type, cstr("@")); 1132 // str_remove_prefix(field_type, cstr("@"));
983 } 1133 // }
984 node->type = field_type; 1134 node->type = field_type;
985 return node->type; 1135 return node->type;
986 } 1136 }
@@ -989,6 +1139,12 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
989 node->type = type_name; 1139 node->type = type_name;
990 return node->type; 1140 return node->type;
991 } break; 1141 } break;
1142 case NODE_PTR: {
1143 Str type = type_inference(a, node->t.next, scope);
1144 type = str_concat(cstr("@"), type, a->storage);
1145 node->type = type;
1146 return node->type;
1147 } break;
992 case NODE_STRUCT_LIT: { 1148 case NODE_STRUCT_LIT: {
993 Str name = node->value.str; 1149 Str name = node->value.str;
994 FindStructResult s = find_struct(scope, name); 1150 FindStructResult s = find_struct(scope, name);
@@ -1031,27 +1187,62 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1031 a->err = true; 1187 a->err = true;
1032 return cstr(""); 1188 return cstr("");
1033 } 1189 }
1034 // Check that actual parameters typecheck 1190 FindSymbolResult sym = find_symbol(scope, symbol);
1035 Str args = cstr(""); 1191 node->unique_name = str_concat(cstr("."), symbol, a->storage);
1192 node->unique_name =
1193 str_concat(node->unique_name,
1194 str_from_int(sym.scope->id, a->storage), a->storage);
1195
1196 // Check function aritiy.
1197 sz arity_fun = fun->val.param_arity;
1198 sz arity_call = array_size(node->elements);
1199 if (arity_fun != -1) {
1200 if (arity_fun != arity_call) {
1201 eprintln(
1202 "%s:%d:%d: error: wrong number of parameters for "
1203 "funcall: "
1204 "%s "
1205 "expected "
1206 "%d"
1207 " got %d",
1208 a->file_name, node->line, node->col, symbol, arity_fun,
1209 arity_call);
1210 a->err = true;
1211 return cstr("");
1212 }
1213 }
1214
1215 if (sym.map->val.kind == SYM_BUILTIN_FUN &&
1216 str_eq(fun->key, cstr("sizeof"))) {
1217 // Node *expr = node->elements[0];
1218 // Str type = type_inference(a, expr, scope);
1219 node->type = fun->val.return_type;
1220 return node->type;
1221 }
1222
1036 for (sz i = 0; i < array_size(node->elements); i++) { 1223 for (sz i = 0; i < array_size(node->elements); i++) {
1037 Node *expr = node->elements[i]; 1224 Node *expr = node->elements[i];
1038 Str type = type_inference(a, expr, scope); 1225 Str type = type_inference(a, expr, scope);
1039 args = str_concat(args, type, a->storage); 1226 if (!str_eq(fun->val.param_type, cstr("..."))) {
1040 if (i != array_size(node->elements) - 1) { 1227 Str expected = fun->val.param_types[i];
1041 args = str_concat(args, cstr(","), a->storage); 1228 if (!str_eq(type, expected)) {
1229 if (!(strset_lookup(&a->integer_types, type) &&
1230 strset_lookup(&a->integer_types, expected)) ||
1231 !(strset_lookup(&a->numeric_types, type) &&
1232 strset_lookup(&a->numeric_types, expected))) {
1233 eprintln(
1234 "%s:%d:%d: error: mismatched parameter types: "
1235 "%s "
1236 "expected "
1237 "%s",
1238 a->file_name, node->line, node->col, type,
1239 expected);
1240 a->err = true;
1241 return cstr("");
1242 }
1243 }
1042 } 1244 }
1043 } 1245 }
1044 if (!args.size) {
1045 args = cstr("nil");
1046 }
1047 Str expected = fun->val.param_type;
1048 if (!str_eq(args, expected) && !str_eq(expected, cstr("..."))) {
1049 eprintln(
1050 "%s:%d:%d: error: mismatched parameter types: %s expected "
1051 "%s",
1052 a->file_name, node->line, node->col, args, expected);
1053 a->err = true;
1054 }
1055 node->type = fun->val.return_type; 1246 node->type = fun->val.return_type;
1056 return node->type; 1247 return node->type;
1057 } break; 1248 } break;
@@ -1061,12 +1252,22 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1061 for (sz i = 0; i < array_size(node->elements); i++) { 1252 for (sz i = 0; i < array_size(node->elements); i++) {
1062 Node *expr = node->elements[i]; 1253 Node *expr = node->elements[i];
1063 type = type_inference(a, expr, scope); 1254 type = type_inference(a, expr, scope);
1255 if (str_has_prefix(type, cstr("ret:")) ||
1256 str_has_prefix(type, cstr("flow:"))) {
1257 break;
1258 }
1064 } 1259 }
1065 node->type = type; 1260 node->type = type;
1066 return node->type; 1261 return node->type;
1067 } break; 1262 } break;
1068 case NODE_RETURN: { 1263 case NODE_RETURN: {
1069 Str ret_type = cstr(""); 1264 if (!scope->name.size) {
1265 emit_semantic_error(
1266 a, node, cstr("return statement outside a function"));
1267 a->err = true;
1268 return cstr("");
1269 }
1270 Str ret_type = cstr("ret:");
1070 for (sz i = 0; i < array_size(node->elements); i++) { 1271 for (sz i = 0; i < array_size(node->elements); i++) {
1071 Node *expr = node->elements[i]; 1272 Node *expr = node->elements[i];
1072 Str type = type_inference(a, expr, scope); 1273 Str type = type_inference(a, expr, scope);
@@ -1081,119 +1282,156 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1081 node->type = ret_type; 1282 node->type = ret_type;
1082 return node->type; 1283 return node->type;
1083 } break; 1284 } break;
1285 case NODE_CONTINUE:
1286 case NODE_BREAK: {
1287 // Check if we are inside a loop.
1288 Node *parent = node->parent;
1289 bool inside_loop = false;
1290 while (parent != NULL) {
1291 if (parent->kind == NODE_WHILE) {
1292 inside_loop = true;
1293 break;
1294 }
1295 parent = parent->parent;
1296 }
1297 if (!inside_loop) {
1298 eprintln(
1299 "%s:%d:%d: error: control flow statement outside a "
1300 "loop",
1301 a->file_name, node->line, node->col);
1302 a->err = true;
1303 return cstr("");
1304 }
1305 node->type = cstr("flow:");
1306 return node->type;
1307 } break;
1084 case NODE_FUN: { 1308 case NODE_FUN: {
1085 node->type = cstr("nil"); 1309 node->type = cstr("nil");
1086 Scope *prev_scope = scope; 1310 Scope *prev_scope = scope;
1087 scope = typescope_alloc(a, scope); 1311 scope = typescope_alloc(a, scope);
1088 Str param_type = cstr(""); 1312 Str param_type = cstr("");
1089 for (sz i = 0; i < array_size(node->func_params); i++) { 1313 Str symbol = node->func.name->value.str;
1090 Node *param = node->func_params[i]; 1314 Fun fun = (Fun){.name = symbol};
1091 Str symbol = param->param_name->value.str; 1315 for (sz i = 0; i < array_size(node->func.params); i++) {
1092 Str type = param->param_type->value.str; 1316 Node *param = node->func.params[i];
1093 if (param->param_type->is_ptr) { 1317 Str symbol = param->param.name->value.str;
1094 type = str_concat(cstr("@"), type, a->storage); 1318 Str type = param->param.type->value.str;
1095 } 1319 param->param.name->type =
1096 if (param->param_type->kind == NODE_ARR_TYPE) { 1320 type_inference(a, param->param.type, scope);
1097 type = str_concat(cstr("@"), type, a->storage);
1098 }
1099 param->param_name->type =
1100 type_inference(a, param->param_type, scope);
1101 param->type = type; 1321 param->type = type;
1322 array_push(fun.param_types, type, a->storage);
1102 symmap_insert(&scope->symbols, symbol, 1323 symmap_insert(&scope->symbols, symbol,
1103 (Symbol){.name = type, .kind = SYM_PARAM}, 1324 (Symbol){.name = type, .kind = SYM_PARAM},
1104 a->storage); 1325 a->storage);
1105 param_type = str_concat(param_type, type, a->storage); 1326 param_type = str_concat(param_type, type, a->storage);
1106 if (i != array_size(node->func_params) - 1) { 1327 if (i != array_size(node->func.params) - 1) {
1107 param_type = str_concat(param_type, cstr(","), a->storage); 1328 param_type = str_concat(param_type, cstr(","), a->storage);
1108 } 1329 }
1330 symbol = str_concat(cstr("."), symbol, a->storage);
1331 symbol = str_concat(symbol, str_from_int(scope->id, a->storage),
1332 a->storage);
1333 param->unique_name = symbol;
1109 } 1334 }
1110 if (!param_type.size) { 1335 if (!param_type.size) {
1111 param_type = cstr("nil"); 1336 param_type = cstr("nil");
1112 } 1337 }
1113 node->fun_params = param_type; 1338 node->type_params = param_type;
1339 fun.param_arity = array_size(node->func.params);
1114 1340
1115 Str ret_type = cstr(""); 1341 Str ret_type = cstr("");
1116 for (sz i = 0; i < array_size(node->func_ret); i++) { 1342 for (sz i = 0; i < array_size(node->func.ret); i++) {
1117 Node *expr = node->func_ret[i]; 1343 Node *expr = node->func.ret[i];
1118 Str type = type_inference(a, expr, scope); 1344 Str type = type_inference(a, expr, scope);
1119 if (expr->is_ptr) {
1120 type = str_concat(cstr("@"), type, a->storage);
1121 }
1122 if (expr->kind == NODE_ARR_TYPE) {
1123 type = str_concat(cstr("@"), type, a->storage);
1124 }
1125 ret_type = str_concat(ret_type, type, a->storage); 1345 ret_type = str_concat(ret_type, type, a->storage);
1126 if (i != array_size(node->func_ret) - 1) { 1346 array_push(fun.return_types, ret_type, a->storage);
1347 if (i != array_size(node->func.ret) - 1) {
1127 ret_type = str_concat(ret_type, cstr(","), a->storage); 1348 ret_type = str_concat(ret_type, cstr(","), a->storage);
1128 } 1349 }
1129 } 1350 }
1351 fun.return_arity = array_size(node->func.ret);
1130 if (!ret_type.size) { 1352 if (!ret_type.size) {
1131 ret_type = cstr("nil"); 1353 ret_type = cstr("nil");
1132 } 1354 }
1133 node->fun_return = ret_type; 1355 node->type_returns = ret_type;
1134 1356
1135 Str symbol = node->func_name->value.str;
1136 if (prev_scope->parent != NULL) { 1357 if (prev_scope->parent != NULL) {
1137 if (symmap_lookup(&prev_scope->symbols, symbol)) { 1358 if (symmap_lookup(&prev_scope->symbols, symbol)) {
1138 eprintln( 1359 eprintln(
1139 "%s:%d:%d: error: function '%s' already defined in " 1360 "%s:%d:%d: error: function '%s' already defined in "
1140 "current " 1361 "current "
1141 "scope ", 1362 "scope ",
1142 a->file_name, node->var_name->line, node->var_name->col, 1363 a->file_name, node->var.name->line, node->var.name->col,
1143 symbol); 1364 symbol);
1144 a->err = true; 1365 a->err = true;
1145 return cstr(""); 1366 return cstr("");
1146 } 1367 }
1147 symmap_insert(&scope->symbols, symbol, 1368 symmap_insert(&prev_scope->symbols, symbol,
1148 (Symbol){.name = symbol, .kind = SYM_FUN}, 1369 (Symbol){.name = symbol, .kind = SYM_FUN},
1149 a->storage); 1370 a->storage);
1150 } 1371 }
1151 scope->name = symbol; 1372 scope->name = symbol;
1152 funmap_insert(&prev_scope->funcs, symbol, 1373 fun.param_type = param_type;
1153 (Fun){.name = symbol, 1374 fun.return_type = ret_type;
1154 .param_type = param_type, 1375 funmap_insert(&prev_scope->funcs, symbol, fun, a->storage);
1155 .return_type = ret_type}, 1376 symbol = str_concat(cstr("."), symbol, a->storage);
1156 a->storage); 1377 symbol = str_concat(
1378 symbol, str_from_int(prev_scope->id, a->storage), a->storage);
1379 node->unique_name = symbol;
1157 1380
1158 if (node->func_body->kind == NODE_BLOCK) { 1381 if (node->func.body->kind == NODE_BLOCK) {
1159 Str type; 1382 Str type;
1160 for (sz i = 0; i < array_size(node->func_body->elements); i++) { 1383 for (sz i = 0; i < array_size(node->func.body->elements); i++) {
1161 Node *expr = node->func_body->elements[i]; 1384 Node *expr = node->func.body->elements[i];
1162 type = type_inference(a, expr, scope); 1385 type = type_inference(a, expr, scope);
1163 } 1386 }
1164 if (!type.size) { 1387 if (!type.size) {
1165 type = cstr("nil"); 1388 type = cstr("nil");
1166 } 1389 }
1167 node->func_body->type = type; 1390 node->func.body->type = type;
1168 } else { 1391 } else {
1169 type_inference(a, node->func_body, scope); 1392 type_inference(a, node->func.body, scope);
1170 } 1393 }
1171 1394
1172 // Ensure main body return matches the prototype. 1395 // Ensure main body return matches the prototype.
1173 if (!str_eq(node->func_body->type, ret_type)) { 1396 Str type = str_remove_prefix(node->func.body->type, cstr("ret:"));
1174 eprintln( 1397 node->func.body->type = type;
1175 "%s:%d:%d: error: mismatched return type %s, expected %s", 1398 if (!str_eq(type, ret_type)) {
1176 a->file_name, node->line, node->col, node->func_body->type, 1399 if (!(strset_lookup(&a->integer_types, type) &&
1177 ret_type); 1400 strset_lookup(&a->integer_types, ret_type)) ||
1178 a->err = true; 1401 !(strset_lookup(&a->numeric_types, type) &&
1402 strset_lookup(&a->numeric_types, ret_type))) {
1403 eprintln(
1404 "%s:%d:%d: error: mismatched return type %s, "
1405 "expected "
1406 "%s",
1407 a->file_name, node->line, node->col, type, ret_type);
1408 a->err = true;
1409 }
1179 } 1410 }
1180 1411
1181 // Ensure ALL return statements match the function prototype. 1412 // Ensure ALL return statements match the function prototype.
1182 typecheck_returns(a, node->func_body, ret_type); 1413 typecheck_returns(a, node->func.body, ret_type);
1183
1184 // TODO: should return statements be allowed on let blocks?
1185 return node->type; 1414 return node->type;
1186 } break; 1415 } break;
1187 default: { 1416 default: {
1188 emit_semantic_error(a, node, 1417 eprintln(
1189 cstr("type inference not implemented for this " 1418 "%s:%d:%d: error: type inference not implemented for node "
1190 "kind of expression")); 1419 "type: %s",
1191 println("KIND: %s", node_str[node->kind]); 1420 a->file_name, node->line, node->col, node_str[node->kind]);
1421 a->err = true;
1192 } break; 1422 } break;
1193 } 1423 }
1194 return cstr(""); 1424 return cstr("");
1195} 1425}
1196 1426
1427typedef struct BuiltinFun {
1428 Str name;
1429 Str param_type;
1430 Str return_type;
1431 sz param_arity;
1432 sz return_arity;
1433} BuiltinFun;
1434
1197void 1435void
1198symbolic_analysis(Analyzer *a, Parser *parser) { 1436symbolic_analysis(Analyzer *a, Parser *parser) {
1199 Scope *scope = typescope_alloc(a, NULL); 1437 Scope *scope = typescope_alloc(a, NULL);
@@ -1201,64 +1439,114 @@ symbolic_analysis(Analyzer *a, Parser *parser) {
1201 assert(parser); 1439 assert(parser);
1202 1440
1203 // Fill builtin tables. 1441 // Fill builtin tables.
1204 Str builtin_functions[] = { 1442 BuiltinFun builtin_functions[] = {
1205 cstr("print"), 1443 {cstr("print"), cstr("..."), cstr("nil"), -1, 0},
1206 cstr("println"), 1444 {cstr("println"), cstr("..."), cstr("nil"), -1, 0},
1445 {cstr("sizeof"), cstr(":"), cstr("Int"), 1, 1},
1207 }; 1446 };
1208 for (sz i = 0; i < LEN(builtin_functions); i++) { 1447 for (sz i = 0; i < LEN(builtin_functions); i++) {
1209 Str symbol = builtin_functions[i]; 1448 Str symbol = builtin_functions[i].name;
1449 Str param_type = builtin_functions[i].param_type;
1450 Str return_type = builtin_functions[i].return_type;
1451 sz param_arity = builtin_functions[i].param_arity;
1452 sz return_arity = builtin_functions[i].return_arity;
1210 symmap_insert(&scope->symbols, symbol, 1453 symmap_insert(&scope->symbols, symbol,
1211 (Symbol){.name = symbol, .kind = SYM_BUILTIN_FUN}, 1454 (Symbol){.name = symbol, .kind = SYM_BUILTIN_FUN},
1212 a->storage); 1455 a->storage);
1213 funmap_insert(&scope->funcs, symbol, 1456 funmap_insert(&scope->funcs, symbol,
1214 (Fun){.name = symbol, 1457 (Fun){
1215 .param_type = cstr("..."), 1458 .name = symbol,
1216 .return_type = cstr("nil")}, 1459 .param_type = param_type,
1460 .return_type = return_type,
1461 .param_arity = param_arity,
1462 .return_arity = return_arity,
1463 },
1217 a->storage); 1464 a->storage);
1218 } 1465 }
1219 Str builtin_types[] = { 1466 Str builtin_types[] = {
1220 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), 1467 cstr("U8"), cstr("S8"), cstr("U16"), cstr("S16"),
1221 cstr("u32"), cstr("s32"), cstr("u64"), cstr("s64"), 1468 cstr("U32"), cstr("S32"), cstr("U64"), cstr("S64"),
1222 cstr("f32"), cstr("f64"), cstr("ptr"), cstr("int"), 1469 cstr("F32"), cstr("F64"), cstr("Ptr"), cstr("Int"),
1223 cstr("uint"), cstr("str"), cstr("bool"), cstr("nil")}; 1470 cstr("UInt"), cstr("Str"), cstr("Bool"), cstr("Nil")};
1224 for (sz i = 0; i < LEN(builtin_types); i++) { 1471 for (sz i = 0; i < LEN(builtin_types); i++) {
1225 Str type = builtin_types[i]; 1472 Str type = builtin_types[i];
1226 symmap_insert(&scope->symbols, type, 1473 symmap_insert(&scope->symbols, type,
1227 (Symbol){.name = type, .kind = SYM_BUILTIN_TYPE}, 1474 (Symbol){.name = cstr("nil"), .kind = SYM_BUILTIN_TYPE},
1228 a->storage); 1475 a->storage);
1476 strset_insert(&scope->types, type, a->storage);
1229 } 1477 }
1230 Str numeric_types[] = { 1478 Str numeric_types[] = {
1231 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), cstr("u32"), 1479 cstr("U8"), cstr("S8"), cstr("U16"), cstr("S16"), cstr("U32"),
1232 cstr("s32"), cstr("u64"), cstr("s64"), cstr("f32"), cstr("f64"), 1480 cstr("S32"), cstr("U64"), cstr("S64"), cstr("F32"), cstr("F64"),
1233 cstr("ptr"), cstr("int"), cstr("uint"), 1481 cstr("Ptr"), cstr("Int"), cstr("UInt"),
1234 }; 1482 };
1235 for (sz i = 0; i < LEN(numeric_types); i++) { 1483 for (sz i = 0; i < LEN(numeric_types); i++) {
1236 Str type = numeric_types[i]; 1484 Str type = numeric_types[i];
1237 strset_insert(&a->numeric_types, type, a->storage); 1485 strset_insert(&a->numeric_types, type, a->storage);
1238 } 1486 }
1239 Str integer_types[] = { 1487 Str integer_types[] = {
1240 cstr("u8"), cstr("s8"), cstr("u16"), cstr("s16"), 1488 cstr("U8"), cstr("S8"), cstr("U16"), cstr("S16"),
1241 cstr("u32"), cstr("s32"), cstr("u64"), cstr("s64"), 1489 cstr("U32"), cstr("S32"), cstr("U64"), cstr("S64"),
1242 cstr("ptr"), cstr("int"), cstr("uint"), 1490 cstr("Ptr"), cstr("Int"), cstr("UInt"),
1243 }; 1491 };
1244 for (sz i = 0; i < LEN(integer_types); i++) { 1492 for (sz i = 0; i < LEN(integer_types); i++) {
1245 Str type = integer_types[i]; 1493 Str type = integer_types[i];
1246 strset_insert(&a->integer_types, type, a->storage); 1494 strset_insert(&a->integer_types, type, a->storage);
1247 } 1495 }
1496 Str float_types[] = {
1497 cstr("F32"),
1498 cstr("F64"),
1499 };
1500 for (sz i = 0; i < LEN(float_types); i++) {
1501 Str type = float_types[i];
1502 strset_insert(&a->float_types, type, a->storage);
1503 }
1248 // Find top level function declarations. 1504 // Find top level function declarations.
1249 for (sz i = 0; i < array_size(parser->nodes); i++) { 1505 for (sz i = 0; i < array_size(parser->nodes); i++) {
1250 Node *root = parser->nodes[i]; 1506 Node *root = parser->nodes[i];
1251 if (root->kind == NODE_FUN) { 1507 if (root->kind == NODE_FUN) {
1252 Str symbol = root->func_name->value.str; 1508 Str symbol = root->func.name->value.str;
1253 if (symmap_lookup(&scope->symbols, symbol)) { 1509 if (symmap_lookup(&scope->symbols, symbol)) {
1254 eprintln( 1510 eprintln(
1255 "%s:%d:%d: error: function '%s' already defined in " 1511 "%s:%d:%d: error: function '%s' already defined in "
1256 "current " 1512 "current "
1257 "scope ", 1513 "scope ",
1258 a->file_name, root->var_name->line, root->var_name->col, 1514 a->file_name, root->var.name->line, root->var.name->col,
1259 symbol); 1515 symbol);
1260 a->err = true; 1516 a->err = true;
1261 } 1517 }
1518 Fun fun = (Fun){.name = symbol};
1519 Str param_type = cstr("");
1520 for (sz i = 0; i < array_size(root->func.params); i++) {
1521 Node *param = root->func.params[i];
1522 Str type = param->param.type->value.str;
1523 array_push(fun.param_types, type, a->storage);
1524 param_type = str_concat(param_type, type, a->storage);
1525 if (i != array_size(root->func.params) - 1) {
1526 param_type = str_concat(param_type, cstr(","), a->storage);
1527 }
1528 }
1529 if (!param_type.size) {
1530 param_type = cstr("nil");
1531 }
1532 root->type_params = param_type;
1533
1534 Str ret_type = cstr("");
1535 for (sz i = 0; i < array_size(root->func.ret); i++) {
1536 Node *expr = root->func.ret[i];
1537 Str type = expr->value.str;
1538 array_push(fun.return_types, ret_type, a->storage);
1539 ret_type = str_concat(ret_type, type, a->storage);
1540 if (i != array_size(root->func.ret) - 1) {
1541 ret_type = str_concat(ret_type, cstr(","), a->storage);
1542 }
1543 }
1544 if (!ret_type.size) {
1545 ret_type = cstr("nil");
1546 }
1547 fun.param_type = param_type;
1548 fun.return_type = ret_type;
1549 funmap_insert(&scope->funcs, symbol, fun, a->storage);
1262 symmap_insert(&scope->symbols, symbol, 1550 symmap_insert(&scope->symbols, symbol,
1263 (Symbol){.name = symbol, .kind = SYM_FUN}, 1551 (Symbol){.name = symbol, .kind = SYM_FUN},
1264 a->storage); 1552 a->storage);