Strings
Zeus provides a first-class string type for working with text. Strings are immutable sequences of UTF-8 encoded bytes.
String Literals
String literals are enclosed in double quotes and create string objects:
let greeting = "Hello, Zeus!";let emoji = "Welcome 👋";let japanese = "こんにちは";String literals fully support UTF-8, including multi-byte characters and emojis.
Escape Sequences
String literals support escape sequences for special characters:
| Escape | Character |
|---|---|
\n | Newline |
\t | Tab |
\r | Carriage return |
\\ | Backslash |
\" | Double quote |
\' | Single quote |
\0 | Null character |
\e | Escape (ESC, 0x1b) |
\xHH | Byte from two hex digits (e.g. \x1b) |
console.log("Line 1\nLine 2"); // Two linesconsole.log("Col1\tCol2\tCol3"); // Tab-separatedconsole.log("Say \"Hello\""); // Embedded quotesconsole.log("Path: C:\\Users"); // Backslashconsole.log("\e[31mred\e[0m"); // ANSI-colored text (see Colors)Output:
Line 1Line 2Col1 Col2 Col3Say "Hello"Path: C:\UsersString vs u8[]
Zeus has two ways to work with text:
| Type | Mutability | Use Case |
|---|---|---|
string | Immutable | Text that shouldn’t change |
u8[] | Mutable | When you need to modify bytes |
Creating Strings
// String literal creates an immutable stringlet message: string = "Hello";Converting to Mutable Bytes
When you assign a string to a u8[], Zeus creates a copy of the underlying bytes. This copy is mutable:
let original: string = "Hello";
// Creates a mutable copy of the byteslet bytes: u8[] = original;
// Modify the copy (original is unchanged)bytes[0] = 'h';
console.log(original); // "Hello" (unchanged)
// To log bytes, convert back to stringlet modified: string = bytes;console.log(modified); // "hello"Properties
length
Returns the length of the string in bytes (not characters).
let text = "Hello";let len = text.length; // 5
let emoji = "👋";let emojiLen = emoji.length; // 4 (UTF-8 bytes)Methods
compare
Compares two strings lexicographically (byte-by-byte).
compare(other: string): i8Returns:
-1if this string comes beforeother0if the strings are equal1if this string comes afterother
let a = "apple";let b = "banana";let c = "apple";
let cmp1 = a.compare(b); // -1 (apple < banana)let cmp2 = b.compare(a); // 1 (banana > apple)let cmp3 = a.compare(c); // 0 (apple == apple)equals
Checks if two strings are equal.
equals(other: string): booleanReturns: true if the strings have the same bytes, false otherwise.
let a: string = "hello";let b: string = "hello";let c: string = "world";
if (a.equals(b)) { // This executes - strings are equal}
if (a.equals(c) == false) { // This executes - strings are different}concat
Concatenates two strings and returns a new string.
concat(other: string): stringReturns: A new string containing both strings joined together.
let hello = "Hello";let world = "World";
let greeting = hello.concat(" ").concat(world);console.log(greeting); // "Hello World"Search, slice, transform
These byte-oriented methods mirror JavaScript’s String methods:
slice(start: i32, end: i32): string // JS-style; negative indices count from the endsubstring(start: i32, end: i32): string // clamps to 0; swaps if start > endindexOf(needle: string): i32 // first index, or -1lastIndexOf(needle: string): i32 // last index, or -1includes(needle: string): booleanstartsWith(prefix: string): booleanendsWith(suffix: string): booleantoUpperCase(): string // ASCIItoLowerCase(): string // ASCIItrim(): string trimStart(): string trimEnd(): stringrepeat(count: i32): stringpadStart(targetLength: i32, pad: string): stringpadEnd(targetLength: i32, pad: string): stringreplace(search: string, replacement: string): string // first occurrence (literal)replaceAll(search: string, replacement: string): string // all occurrences (literal)charAt(index: i32): string // 1-char string, or "" out of rangecharCodeAt(index: i32): i32 // byte value, or -1 out of rangesplit(separator: string): string[] // "" separator splits into single byteslet s = "Hello, World";console.log(s.slice(7, s.length)); // "World"console.log(s.slice(-5, s.length)); // "World"console.log(s.toUpperCase()); // "HELLO, WORLD"console.log(" trim me ".trim()); // "trim me"console.log("7".padStart(3, "0")); // "007"console.log("a,b,c".replaceAll(",", "-")); // "a-b-c"
let parts: string[] = "a,b,c".split(","); // ["a", "b", "c"]console.log(parts.length); // 3String Operators
Zeus supports operators for string manipulation and comparison:
Concatenation (+)
The + operator concatenates two strings:
let first = "Hello";let second = "World";let result = first + " " + second;console.log(result); // "Hello World"Equality Operators (== and !=)
Compare strings for equality or inequality:
let a = "hello";let b = "hello";let c = "world";
if (a == b) { console.log("a equals b"); // This executes}
if (a != c) { console.log("a not equals c"); // This executes}Comparison Operators (<, >, <=, >=)
Compare strings lexicographically (dictionary order):
let apple = "apple";let banana = "banana";
if (apple < banana) { console.log("apple comes before banana"); // This executes}
if (banana > apple) { console.log("banana comes after apple"); // This executes}
let a = "hello";let b = "hello";
if (a <= b) { console.log("a <= b"); // This executes (they're equal)}
if (a >= b) { console.log("a >= b"); // This executes (they're equal)}Indexing
You can read individual bytes from a string using indexing:
let greeting: string = "Hello";
let h: u8 = greeting[0]; // 72 ('H')let e: u8 = greeting[1]; // 101 ('e')let o: u8 = greeting[4]; // 111 ('o')Since strings are immutable, you cannot assign to a string index:
let text: string = "Hello";text[0] = 'h'; // Error: cannot assign to string index: strings are immutableTo modify characters, convert to u8[] first:
let text: string = "Hello";let bytes: u8[] = text; // Create mutable copybytes[0] = 'h'; // Modify the copylet modified: string = bytes; // "hello"Implicit Conversions
Zeus supports implicit conversion between string and u8[]:
string → u8[]
Creates a mutable copy of the string’s bytes:
let text: string = "Hello";let bytes: u8[] = text; // Mutable copybytes[0] = 'J'; // Modify the copyu8[] → string
Creates a new immutable string from the bytes:
let bytes: u8[] = new u8[];bytes[0] = 'H';bytes[1] = 'i';
let text: string = bytes; // Creates immutable string "Hi"Working with Bytes
Since strings are UTF-8 encoded, you can work with individual bytes through u8[]:
let greeting: string = "Hi!";
// Convert to mutable byteslet bytes: u8[] = greeting;
// Access individual byteslet h: u8 = bytes[0]; // 72 ('H')let i: u8 = bytes[1]; // 105 ('i')let exclaim: u8 = bytes[2]; // 33 ('!')
// Modify bytesbytes[0] = 'h'; // lowercase
// Convert back to string for outputlet modified: string = bytes;console.log(modified); // "hi!"UTF-8 Encoding
Strings use UTF-8 encoding, where characters can be 1-4 bytes:
| Character | Bytes | Example |
|---|---|---|
| ASCII | 1 byte | 'A' = 65 |
| Extended Latin | 2 bytes | 'é' |
| CJK | 3 bytes | '日' |
| Emoji | 4 bytes | '👋' |
let ascii = "A";let asciiLen = ascii.length; // 1
let emoji = "👋";let emojiLen = emoji.length; // 4Template String Literals
Template string literals use backticks and ${expression} placeholders to embed values inline:
let name = "Zeus";let count = 3;
let greeting = `Hello, ${name}!`; // "Hello, Zeus!"let stats = `${name} has ${count} fans`; // "Zeus has 3 fans"let plain = `no interpolation here`; // "no interpolation here"Any value can be interpolated — numbers, booleans, objects, and arrays are converted to a string
automatically (via their toString, structural reflection for objects/arrays otherwise). The same
conversion powers + string concatenation:
class Point { x: i32; constructor(x: i32) { this.x = x; } }
let n = 42;let p = new Point(7);let msg = `n=${n}, p=${p}`; // "n=42, p=Point { x: 7 }"let sum = "value: " + n; // "value: 42"Future Features
Regular-expression matching (match, regex-based replace/split) is planned once Zeus gains a
regex engine.