aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-25 10:36:02 +0200
committerBad Diode <bd@badd10de.dev>2024-06-25 10:36:02 +0200
commitbcc40682a0d699e8c36df62975c12cdea491d167 (patch)
tree6511cdef1730d39bb81fceaf9839658654280f32 /src
parent9eb5c9bfa3fcf8d7b03efd7d4def71e39ae3f799 (diff)
downloadbdl-bcc40682a0d699e8c36df62975c12cdea491d167.tar.gz
bdl-bcc40682a0d699e8c36df62975c12cdea491d167.zip
Add struct literals typechecking
Diffstat (limited to 'src')
-rw-r--r--src/main.c58
-rw-r--r--src/parser.c2
2 files changed, 50 insertions, 10 deletions
diff --git a/src/main.c b/src/main.c
index 33d193b..6c3f3a5 100644
--- a/src/main.c
+++ b/src/main.c
@@ -12,6 +12,8 @@
12// TODO: nested structs 12// TODO: nested structs
13// TODO: unions 13// TODO: unions
14// TODO: match deconstruct structs 14// TODO: match deconstruct structs
15// TODO: arrays and pointers
16// TODO: struct literals
15 17
16typedef enum ExecMode { 18typedef enum ExecMode {
17 RUN_NORMAL, 19 RUN_NORMAL,
@@ -486,13 +488,18 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
486 } 488 }
487 // TODO: Consider compatible types. 489 // TODO: Consider compatible types.
488 if (!str_eq(type, type_name)) { 490 if (!str_eq(type, type_name)) {
489 eprintln( 491 // Special case, enums can be treated as ints.
490 "%s:%d:%d: error: type mismatch, trying to assing " 492 EnumMap *e = find_enum(scope, type_name);
491 "%s" 493 if (!(e && str_eq(type, cstr("int")))) {
492 " to a variable of type %s", 494 eprintln(
493 a->file_name, node->var_type->line, 495 "%s:%d:%d: error: type mismatch, trying to "
494 node->var_type->col, type, type_name); 496 "assing "
495 return cstr(""); 497 "%s"
498 " to a variable of type %s",
499 a->file_name, node->var_type->line,
500 node->var_type->col, type, type_name);
501 return cstr("");
502 }
496 } 503 }
497 } 504 }
498 typemap_insert(&scope->types, symbol, type->val, a->storage); 505 typemap_insert(&scope->types, symbol, type->val, a->storage);
@@ -515,8 +522,7 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
515 "%s:%d:%d: error: type mismatch, trying to assing " 522 "%s:%d:%d: error: type mismatch, trying to assing "
516 "%s" 523 "%s"
517 " to a variable of type %s", 524 " to a variable of type %s",
518 a->file_name, node->line, node->col, 525 a->file_name, node->line, node->col, val, name);
519 val, name);
520 return cstr(""); 526 return cstr("");
521 } 527 }
522 node->type = cstr("nil"); 528 node->type = cstr("nil");
@@ -849,6 +855,40 @@ type_inference(Analyzer *a, Node *node, TypeScope *scope) {
849 node->type = type->val; 855 node->type = type->val;
850 return node->type; 856 return node->type;
851 } break; 857 } break;
858 case NODE_STRUCT_LIT: {
859 Str name = node->value.str;
860 StructMap *s = find_struct(scope, name);
861 if (!s) {
862 eprintln("%s:%d:%d: error: unknown struct type '%s'",
863 a->file_name, node->line, node->col, name);
864 return cstr("");
865 }
866 for (sz i = 0; i < array_size(node->elements); i++) {
867 Node *next = node->elements[i];
868 Str field_name = next->field_name->value.str;
869 FieldMap *field = fieldmap_lookup(&s->val.fields, field_name);
870 if (!field) {
871 eprintln(
872 "%s:%d:%d: error: unknown struct field for symbol '%s'",
873 a->file_name, next->line, next->col, field_name);
874 } else {
875 if (next->field_val) {
876 Type type = type_inference(a, next->field_val, scope);
877 if (!str_eq(type, field->val.type)) {
878 eprintln(
879 "%s:%d:%d: error: mismatched types in struct "
880 "value "
881 "for '%s.%s': %s expected %s",
882 a->file_name, next->line, next->col, name,
883 field_name, type, field->val.type);
884 }
885 }
886 next->type = field->val.type;
887 }
888 }
889 node->type = name;
890 return node->type;
891 } break;
852 case NODE_FUNCALL: { 892 case NODE_FUNCALL: {
853 Str symbol = node->value.str; 893 Str symbol = node->value.str;
854 FunMap *fun = find_fun(scope, symbol); 894 FunMap *fun = find_fun(scope, symbol);
diff --git a/src/parser.c b/src/parser.c
index 7b49b55..b08c82a 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -959,7 +959,7 @@ parse_symbol(Parser *parser) {
959 field->field_name = array_pop(parser->nodes); 959 field->field_name = array_pop(parser->nodes);
960 parse_consume(parser, TOK_ASSIGN, cstr("expected assignment")); 960 parse_consume(parser, TOK_ASSIGN, cstr("expected assignment"));
961 parse_expr(parser, PREC_LOW); 961 parse_expr(parser, PREC_LOW);
962 field->field_type = array_pop(parser->nodes); 962 field->field_val = array_pop(parser->nodes);
963 array_push(node->elements, field, parser->storage); 963 array_push(node->elements, field, parser->storage);
964 } 964 }
965 } else if (parse_match(parser, TOK_LSQUARE)) { 965 } else if (parse_match(parser, TOK_LSQUARE)) {