aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-27 17:01:21 +0200
committerBad Diode <bd@badd10de.dev>2024-06-27 17:01:21 +0200
commit3a639adc1daa7a17d100403583003c79d116748f (patch)
tree875174b37d6d52867fb29ac9d19215149de88f6a
parent7f81a3e35ab0b02ef7695cb399cd7302e98d6296 (diff)
downloadbdl-3a639adc1daa7a17d100403583003c79d116748f.tar.gz
bdl-3a639adc1daa7a17d100403583003c79d116748f.zip
More pointers and array typechecking
-rw-r--r--src/main.c32
-rw-r--r--tests/semantics.bad28
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 @@
8#include "vm.c" 8#include "vm.c"
9 9
10// TODO: unions 10// TODO: unions
11// TODO: arrays and pointers
12// TODO: embed (binary file) and include (source file) 11// TODO: embed (binary file) and include (source file)
12// TODO: revisit ast parsing for pointers and arrays (I think I'm missing corner
13// cases).
13 14
14typedef enum ExecMode { 15typedef enum ExecMode {
15 RUN_NORMAL, 16 RUN_NORMAL,
@@ -57,12 +58,6 @@ typedef struct Symbol {
57 SymbolKind kind; 58 SymbolKind kind;
58} Symbol; 59} Symbol;
59 60
60typedef struct ArraySymbol {
61 Str name;
62 Str type;
63 sz size;
64} ArraySymbol;
65
66typedef struct Fun { 61typedef struct Fun {
67 Str name; 62 Str name;
68 Str param_type; 63 Str param_type;
@@ -80,7 +75,6 @@ typedef struct Struct {
80 Node *val; 75 Node *val;
81} Struct; 76} Struct;
82 77
83MAPDEF(ArrayMap, arraymap, Str, ArraySymbol, str_hash, str_eq)
84MAPDEF(SymbolMap, symmap, Str, Symbol, str_hash, str_eq) 78MAPDEF(SymbolMap, symmap, Str, Symbol, str_hash, str_eq)
85MAPDEF(FunMap, funmap, Str, Fun, str_hash, str_eq) 79MAPDEF(FunMap, funmap, Str, Fun, str_hash, str_eq)
86MAPDEF(EnumMap, enummap, Str, Enum, str_hash, str_eq) 80MAPDEF(EnumMap, enummap, Str, Enum, str_hash, str_eq)
@@ -94,7 +88,6 @@ typedef struct Scope {
94 FunMap *funcs; 88 FunMap *funcs;
95 EnumMap *enums; 89 EnumMap *enums;
96 StructMap *structs; 90 StructMap *structs;
97 ArrayMap *arrays;
98 struct Scope *parent; 91 struct Scope *parent;
99} Scope; 92} Scope;
100 93
@@ -315,6 +308,12 @@ typecheck_field(Analyzer *a, Node *node, Scope *scope, Str symbol) {
315 node->field_type->line, node->field_type->col, field_type); 308 node->field_type->line, node->field_type->col, field_type);
316 a->err = true; 309 a->err = true;
317 } 310 }
311 if (node->field_type->is_ptr) {
312 field_type = str_concat(cstr("@"), field_type, a->storage);
313 }
314 if (node->field_type->kind == NODE_ARR_TYPE) {
315 field_type = str_concat(cstr("@"), field_type, a->storage);
316 }
318 if (structmap_lookup(&scope->structs, field_name)) { 317 if (structmap_lookup(&scope->structs, field_name)) {
319 eprintln("%s:%d:%d: error: struct field '%s' already exists", 318 eprintln("%s:%d:%d: error: struct field '%s' already exists",
320 a->file_name, node->line, node->col, field_name); 319 a->file_name, node->line, node->col, field_name);
@@ -956,7 +955,20 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
956 a->err = true; 955 a->err = true;
957 return cstr(""); 956 return cstr("");
958 } 957 }
959 node->type = field->val.type; 958 Str field_type = field->val.type;
959 if (next->kind == NODE_SYMBOL_IDX) {
960 Str idx_type =
961 type_inference(a, next->arr_size, scope);
962 if (!strset_lookup(&a->integer_types, idx_type)) {
963 emit_semantic_error(
964 a, next,
965 cstr("can't resolve non integer index"));
966 return cstr("");
967 }
968 field_type =
969 str_remove_prefix(field_type, cstr("@"));
970 }
971 node->type = field_type;
960 return node->type; 972 return node->type;
961 } 973 }
962 } 974 }
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 @@
1; We can have static arrays and have indexed access.
2let a = 1 1let a = 1
3let numbers: @int 2let numbers: @int
4set numbers[a] = 32 3set numbers[a] = 32
5set numbers[1] = numbers[0] 4set numbers[1] = numbers[0]
5
6let numbers_arr: int[0xff] 6let numbers_arr: int[0xff]
7set numbers_arr[0] = numbers[0] 7set numbers_arr[0] = numbers[0]
8
8let ptr_arr: @int[0xff] 9let ptr_arr: @int[0xff]
9set ptr_arr[0] = @numbers[0] 10set ptr_arr[0] = @numbers[0]
10 11
11; TODO: test pointers/arrays on structs 12struct vec {
12 13 a: int
13; ; Arrays are syntactic sugar for pointers (@). 14 b: str
14; let ptr:@u32 = numbers 15}
15; set ptr[10] = 33 16let b: @vec
16 17set b[0].a = 1
17; ; Strings hold a .mem and .size fields with the number of bytes it holds. 18
18; let hello: str = "hello world" 19struct ptrs {
19; set c[1] = 'a' ; "hallo world" 20 a: @int
21 b: str[128]
22 c: vec[100]
23}
24let c: ptrs
25set c.a[0] = 1
26set c.b[0] = "ho"
27; set c.c[0].a = 1 ; this doesn't work at the moment
20 28
21; ; fun foo(a: int): int { 29; ; fun foo(a: int): int {
22; ; 1 30; ; 1