Text processing
The language keeps the String primitives; everything else is std.strings, written in ordinary Luce. With the import in scope the method spelling works: s.split(x) is strings.split(s, x).
import std.strings
func main():
let line = " name , age , city "
var fields: List(String) = []
for raw in line.split(","):
fields.append(raw.trim())
print(f"{len(fields)}: [{fields.join("][")}]")3: [name][age][city]
Searching and testing#
import std.strings
func main():
let path = "src/luce/06_mir/module.zig"
print(f"find '/': {path.find("/")}")
print(f"find_from '/' after 4: {path.find_from("/", 4)}")
print(f"contains 'mir': {path.contains("mir")}")
print(f"starts_with 'src': {path.starts_with("src")}")
print(f"ends_with '.zig': {path.ends_with(".zig")}")
print(f"count '/': {path.count("/")}")find '/': 3 find_from '/' after 4: 8 contains 'mir': true starts_with 'src': true ends_with '.zig': true count '/': 3
Reshaping#
import std.strings
func main():
let messy = "\tThe Quick Brown Fox\n"
print(f"[{messy.trim()}]")
print(messy.trim().lower())
print(messy.trim().upper())
print(messy.trim().replace("Quick", "Slow"))
print(f"[{"-".repeat(20)}]")
print(f"[{"42".pad_left(6)}][{"42".pad_right(6)}]")[The Quick Brown Fox] the quick brown fox THE QUICK BROWN FOX The Slow Brown Fox [--------------------] [ 42][42 ]
An empty separator splits on runs of whitespace and drops the empty pieces — Python's split(). A real separator keeps them.
import std.strings
func main():
let messy = " a b c "
print(f"whitespace: {len(messy.split(""))} pieces")
print(f"on space: {len(messy.split(" "))} pieces")whitespace: 3 pieces on space: 10 pieces
Building text#
Repeated + allocates every time; a Builder does not.
func main():
var table = new Builder()
for row in range(0, 4):
for column in range(0, 4):
table.append(str(row * column))
table.append_ascii(9) # a tab, without allocating a String
table.append("\n")
print(str(table))0 0 0 0 0 1 2 3 0 2 4 6 0 3 6 9
Walking bytes#
len(s) is bytes, byte_at(i) reads one, and find_byte(byte, start) scans. Those three are the primitives everything else is built on, and the seam where the runtime may vectorize.
func main():
let text = "a,bb,ccc"
var start = 0
var pieces = 0
while true:
let comma = text.find_byte(44, start)
if comma < 0:
pieces += 1
print(f"piece: {text[start:len(text)]}")
break
pieces += 1
print(f"piece: {text[start:comma]}")
start = comma + 1
print(f"{pieces} pieces, {len(text)} bytes")piece: a piece: bb piece: ccc 3 pieces, 8 bytes
Formatting numbers#
str gives the shortest round-trip form of a Float. strings.format_float(x, decimals) gives fixed point, rounding half away from zero.
import std.strings
func main():
print(str(1.0 / 3.0))
print(strings.format_float(1.0 / 3.0, 4))
print(strings.format_float(2.5, 0))
print(strings.format_float(-2.345, 2))0.3333333333333333 0.3333 3 -2.35