Skip to content

Commit f9ddbdc

Browse files
authored
Merge pull request #20 from EpitechPGE3-2025/dev/std-lib
Dev/std lib
2 parents 5be74f9 + 65b1a8c commit f9ddbdc

File tree

9 files changed

+942
-1
lines changed

9 files changed

+942
-1
lines changed

docs/STDLIB.md

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@ stdlib/
99
std/
1010
core.top
1111
string.top
12+
math.top
1213
collections/
1314
list.top
15+
aliases.top
16+
functional.top
1417
```
1518

1619
### std.core
@@ -37,7 +40,35 @@ Utilities layered on top of the VM's native list support (`VList`, `IListGet`, `
3740
| `list_concat` | Delegates to the runtime concatenation primitive. |
3841
| `list_single` | Creates a one-element list. |
3942

40-
At this stage higher-order helpers (`map`, `filter`, …) are earmarked for a future iteration once the parser grows richer list syntax.
43+
### std.collections.aliases
44+
45+
Convenient short aliases for common list operations:
46+
47+
| Symbol | Description |
48+
|--------|-------------|
49+
| `length(lst)` | Alias for `__list_length`. Returns the number of elements in a list. |
50+
| `head(lst)` | Alias for safe first element access. Returns `nil` if list is empty. |
51+
| `tail(lst)` | Returns all elements except the first. Returns `[]` if list is empty or has one element. |
52+
| `concat(left, right)` | Alias for `__list_append`. Concatenates two lists. |
53+
| `last(lst)` | Alias for safe last element access. Returns `nil` if list is empty. |
54+
55+
### std.collections.functional
56+
57+
Higher-order list functions for functional programming:
58+
59+
| Symbol | Description |
60+
|--------|-------------|
61+
| `fold(lst, init, func)` | Reduces a list to a single value using an accumulator function. Left fold. |
62+
| `map(lst, func)` | Transforms each element of a list using the provided function. |
63+
| `filter(lst, predicate)` | Returns a new list containing only elements that satisfy the predicate. |
64+
| `reverse(lst)` | Returns a new list with elements in reverse order. |
65+
| `take(lst, n)` | Returns the first `n` elements of the list. |
66+
| `drop(lst, n)` | Returns all elements after dropping the first `n`. |
67+
| `find(lst, predicate)` | Returns the first element matching the predicate, or `nil` if none found. |
68+
| `contains(lst, value)` | Returns `true` if the list contains the value, `false` otherwise. |
69+
| `index_of(lst, value)` | Returns the index of the first occurrence of value, or `-1` if not found. |
70+
| `range(start, end)` | Generates a list of integers from `start` to `end` (inclusive). |
71+
| `zip(lst1, lst2)` | Zips two lists into a list of pairs up to the shorter length. |
4172

4273
### std.string
4374

@@ -48,6 +79,74 @@ Convenience wrappers around the existing string builtins:
4879
| `string_is_empty` | Checks whether a string has length zero. |
4980
| `string_starts_with` / `string_ends_with` | Prefix and suffix checks expressed via `__substring`. |
5081

82+
## Built-in Functions
83+
84+
The Topineur runtime provides several built-in functions implemented in Haskell:
85+
86+
### Math Functions
87+
88+
| Function | Signature | Description |
89+
|----------|-----------|-------------|
90+
| `abs(x)` | `Int\|Float -> Int\|Float` | Returns the absolute value. Preserves input type. |
91+
| `sqrt(x)` | `Int\|Float -> Float` | Returns the square root. Always returns Float. |
92+
| `pow(a, b)` | `Int\|Float, Int\|Float -> Float` | Exponentiation. Returns Float. |
93+
| `floor(x)` | `Int\|Float -> Int` | Largest integer not greater than `x`. For Int, passthrough. |
94+
| `ceil(x)` | `Int\|Float -> Int` | Smallest integer not less than `x`. For Int, passthrough. |
95+
| `round(x)` | `Int\|Float -> Int` | Rounds to the nearest integer (banker's rounding as in Haskell). For Int, passthrough. |
96+
| `sin(x)` | `Int\|Float -> Float` | Sine of `x` in radians. |
97+
| `cos(x)` | `Int\|Float -> Float` | Cosine of `x` in radians. |
98+
| `tan(x)` | `Int\|Float -> Float` | Tangent of `x` in radians. |
99+
| `asin(x)` | `Int\|Float -> Float` | Arc-sine in radians. Domain [-1,1]. |
100+
| `acos(x)` | `Int\|Float -> Float` | Arc-cosine in radians. Domain [-1,1]. |
101+
| `atan(x)` | `Int\|Float -> Float` | Arc-tangent in radians. |
102+
| `atan2(y, x)` | `Int\|Float, Int\|Float -> Float` | Arc-tangent of `y/x` accounting for quadrant, in radians. |
103+
| `pi` | `Float` | π constant (3.14159…). |
104+
| `e` | `Float` | Euler's number e (2.71828…). |
105+
106+
### std.math (Topineur)
107+
108+
Convenience numeric utilities implemented in Topineur:
109+
110+
| Function | Signature | Description |
111+
|----------|-----------|-------------|
112+
| `min(a, b)` | `Int\|Float -> Int\|Float` | Returns the smaller of two numbers. |
113+
| `max(a, b)` | `Int\|Float -> Int\|Float` | Returns the larger of two numbers. |
114+
| `clamp(x, lo, hi)` | `Int\|Float -> Int\|Float` | Clamps `x` into `[lo, hi]` using `max(lo, min(x, hi))`. |
115+
| `sign(x)` | `Int\|Float -> Int` | Returns `-1`, `0`, or `1`. |
116+
117+
### Type Conversions
118+
119+
| Function | Signature | Description |
120+
|----------|-----------|-------------|
121+
| `int(x)` | `Int\|Float\|String -> Int` | Converts to Int. Truncates floats towards zero. |
122+
| `float(x)` | `Int\|Float\|String -> Float` | Converts to Float. |
123+
| `show(x)` | `Any -> String` | Converts any value to its string representation. |
124+
125+
**Conversion behaviors:**
126+
- `int(3.9)``3` (truncate towards zero)
127+
- `int(-3.9)``-3` (truncate towards zero)
128+
- `float(42)``42.0`
129+
- `abs(-5)``5` (preserves Int type)
130+
- `abs(-3.14)``3.14` (preserves Float type)
131+
- `sqrt(16)``4.0` (always Float)
132+
133+
### List Primitives
134+
135+
| Function | Description |
136+
|----------|-------------|
137+
| `__list_length(lst)` | Runtime primitive for list length. |
138+
| `__list_get(lst, idx)` | Runtime primitive for element access by index. |
139+
| `__list_append(left, right)` | Runtime primitive for list concatenation. |
140+
| `__list_single(value)` | Runtime primitive to create a single-element list. |
141+
142+
### String Primitives
143+
144+
| Function | Description |
145+
|----------|-------------|
146+
| `__string_length(str)` | Runtime primitive for string length. |
147+
| `__string_append(s1, s2)` | Runtime primitive for string concatenation. |
148+
| `__substring(str, start, end)` | Runtime primitive to extract substring. |
149+
51150
## Using the Stdlib
52151

53152
```topineur
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package test_math_builtins
2+
3+
|- Test abs function
4+
def test_abs(): Int {
5+
println("Testing abs():")
6+
7+
|- Test with positive integer
8+
let abs_pos = abs(42)
9+
println(" abs(42) = " ++ show(abs_pos))
10+
11+
|- Test with negative integer
12+
let abs_neg = abs(-42)
13+
println(" abs(-42) = " ++ show(abs_neg))
14+
15+
|- Test with zero
16+
let abs_zero = abs(0)
17+
println(" abs(0) = " ++ show(abs_zero))
18+
19+
|- Test with positive float
20+
let abs_float_pos = abs(3.14)
21+
println(" abs(3.14) = " ++ show(abs_float_pos))
22+
23+
|- Test with negative float
24+
let abs_float_neg = abs(-3.14)
25+
println(" abs(-3.14) = " ++ show(abs_float_neg))
26+
27+
top 0
28+
}
29+
30+
|- Test sqrt function
31+
def test_sqrt(): Int {
32+
println("")
33+
println("Testing sqrt():")
34+
35+
|- Test with perfect square
36+
let sqrt_16 = sqrt(16.0)
37+
println(" sqrt(16.0) = " ++ show(sqrt_16))
38+
39+
|- Test with integer input (should convert to float)
40+
let sqrt_25 = sqrt(25)
41+
println(" sqrt(25) = " ++ show(sqrt_25))
42+
43+
|- Test with non-perfect square
44+
let sqrt_2 = sqrt(2.0)
45+
println(" sqrt(2.0) = " ++ show(sqrt_2))
46+
47+
|- Test with zero
48+
let sqrt_zero = sqrt(0.0)
49+
println(" sqrt(0.0) = " ++ show(sqrt_zero))
50+
51+
top 0
52+
}
53+
54+
|- Test int function
55+
def test_int(): Int {
56+
println("")
57+
println("Testing int():")
58+
59+
|- Test with integer input (should return same)
60+
let int_42 = int(42)
61+
println(" int(42) = " ++ show(int_42))
62+
63+
|- Test truncation (positive)
64+
let int_pos = int(3.9)
65+
println(" int(3.9) = " ++ show(int_pos) ++ " (should be 3, truncate towards zero)")
66+
67+
|- Test truncation (negative)
68+
let int_neg = int(-3.9)
69+
println(" int(-3.9) = " ++ show(int_neg) ++ " (should be -3, truncate towards zero)")
70+
71+
|- Test with exact float
72+
let int_exact = int(5.0)
73+
println(" int(5.0) = " ++ show(int_exact))
74+
75+
top 0
76+
}
77+
78+
|- Test float function
79+
def test_float(): Int {
80+
println("")
81+
println("Testing float():")
82+
83+
|- Test with float input (should return same)
84+
let float_pi = float(3.14)
85+
println(" float(3.14) = " ++ show(float_pi))
86+
87+
|- Test with integer input
88+
let float_42 = float(42)
89+
println(" float(42) = " ++ show(float_42) ++ " (should be 42.0)")
90+
91+
|- Test with zero
92+
let float_zero = float(0)
93+
println(" float(0) = " ++ show(float_zero))
94+
95+
top 0
96+
}
97+
98+
def main(): Int {
99+
println("=== Math Builtins Test Suite ===")
100+
println("")
101+
102+
test_abs()
103+
test_sqrt()
104+
test_int()
105+
test_float()
106+
107+
println("")
108+
println("=== All Tests Complete ===")
109+
top 0
110+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package test_adv_math
2+
3+
|- Advanced math builtins tests: pow, floor, ceil, round, trig, constants
4+
5+
def test_pow(): Int {
6+
println("Testing pow():")
7+
println(" pow(2, 3) = " ++ show(pow(2, 3)) ++ " (should be 8.0)")
8+
println(" pow(9, 0.5) = " ++ show(pow(9, 0.5)) ++ " (should be 3.0)")
9+
println(" pow(2.5, 2) = " ++ show(pow(2.5, 2)) ++ " (should be 6.25)")
10+
top 0
11+
}
12+
13+
def test_rounding(): Int {
14+
println("")
15+
println("Testing floor/ceil/round:")
16+
println(" floor(3.7) = " ++ show(floor(3.7)) ++ " (should be 3)")
17+
println(" ceil(3.1) = " ++ show(ceil(3.1)) ++ " (should be 4)")
18+
println(" round(3.5) = " ++ show(round(3.5)) ++ " (Haskell rounds to 4)")
19+
println(" round(2.5) = " ++ show(round(2.5)) ++ " (Haskell rounds to 2)")
20+
println(" floor(5) = " ++ show(floor(5)) ++ " (should be 5)")
21+
println(" ceil(5) = " ++ show(ceil(5)) ++ " (should be 5)")
22+
println(" round(5) = " ++ show(round(5)) ++ " (should be 5)")
23+
top 0
24+
}
25+
26+
def test_trig(): Int {
27+
println("")
28+
println("Testing trig functions (radians):")
29+
println(" sin(0) = " ++ show(sin(0)) ++ " (should be 0.0)")
30+
println(" cos(0) = " ++ show(cos(0)) ++ " (should be 1.0)")
31+
println(" tan(0) = " ++ show(tan(0)) ++ " (should be 0.0)")
32+
println(" asin(0) = " ++ show(asin(0)) ++ " (should be 0.0)")
33+
println(" acos(1) = " ++ show(acos(1)) ++ " (should be 0.0)")
34+
println(" atan(1) = " ++ show(atan(1)) ++ " (should be ~0.785)")
35+
println(" atan2(1, 1) = " ++ show(atan2(1, 1)) ++ " (should be ~0.785)")
36+
top 0
37+
}
38+
39+
def test_constants(): Int {
40+
println("")
41+
println("Testing constants:")
42+
println(" pi = " ++ show(pi))
43+
println(" e = " ++ show(e))
44+
top 0
45+
}
46+
47+
def main(): Int {
48+
println("=== Advanced Math Builtins Test Suite ===")
49+
println("")
50+
51+
test_pow()
52+
test_rounding()
53+
test_trig()
54+
test_constants()
55+
56+
println("")
57+
println("=== All Adv Math Tests Complete ===")
58+
top 0
59+
}

0 commit comments

Comments
 (0)