From 532a6ce0b88fde6ae747589de9752dba86cece39 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Fri, 28 Jun 2024 08:36:45 +0200 Subject: Fix some typechecking errors --- src/main.c | 16 ++- tests/functions.bad | 4 +- tests/semantics.bad | 404 +++++++++++++++++++--------------------------------- tests/variables.bad | 6 +- 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) { node->type = cstr("str"); return node->type; } break; + case NODE_ARR_TYPE: case NODE_TYPE: { SymbolMap *type = find_type(scope, node->value.str); if (!type) { @@ -1077,9 +1078,15 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { Node *param = node->func_params[i]; Str symbol = param->param_name->value.str; Str type = param->param_type->value.str; + if (param->param_type->is_ptr) { + type = str_concat(cstr("@"), type, a->storage); + } + if (param->param_type->kind == NODE_ARR_TYPE) { + type = str_concat(cstr("@"), type, a->storage); + } param->param_name->type = type_inference(a, param->param_type, scope); - param->type = param->param_name->type; + param->type = type; symmap_insert(&scope->symbols, symbol, (Symbol){.name = type, .kind = SYM_PARAM}, a->storage); @@ -1097,6 +1104,12 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { for (sz i = 0; i < array_size(node->func_ret); i++) { Node *expr = node->func_ret[i]; Str type = type_inference(a, expr, scope); + if (expr->is_ptr) { + type = str_concat(cstr("@"), type, a->storage); + } + if (expr->kind == NODE_ARR_TYPE) { + type = str_concat(cstr("@"), type, a->storage); + } ret_type = str_concat(ret_type, type, a->storage); if (i != array_size(node->func_ret) - 1) { ret_type = str_concat(ret_type, cstr(","), a->storage); @@ -1163,6 +1176,7 @@ type_inference(Analyzer *a, Node *node, Scope *scope) { emit_semantic_error(a, node, cstr("type inference not implemented for this " "kind of expression")); + println("KIND: %s", node_str[node->kind]); } break; } 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) { } ; Make sure we can use pointer types on params and return values. -fun test(a: @int[256], b: @str): @int { - a +fun test(a: int[256], b: @str): @int { + @a[32] } 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 @@ -let a = 1 +let idx = 1 let numbers: @int -set numbers[a] = 32 +set numbers[idx] = 32 set numbers[1] = numbers[0] let numbers_arr: int[0xff] @@ -9,295 +9,181 @@ set numbers_arr[0] = numbers[0] let ptr_arr: @int[0xff] set ptr_arr[0] = @numbers[0] -struct vec { +struct hallo { a: int b: str } -let b: @vec +let b: @hallo set b[0].a = 1 struct ptrs { a: @int b: str[128] - c: vec[100] + c: hallo[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 -; ; } -; ; fun bar(): int { -; ; fun foo(): int 1 + 2 -; ; 1 -; ; } -; struct vec { -; x: f64 -; y: f64 -; huh: { -; z: int -; id: str -; } -; } -; let a = 1 - -; match a { -; case 1 = "ha" -; case 2 = "ho" -; } - -; cond { -; 1 == 1 = "ha" -; 2 != 2 = "ho" -; } - -; ; struct vec { -; ; x: f64 -; ; y: f64 -; ; huh: { -; ; z: int -; ; id: str -; ; } -; ; } - -; ; let v: vec = vec : { -; ; x = 10.0 -; ; huh = { -; ; z = 10 -; ; id = "blah" -; ; } -; ; } - -; ; fun foo(): nil { -; ; struct vec { -; ; z: f64 -; ; } -; ; let a: vec -; ; set a.z = 1.0 -; ; } - -; ; struct vec { -; ; x: f64 = 2.0 -; ; y: f64 = 1.0 -; ; bruh: { -; ; id: int = 10 -; ; msg: str = "hello" -; ; inner: { -; ; x: int = 32 -; ; y: str -; ; } -; ; } -; ; } - -; ; let v: vec -; ; set v.x = 1.0 -; ; set v.bruh.id = 1 -; ; set v.bruh.inner.y = "yo" - -; ; set v = vec : { -; ; x = 1.0 -; ; y = 32.0 -; ; ; bruh = dud : { -; ; ; id = 1 -; ; ; } -; ; } - -; ; struct person { -; ; name: str = "joe" -; ; age: int = 18 * 2 -; ; } - -; ; ; We can use the dot operator to access fields. -; ; let player_a: person -; ; set player_a.name = "alex" - -; ; struct vec { -; ; x: f64 -; ; y: f64 -; ; z: f64 -; ; } -; ; let v = vec : { x = 1.0 } - -; enum weekdays { -; mon = 1 -; tue -; wed -; thu -; fri -; sat -; sun -; } -; let d = weekdays.tue -; ; let b = a - -; match 1 { -; case 2 = "monday" -; case 3 = "tuesday" -; else = "whateverday" -; } - -; match d { -; case mon = "monday" -; case tue = "tuesday" -; else = "whateverday" -; } - -; struct item { -; id: int -; name: str -; } - -; ; let a: item = item { -; ; id = 1 -; ; } -; ; let a: item = item ; this shouldn't work, or should it return the default val? -; let c: item -; set c.id = 1 -; let d = c.id -; set a.name = "hello" -; let b = a.id -; let c = a.name - -; fun add10(a: int, b: str): int { -; a + 10 -; } - -; fun foo(): int { -; add10(1, "hello") -; } +fun foo(a: int): int { + 1 +} +fun bar(): int { + fun foo(): int 1 + 2 + 1 +} -; let a:f32 = (1.0 + 2.0 * 2.0) / 2.0 +let a = 1 +match a { + case 1 = "ha" + case 2 = "ho" +} +cond { + 1 == 1 = "ha" + 2 != 2 = "ho" +} -; let annotated:int = (1 + 2 * 2) / 2 -; let numbers = 1 -; let symbols = numbers -; let arith = 1 + 2 * 4 -; let cmp = 1 <= 2 -; let logic = !true && false || (1 <= 2) -; let bits = 0xff & 0b00001111 -; let block = { -; let a = 1 + 2 -; a + 3 -; } +struct vec { + x: f64 + y: f64 + huh: { + z: int + id: str + } +} -; let maybe = if (1 == 2) { -; 32 -; } else { -; 44 -; } +let v: vec = vec : { + x = 10.0 + huh = { + z = 10 + id = "blah" + } +} -; let single = if (true) { -; 123 -; } +fun baz(): nil { + struct vec { + z: f64 + } + let a: vec + set a.z = 1.0 +} -; while (!true) { -; "asjdflasdjf" -; } +struct ext { + x: f64 = 2.0 + y: f64 = 1.0 + bruh: { + id: int = 10 + msg: str = "hello" + inner: { + x: int = 32 + y: str + } + } +} -; set single = 32 +let v2: ext +set v2.x = 1.0 +set v2.bruh.id = 1 +set v2.bruh.inner.y = "yo" + +set v2 = ext : { + x = 1.0 + y = 32.0 + bruh = { + id = 1 + } +} -; cond { -; 1 == 2 = "hello" -; else = "dong" -; } +struct person { + name: str = "joe" + age: int = 18 * 2 +} -; enum test { -; a = 1 -; b -; } -; ; Resolve struct accessors. -; struct my_struct { -; field_a: int -; field_b: int -; } +; We can use the dot operator to access fields. +let player_a: person +set player_a.name = "alex" -; let a:my_struct -; set a.field_a = 1 +struct vecf { + x: f64 + y: f64 + z: f64 +} +let v3 = vecf : { x = 1.0 } + +enum weekdays { + mon = 1 + tue + wed + thu + fri + sat + sun +} +let d = weekdays.tue -; fun nested(): int { -; fun adder(a: u32, b: u32): u32 { -; a + b -; } -; if (1 + 1 == 2) { -; let b = 15 -; { -; let c = 32 -; 5 + c -; } -; } -; } +match 1 { + case 2 = "monday" + case 3 = "tuesday" + else = "whateverday" +} -; enum field { -; a -; b -; } +match d { + case mon = "monday" + case tue = "tuesday" + else = "whateverday" +} -; struct vec { -; a: int -; b: int -; } +fun add10(a: int, b: str): int { + a + 10 +} -; fun foo(): nil { -; bar() -; } +fun add(): int { + add10(1, "hello") +} -; fun bar(): nil { -; foo() -; } +let f:f64 = (1.0 + 2.0 * 2.0) / 2.0 -; ; There are some builtint functions. -; println("hello world") +let annotated:int = (1 + 2 * 2) / 2 +let arith = 1 + 2 * 4 +let cmp = 1 <= 2 +let logic = !true && false || (1 <= 2) +let bits = 0xff & 0b00001111 +let block = { + let a = 1 + 2 + a + 3 +} -; ; Let/set. -; let num = 1 -; set num = 2 -; set num = 0 + num +let maybe = if (1 == 2) { + 32 +} else { + 44 +} -; ; Loops and conditionals. -; if (num) 3 else 1 -; let val = if (2 + num == 4) num else num -; if (true) { -; let c = 1 -; 1 + 1 + c -; } +let single = if (true) { + 123 +} -; fun testmatches(num: int): int { -; ; match (num) { -; ; case 1 = 23 -; ; case 2 = num -; ; else = num -; ; } +while (!true) { + println("asjdflasdjf") +} -; cond { -; 1 == 1 = 23 -; 2 != 1 = num -; else = num -; } -; } +set single = 32 -; while (num == 1) num -; while (true) { -; let c = 1 -; 1 + 1 + c -; } -; fun foo(a: int b: str): (f64, f64) { -; fun bar(): nil { -; println("ding") -; } -; if (a == 1) { -; ; return("test", b) -; return (3.0, 4.0) -; } -; return (1.0, 2.0) -; } +cond { + 1 == 2 = "hello" + else = "dong" +} -; let b = a -; let a = a -; set a = 10 -; set num = 1 << a -; baz() -; if (a) 1 -; if (num == 1) a -; if (num == 1) 1 else a +fun nested(): int { + fun adder(a: u32, b: u32): u32 { + a + b + } + if (1 + 1 == 2) { + let b = 15 + { + let c = 32 + 5 + c + } + } +} 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 : { set particle = entity : {} ; We can have static arrays and have indexed access. -let numbers: u32[0xff] +let numbers: int[0xff] set numbers[0] = 32 set numbers[1] = numbers[0] ; Arrays are syntactic sugar for pointers (@). -let ptr:@u32 = numbers -set ptr[10] = 33 +let numptr: @int = numbers +set numptr[10] = 33 ; Strings hold a .mem and .size fields with the number of bytes it holds. let hello: str = "hello world" -- cgit v1.2.1