aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-28 08:36:45 +0200
committerBad Diode <bd@badd10de.dev>2024-06-28 08:36:45 +0200
commit532a6ce0b88fde6ae747589de9752dba86cece39 (patch)
tree3dc18a39a3aaf77a045b74c67958282362c7b922
parent3a639adc1daa7a17d100403583003c79d116748f (diff)
downloadbdl-532a6ce0b88fde6ae747589de9752dba86cece39.tar.gz
bdl-532a6ce0b88fde6ae747589de9752dba86cece39.zip
Fix some typechecking errors
-rw-r--r--src/main.c16
-rw-r--r--tests/functions.bad4
-rw-r--r--tests/semantics.bad404
-rw-r--r--tests/variables.bad6
4 files changed, 165 insertions, 265 deletions
diff --git a/src/main.c b/src/main.c
index b1dc0ce..cb93649 100644
--- a/src/main.c
+++ b/src/main.c
@@ -867,6 +867,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
867 node->type = cstr("str"); 867 node->type = cstr("str");
868 return node->type; 868 return node->type;
869 } break; 869 } break;
870 case NODE_ARR_TYPE:
870 case NODE_TYPE: { 871 case NODE_TYPE: {
871 SymbolMap *type = find_type(scope, node->value.str); 872 SymbolMap *type = find_type(scope, node->value.str);
872 if (!type) { 873 if (!type) {
@@ -1077,9 +1078,15 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1077 Node *param = node->func_params[i]; 1078 Node *param = node->func_params[i];
1078 Str symbol = param->param_name->value.str; 1079 Str symbol = param->param_name->value.str;
1079 Str type = param->param_type->value.str; 1080 Str type = param->param_type->value.str;
1081 if (param->param_type->is_ptr) {
1082 type = str_concat(cstr("@"), type, a->storage);
1083 }
1084 if (param->param_type->kind == NODE_ARR_TYPE) {
1085 type = str_concat(cstr("@"), type, a->storage);
1086 }
1080 param->param_name->type = 1087 param->param_name->type =
1081 type_inference(a, param->param_type, scope); 1088 type_inference(a, param->param_type, scope);
1082 param->type = param->param_name->type; 1089 param->type = type;
1083 symmap_insert(&scope->symbols, symbol, 1090 symmap_insert(&scope->symbols, symbol,
1084 (Symbol){.name = type, .kind = SYM_PARAM}, 1091 (Symbol){.name = type, .kind = SYM_PARAM},
1085 a->storage); 1092 a->storage);
@@ -1097,6 +1104,12 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1097 for (sz i = 0; i < array_size(node->func_ret); i++) { 1104 for (sz i = 0; i < array_size(node->func_ret); i++) {
1098 Node *expr = node->func_ret[i]; 1105 Node *expr = node->func_ret[i];
1099 Str type = type_inference(a, expr, scope); 1106 Str type = type_inference(a, expr, scope);
1107 if (expr->is_ptr) {
1108 type = str_concat(cstr("@"), type, a->storage);
1109 }
1110 if (expr->kind == NODE_ARR_TYPE) {
1111 type = str_concat(cstr("@"), type, a->storage);
1112 }
1100 ret_type = str_concat(ret_type, type, a->storage); 1113 ret_type = str_concat(ret_type, type, a->storage);
1101 if (i != array_size(node->func_ret) - 1) { 1114 if (i != array_size(node->func_ret) - 1) {
1102 ret_type = str_concat(ret_type, cstr(","), a->storage); 1115 ret_type = str_concat(ret_type, cstr(","), a->storage);
@@ -1163,6 +1176,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) {
1163 emit_semantic_error(a, node, 1176 emit_semantic_error(a, node,
1164 cstr("type inference not implemented for this " 1177 cstr("type inference not implemented for this "
1165 "kind of expression")); 1178 "kind of expression"));
1179 println("KIND: %s", node_str[node->kind]);
1166 } break; 1180 } break;
1167 } 1181 }
1168 return cstr(""); 1182 return cstr("");
diff --git a/tests/functions.bad b/tests/functions.bad
index 3149a24..8286908 100644
--- a/tests/functions.bad
+++ b/tests/functions.bad
@@ -24,6 +24,6 @@ fun baz(a: int, b: str): (int, str) {
24} 24}
25 25
26; Make sure we can use pointer types on params and return values. 26; Make sure we can use pointer types on params and return values.
27fun test(a: @int[256], b: @str): @int { 27fun test(a: int[256], b: @str): @int {
28 a 28 @a[32]
29} 29}
diff --git a/tests/semantics.bad b/tests/semantics.bad
index 4acc8d5..acf4316 100644
--- a/tests/semantics.bad
+++ b/tests/semantics.bad
@@ -1,6 +1,6 @@
1let a = 1 1let idx = 1
2let numbers: @int 2let numbers: @int
3set numbers[a] = 32 3set numbers[idx] = 32
4set numbers[1] = numbers[0] 4set numbers[1] = numbers[0]
5 5
6let numbers_arr: int[0xff] 6let numbers_arr: int[0xff]
@@ -9,295 +9,181 @@ set numbers_arr[0] = numbers[0]
9let ptr_arr: @int[0xff] 9let ptr_arr: @int[0xff]
10set ptr_arr[0] = @numbers[0] 10set ptr_arr[0] = @numbers[0]
11 11
12struct vec { 12struct hallo {
13 a: int 13 a: int
14 b: str 14 b: str
15} 15}
16let b: @vec 16let b: @hallo
17set b[0].a = 1 17set b[0].a = 1
18 18
19struct ptrs { 19struct ptrs {
20 a: @int 20 a: @int
21 b: str[128] 21 b: str[128]
22 c: vec[100] 22 c: hallo[100]
23} 23}
24let c: ptrs 24let c: ptrs
25set c.a[0] = 1 25set c.a[0] = 1
26set c.b[0] = "ho" 26set c.b[0] = "ho"
27; set c.c[0].a = 1 ; this doesn't work at the moment 27; set c.c[0].a = 1 ; this doesn't work at the moment
28 28
29; ; fun foo(a: int): int { 29fun foo(a: int): int {
30; ; 1 30 1
31; ; } 31}
32; ; fun bar(): int { 32fun bar(): int {
33; ; fun foo(): int 1 + 2 33 fun foo(): int 1 + 2
34; ; 1 34 1
35; ; } 35}
36; struct vec {
37; x: f64
38; y: f64
39; huh: {
40; z: int
41; id: str
42; }
43; }
44; let a = 1
45
46; match a {
47; case 1 = "ha"
48; case 2 = "ho"
49; }
50
51; cond {
52; 1 == 1 = "ha"
53; 2 != 2 = "ho"
54; }
55
56; ; struct vec {
57; ; x: f64
58; ; y: f64
59; ; huh: {
60; ; z: int
61; ; id: str
62; ; }
63; ; }
64
65; ; let v: vec = vec : {
66; ; x = 10.0
67; ; huh = {
68; ; z = 10
69; ; id = "blah"
70; ; }
71; ; }
72
73; ; fun foo(): nil {
74; ; struct vec {
75; ; z: f64
76; ; }
77; ; let a: vec
78; ; set a.z = 1.0
79; ; }
80
81; ; struct vec {
82; ; x: f64 = 2.0
83; ; y: f64 = 1.0
84; ; bruh: {
85; ; id: int = 10
86; ; msg: str = "hello"
87; ; inner: {
88; ; x: int = 32
89; ; y: str
90; ; }
91; ; }
92; ; }
93
94; ; let v: vec
95; ; set v.x = 1.0
96; ; set v.bruh.id = 1
97; ; set v.bruh.inner.y = "yo"
98
99; ; set v = vec : {
100; ; x = 1.0
101; ; y = 32.0
102; ; ; bruh = dud : {
103; ; ; id = 1
104; ; ; }
105; ; }
106
107; ; struct person {
108; ; name: str = "joe"
109; ; age: int = 18 * 2
110; ; }
111
112; ; ; We can use the dot operator to access fields.
113; ; let player_a: person
114; ; set player_a.name = "alex"
115
116; ; struct vec {
117; ; x: f64
118; ; y: f64
119; ; z: f64
120; ; }
121; ; let v = vec : { x = 1.0 }
122
123; enum weekdays {
124; mon = 1
125; tue
126; wed
127; thu
128; fri
129; sat
130; sun
131; }
132; let d = weekdays.tue
133; ; let b = a
134
135; match 1 {
136; case 2 = "monday"
137; case 3 = "tuesday"
138; else = "whateverday"
139; }
140
141; match d {
142; case mon = "monday"
143; case tue = "tuesday"
144; else = "whateverday"
145; }
146
147; struct item {
148; id: int
149; name: str
150; }
151
152; ; let a: item = item {
153; ; id = 1
154; ; }
155; ; let a: item = item ; this shouldn't work, or should it return the default val?
156; let c: item
157; set c.id = 1
158; let d = c.id
159; set a.name = "hello"
160; let b = a.id
161; let c = a.name
162
163; fun add10(a: int, b: str): int {
164; a + 10
165; }
166
167; fun foo(): int {
168; add10(1, "hello")
169; }
170 36
171; let a:f32 = (1.0 + 2.0 * 2.0) / 2.0 37let a = 1
38match a {
39 case 1 = "ha"
40 case 2 = "ho"
41}
42cond {
43 1 == 1 = "ha"
44 2 != 2 = "ho"
45}
172 46
173; let annotated:int = (1 + 2 * 2) / 2 47struct vec {
174; let numbers = 1 48 x: f64
175; let symbols = numbers 49 y: f64
176; let arith = 1 + 2 * 4 50 huh: {
177; let cmp = 1 <= 2 51 z: int
178; let logic = !true && false || (1 <= 2) 52 id: str
179; let bits = 0xff & 0b00001111 53 }
180; let block = { 54}
181; let a = 1 + 2
182; a + 3
183; }
184 55
185; let maybe = if (1 == 2) { 56let v: vec = vec : {
186; 32 57 x = 10.0
187; } else { 58 huh = {
188; 44 59 z = 10
189; } 60 id = "blah"
61 }
62}
190 63
191; let single = if (true) { 64fun baz(): nil {
192; 123 65 struct vec {
193; } 66 z: f64
67 }
68 let a: vec
69 set a.z = 1.0
70}
194 71
195; while (!true) { 72struct ext {
196; "asjdflasdjf" 73 x: f64 = 2.0
197; } 74 y: f64 = 1.0
75 bruh: {
76 id: int = 10
77 msg: str = "hello"
78 inner: {
79 x: int = 32
80 y: str
81 }
82 }
83}
198 84
199; set single = 32 85let v2: ext
86set v2.x = 1.0
87set v2.bruh.id = 1
88set v2.bruh.inner.y = "yo"
89
90set v2 = ext : {
91 x = 1.0
92 y = 32.0
93 bruh = {
94 id = 1
95 }
96}
200 97
201; cond { 98struct person {
202; 1 == 2 = "hello" 99 name: str = "joe"
203; else = "dong" 100 age: int = 18 * 2
204; } 101}
205 102
206; enum test { 103; We can use the dot operator to access fields.
207; a = 1 104let player_a: person
208; b 105set player_a.name = "alex"
209; }
210; ; Resolve struct accessors.
211; struct my_struct {
212; field_a: int
213; field_b: int
214; }
215 106
216; let a:my_struct 107struct vecf {
217; set a.field_a = 1 108 x: f64
109 y: f64
110 z: f64
111}
112let v3 = vecf : { x = 1.0 }
113
114enum weekdays {
115 mon = 1
116 tue
117 wed
118 thu
119 fri
120 sat
121 sun
122}
123let d = weekdays.tue
218 124
219; fun nested(): int { 125match 1 {
220; fun adder(a: u32, b: u32): u32 { 126 case 2 = "monday"
221; a + b 127 case 3 = "tuesday"
222; } 128 else = "whateverday"
223; if (1 + 1 == 2) { 129}
224; let b = 15
225; {
226; let c = 32
227; 5 + c
228; }
229; }
230; }
231 130
232; enum field { 131match d {
233; a 132 case mon = "monday"
234; b 133 case tue = "tuesday"
235; } 134 else = "whateverday"
135}
236 136
237; struct vec { 137fun add10(a: int, b: str): int {
238; a: int 138 a + 10
239; b: int 139}
240; }
241 140
242; fun foo(): nil { 141fun add(): int {
243; bar() 142 add10(1, "hello")
244; } 143}
245 144
246; fun bar(): nil { 145let f:f64 = (1.0 + 2.0 * 2.0) / 2.0
247; foo()
248; }
249 146
250; ; There are some builtint functions. 147let annotated:int = (1 + 2 * 2) / 2
251; println("hello world") 148let arith = 1 + 2 * 4
149let cmp = 1 <= 2
150let logic = !true && false || (1 <= 2)
151let bits = 0xff & 0b00001111
152let block = {
153 let a = 1 + 2
154 a + 3
155}
252 156
253; ; Let/set. 157let maybe = if (1 == 2) {
254; let num = 1 158 32
255; set num = 2 159} else {
256; set num = 0 + num 160 44
161}
257 162
258; ; Loops and conditionals. 163let single = if (true) {
259; if (num) 3 else 1 164 123
260; let val = if (2 + num == 4) num else num 165}
261; if (true) {
262; let c = 1
263; 1 + 1 + c
264; }
265 166
266; fun testmatches(num: int): int { 167while (!true) {
267; ; match (num) { 168 println("asjdflasdjf")
268; ; case 1 = 23 169}
269; ; case 2 = num
270; ; else = num
271; ; }
272 170
273; cond { 171set single = 32
274; 1 == 1 = 23
275; 2 != 1 = num
276; else = num
277; }
278; }
279 172
280; while (num == 1) num 173cond {
281; while (true) { 174 1 == 2 = "hello"
282; let c = 1 175 else = "dong"
283; 1 + 1 + c 176}
284; }
285; fun foo(a: int b: str): (f64, f64) {
286; fun bar(): nil {
287; println("ding")
288; }
289; if (a == 1) {
290; ; return("test", b)
291; return (3.0, 4.0)
292; }
293; return (1.0, 2.0)
294; }
295 177
296; let b = a 178fun nested(): int {
297; let a = a 179 fun adder(a: u32, b: u32): u32 {
298; set a = 10 180 a + b
299; set num = 1 << a 181 }
300; baz() 182 if (1 + 1 == 2) {
301; if (a) 1 183 let b = 15
302; if (num == 1) a 184 {
303; if (num == 1) 1 else a 185 let c = 32
186 5 + c
187 }
188 }
189}
diff --git a/tests/variables.bad b/tests/variables.bad
index 8043c14..8c7a375 100644
--- a/tests/variables.bad
+++ b/tests/variables.bad
@@ -54,13 +54,13 @@ let particle = entity : {
54set particle = entity : {} 54set particle = entity : {}
55 55
56; We can have static arrays and have indexed access. 56; We can have static arrays and have indexed access.
57let numbers: u32[0xff] 57let numbers: int[0xff]
58set numbers[0] = 32 58set numbers[0] = 32
59set numbers[1] = numbers[0] 59set numbers[1] = numbers[0]
60 60
61; Arrays are syntactic sugar for pointers (@). 61; Arrays are syntactic sugar for pointers (@).
62let ptr:@u32 = numbers 62let numptr: @int = numbers
63set ptr[10] = 33 63set numptr[10] = 33
64 64
65; Strings hold a .mem and .size fields with the number of bytes it holds. 65; Strings hold a .mem and .size fields with the number of bytes it holds.
66let hello: str = "hello world" 66let hello: str = "hello world"