harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 8f9d7c1bb2e85da1fae80ccd06d98c69fb3c35ac
parent 62c1dd748d3f2f81d514d508fa5cab46c0a3fb52
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 12 Aug 2021 08:56:23 +0200

tests: merge new and old test suites

Diffstat:
Mtests/13-tagged.ha | 75+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/31-postfix.ha | 93+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atests/32-copy.ha | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dtests/900-basics.ha | 4----
Dtests/901-primitives.ha | 13-------------
Dtests/902-arithm.ha | 11-----------
Dtests/903-postfix.ha | 96-------------------------------------------------------------------------------
Dtests/904-copy.ha | 65-----------------------------------------------------------------
Dtests/905-assign.ha | 9---------
Dtests/906-if.ha | 19-------------------
Dtests/907-casts.ha | 45---------------------------------------------
Dtests/908-loops.ha | 26--------------------------
Dtests/909-defer.ha | 15---------------
Dtests/910-tagged.ha | 78------------------------------------------------------------------------------
Dtests/911-slices.ha | 46----------------------------------------------
Dtests/912-enums.ha | 36------------------------------------
Dtests/913-match.ha | 65-----------------------------------------------------------------
Dtests/914-switch.ha | 57---------------------------------------------------------
Mtests/configure | 41++++-------------------------------------
Dtests/rt.c | 38--------------------------------------
Dtests/rt.ha | 46----------------------------------------------
21 files changed, 235 insertions(+), 706 deletions(-)

diff --git a/tests/13-tagged.ha b/tests/13-tagged.ha @@ -90,6 +90,78 @@ fn casts() void = { assert(x == (if (is_little) 0xFEu8 else 0xCAu8)); }; +fn membercast() void = { + // Simple case + let x: (int | void) = void; + let p = &x: *struct { + id: uint, + data: int, + }; + assert(p.id == 3012680272); + x = 1337; + assert(p.id == 1737287038); + assert(p.data == 1337); + + // Align of 4 + let x: (int | f32 | void) = 1337; + let p = &x: *struct { + id: uint, + data: union { + idata: int, + fdata: f32, + }, + }; + assert(p.id == 1737287038); + assert(p.data.idata == 1337); + x = 13.37f32; + assert(p.id == 930681398); + assert(p.data.fdata == 13.37f32); + + // Align of 8 + let x: (size | void) = 1337z; + let p = &x: *struct { + id: uint, + data: size, + }; + assert(p.id == 4119164483); + assert(p.data == 1337z); +}; + +fn subsetcast() void = { + // Equal alignment + let x: (size | void) = 1337z; + let y: (size | int | void) = x; + let p = &y: *struct { + tag: uint, + data: union { + z: size, + i: int, + }, + }; + assert(p.tag == 4119164483); + assert(p.data.z == 1337z); + + // Disjoint alignment + let x: (int | void) = 1337; + let y: (size | int | void) = x; + let p = &y: *struct { + tag: uint, + data: union { + z: size, + i: int, + }, + }; + assert(p.tag == 1737287038); + assert(p.data.i == 1337); +}; + +fn castout() void = { + let x: (int | void) = 1337; + let y = x: int; + assert(y == 1337); + // XXX: We can probably expand this +}; + fn assertions() void = { let a: (u8 | u16) = 42u16; assert(a is u16); @@ -102,5 +174,8 @@ export fn main() void = { operators(); reduction(); casts(); + membercast(); + subsetcast(); + castout(); assertions(); }; diff --git a/tests/31-postfix.ha b/tests/31-postfix.ha @@ -0,0 +1,93 @@ +type coords = struct { x: size, y: size }; +type coords3 = struct { _2: coords, z: size }; + +fn foo() size = 2; +fn equal(x: int, y: int) bool = x == y; +fn aggregate(c: coords) coords = c; +fn not(x: bool) bool = x == false; + +fn nested() void = { + let c = coords3 { + _2 = coords { + x = 10, + y = 20, + }, + z = 30, + }; + assert(c._2.x == 10); + assert(c._2.y == 20); + assert(c.z == 30); + + let x = coords { x = 10, y = 20 }; + let a = [x, x, x, x]; + assert(a[0].x == 10); + assert(a[0].y == 20); + assert(a[1].x == 10); + assert(a[1].y == 20); + assert(a[2].x == 10); + assert(a[2].y == 20); + assert(a[3].x == 10); + assert(a[3].y == 20); +}; + +fn nonaccess() void = { + let c = coords { x = 10, y = 20 }; + assert(aggregate(coords { x = 10, y = 20 }).x == 10); + assert(aggregate(c).y == 20); + assert(coords { x = 10, y = 20 }.x == 10); + assert(coords { x = 10, y = 20 }.y == 20); + assert([1, 2, 3, 4][2] == 3); +}; + +fn deref() void = { + let a = coords { x = 10, y = 20 }; + let b = &a; + let c = &b; + assert(a.x == 10); + assert(b.x == 10); + assert(c.x == 10); + + let x = [1, 3, 3, 7]; + let y = &x; + let z = &y; + assert(x[2] == 3); + assert(y[2] == 3); + assert(z[2] == 3); + + let q = coords { x = 2, y = 2 }; + let o = &q; + assert(x[q.x] == 3); + assert(x[o.x] == 3); + + let f = &not; + let g = &f; + assert(not(true) == false); + assert(f(true) == false); + assert(g(true) == false); +}; + +fn calls() void = { + // Indirect + let x: size = foo(); + assert(x == 2); + + // Direct + let x = [1, 2, 3]; + assert(x[foo()] == 3); + + // Direct & indirect params + let x = 1234; + assert(equal(x, 1234)); + + // Aggregate params and return + let x = coords { x = 1234, y = 4321 }; + let x = aggregate(x); + assert(x.x == 1234 && x.y == 4321); +}; + +export fn main() void = { + nested(); + nonaccess(); + deref(); + calls(); +}; diff --git a/tests/32-copy.ha b/tests/32-copy.ha @@ -0,0 +1,63 @@ +type coords = struct { x: i8, y: int, z: size }; +type anyint = struct { _8: i8, _16: i16, _32: i32, _64: i64 }; + +export fn main() void = { + // Simple case + let x = 10; + let y = x; + assert(y == 10); + + // With indirect target + let a = [1, 2, 3, 4]; + let x = 2z; + assert(a[x] == 3); + + // Aggregate types: + // arrays + let x = [1, 2, 3, 4]; + let y = x; + assert(&x != &y); + assert(x[0] == y[0]); + assert(x[1] == y[1]); + assert(x[2] == y[2]); + assert(x[3] == y[3]); + + // structs + let a = coords { x = 10, y = 20, z = 30 }; + let b = a; + assert(&a != &b); + assert(a.x == b.x); + assert(a.y == b.y); + assert(a.z == b.z); + + // unions + let a = anyint { _16 = 10 }; + let b = a; + assert(&a != &b); + assert(a._16 == b._16); + + // tuples + let a = (1, 2z, 3u8); + let b = a; + assert(a.0 == b.0); + assert(a.1 == b.1); + assert(a.2 == b.2); + + let x = "hello world"; + let y = x; + let px = &x: *struct { + data: *[*]u8, + length: size, + capacity: size, + }; + let py = &y: *struct { + data: *[*]u8, + length: size, + capacity: size, + }; + assert(px.length == py.length); + assert(px.capacity == py.capacity); + assert(px.data == py.data); + + // TODO: Slices +}; diff --git a/tests/900-basics.ha b/tests/900-basics.ha @@ -1,4 +0,0 @@ -export fn main() int = { - assert(true); - return 0; -}; diff --git a/tests/901-primitives.ha b/tests/901-primitives.ha @@ -1,13 +0,0 @@ -export fn main() int = { - let a: int = 10; - assert(a == 10); - a = 20; - assert(a == 20); - - let a: u8 = 5u8; - assert(a == 5u8); - a = 10u8; - assert(a == 10u8); - - return 0; -}; diff --git a/tests/902-arithm.ha b/tests/902-arithm.ha @@ -1,11 +0,0 @@ -export fn main() int = { - // Indirect - let x: int = 10; - x = 2 + 2; - assert(x == 4); - - // Direct - let x = [1, 2, 3]; - assert(x[1 + 1] == 3); - return 0; -}; diff --git a/tests/903-postfix.ha b/tests/903-postfix.ha @@ -1,96 +0,0 @@ -type coords = struct { x: size, y: size }; -type coords3 = struct { _2: coords, z: size }; - -fn foo() size = 2; -fn equal(x: int, y: int) bool = x == y; -fn aggregate(c: coords) coords = c; -fn not(x: bool) bool = x == false; - -fn nested() void = { - let c = coords3 { - _2 = coords { - x = 10, - y = 20, - }, - z = 30, - }; - assert(c._2.x == 10); - assert(c._2.y == 20); - assert(c.z == 30); - - let x = coords { x = 10, y = 20 }; - let a = [x, x, x, x]; - assert(a[0].x == 10); - assert(a[0].y == 20); - assert(a[1].x == 10); - assert(a[1].y == 20); - assert(a[2].x == 10); - assert(a[2].y == 20); - assert(a[3].x == 10); - assert(a[3].y == 20); -}; - -fn nonaccess() void = { - let c = coords { x = 10, y = 20 }; - assert(aggregate(coords { x = 10, y = 20 }).x == 10); - assert(aggregate(c).y == 20); - assert(coords { x = 10, y = 20 }.x == 10); - assert(coords { x = 10, y = 20 }.y == 20); - assert([1, 2, 3, 4][2] == 3); -}; - -fn deref() void = { - let a = coords { x = 10, y = 20 }; - let b = &a; - let c = &b; - assert(a.x == 10); - assert(b.x == 10); - assert(c.x == 10); - - let x = [1, 3, 3, 7]; - let y = &x; - let z = &y; - assert(x[2] == 3); - assert(y[2] == 3); - assert(z[2] == 3); - - let q = coords { x = 2, y = 2 }; - let o = &q; - assert(x[q.x] == 3); - assert(x[o.x] == 3); - - let f = &not; - let g = &f; - assert(not(true) == false); - assert(f(true) == false); - assert(g(true) == false); -}; - -fn calls() void = { - // Indirect - let x: size = foo(); - assert(x == 2); - - // Direct - let x = [1, 2, 3]; - assert(x[foo()] == 3); - - // Direct & indirect params - let x = 1234; - assert(equal(x, 1234)); - - // Aggregate params and return - let x = coords { x = 1234, y = 4321 }; - let x = aggregate(x); - // TODO: Use && - assert(x.x == 1234); - assert(x.y == 4321); -}; - -export fn main() int = { - nested(); - nonaccess(); - deref(); - calls(); - return 0; -}; diff --git a/tests/904-copy.ha b/tests/904-copy.ha @@ -1,65 +0,0 @@ -type coords = struct { x: i8, y: int, z: size }; -type anyint = struct { _8: i8, _16: i16, _32: i32, _64: i64 }; - -export fn main() int = { - // Simple case - let x = 10; - let y = x; - assert(y == 10); - - // With indirect target - let a = [1, 2, 3, 4]; - let x = 2z; - assert(a[x] == 3); - - // Aggregate types: - // arrays - let x = [1, 2, 3, 4]; - let y = x; - assert(&x != &y); - assert(x[0] == y[0]); - assert(x[1] == y[1]); - assert(x[2] == y[2]); - assert(x[3] == y[3]); - - // structs - let a = coords { x = 10, y = 20, z = 30 }; - let b = a; - assert(&a != &b); - assert(a.x == b.x); - assert(a.y == b.y); - assert(a.z == b.z); - - // unions - let a = anyint { _16 = 10 }; - let b = a; - assert(&a != &b); - assert(a._16 == b._16); - - // tuples - let a = (1, 2z, 3u8); - let b = a; - assert(a.0 == b.0); - assert(a.1 == b.1); - assert(a.2 == b.2); - - let x = "hello world"; - let y = x; - let px = &x: *struct { - data: *[*]u8, - length: size, - capacity: size, - }; - let py = &y: *struct { - data: *[*]u8, - length: size, - capacity: size, - }; - assert(px.length == py.length); - assert(px.capacity == py.capacity); - assert(px.data == py.data); - - // TODO: Slices - - return 0; -}; diff --git a/tests/905-assign.ha b/tests/905-assign.ha @@ -1,9 +0,0 @@ -export fn main() int = { - let x = 0; - x += 1; - assert(x == 1); - let y = &x; - *y += 1; - assert(x == 2); - return 0; -}; diff --git a/tests/906-if.ha b/tests/906-if.ha @@ -1,19 +0,0 @@ -type coords = struct { x: int, y: int }; - -export fn main() int = { - let x = 10; - assert((if (false) x else 20) == 20); - - let x = if (true) 10 else abort(); - assert(x == 10); - - let x = if (true) coords { - x = 10, - y = 20, - } else abort(); - assert(x.x == 10); - - if (true) void else void; - - return 0; -}; diff --git a/tests/907-casts.ha b/tests/907-casts.ha @@ -1,45 +0,0 @@ -fn integers() void = { - let x: u8 = 42; - let y = x: int; - assert(y == 42); - - let x = 0xBEEF; - let y = x: u8; - assert(y == 0xEF); - - let x = -10i8; - let y = x: u8; - assert(y == 246); -}; - -fn floats() void = { - let x = 10; - let y = x: f32; - assert(y == 10f32); - - let x = 10; - let y = x: f64; - assert(y == 10f64); - - let x = 13.37f32; - let y = x: int; - assert(y == 13); - - let x = 13.37f64; - let y = x: int; - assert(y == 13); -}; - -fn slices() void = { - let x: [_]int = [1, 2, 3, 4]; - let y: []int = x; - let z = y: *[*]int; - assert(z == &x); -}; - -export fn main() int = { - integers(); - floats(); - slices(); - return 0; -}; diff --git a/tests/908-loops.ha b/tests/908-loops.ha @@ -1,26 +0,0 @@ -fn basics() void = { - let x = 0z; - for (let i = 0z; i < 10; i += 1) { - assert(i == x); - x += 1; - }; - assert(x == 10); - - let x = 0z; - for (let i = 0z; i < 10) { - assert(i == x); - x += 1; - i += 1; - }; - assert(x == 10); - - let x = 0z; - for (x < 10; x += 1) void; - assert(x == 10); -}; - -export fn main() int = { - basics(); - // TODO: test flow control - return 0; -}; diff --git a/tests/909-defer.ha b/tests/909-defer.ha @@ -1,15 +0,0 @@ -let x: int = 0; - -fn basics() void = { - x = 10; - defer x += 1; - assert(x == 10); - defer x += 1; - x = 20; -}; - -export fn main() int = { - basics(); - assert(x == 22); - return 0; -}; diff --git a/tests/910-tagged.ha b/tests/910-tagged.ha @@ -1,78 +0,0 @@ -fn membercast() void = { - // Simple case - let x: (int | void) = void; - let p = &x: *struct { - id: uint, - data: int, - }; - assert(p.id == 3012680272); - x = 1337; - assert(p.id == 1737287038); - assert(p.data == 1337); - - // Align of 4 - let x: (int | f32 | void) = 1337; - let p = &x: *struct { - id: uint, - data: union { - idata: int, - fdata: f32, - }, - }; - assert(p.id == 1737287038); - assert(p.data.idata == 1337); - x = 13.37f32; - assert(p.id == 930681398); - assert(p.data.fdata == 13.37f32); - - // Align of 8 - let x: (size | void) = 1337z; - let p = &x: *struct { - id: uint, - data: size, - }; - assert(p.id == 4119164483); - assert(p.data == 1337z); -}; - -fn subsetcast() void = { - // Equal alignment - let x: (size | void) = 1337z; - let y: (size | int | void) = x; - let p = &y: *struct { - tag: uint, - data: union { - z: size, - i: int, - }, - }; - assert(p.tag == 4119164483); - assert(p.data.z == 1337z); - - // Disjoint alignment - let x: (int | void) = 1337; - let y: (size | int | void) = x; - let p = &y: *struct { - tag: uint, - data: union { - z: size, - i: int, - }, - }; - assert(p.tag == 1737287038); - assert(p.data.i == 1337); -}; - -fn castout() void = { - let x: (int | void) = 1337; - let y = x: int; - assert(y == 1337); - // XXX: We can probably expand this -}; - -export fn main() int = { - membercast(); - subsetcast(); - castout(); - return 0; -}; diff --git a/tests/911-slices.ha b/tests/911-slices.ha @@ -1,46 +0,0 @@ -fn castarray() void = { - let a: [_]int = [1, 2, 3]; - let x: []int = a; - let p = &x: *struct { - data: *[3]int, - length: size, - capacity: size, - }; - assert(p.data == &a); - assert(p.length == len(a)); - assert(p.capacity == len(a)); -}; - -fn assert_slice_eq(actual: []int, expected: []int) void = { - assert(len(expected) == len(actual)); - for (let i = 0z; i < len(expected); i += 1) { - assert(expected[i] == actual[i]); - }; -}; - -fn slicing() void = { - let a = [1, 2, 3, 4, 5]; - assert_slice_eq(a[..], [1, 2, 3, 4, 5]); - assert_slice_eq(a[..3], [1, 2, 3]); - assert_slice_eq(a[1..3], [2, 3]); - assert_slice_eq(a[1..], [2, 3, 4, 5]); - - let b: []int = [1, 2, 3, 4, 5]; - assert_slice_eq(b[..], [1, 2, 3, 4, 5]); - assert_slice_eq(b[..3], [1, 2, 3]); - assert_slice_eq(b[1..3], [2, 3]); - assert_slice_eq(b[1..], [2, 3, 4, 5]); - - let p = &a; - assert_slice_eq(p[..], [1, 2, 3, 4, 5]); - assert_slice_eq(p[..3], [1, 2, 3]); - assert_slice_eq(p[1..3], [2, 3]); - assert_slice_eq(p[1..], [2, 3, 4, 5]); -}; - -export fn main() int = { - castarray(); - slicing(); - // TODO: slice assignment - return 0; -}; diff --git a/tests/912-enums.ha b/tests/912-enums.ha @@ -1,36 +0,0 @@ -type implicit = enum { - ZERO, - ONE, - TWO, -}; - -type explicit = enum { - NEGATIVE = -1, - FORTY_TWO = 42, - FORTY_THREE, -}; - -type with_storage = enum u16 { - ZERO, - A_LOT = 0xCAFE, -}; - -export fn main() int = { - assert(implicit::ZERO == 0); - assert(implicit::ONE == 1); - assert(implicit::TWO == 2); - const val = implicit::TWO; - assert(val == 2); - - assert(explicit::NEGATIVE == -1); - assert(explicit::FORTY_TWO == 42); - assert(explicit::FORTY_THREE == 43); - const val = explicit::FORTY_TWO; - assert(val == 42); - - assert(with_storage::ZERO == 0); - assert(with_storage::A_LOT == 0xCAFE); - const val = with_storage::A_LOT; - assert(val == 0xCAFE); - return 0; -}; diff --git a/tests/913-match.ha b/tests/913-match.ha @@ -1,65 +0,0 @@ -fn subtype() void = { - let cases: [3](int | uint | str) = [10i, 10u, "hello"]; - let expected: [_]size = [1, 2, 5]; - for (let i = 0z; i < len(cases); i += 1) { - let y: size = match (cases[i]) { - int => 1, - uint => 2, - s: str => len(s), - }; - assert(y == expected[i]); - }; -}; - -type foo = (int | void); -type bar = (size | foo); - -fn nested_subtype() void = { - let x: bar = 1337; - match (x) { - i: int => assert(i == 1337), - size => abort(), - void => abort(), - }; -}; - -fn subset() void = { - // Alignment compatible - let x: (int | size | void) = 1337z; - match (x) { - n: (int | size) => assert(n as size == 1337), - void => abort(), - }; - - // Alignment incompatible - let x: (int | size | void) = 1337; - match (x) { - n: (int | void) => assert(n as int == 1337), - size => abort(), - }; -}; - -fn pointer() void = { - let x = 42; - let y: nullable *int = &x; - let z: int = match (y) { - y: *int => *y, - null => abort(), - }; - assert(z == 42); - - y = null; - z = match(y) { - *int => abort(), - null => 1337, - }; - assert(z == 1337); -}; - -export fn main() int = { - subtype(); - nested_subtype(); - subset(); - pointer(); - return 0; -}; diff --git a/tests/914-switch.ha b/tests/914-switch.ha @@ -1,57 +0,0 @@ -fn basics() void = { - let cases = [[0, 1], [1, 3], [10, 20], [11, 21], [12, 22], [13, 13]]; - for (let i = 0z; i < len(cases); i += 1) { - let x = cases[i][0]; - let y: int = switch (x) { - 0 => x + 1, - 1 => x + 2, - 10, 11, 12 => x + 10, - * => { - x; - }, - }; - assert(y == cases[i][1]); - }; -}; - -fn termination() void = { - let x = 42; - let y: int = switch (x) { - 42 => 1337, - 24 => abort(), - * => abort(), - }; - assert(y == 1337); -}; - -fn tagged_result() void = { - let x = 42; - let y: (int | uint) = switch (x) { - 42 => 1337i, - * => 1337u, - }; - assert(y is int); - - x = 24; - y = switch (x) { - 42 => 1337i, - * => 1337u, - }; - assert(y is uint); -}; - -fn str_switching() void = { - let result = switch ("hare") { - "world" => abort(), - "hare" => true, - }; - assert(result == true); -}; - -export fn main() int = { - basics(); - termination(); - tagged_result(); - str_switching(); - return 0; -}; diff --git a/tests/configure b/tests/configure @@ -2,42 +2,7 @@ all="$all tests" tests() { - # Temporary test suite - for t in \ - 900-basics \ - 901-primitives \ - 902-arithm \ - 903-postfix \ - 904-copy \ - 905-assign \ - 906-if \ - 907-casts \ - 908-loops \ - 909-defer \ - 910-tagged \ - 911-slices \ - 912-enums \ - 913-match \ - 914-switch - do - cat <<EOF -tests/$t: harec tests/$t.ha tests/rt.o - @printf 'HARECC\t%s\t$@\n' "tests/$t" - @HARECACHE=\$(HARECACHE) ./harec -o tests/$t.ssa tests/$t.ha - @\$(QBE) -o tests/$t.s tests/$t.ssa - @\$(CC) -g -o tests/$t tests/$t.s tests/rt.c tests/rt.o - -check: tests/$t - -clean-test-$t: - @rm -f tests/$t -.PHONY: clean-test-$t - -clean-tests: clean-test-$t -EOF - done - - # Hare tests + # harec tests for t in \ 00-constants \ 01-arrays \ @@ -66,7 +31,9 @@ EOF 25-promotion \ 26-gen \ 27-rt \ - 29-unarithm + 29-unarithm \ + 31-postfix \ + 32-copy # Disabled tests #22-delete \ diff --git a/tests/rt.c b/tests/rt.c @@ -1,38 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -void *c_memcpy(void *dest, const void *src, size_t n) { - unsigned char *a = dest; - const unsigned char *b = src; - for (size_t i = 0; i < n; ++i) { - a[i] = b[i]; - } - return dest; -} - -struct ha_str { - char *str; - size_t len, cap; -}; - -void c_abort(struct ha_str str) { - write(2, str.str, str.len); - write(2, "\n", 1); - abort(); -} - -const char *reasons[] = { - "Slice or array access out of bounds", // 0 - "Type assertion failed", // 1 - "Out of memory", // 2 -}; - -void c_abort_fixed(struct ha_str loc, int i) { - write(2, "Abort: ", 7); - write(2, loc.str, loc.len); - write(2, ": ", 2); - write(2, reasons[i], strlen(reasons[i])); - write(2, "\n", 1); - abort(); -}; diff --git a/tests/rt.ha b/tests/rt.ha @@ -1,46 +0,0 @@ -fn c_abort(m: str) void; -export @symbol("rt.abort") fn abort_(m: str) void = c_abort(m); - -fn c_abort_fixed(loc: str, i: int) void; -export @symbol("rt.abort_fixed") fn abort_fixed(loc: str, i: int) void = - c_abort_fixed(loc, i); - -fn c_memcpy(x: *void, y: *void, z: size) *void; -export @symbol("rt.memcpy") fn memcpy(x: *void, y: *void, z: size) *void = { - return c_memcpy(x, y, z); -}; - -type string = struct { - data: *[*]u8, - length: size, - capacity: size, -}; - -export @symbol("rt.strcmp") fn strcmp(_a: str, _b: str) bool = { - if (len(_a) != len(_b)) { - return false; - }; - let a = (&_a: *string).data, b = (&_b: *string).data; - for (let i = 0z; i < len(_a); i += 1) { - if (a[i] != b[i]) { - return false; - }; - }; - return true; -}; - -export @symbol("malloc") fn c_malloc(n: size) nullable *void; -export @symbol("free") fn c_free(p: nullable *void) nullable *void; -export @symbol("realloc") fn c_realloc(p: nullable *void, n: size) nullable *void; - -export @symbol("rt.malloc") fn malloc(n: size) nullable *void = { - return c_malloc(n); -}; - -export @symbol("rt.free") fn free_(p: nullable *void) void = { - c_free(p); -}; - -export @symbol("rt.realloc") fn realloc(p: nullable *void, n: size) nullable *void = { - c_realloc(p, n); -};