Files
bux-lang/docs/Stdlib.md
T
dimgigov fe3b1e8b6a
ci / build (ubuntu) (push) Has been cancelled
ci / unit + fmt (push) Has been cancelled
ci / examples (push) Has been cancelled
ci / goldens + tools (push) Has been cancelled
ci / apps (push) Has been cancelled
ci / selfhost smoke (push) Has been cancelled
ci / macos smoke (push) Has been cancelled
ci / windows smoke (push) Has been cancelled
ci / CI gate (push) Has been cancelled
selfhost-loop / bootstrap determinism (push) Has been cancelled
feat: macros (multi-rep, hygiene), Drop field-move, lean multi-OS CI
Sessions 56–69: declarative macro! with rep/zip/literal/block and
unhygienic var $name binders; partial field-move skip Drop; @[Release]
polish; LSP type hierarchy; CI Nim cache + lean macOS + Windows smoke.
2026-07-20 17:19:46 +03:00

1048 lines
35 KiB
Markdown

# Bux Standard Library
The Bux standard library provides core functionality for systems programming. All modules are merged into every compilation, so no explicit linking is needed.
---
## Std::Io
Basic I/O and file operations wrapping C stdio.
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `PrintLine` | `func PrintLine(s: String)` | Print string with newline |
| `Print` | `func Print(s: String)` | Print string without newline |
| `PrintInt` | `func PrintInt(n: int)` | Print integer |
| `PrintFloat` | `func PrintFloat(f: float64)` | Print float |
| `PrintBool` | `func PrintBool(b: bool)` | Print boolean |
| `ReadLine` | `func ReadLine() -> String` | Read line from stdin |
| `ReadFile` | `func ReadFile(path: String) -> String` | Read entire file into string |
| `WriteFile` | `func WriteFile(path: String, content: String) -> bool` | Write string to file |
| `FileExists` | `func FileExists(path: String) -> bool` | Check if file exists |
---
## Std::Fs
File system operations beyond basic I/O.
| Function | Signature | Description |
|----------|-----------|-------------|
| `DirExists` | `func DirExists(path: String) -> bool` | Check if directory exists |
| `Mkdir` | `func Mkdir(path: String) -> bool` | Create directory (and parents if needed) |
| `ListDir` | `func ListDir(dir: String, ext: String, count: *int) -> *String` | List files matching extension |
### Example
```bux
import Std::Fs::{DirExists, Mkdir, ListDir};
func Main() -> int {
if DirExists("/tmp") {
PrintLine("/tmp exists");
}
Mkdir("build/output");
var count: int = 0;
let files: *String = ListDir("src", ".bux", &count);
return 0;
}
```
### Example
```bux
import Std::Io::{PrintLine, ReadFile, WriteFile};
func Main() -> int {
WriteFile("/tmp/test.txt", "Hello, Bux!");
PrintLine(ReadFile("/tmp/test.txt"));
return 0;
}
```
---
## Std::Array
Fully generic dynamic array `Array<T>`.
### Types
```bux
struct Array<T> {
data: *T,
len: uint,
cap: uint,
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Array_New<T>` | `func Array_New<T>(cap: uint) -> Array<T>` | Create new array |
| `Array_Push<T>` | `func Array_Push<T>(arr: *Array<T>, value: T)` | Append element |
| `Array_Pop<T>` | `func Array_Pop<T>(arr: *Array<T>) -> T` | Remove and return last element |
| `Array_Contains<T>` | `func Array_Contains<T>(arr: *Array<T>, value: T) -> bool` | Linear search for value |
| `Array_IndexOf<T>` | `func Array_IndexOf<T>(arr: *Array<T>, value: T) -> int` | First index or -1 |
| `Array_Extend<T>` | `func Array_Extend<T>(arr: *Array<T>, other: *Array<T>)` | Append all from other |
| `Array_Get<T>` | `func Array_Get<T>(arr: *Array<T>, index: uint) -> T` | Get element at index |
| `Array_Set<T>` | `func Array_Set<T>(arr: *Array<T>, index: uint, value: T)` | Set element at index |
| `Array_First<T>` | `func Array_First<T>(arr: *Array<T>) -> T` | First element (bounds-checked) |
| `Array_Last<T>` | `func Array_Last<T>(arr: *Array<T>) -> T` | Last element (bounds-checked) |
| `Array_Len<T>` | `func Array_Len<T>(arr: *Array<T>) -> uint` | Get length |
| `Array_Cap<T>` | `func Array_Cap<T>(arr: *Array<T>) -> uint` | Get capacity |
| `Array_IsEmpty<T>` | `func Array_IsEmpty<T>(arr: *Array<T>) -> bool` | True if length is 0 |
| `Array_Clear<T>` | `func Array_Clear<T>(arr: *Array<T>)` | Set length to 0 (keeps capacity) |
| `Array_Reserve<T>` | `func Array_Reserve<T>(arr: *Array<T>, minCap: uint)` | Grow capacity if needed |
| `Array_Free<T>` | `func Array_Free<T>(arr: *Array<T>)` | Free memory |
| `Array_Drop<T>` | `func Array_Drop<T>(self: *Array<T>)` | Drop trait entry (same as `Array_Free`) |
**RAII:** `Array<T>` is auto-dropped at scope exit. Prefer letting the compiler call
`Array_Drop` over manual `Array_Free` when ownership is clear. If you move an
array into a struct field, the **source local is not dropped** (see LanguageRef
[Drop and RAII](LanguageRef.md#drop-and-raii) / `examples/move_field.bux`).
### Example
```bux
import Std::Array::{Array, Array_New, Array_Push, Array_Get};
func Main() -> int {
let arr: Array<int> = Array_New<int>(4);
Array_Push<int>(&arr, 10);
Array_Push<int>(&arr, 20);
PrintInt(Array_Get<int>(&arr, 0)); // 10
// Array_Drop runs at end of Main (or call Array_Free manually)
return 0;
}
```
---
## Std::Drop
Trait for automatic cleanup (RAII). Defined in `lib/Drop.bux`:
```bux
interface Drop {
func Drop(self: *Self);
}
```
Implement with `extend Type for Drop { func Drop(self: *Type) { … } }` or mark
the type `@[Drop]` and provide `Type_Drop`. Full rules (early return, field-move
skip Drop, move-on-return): **LanguageRef → Drop and RAII**.
Examples: `examples/drop_early_return.bux`, `examples/move_field.bux`.
---
## Std::Iter
Lightweight iterator over `Array<T>` (index-based, no allocation).
### Types
```bux
struct Iter<T> {
data: *T,
len: uint,
pos: uint,
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Array_Iter<T>` | `func Array_Iter<T>(arr: *Array<T>) -> Iter<T>` | Create iterator from array |
| `Iter_HasNext<T>` | `func Iter_HasNext<T>(it: *Iter<T>) -> bool` | Check if more elements remain |
| `Iter_Next<T>` | `func Iter_Next<T>(it: *Iter<T>) -> T` | Get next element and advance |
| `Iter_Peek<T>` | `func Iter_Peek<T>(it: *Iter<T>) -> T` | Peek current element without advancing |
| `Iter_Reset<T>` | `func Iter_Reset<T>(it: *Iter<T>)` | Reset to start |
| `Iter_Pos<T>` | `func Iter_Pos<T>(it: *Iter<T>) -> uint` | Current position |
| `Iter_Len<T>` | `func Iter_Len<T>(it: *Iter<T>) -> uint` | Total length |
| `Iter_Count<T>` | `func Iter_Count<T>(it: *Iter<T>) -> uint` | Count remaining elements |
| `Iter_Skip<T>` | `func Iter_Skip<T>(it: *Iter<T>, n: uint)` | Skip N elements |
| `Iter_Take<T>` | `func Iter_Take<T>(it: *Iter<T>, n: uint) -> Iter<T>` | Take first N elements as new iterator |
| `Iter_AnyEq<T>` | `func Iter_AnyEq<T>(it: *Iter<T>, value: T) -> bool` | True if any remaining element equals value |
| `Iter_AllEq<T>` | `func Iter_AllEq<T>(it: *Iter<T>, value: T) -> bool` | True if all remaining equal value |
| `Iter_Collect<T>` | `func Iter_Collect<T>(it: *Iter<T>) -> Array<T>` | Collect remaining into a new Array |
### Higher-order (generic + int aliases)
Take fat function pointers / closures. Prefer the generic forms; `*Int` aliases remain for compatibility.
| Function | Signature | Description |
|----------|-----------|-------------|
| `Iter_Map<T,U>` | `func Iter_Map<T,U>(it: *Iter<T>, f: func(T) -> U) -> Array<U>` | Map `T → U` |
| `Iter_Filter<T>` | `func Iter_Filter<T>(it: *Iter<T>, pred: func(T) -> bool) -> Array<T>` | Keep matching |
| `Iter_Fold<T,Acc>` | `func Iter_Fold<T,Acc>(it: *Iter<T>, init: Acc, f: func(Acc, T) -> Acc) -> Acc` | Left fold |
| `Iter_ForEach<T>` | `func Iter_ForEach<T>(it: *Iter<T>, f: func(T) -> int)` | Side-effect per element |
| `Iter_Any<T>` | `func Iter_Any<T>(it: *Iter<T>, pred: func(T) -> bool) -> bool` | Any matches pred |
| `Iter_All<T>` | `func Iter_All<T>(it: *Iter<T>, pred: func(T) -> bool) -> bool` | All match pred |
| `Iter_MapInt` … | wrappers → `Iter_Map<int,int>` etc. | Back-compat |
| `Iter_SumInt` | `func Iter_SumInt(it: *Iter<int>) -> int` | Sum remaining ints |
### Example
```bux
import Std::Array::*;
import Std::Iter::*;
import Std::Io::{PrintInt, PrintLine};
func Main() -> int {
let arr: Array<int> = Array_New<int>(4);
Array_Push<int>(&arr, 10);
Array_Push<int>(&arr, 20);
Array_Push<int>(&arr, 30);
let it: Iter<int> = Array_Iter<int>(&arr);
while Iter_HasNext<int>(&it) {
PrintInt(Iter_Next<int>(&it));
PrintLine("");
}
Array_Free<int>(&arr);
return 0;
}
```
---
## Std::String
String manipulation utilities.
### Core Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `String_Len` | `func String_Len(s: String) -> uint` | Length of string |
| `String_Eq` | `func String_Eq(a: String, b: String) -> bool` | Compare strings |
| `String_Concat` | `func String_Concat(a: String, b: String) -> String` | Concatenate (allocates) |
| `String_Copy` | `func String_Copy(s: String) -> String` | Copy string (allocates) |
| `String_StartsWith` | `func String_StartsWith(s: String, prefix: String) -> bool` | Check prefix |
| `String_EndsWith` | `func String_EndsWith(s: String, suffix: String) -> bool` | Check suffix |
| `String_Contains` | `func String_Contains(s: String, substr: String) -> bool` | Check substring |
### Slicing & Trimming
| Function | Signature | Description |
|----------|-----------|-------------|
| `String_Slice` | `func String_Slice(s: String, start: uint, len: uint) -> String` | Extract substring |
| `String_Trim` | `func String_Trim(s: String) -> String` | Trim both sides |
| `String_TrimLeft` | `func String_TrimLeft(s: String) -> String` | Trim left side |
| `String_TrimRight` | `func String_TrimRight(s: String) -> String` | Trim right side |
### Split & Join
| Function | Signature | Description |
|----------|-----------|-------------|
| `String_SplitCount` | `func String_SplitCount(s: String, delim: String) -> uint` | Count parts |
| `String_SplitPart` | `func String_SplitPart(s: String, delim: String, index: uint) -> String` | Get nth part (0-indexed) |
| `String_Join2` | `func String_Join2(a: String, b: String, sep: String) -> String` | Join two strings with separator |
### Conversion
| Function | Signature | Description |
|----------|-----------|-------------|
| `String_FromInt` | `func String_FromInt(n: int64) -> String` | Int to string |
| `String_FromFloat` | `func String_FromFloat(f: float64) -> String` | Float to string |
| `String_ToInt` | `func String_ToInt(s: String) -> int64` | String to int |
| `String_ToFloat` | `func String_ToFloat(s: String) -> float64` | String to float |
### Find, Replace & Format
| Function | Signature | Description |
|----------|-----------|-------------|
| `String_IsEmpty` | `func String_IsEmpty(s: String) -> bool` | True if length is 0 |
| `String_IsBlank` | `func String_IsBlank(s: String) -> bool` | True if empty or only whitespace |
| `String_Repeat` | `func String_Repeat(s: String, count: uint) -> String` | Repeat string N times |
| `String_Find` | `func String_Find(haystack: String, needle: String) -> String` | Find substring (returns pointer; 0 = not found) |
| `String_Replace` | `func String_Replace(s: String, old: String, new: String) -> String` | Replace first occurrence |
| `String_ReplaceAll` | `func String_ReplaceAll(s: String, old: String, new: String) -> String` | Replace all non-overlapping occurrences |
| `String_Format1` | `func String_Format1(pattern: String, a0: String) -> String` | Format with 1 arg (`{0}`) |
| `String_Format2` | `func String_Format2(pattern: String, a0: String, a1: String) -> String` | Format with 2 args |
| `String_Format3` | `func String_Format3(pattern: String, a0: String, a1: String, a2: String) -> String` | Format with 3 args |
### Example
```bux
import Std::String;
func Main() -> int {
let s: String = String_Replace("hello world", "world", "Bux");
PrintLine(s); // "hello Bux"
let fmt: String = String_Format2("{0} + {1} = magic", "Bux", "QBE");
PrintLine(fmt); // "Bux + QBE = magic"
let found: String = String_Find("hello world", "world");
if found as uint != 0 {
PrintLine("found!");
}
return 0;
}
```
---
## Std::StringBuilder
Efficient string construction using a dynamic buffer.
### Types
```bux
struct StringBuilder {
handle: *void,
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `StringBuilder_New` | `func StringBuilder_New() -> StringBuilder` | Create with default capacity (64) |
| `StringBuilder_NewCap` | `func StringBuilder_NewCap(cap: uint) -> StringBuilder` | Create with custom capacity |
| `StringBuilder_Append` | `func StringBuilder_Append(sb: *StringBuilder, s: String)` | Append string |
| `StringBuilder_AppendInt` | `func StringBuilder_AppendInt(sb: *StringBuilder, n: int64)` | Append integer |
| `StringBuilder_AppendFloat` | `func StringBuilder_AppendFloat(sb: *StringBuilder, f: float64)` | Append float |
| `StringBuilder_AppendChar` | `func StringBuilder_AppendChar(sb: *StringBuilder, c: char8)` | Append char |
| `StringBuilder_Build` | `func StringBuilder_Build(sb: *StringBuilder) -> String` | Build result string |
| `StringBuilder_Free` | `func StringBuilder_Free(sb: *StringBuilder)` | Free memory |
### Example
```bux
import Std::String::{StringBuilder, StringBuilder_New, StringBuilder_Append, StringBuilder_AppendInt, StringBuilder_Build, StringBuilder_Free};
func Main() -> int {
let sb: StringBuilder = StringBuilder_New();
StringBuilder_Append(&sb, "Hello, ");
StringBuilder_Append(&sb, "World! #");
StringBuilder_AppendInt(&sb, 42);
PrintLine(StringBuilder_Build(&sb)); // "Hello, World! #42"
StringBuilder_Free(&sb);
return 0;
}
```
---
## Std::Mem
Memory management wrappers around C runtime functions.
| Function | Signature | Description |
|----------|-----------|-------------|
| `Alloc` | `func Alloc(size: uint) -> *void` | Allocate memory |
| `Realloc` | `func Realloc(ptr: *void, size: uint) -> *void` | Reallocate memory |
| `Free` | `func Free(ptr: *void)` | Free memory |
| `MemEq` | `func MemEq(a: *void, b: *void, size: uint) -> bool` | Byte-wise memory comparison |
| `New` | `func New<T>() -> *T` | Typed allocation (`sizeof(T)` bytes) |
### Example
```bux
import Std::Mem;
func Main() -> int {
let p: *void = Alloc(64);
Free(p);
let n: *int = New<int>();
// use n...
Free(n as *void);
return 0;
}
```
---
## Std::Set
Generic hash set for deduplication and membership testing.
### Types
```bux
struct SetEntry<T> {
value: T,
occupied: bool,
}
struct Set<T> {
entries: *SetEntry<T>,
cap: uint,
len: uint,
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Set_New<T>` | `func Set_New<T>(cap: uint) -> Set<T>` | Create set |
| `Set_Add<T>` | `func Set_Add<T>(s: *Set<T>, value: T)` | Insert element (ignores duplicates) |
| `Set_Has<T>` | `func Set_Has<T>(s: *Set<T>, value: T) -> bool` | Check membership |
| `Set_Remove<T>` | `func Set_Remove<T>(s: *Set<T>, value: T) -> bool` | Remove value |
| `Set_Clear<T>` | `func Set_Clear<T>(s: *Set<T>)` | Clear all elements |
| `Set_IsEmpty<T>` | `func Set_IsEmpty<T>(s: *Set<T>) -> bool` | True if empty |
| `Set_Len<T>` | `func Set_Len<T>(s: *Set<T>) -> uint` | Element count |
| `Set_Free<T>` | `func Set_Free<T>(s: *Set<T>)` | Free memory |
### Example
```bux
import Std::Set;
func Main() -> int {
var s: Set<int> = Set_New<int>(16);
Set_Add(&s, 10);
Set_Add(&s, 20);
Set_Add(&s, 10); // duplicate, ignored
if Set_Has(&s, 10) {
PrintLine("has 10");
}
Set_Free(&s);
return 0;
}
```
---
## Std::Map
Generic hash map `Map<K, V>` for value-type keys (int, float, etc.).
### Types
```bux
struct MapEntry<K, V> {
key: K,
value: V,
occupied: bool,
}
struct Map<K, V> {
entries: *MapEntry<K, V>,
cap: uint,
len: uint,
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Map_New<K,V>` | `func Map_New<K,V>(cap: uint) -> Map<K,V>` | Create map |
| `Map_Set<K,V>` | `func Map_Set<K,V>(m: *Map<K,V>, key: K, value: V)` | Insert/update |
| `Map_Get<K,V>` | `func Map_Get<K,V>(m: *Map<K,V>, key: K) -> V` | Get value (zero if missing) |
| `Map_Has<K,V>` | `func Map_Has<K,V>(m: *Map<K,V>, key: K) -> bool` | Check key exists |
| `Map_Remove<K,V>` | `func Map_Remove<K,V>(m: *Map<K,V>, key: K) -> bool` | Remove key (true if present) |
| `Map_Clear<K,V>` | `func Map_Clear<K,V>(m: *Map<K,V>)` | Remove all entries (keeps capacity) |
| `Map_IsEmpty<K,V>` | `func Map_IsEmpty<K,V>(m: *Map<K,V>) -> bool` | True if no entries |
| `Map_Len<K,V>` | `func Map_Len<K,V>(m: *Map<K,V>) -> uint` | Entry count |
| `Map_Free<K,V>` | `func Map_Free<K,V>(m: *Map<K,V>)` | Free memory |
### Example
```bux
import Std::Map::{Map, Map_New, Map_Set, Map_Get, Map_Free};
func Main() -> int {
let m: Map<int, String> = Map_New<int, String>(16);
Map_Set<int, String>(&m, 1, "one");
Map_Set<int, String>(&m, 2, "two");
PrintLine(Map_Get<int, String>(&m, 1)); // "one"
Map_Free<int, String>(&m);
return 0;
}
```
> **Note:** For `String` keys, use `StringMap<V>` below which uses `strcmp` for key comparison.
---
## Std::StringMap
Specialized hash map for `String` keys with any value type.
### Types
```bux
struct StringMapEntry<V> {
key: String,
value: V,
occupied: bool,
}
struct StringMap<V> {
entries: *StringMapEntry<V>,
cap: uint,
len: uint,
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `StringMap_New<V>` | `func StringMap_New<V>(cap: uint) -> StringMap<V>` | Create map |
| `StringMap_Set<V>` | `func StringMap_Set<V>(m: *StringMap<V>, key: String, value: V)` | Insert/update |
| `StringMap_Get<V>` | `func StringMap_Get<V>(m: *StringMap<V>, key: String) -> V` | Get value |
| `StringMap_Has<V>` | `func StringMap_Has<V>(m: *StringMap<V>, key: String) -> bool` | Check key exists |
| `StringMap_Remove<V>` | `func StringMap_Remove<V>(m: *StringMap<V>, key: String) -> bool` | Remove key |
| `StringMap_Clear<V>` | `func StringMap_Clear<V>(m: *StringMap<V>)` | Clear all entries |
| `StringMap_IsEmpty<V>` | `func StringMap_IsEmpty<V>(m: *StringMap<V>) -> bool` | True if empty |
| `StringMap_Len<V>` | `func StringMap_Len<V>(m: *StringMap<V>) -> uint` | Entry count |
| `StringMap_Free<V>` | `func StringMap_Free<V>(m: *StringMap<V>)` | Free memory |
---
## Std::Path
Path manipulation utilities.
| Function | Signature | Description |
|----------|-----------|-------------|
| `Path_Join` | `func Path_Join(a: String, b: String) -> String` | Join path segments |
| `Path_Parent` | `func Path_Parent(path: String) -> String` | Get parent directory |
| `Path_Ext` | `func Path_Ext(path: String) -> String` | Get file extension |
### Example
```bux
import Std::Path::{Path_Join, Path_Parent, Path_Ext};
func Main() -> int {
PrintLine(Path_Join("/home", "docs")); // "/home/docs"
PrintLine(Path_Parent("/a/b/c.txt")); // "/a/b"
PrintLine(Path_Ext("main.bux")); // ".bux"
return 0;
}
```
---
## Runtime Functions
These C functions are provided by `runtime.c` and are available via `extern` declarations.
| Function | Signature | Description |
|----------|-----------|-------------|
| `bux_alloc` | `func bux_alloc(size: uint) -> *void` | Allocate memory |
| `bux_realloc` | `func bux_realloc(ptr: *void, size: uint) -> *void` | Reallocate memory |
| `bux_free` | `func bux_free(ptr: *void)` | Free memory |
| `bux_bounds_check` | `func bux_bounds_check(index: uint, len: uint)` | Panic on OOB |
| `bux_hash_string` | `func bux_hash_string(s: String) -> uint` | DJB2 hash for strings |
| `bux_hash_bytes` | `func bux_hash_bytes(ptr: *void, size: uint) -> uint` | DJB2 hash for raw bytes |
---
## Std::Task
Pthread-based threading primitives.
### Types
```bux
struct TaskHandle {
handle: *void;
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Task_Spawn` | `func Task_Spawn(fn: *void, arg: *void) -> TaskHandle` | Spawn a new thread running `fn(arg)` |
| `Task_Join` | `func Task_Join(t: TaskHandle)` | Block until thread completes |
| `Task_Sleep` | `func Task_Sleep(ms: int64)` | Sleep current thread for N milliseconds |
### Example
```bux
import Std::Task::{Task_Spawn, Task_Join, TaskHandle};
func Worker(arg: *void) -> *void {
PrintLine("Hello from thread!");
return null;
}
func Main() -> int {
let handle: TaskHandle = Task_Spawn(Worker as *void, null);
Task_Join(handle);
PrintLine("Thread finished");
return 0;
}
```
---
## Std::Sync
Synchronization primitives: `Mutex` and `RwLock`.
### Types
```bux
struct Mutex {
handle: *void;
}
struct RwLock {
handle: *void;
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Mutex_New` | `func Mutex_New() -> Mutex` | Create a new mutex |
| `Mutex_Lock` | `func Mutex_Lock(m: *Mutex)` | Acquire lock (blocks) |
| `Mutex_Unlock` | `func Mutex_Unlock(m: *Mutex)` | Release lock |
| `Mutex_Free` | `func Mutex_Free(m: *Mutex)` | Destroy mutex |
| `RwLock_New` | `func RwLock_New() -> RwLock` | Create a new read-write lock |
| `RwLock_ReadLock` | `func RwLock_ReadLock(rw: *RwLock)` | Acquire read lock (shared) |
| `RwLock_WriteLock` | `func RwLock_WriteLock(rw: *RwLock)` | Acquire write lock (exclusive) |
| `RwLock_Unlock` | `func RwLock_Unlock(rw: *RwLock)` | Release read or write lock |
| `RwLock_Free` | `func RwLock_Free(rw: *RwLock)` | Destroy rwlock |
### Example
```bux
import Std::Io::{PrintLine, PrintInt};
import Std::Task::{Task_Join, TaskHandle};
import Std::Sync::{Mutex, Mutex_New, Mutex_Lock, Mutex_Unlock};
struct Counter {
value: int;
mtx: Mutex;
}
func Incrementer(arg: *void) -> *void {
let c: *Counter = arg as *Counter;
var i: int = 0;
while i < 100000 {
Mutex_Lock(&c.mtx);
c.value = c.value + 1;
Mutex_Unlock(&c.mtx);
i = i + 1;
}
return null;
}
func Main() -> int {
var counter: Counter = Counter { value: 0, mtx: Mutex_New() };
let a: *void = spawn Incrementer(&counter);
let b: *void = spawn Incrementer(&counter);
Task_Join(TaskHandle { handle: a });
Task_Join(TaskHandle { handle: b });
PrintLine("Counter:");
PrintInt(counter.value);
return 0;
}
```
---
## Std::Channel
Generic channel for thread communication over pthread mutex/cond.
### Types
```bux
struct Channel<T> {
handle: *void;
}
```
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Channel_New<T>` | `func Channel_New<T>(capacity: int64) -> Channel<T>` | Create buffered channel |
| `Channel_Send<T>` | `func Channel_Send<T>(ch: *Channel<T>, value: T)` | Send value (blocks if full) |
| `Channel_Recv<T>` | `func Channel_Recv<T>(ch: *Channel<T>) -> T` | Receive value (blocks if empty) |
| `Channel_Close<T>` | `func Channel_Close<T>(ch: *Channel<T>)` | Close channel |
| `Channel_Free<T>` | `func Channel_Free<T>(ch: *Channel<T>)` | Free channel memory |
### Non-generic wrappers
| Function | Signature | Description |
|----------|-----------|-------------|
| `Channel_SendInt` | `func Channel_SendInt(ch: *Channel<int>, value: int)` | Send int (no monomorphization issues) |
| `Channel_RecvInt` | `func Channel_RecvInt(ch: *Channel<int>) -> int` | Recv int (returns 0 if closed+empty) |
| `Channel_SendFloat64` | `func Channel_SendFloat64(ch: *Channel<float64>, value: float64)` | Send float64 |
| `Channel_RecvFloat64` | `func Channel_RecvFloat64(ch: *Channel<float64>) -> float64` | Recv float64 |
### Example
```bux
import Std::Io::{PrintLine, PrintInt};
import Std::Task::{Task_Join, TaskHandle};
import Std::Channel::{Channel, Channel_New, Channel_SendInt, Channel_RecvInt, Channel_Close};
func Producer(chPtr: *Channel<int>) {
var i: int = 1;
while i <= 5 {
Channel_SendInt(chPtr, i * 10);
i = i + 1;
}
Channel_Close<int>(chPtr);
}
func Consumer(chPtr: *Channel<int>) {
var total: int = 0;
while true {
let val: int = Channel_RecvInt(chPtr);
if val == 0 { break; }
total = total + val;
}
PrintLine("Total:");
PrintInt(total);
}
func Main() -> int {
let ch: Channel<int> = Channel_New<int>(3);
let p: *void = spawn Producer(&ch);
let c: *void = spawn Consumer(&ch);
Task_Join(TaskHandle { handle: p });
Task_Join(TaskHandle { handle: c });
return 0;
}
```
---
## Std::Net
TCP socket operations.
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Net_Create` | `func Net_Create() -> int` | Create TCP socket (-1 on error) |
| `Net_SetReuse` | `func Net_SetReuse(fd: int) -> bool` | Enable SO_REUSEADDR |
| `Net_Bind` | `func Net_Bind(fd: int, addr: String, port: int) -> bool` | Bind socket |
| `Net_Listen` | `func Net_Listen(fd: int, backlog: int) -> bool` | Start listening |
| `Net_Accept` | `func Net_Accept(fd: int) -> int` | Accept connection (-1 on error) |
| `Net_Connect` | `func Net_Connect(fd: int, addr: String, port: int) -> bool` | Connect to remote |
| `Net_Send` | `func Net_Send(fd: int, data: String) -> int` | Send data (bytes sent or -1) |
| `Net_Recv` | `func Net_Recv(fd: int, maxLen: int) -> String` | Receive up to maxLen bytes |
| `Net_Close` | `func Net_Close(fd: int) -> bool` | Close socket |
| `Net_LastError` | `func Net_LastError() -> String` | Get last socket error |
### Example — Echo Server
```bux
import Std::Net::*;
import Std::Io::PrintLine;
func Main() -> int {
let fd: int = Net_Create();
Net_SetReuse(fd);
Net_Bind(fd, "127.0.0.1", 8080);
Net_Listen(fd, 10);
PrintLine("Listening on :8080");
let client: int = Net_Accept(fd);
let msg: String = Net_Recv(client, 1024);
Net_Send(client, msg);
Net_Close(client);
Net_Close(fd);
return 0;
}
```
---
## Std::Json
JSON parser and serializer using a flat struct with int tag.
### Types
```bux
struct JsonValue {
tag: int,
boolVal: bool,
numVal: float64,
strVal: String,
arrData: *JsonValue,
arrLen: uint,
objKeys: *String,
objValues: *JsonValue,
objLen: uint
}
```
### Constructors
| Function | Signature | Description |
|----------|-----------|-------------|
| `Json_Null` | `func Json_Null() -> JsonValue` | Null value |
| `Json_Bool` | `func Json_Bool(b: bool) -> JsonValue` | Boolean value |
| `Json_Number` | `func Json_Number(n: float64) -> JsonValue` | Number value |
| `Json_String` | `func Json_String(s: String) -> JsonValue` | String value |
| `Json_Array` | `func Json_Array() -> JsonValue` | Empty array |
| `Json_Object` | `func Json_Object() -> JsonValue` | Empty object |
### Accessors
| Function | Signature | Description |
|----------|-----------|-------------|
| `Json_IsNull` | `func Json_IsNull(v: JsonValue) -> bool` | Check if null |
| `Json_AsBool` | `func Json_AsBool(v: JsonValue) -> bool` | Get bool (false if wrong type) |
| `Json_AsNumber` | `func Json_AsNumber(v: JsonValue) -> float64` | Get number (0.0 if wrong type) |
| `Json_AsString` | `func Json_AsString(v: JsonValue) -> String` | Get string ("" if wrong type) |
| `Json_ArrayLen` | `func Json_ArrayLen(v: JsonValue) -> uint` | Array length |
| `Json_ArrayGet` | `func Json_ArrayGet(v: JsonValue, index: uint) -> JsonValue` | Get array element |
| `Json_ObjectLen` | `func Json_ObjectLen(v: JsonValue) -> uint` | Object key count |
| `Json_ObjectGet` | `func Json_ObjectGet(v: JsonValue, key: String) -> JsonValue` | Get object value by key |
| `Json_ObjectHas` | `func Json_ObjectHas(v: JsonValue, key: String) -> bool` | Check if key exists |
### Mutators
| Function | Signature | Description |
|----------|-----------|-------------|
| `Json_ArrayPush` | `func Json_ArrayPush(self: *JsonValue, val: JsonValue)` | Append to array |
| `Json_ObjectSet` | `func Json_ObjectSet(self: *JsonValue, key: String, val: JsonValue)` | Set object key |
### Parser / Serializer
| Function | Signature | Description |
|----------|-----------|-------------|
| `Json_Parse` | `func Json_Parse(s: String) -> JsonValue` | Parse JSON string |
| `Json_Stringify` | `func Json_Stringify(v: JsonValue) -> String` | Serialize to JSON string |
### Example
```bux
import Std::Json::*;
import Std::Io::PrintLine;
func Main() -> int {
let json: JsonValue = Json_Parse(`{"name": "Bux", "version": 1}`);
let name: String = Json_AsString(Json_ObjectGet(json, "name"));
PrintLine(name); // "Bux"
var arr: JsonValue = Json_Array();
Json_ArrayPush(&arr, Json_Number(10));
Json_ArrayPush(&arr, Json_Number(20));
PrintLine(Json_Stringify(arr)); // [10,20]
return 0;
}
```
---
## Std::Crypto
Cryptographic primitives via OpenSSL (`-lcrypto`).
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Crypto_Sha256` | `func Crypto_Sha256(data: String) -> String` | SHA-256 hex string |
| `Crypto_HmacSha256` | `func Crypto_HmacSha256(key: String, message: String) -> String` | HMAC-SHA256 hex string |
| `Crypto_HmacSha256Raw` | `func Crypto_HmacSha256Raw(key: String, message: String) -> String` | HMAC-SHA256 base64 string |
| `Crypto_RandomBytes` | `func Crypto_RandomBytes(n: int) -> String` | `n` random bytes as base64 |
| `Crypto_Base64Encode` | `func Crypto_Base64Encode(s: String) -> String` | Base64 encode |
| `Crypto_Base64Decode` | `func Crypto_Base64Decode(s: String) -> String` | Base64 decode |
### Example
```bux
import Std::Crypto::*;
import Std::Io::PrintLine;
func Main() -> int {
let hash: String = Crypto_Sha256("hello");
PrintLine(hash);
let hmac: String = Crypto_HmacSha256("key", "message");
PrintLine(hmac);
let rand: String = Crypto_RandomBytes(16);
PrintLine(rand);
return 0;
}
```
---
## Std::Fmt
Convenience wrappers for string formatting.
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Fmt_Fmt1` | `func Fmt_Fmt1(pattern: String, a: String) -> String` | Format with 1 arg |
| `Fmt_Fmt2` | `func Fmt_Fmt2(pattern: String, a: String, b: String) -> String` | Format with 2 args |
| `Fmt_Fmt3` | `func Fmt_Fmt3(pattern: String, a: String, b: String, c: String) -> String` | Format with 3 args |
| `Fmt_FmtInt` | `func Fmt_FmtInt(pattern: String, n: int64) -> String` | Format with int arg |
| `Fmt_FmtInt2` | `func Fmt_FmtInt2(pattern: String, n1: int64, n2: int64) -> String` | Format with 2 int args |
| `Fmt_FmtFloat` | `func Fmt_FmtFloat(pattern: String, f: float64) -> String` | Format with float arg |
| `Fmt_FmtBool` | `func Fmt_FmtBool(pattern: String, b: bool) -> String` | Format with bool arg |
### Example
```bux
import Std::Fmt::*;
import Std::Io::PrintLine;
func Main() -> int {
PrintLine(Fmt_Fmt1("Hello, {0}!", "World"));
PrintLine(Fmt_FmtInt("Count: {0}", 42));
PrintLine(Fmt_FmtFloat("Pi: {0}", 3.14159));
return 0;
}
```
---
## Std::Math
Mathematical functions.
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `Sqrt` | `func Sqrt(x: float64) -> float64` | Square root |
| `Pow` | `func Pow(x: float64, y: float64) -> float64` | Power |
| `Abs` | `func Abs(n: int64) -> int64` | Absolute value (int) |
| `AbsF` | `func AbsF(f: float64) -> float64` | Absolute value (float) |
| `Min` | `func Min(a: int64, b: int64) -> int64` | Minimum (int) |
| `Max` | `func Max(a: int64, b: int64) -> int64` | Maximum (int) |
| `MinF` | `func MinF(a: float64, b: float64) -> float64` | Minimum (float) |
| `MaxF` | `func MaxF(a: float64, b: float64) -> float64` | Maximum (float) |
### Example
```bux
import Std::Math::*;
import Std::Io::PrintInt;
func Main() -> int {
PrintInt(Max(10, 20) as int); // 20
PrintInt(Min(10, 20) as int); // 10
return 0;
}
```
---
## Std::Async
Low-level async runtime for stackful coroutines. These functions are used by the `async`/`await` language features.
### Functions
| Function | Signature | Description |
|----------|-----------|-------------|
| `bux_async_spawn` | `func bux_async_spawn(fn: *void) -> *void` | Create a new coroutine from a function pointer |
| `bux_async_yield` | `func bux_async_yield()` | Yield control to the scheduler |
| `bux_async_await` | `func bux_async_await(handle: *void) -> *void` | Block until coroutine completes, return result pointer |
| `bux_async_run` | `func bux_async_run()` | Run the round-robin scheduler |
| `bux_async_sleep` | `func bux_async_sleep(ms: int64)` | Non-blocking sleep for `ms` milliseconds |
| `bux_async_return` | `func bux_async_return(value: *void, size: int64)` | Copy return value into task result buffer |
| `bux_now_ms` | `func bux_now_ms() -> int64` | Monotonic clock in milliseconds |
### Example
```bux
extern func bux_async_yield();
extern func bux_async_spawn(fn: *void) -> *void;
extern func bux_async_await(handle: *void) -> *void;
async func Compute() -> int {
bux_async_yield();
return 42;
}
func Main() -> int {
let h = spawn Compute();
let r: int = h.await as int;
return 0;
}
```
---
## Future Modules
- `Std::Result` — Shipped via algebraic enums ✅
- `Std::Option` — Shipped via algebraic enums ✅
- `Std::Math``Sqrt`, `Pow`, `Min`, `Max`, `Abs`
- `Std::Fs` — Directory operations ✅
- `Std::Mem` — Memory wrappers ✅
- `Std::Set` — Hash set ✅
- `Std::Path` — Path manipulation ✅
- `Std::Os``Args`, `Env`, `Cwd`, `Chdir`
- `Std::Time``NowMs`, `NowUs`, `SleepMs`
- `Std::Process``Run`, `Output`
- `Std::Fmt` — String formatting with interpolation ✅
- `Std::Iter` — Iterator over `Array<T>`
- `Std::Task` / `Std::Channel` — Lightweight concurrency (pthread-based threads) ✅
- `Std::Net` — TCP sockets ✅
- `Std::Json` — JSON parser/serializer ✅
- `Std::Crypto` — SHA-256, HMAC, Base64, random bytes ✅
- `Std::Math` — Sqrt, Pow, Abs, Min, Max ✅
---
## Std::Os
Operating system interface.
```bux
import Std::Os::{Os_ArgsCount, Os_Args, Os_GetEnv, Os_SetEnv, Os_GetCwd, Os_Chdir, Os_Exit};
```
| Function | Signature | Description |
|----------|-----------|-------------|
| `Os_ArgsCount` | `func Os_ArgsCount() -> int` | Number of command-line arguments |
| `Os_Args` | `func Os_Args(index: int) -> String` | Get argument at index |
| `Os_GetEnv` | `func Os_GetEnv(name: String) -> String` | Get environment variable |
| `Os_SetEnv` | `func Os_SetEnv(name: String, value: String) -> bool` | Set environment variable |
| `Os_GetCwd` | `func Os_GetCwd() -> String` | Get current working directory |
| `Os_Chdir` | `func Os_Chdir(path: String) -> bool` | Change directory |
| `Os_Exit` | `func Os_Exit(code: int)` | Terminate process with exit code |
---
## Std::Test
Lightweight assertions for `bux test` and example programs.
```bux
import Std::Test::*;
```
| Function | Signature | Description |
|----------|-----------|-------------|
| `Test_Assert` | `func Test_Assert(cond: bool)` | Panic if false |
| `Test_AssertTrue` / `Test_AssertFalse` | `func ...(cond: bool)` | Boolean asserts |
| `Test_AssertEqInt` | `func Test_AssertEqInt(a: int, b: int)` | Integer equality |
| `Test_AssertNeqInt` | `func Test_AssertNeqInt(a: int, b: int)` | Integer inequality |
| `Test_AssertEqString` | `func Test_AssertEqString(a: String, b: String)` | String equality |
| `Test_AssertEqBool` | `func Test_AssertEqBool(a: bool, b: bool)` | Boolean equality |
| `Test_Fail` / `Test_Pass` | `func ...(msg: String)` | Explicit fail / log pass |
| `Test_Exit` | `func Test_Exit(code: int)` | Exit with code |
---
## Std::Time
Time utilities.
```bux
import Std::Time::{Time_NowMs, Time_NowUs, Time_SleepMs};
```
| Function | Signature | Description |
|----------|-----------|-------------|
| `Time_NowMs` | `func Time_NowMs() -> int64` | Current time in milliseconds |
| `Time_NowUs` | `func Time_NowUs() -> int64` | Current time in microseconds |
| `Time_SleepMs` | `func Time_SleepMs(ms: int64)` | Sleep for N milliseconds |
---
## Std::Process
Process spawning.
```bux
import Std::Process::{Process_Run, Process_Output};
```
| Function | Signature | Description |
|----------|-----------|-------------|
| `Process_Run` | `func Process_Run(cmd: String) -> int` | Run command, return exit code |
| `Process_Output` | `func Process_Output(cmd: String) -> String` | Run command, capture stdout |