Skip to content

Commit db13fc3

Browse files
authored
feat: expand standard library with math and string modules (#270)
This commit populates the Wave standard library with foundational modules for mathematics and string manipulation. It also updates the library manifest and provides a basic README. Changes: - **Library Infrastructure**: - Added `std/README.md` to define the library's scope. - Updated `std/manifest.json` to include the `math` and `string` modules. - **`std/math` Module**: - `bits.wave`: Implemented bitwise utilities including `is_pow2`, `popcount`, `ctz32`, and integer logarithm functions (`ilog2`). - `float.wave`: Added `abs`, `min`, `max`, and `clamp` for `f32`. - `int.wave`: Added integer utilities including `abs`, `sign`, parity checks, ceiling/floor division, and a pointer-based `swap_i32`. - `num.wave`: Implemented `gcd`, `lcm`, and exponentiation (`pow_i32`). - **`std/string` Module**: - `ascii.wave`: Added ASCII character classification (digit, alpha, space, etc.) and case conversion. - `cmp.wave`: Implemented string equality, lexical comparison, and prefix/suffix checks (`starts_with`, `ends_with`). - `find.wave`: Added character and substring searching logic, including `find`, `contains`, and `count`. - `len.wave`: Added basic length and empty-string checks. - `trim.wave`: Implemented index-based whitespace trimming for strings. - **Cleanup**: - Removed obsolete `import("std::iosys")` calls from test files. These additions provide the essential building blocks for writing complex Wave applications using standardized utility functions. Signed-off-by: LunaStev <luna@lunastev.org>
1 parent 773d7d9 commit db13fc3

File tree

15 files changed

+650
-8
lines changed

15 files changed

+650
-8
lines changed

std/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Wave Standard Library
2+
3+
This is Wave's standard library. This standard library operates independently of Wave's compiler and is not part of the compiler itself.

std/io/format.wave

Lines changed: 0 additions & 3 deletions
This file was deleted.

std/manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"name": "std",
33
"format": 1,
4-
"modules": ["io", "fs", "net", "math", "sys", "json"]
4+
"modules": ["string", "math"]
55
}

std/math/bits.wave

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
fun is_pow2(x: i32) -> bool {
2+
if (x <= 0) {
3+
return false;
4+
}
5+
6+
if ((x & (x - 1)) == 0) {
7+
return true;
8+
}
9+
10+
return false;
11+
}
12+
13+
fun align_down(x: i32, align: i32) -> i32 {
14+
if (align <= 0) {
15+
return x;
16+
}
17+
18+
return x & ~(align - 1);
19+
}
20+
21+
fun align_up(x: i32, align: i32) -> i32 {
22+
if (align <= 0) {
23+
return x;
24+
}
25+
26+
return (x + (align - 1)) & ~(align - 1);
27+
}
28+
29+
fun low_bit(x: i32) -> i32 {
30+
return x & (-x);
31+
}
32+
33+
fun popcount(x0: i32) -> i32 {
34+
let mut x: i32 = x0;
35+
let mut c: i32 = 0;
36+
37+
while (x != 0) {
38+
x = x & (x - 1);
39+
c += 1;
40+
}
41+
42+
return c;
43+
}
44+
45+
fun ctz32(x: i32) -> i32 {
46+
if (x == 0) {
47+
return 32;
48+
}
49+
50+
let lb: i32 = low_bit(x);
51+
return popcount(lb - 1);
52+
}
53+
54+
fun bit_length(x0: i32) -> i32 {
55+
if (x0 <= 0) {
56+
return 0;
57+
}
58+
59+
let mut x: i32 = x0;
60+
let mut n: i32 = 0;
61+
62+
while (x > 0) {
63+
x = x >> 1;
64+
n += 1;
65+
}
66+
67+
return n;
68+
}
69+
70+
fun ilog2_floor(x: i32) -> i32 {
71+
if (x <= 0) {
72+
return -1;
73+
}
74+
75+
return bit_length(x) - 1;
76+
}
77+
78+
fun ilog2_ceil(x: i32) -> i32 {
79+
if (x <= 1) {
80+
return 0;
81+
}
82+
83+
return ilog2_floor(x - 1) + 1;
84+
}

std/math/float.wave

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
fun abs_f32(x: f32) -> f32 {
2+
if (x < 0.0) {
3+
return -x;
4+
}
5+
6+
return x;
7+
}
8+
9+
fun min_f32(a: f32, b: f32) -> f32 {
10+
if (a < b) {
11+
return a;
12+
}
13+
14+
return b;
15+
}
16+
17+
fun max_f32(a: f32, b: f32) -> f32 {
18+
if (a > b) {
19+
return a;
20+
}
21+
22+
return b;
23+
}
24+
25+
fun clamp_f32(x: f32, lo: f32, hi: f32) -> f32 {
26+
if (x < lo) {
27+
return lo;
28+
}
29+
30+
if (x > hi) {
31+
return hi;
32+
}
33+
34+
return x;
35+
}

std/math/int.wave

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
fun abs(x: i32) -> i32 {
2+
if (x < 0) {
3+
return -x;
4+
}
5+
6+
return x;
7+
}
8+
9+
fun min(a: i32, b: i32) -> i32 {
10+
if (a < b) {
11+
return a;
12+
}
13+
14+
return b;
15+
}
16+
17+
fun max(a: i32, b: i32) -> i32 {
18+
if (a > b) {
19+
return a;
20+
}
21+
22+
return b;
23+
}
24+
25+
fun clamp(x: i32, lo: i32, hi: i32) -> i32 {
26+
if (x < lo) {
27+
return lo;
28+
}
29+
30+
if (x > hi) {
31+
return hi;
32+
}
33+
34+
return x;
35+
}
36+
37+
fun sign(x: i32) -> i32 {
38+
if (x < 0) {
39+
return -1;
40+
}
41+
42+
if (x > 0) {
43+
return 1;
44+
}
45+
46+
return 0;
47+
}
48+
49+
fun is_even(x: i32) -> bool {
50+
if ((x % 2) == 0) {
51+
return true;
52+
}
53+
54+
return false;
55+
}
56+
57+
fun is_odd(x: i32) -> bool {
58+
if ((x % 2) != 0) {
59+
return true;
60+
}
61+
62+
return false;
63+
}
64+
65+
fun div_ceil_pos(a: i32, b: i32) -> i32 {
66+
if (b == 0) {
67+
return 0;
68+
}
69+
70+
if (a <= 0) {
71+
return 0;
72+
}
73+
74+
return (a + (b - 1)) / b;
75+
}
76+
77+
fun div_floor_pos(a: i32, b: i32) -> i32 {
78+
if (b == 0) {
79+
return 0;
80+
}
81+
82+
if (a <= 0) {
83+
return 0;
84+
}
85+
86+
return a / b;
87+
}
88+
89+
fun swap_i32(a: ptr<i32>, b: ptr<i32>) {
90+
let t: i32 = deref a;
91+
92+
deref a = deref b;
93+
deref b = t;
94+
}

std/math/num.wave

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
fun gcd(a0: i32, b0: i32) -> i32 {
2+
let mut a: i32 = a0;
3+
let mut b: i32 = b0;
4+
5+
if (a < 0) {
6+
a = -a;
7+
}
8+
9+
if (b < 0) {
10+
b = -b;
11+
}
12+
13+
while (b != 0) {
14+
let t: i32 = a % b;
15+
a = b;
16+
b = t;
17+
}
18+
19+
return a;
20+
}
21+
22+
fun lcm(a: i32, b: i32) -> i32 {
23+
if (a == 0 || b == 0) {
24+
return 0;
25+
}
26+
27+
let g: i32 = gcd(a, b);
28+
let x: i32 = a / g;
29+
let mut r: i32 = x * b;
30+
31+
if (r < 0) {
32+
r = -r;
33+
}
34+
35+
return r;
36+
}
37+
38+
fun pow_i32(base0: i32, exp0: i32) -> i32 {
39+
let mut base: i32 = base0;
40+
let mut exp: i32 = exp0;
41+
let mut result: i32 = 1;
42+
43+
while (exp > 0) {
44+
if ((exp & 1) == 1) {
45+
result = result * base;
46+
}
47+
48+
base = base * base;
49+
exp = exp >> 1;
50+
}
51+
52+
return result;
53+
}

std/string/ascii.wave

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
fun is_digit(c: u8) -> bool {
2+
if (c >= 48 && c <= 57) {
3+
return true;
4+
}
5+
6+
return false;
7+
}
8+
9+
fun is_lower(c: u8) -> bool {
10+
if (c >= 97 && c <= 122) {
11+
return true;
12+
}
13+
14+
return false;
15+
}
16+
17+
fun is_upper(c: u8) -> bool {
18+
if (c >= 65 && c <= 90) {
19+
return true;
20+
}
21+
22+
return false;
23+
}
24+
25+
fun is_alpha(c: u8) -> bool {
26+
if (is_lower(c)) {
27+
return true;
28+
}
29+
30+
if (is_upper(c)) {
31+
return true;
32+
}
33+
34+
return false;
35+
}
36+
37+
fun is_alnum(c: u8) -> bool {
38+
if (is_alpha(c)) {
39+
return true;
40+
}
41+
42+
if (is_digit(c)) {
43+
return true;
44+
}
45+
46+
return false;
47+
}
48+
49+
fun is_space(c: u8) -> bool {
50+
if (c == 32) {
51+
return true;
52+
}
53+
54+
if (c == 9) {
55+
return true;
56+
}
57+
58+
if (c == 10) {
59+
return true;
60+
}
61+
62+
if (c == 13) {
63+
return true;
64+
}
65+
66+
return false;
67+
}
68+
69+
fun to_lower(c: u8) -> u8 {
70+
if (is_upper(c)) {
71+
return c + 32;
72+
}
73+
74+
return c;
75+
}
76+
77+
fun to_upper(c: u8) -> u8 {
78+
if (is_lower(c)) {
79+
return c - 32;
80+
}
81+
82+
return c;
83+
}

0 commit comments

Comments
 (0)