string
Length-prefixed strings built on &i8 byte buffers. All operations return new strings (immutable-style API) – the original string is never modified.
Memory Layout
Each string is a pointer to a 3-word header (&i64):
| Offset | Field | Description |
|---|---|---|
[0] | length | Byte count of the string content |
[1] | capacity | Allocated bytes in the data buffer |
[2] | data_ptr | &i8 pointer to the raw byte buffer |
Usage
import string
fn main() {
// Create a string from a literal
let greeting = str_from("hello", 5)
let world = str_from(" world", 6)
// Concatenate
let msg = str_concat(greeting, world)
str_print(msg) // prints: hello world
// Search
let pos = str_index_of(msg, str_from("world", 5))
print(pos) // prints: 6
// Transform
let upper = str_to_upper(msg)
str_print(upper) // prints: HELLO WORLD
}Function Reference
| Function | Signature | Description |
|---|---|---|
str_new | () -> &i64 | Create an empty string |
str_from | (src: &i8, len: i64) -> &i64 | Create a string from a byte literal |
str_clone | (s: &i64) -> &i64 | Deep copy a string |
str_len | (s: &i64) -> i64 | Get byte length |
str_byte | (s: &i64, idx: i64) -> i64 | Get byte at index |
str_eq | (a: &i64, b: &i64) -> i64 | Content equality (returns 1 or 0) |
str_concat | (a: &i64, b: &i64) -> &i64 | Concatenate two strings |
str_append | (s: &i64, src: &i8, len: i64) -> &i64 | Append literal bytes |
str_slice | (s: &i64, start: i64, end: i64) -> &i64 | Substring [start, end) |
str_index_of | (s: &i64, sub: &i64) -> i64 | Find first occurrence (or -1) |
str_contains | (s: &i64, sub: &i64) -> i64 | Check if string contains substring |
str_starts_with | (s: &i64, pfx: &i64) -> i64 | Check prefix match |
str_ends_with | (s: &i64, sfx: &i64) -> i64 | Check suffix match |
str_count | (s: &i64, sub: &i64) -> i64 | Count non-overlapping occurrences |
str_to_upper | (s: &i64) -> &i64 | ASCII uppercase copy |
str_to_lower | (s: &i64) -> &i64 | ASCII lowercase copy |
str_print | (s: &i64) | Write string to stdout |
Detailed API
str_new
fn str_new() -> &i64Create an empty string with a default capacity of 16 bytes.
let s = str_new()
print(str_len(s)) // 0Returns: Pointer to a new empty string header.
str_from
fn str_from(src: &i8, len: i64) -> &i64Create a string by copying len bytes from a byte buffer src. This is the primary way to create strings from literals.
let name = str_from("Jda", 3)
str_print(name) // Jda
print(str_len(name)) // 3Parameters:
src– pointer to the source byte buffer (typically a string literal)len– number of bytes to copy
Returns: A new string containing a copy of the source bytes.
str_clone
fn str_clone(s: &i64) -> &i64Create an independent deep copy of a string. The new string has its own data buffer.
let original = str_from("hello", 5)
let copy = str_clone(original)
print(str_eq(original, copy)) // 1Returns: A new string with identical content but separate storage.
str_len
fn str_len(s: &i64) -> i64Get the byte length of a string.
let s = str_from("hello", 5)
print(str_len(s)) // 5Returns: Number of bytes in the string.
str_byte
fn str_byte(s: &i64, idx: i64) -> i64Get the byte value at a given index. No bounds checking is performed.
let s = str_from("ABC", 3)
print(str_byte(s, 0)) // 65 (ASCII 'A')
print(str_byte(s, 2)) // 67 (ASCII 'C')Returns: The byte value (0-255) at position idx.
str_eq
fn str_eq(a: &i64, b: &i64) -> i64Test two strings for content equality. Compares lengths first, then byte-by-byte.
let a = str_from("hello", 5)
let b = str_from("hello", 5)
let c = str_from("world", 5)
print(str_eq(a, b)) // 1
print(str_eq(a, c)) // 0Returns: 1 if strings are equal, 0 otherwise.
str_concat
fn str_concat(a: &i64, b: &i64) -> &i64Concatenate two strings into a new string. Neither input is modified.
let first = str_from("hello", 5)
let second = str_from(" world", 6)
let result = str_concat(first, second)
str_print(result) // hello worldReturns: A new string containing a followed by b.
str_append
fn str_append(s: &i64, src: &i8, len: i64) -> &i64Append raw bytes from a literal to a string, returning a new string.
let s = str_from("hello", 5)
let s2 = str_append(s, "!", 1)
str_print(s2) // hello!Returns: A new string with the appended bytes.
str_slice
fn str_slice(s: &i64, start: i64, end: i64) -> &i64Extract a substring from index start (inclusive) to end (exclusive). Out-of-bounds indices are clamped. Returns an empty string if start >= end.
let s = str_from("hello world", 11)
let sub = str_slice(s, 0, 5)
str_print(sub) // helloReturns: A new string containing bytes [start, end).
str_index_of
fn str_index_of(s: &i64, sub: &i64) -> i64Find the first occurrence of substring sub in s. Uses a linear scan with byte-by-byte comparison.
let s = str_from("hello world", 11)
let target = str_from("world", 5)
print(str_index_of(s, target)) // 6
let missing = str_from("xyz", 3)
print(str_index_of(s, missing)) // -1Returns: Index of first match, or -1 if not found.
str_contains
fn str_contains(s: &i64, sub: &i64) -> i64Check whether s contains the substring sub.
let s = str_from("hello world", 11)
let sub = str_from("world", 5)
print(str_contains(s, sub)) // 1Returns: 1 if found, 0 otherwise.
str_starts_with
fn str_starts_with(s: &i64, pfx: &i64) -> i64Check whether s starts with the prefix pfx.
let s = str_from("/api/users", 10)
let pfx = str_from("/api", 4)
print(str_starts_with(s, pfx)) // 1Returns: 1 if s starts with pfx, 0 otherwise.
str_ends_with
fn str_ends_with(s: &i64, sfx: &i64) -> i64Check whether s ends with the suffix sfx.
let path = str_from("main.jda", 8)
let ext = str_from(".jda", 4)
print(str_ends_with(path, ext)) // 1Returns: 1 if s ends with sfx, 0 otherwise.
str_count
fn str_count(s: &i64, sub: &i64) -> i64Count non-overlapping occurrences of sub in s. After each match, scanning advances by the length of sub.
let s = str_from("abababab", 8)
let sub = str_from("ab", 2)
print(str_count(s, sub)) // 4Returns: Number of non-overlapping matches.
str_to_upper
fn str_to_upper(s: &i64) -> &i64Create a new string with all ASCII lowercase letters (a-z) converted to uppercase (A-Z). Non-ASCII bytes are copied unchanged.
let s = str_from("Hello World", 11)
let upper = str_to_upper(s)
str_print(upper) // HELLO WORLDReturns: A new uppercase string.
str_to_lower
fn str_to_lower(s: &i64) -> &i64Create a new string with all ASCII uppercase letters (A-Z) converted to lowercase (a-z).
let s = str_from("Hello World", 11)
let lower = str_to_lower(s)
str_print(lower) // hello worldReturns: A new lowercase string.
str_print
fn str_print(s: &i64)Write the string content to stdout using the write syscall.
let s = str_from("hello\n", 6)
str_print(s) // hellostr_alloc
fn str_alloc(cap: i64) -> &i64Internal: Allocate a new string header and data buffer with the given capacity. Minimum capacity is 16.
str_copy
fn str_copy(n: i64)Internal: Copy n bytes from the source pointer g_str_a to the destination pointer g_str_b. Used for fast string concatenation and cloning.
str_copy_at
fn str_copy_at(off_b: i64, off_a: i64, n: i64)Internal: Copy n bytes from offset off_a in g_str_a to offset off_b in g_str_b.
str_match_at
fn str_match_at(s: &i64, pos: i64, sub: &i64) -> i64Internal: Check if the substring sub matches at the given position pos within the string s.
Internal Functions
These functions are used internally by the string module. They are exported but generally should not be called directly.
| Function | Signature | Description |
|---|---|---|
str_alloc | (cap: i64) -> &i64 | Allocate a string header with given capacity (minimum 16) |
str_copy | (n: i64) | Copy n bytes using global pointers g_str_a and g_str_b |
str_copy_at | (off_b: i64, off_a: i64, n: i64) | Copy n bytes between offsets in global pointers |
str_match_at | (s: &i64, pos: i64, sub: &i64) -> i64 | Check if sub matches at position pos in s |