From 3a639adc1daa7a17d100403583003c79d116748f Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 27 Jun 2024 17:01:21 +0200 Subject: More pointers and array typechecking --- src/main.c | 32 ++++++++++++++++++++++---------- tests/semantics.bad | 28 ++++++++++++++++++---------- 2 files changed, 40 insertions(+), 20 deletions(-) diff --git a/src/main.c b/src/main.c index 669984b..b1dc0ce 100644 --- a/src/main.c +++ b/src/main.c @@ -8,8 +8,9 @@ #include "vm.c" // TODO: unions -// TODO: arrays and pointers // TODO: embed (binary file) and include (source file) +// TODO: revisit ast parsing for pointers and arrays (I think I'm missing corner +// cases). typedef enum ExecMode { RUN_NORMAL, @@ -57,12 +58,6 @@ typedef struct Symbol { SymbolKind kind; } Symbol; -typedef struct ArraySymbol { - Str name; - Str type; - sz size; -} ArraySymbol; - typedef struct Fun { Str name; Str param_type; @@ -80,7 +75,6 @@ typedef struct Struct { Node *val; } Struct; -MAPDEF(ArrayMap, arraymap, Str, ArraySymbol, str_hash, str_eq) MAPDEF(SymbolMap, symmap, Str, Symbol, str_hash, str_eq) MAPDEF(FunMap, funmap, Str, Fun, str_hash, str_eq) MAPDEF(EnumMap, enummap, Str, Enum, str_hash, str_eq) @@ -94,7 +88,6 @@ typedef struct Scope { FunMap *funcs; EnumMap *enums; StructMap *structs; - ArrayMap *arrays; struct Scope *parent; } Scope; @@ -315,6 +308,12 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) { node->field_type->line, node->field_type->col, field_type); a->err = true; } + if (node->field_type->is_ptr) { + field_type = str_concat(cstr("@"), field_type, a->storage); + } + if (node->field_type->kind == NODE_ARR_TYPE) { + field_type = str_concat(cstr("@"), field_type, a->storage); + } if (structmap_lookup(&scope->structs, field_name)) { eprintln("%s:%d:%d: error: struct field '%s' already exists", a->file_name, node->line, node->col, field_name); @@ -956,7 +955,20 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { a->err = true; return cstr(""); } - node->type = field->val.type; + Str field_type = field->val.type; + if (next->kind == NODE_SYMBOL_IDX) { + Str idx_type = + type_inference(a, next->arr_size, scope); + if (!strset_lookup(&a->integer_types, idx_type)) { + emit_semantic_error( + a, next, + cstr("can't resolve non integer index")); + return cstr(""); + } + field_type = + str_remove_prefix(field_type, cstr("@")); + } + node->type = field_type; return node->type; } } diff --git a/tests/semantics.bad b/tests/semantics.bad index 1bb2ceb..4acc8d5 100644 --- a/tests/semantics.bad +++ b/tests/semantics.bad @@ -1,22 +1,30 @@ -; We can have static arrays and have indexed access. let a = 1 let numbers: @int set numbers[a] = 32 set numbers[1] = numbers[0] + let numbers_arr: int[0xff] set numbers_arr[0] = numbers[0] + let ptr_arr: @int[0xff] set ptr_arr[0] = @numbers[0] -; TODO: test pointers/arrays on structs - -; ; Arrays are syntactic sugar for pointers (@). -; let ptr:@u32 = numbers -; set ptr[10] = 33 - -; ; Strings hold a .mem and .size fields with the number of bytes it holds. -; let hello: str = "hello world" -; set c[1] = 'a' ; "hallo world" +struct vec { + a: int + b: str +} +let b: @vec +set b[0].a = 1 + +struct ptrs { + a: @int + b: str[128] + c: vec[100] +} +let c: ptrs +set c.a[0] = 1 +set c.b[0] = "ho" +; set c.c[0].a = 1 ; this doesn't work at the moment ; ; fun foo(a: int): int { ; ; 1 -- cgit v1.2.1