Built-in functions
The output, time, filesystem, serialization, string, collection and mathematics API available today.
func main() {
local var message string = " Hello, Sarlin "
local var values string[] = message.trim().split(", ")
local var scores dictionary[string, int32] = ["Bob": 100]
print(message.to_upper())
print(values)
print(scores.get("Alice", 0))
print(square_root(81.0))
}Output
print(value) writes one value followed by a newline. It accepts one argument and supports numeric values, booleans, strings, arrays and dictionaries.
Time
func main() {
local var launch Time = Time.countdown(01:30:00:000)
launch.start()
if launch {
print(launch.remaining)
}
if launch.finished {
print("Launch")
}
}| Property or function | Result |
|---|---|
| Time.countdown(duration) | Creates a stopped timer that counts down from the duration. |
| Time.stopwatch(duration) | Creates a stopped timer that counts upward and finishes at the duration. |
| Time.get_local(format) | Current device-local date and time as a formatted string. |
| timer.start() | Starts from the beginning. Does nothing when already running. |
| timer.pause() | Freezes a running timer at its current position. |
| timer.resume() | Continues a paused timer. |
| timer.stop() | Stops and resets the timer to its initial position. |
| timer.restart() | Resets and immediately starts the timer. |
| timer.remaining | Milliseconds remaining as uint64. |
| timer.elapsed | Milliseconds elapsed as uint64. |
| timer.running | Whether the timer is currently running. |
| timer.paused | Whether the timer is paused. |
| timer.finished | Whether the timer reached its limit. |
Duration fields are read from right to left as milliseconds, seconds, minutes, hours, days and weeks. Time.countdown(30) is 30 milliseconds;Time.countdown(05:000) is five seconds; andTime.countdown(01:30:00:000) is one hour and 30 minutes.
A timer used as an if or while condition is true only while running. The clock advances independently, but a normalwhile loop still repeats as fast as its body allows. A timer cannot be printed directly; print remaining, elapsedor a state property instead.
Files
func main() {
local const folder string = "saves"
local const save_file string = path.join(folder, "player.txt")
directory.ensure(folder)
file.write(save_file, "score: 100")
file.append_line(save_file, "ready")
if file.exists(save_file) {
print(file.read(save_file))
print(file.size(save_file))
}
print(directory.list(folder))
}| Property or function | Result |
|---|---|
| file.exists(path) | Whether path names an existing regular file. |
| file.read(path) | Complete file contents as a string. Missing or unreadable files are fatal. |
| file.write(path, contents) | Creates or replaces a text file. |
| file.append(path, contents) | Creates a text file or appends without adding a separator. |
| file.append_line(path, contents) | Creates a text file or appends contents followed by a newline. |
| file.ensure(path) | Creates an empty file when absent and preserves an existing file. |
| file.remove(path) | Removes a file. Does nothing when it is already absent. |
| file.size(path) | File size in bytes as uint64. |
Directories
| Property or function | Result |
|---|---|
| directory.exists(path) | Whether path names an existing directory. |
| directory.create(path) | Creates one directory. Its parent must exist and the target must be absent. |
| directory.ensure(path) | Creates the directory and any missing parents; preserves existing directories. |
| directory.remove(path) | Removes an empty directory. Does nothing when it is absent. |
| directory.list(path) | Sorted string[] of entry names, excluding . and ... |
directory.remove() removes empty directories only. Recursive deletion is deliberately not provided.
Paths
| Property or function | Result |
|---|---|
| path.join(left, right) | Joins two path segments with one forward slash. |
| path.name(value) | Final file or directory name. |
| path.extension(value) | Final extension without the dot, or an empty string. |
| path.parent(value) | Parent portion, or . when there is no parent portion. |
| path.absolute(value) | Prefixes a relative path with the current working directory; absolute paths are preserved. |
Path functions are lexical: they do not require the target to exist. They use forward slashes and do not resolve . or .. segments.
Serialization
func main() {
local var scores dictionary[string, int32] = [
"Ada": 10
"Grace": 20
]
local var encoded string = JSON.stringify(scores)
print(encoded)
local var decoded dictionary[string, int32] = JSON.parse(encoded)
print(decoded["Ada"])
}| Property or function | Result |
|---|---|
| JSON.stringify(value) | Encodes a number, boolean, string, array or string-keyed dictionary as JSON text. |
| JSON.parse(text) | Decodes JSON text into the destination type the surrounding declaration supplies. |
| CSV.stringify(rows) | Encodes a string[][] as CSV text, quoting fields only where required. |
| CSV.parse(text) | Decodes CSV text into a string[][]. |
JSON.parse is directed by the type it is being stored into, so it always needs a destination: local var scores dictionary[string, int32] = JSON.parse(text) works, while print(JSON.parse(text))is rejected. Decoding checks the text against that type, so a value outside the destination integer range, a missing entry in a fixed dictionary, or a JSON nullstops the program with a clear runtime diagnostic.
Both directions support numbers, booleans, strings, arrays and dictionaries. Dictionaries must use string keys, because JSON object names are always strings. Classes and defines are not supported in either direction, andJSON.parse additionally rejects fixed-size array destinations.
func main() {
local var rows string[][] = [
["name", "note"],
["Ada", "math, logic"]
]
local var encoded string = CSV.stringify(rows)
print(encoded)
local var decoded string[][] = CSV.parse(encoded)
print(decoded[1][1])
}CSV is always string[][]: one array per row, one string per field. Rows may have different field counts. Parsing accepts both LF andCRLF line endings, and understands quoted fields containing commas, line breaks and doubled quotes. Encoding quotes a field only when it contains a comma, a quote or a line break.
Strings
| Property or function | Result |
|---|---|
| text.length | Number of stored bytes, as uint64. |
| text.contains(value) | Whether value occurs in the string. |
| text.starts_with(value) | Whether the string starts with value. |
| text.ends_with(value) | Whether the string ends with value. |
| text.to_upper() | A new string with ASCII a-z changed to A-Z. |
| text.to_lower() | A new string with ASCII A-Z changed to a-z. |
| text.trim() | A new string without leading or trailing spaces, tabs, CR or LF. |
| text.replace(old, new) | A new string with occurrences replaced. |
| text.split(separator) | A string[] split at the separator. |
Strings are immutable and their operations are byte-based. ASCII case conversion and ASCII whitespace trimming do not perform full Unicode case or whitespace processing. Every transforming method returns a new string.
Arrays
| Property or function | Result |
|---|---|
| values.length | Element count as uint64. |
| values.is_empty() | Whether the array has no elements. |
| values.contains(value) | Whether an equal element is present. |
| values.add(value) | Appends a value. |
| values.insert(index, value) | Inserts a value at an int64 position. |
| values.remove_at(index) | Removes the value at an int64 index. |
| values.clear() | Removes all values. |
| values.duplicate() | Returns a shallow copy. |
| values.duplicate_deep() | Recursively copies nested collections. |
Dictionaries
| Property or function | Result |
|---|---|
| values.length | Entry count as uint64. |
| values.is_empty() | Whether the dictionary has no entries. |
| values.contains(key) | Whether the key is present. |
| values.get(key, fallback) | Stored value, or fallback when absent. |
| values.remove(key) | Removes a key and returns whether it existed. |
| values.clear() | Removes all entries. |
| values.keys() | An array of all keys. |
| values.values() | An array of all values. |
| values.duplicate() | Returns a shallow copy. |
| values.duplicate_deep() | Recursively copies nested collection values. |
Mathematics
| Property or function | Result |
|---|---|
| absolute(value) | Absolute value of a signed integer or float. |
| minimum(left, right) | Smaller of two numeric values. |
| maximum(left, right) | Larger of two numeric values. |
| round(value) | Floating-point value rounded to the nearest whole value. |
| round_up(value) | Floating-point value rounded toward positive infinity. |
| round_down(value) | Floating-point value rounded toward negative infinity. |
| square_root(value) | Floating-point square root; negative input is a runtime error. |
| power(base, exponent) | Floating-point base raised to an exponent. |
absolute, minimum andmaximum preserve their numeric input type. Rounding, square root and power operate on float32 or float64 and preserve that floating-point type.