Documentation menu
Built-ins

System & files

Everything that reaches outside the program: the disk, the process table, the environment, the clock and the terminal. This is also where permissions bite, so that section comes first.

Permissions

OS/hardware namespaces are sandboxed by default. Grant access with a three-level permission model:

// Level 1 — serez.json (project-wide)
// { "permissions": ["Terminal", "OS", "Env"] }

// Level 2 — file-level
use permissions { OS, Time }

// Level 3 — operation-level (unsafe required for destructive ops)
unsafe {
    OS.exec("git", ["status"])
    File.delete("temp.txt")
}

File I/O

Read and write files with the File namespace:

// Write a file (creates it if it doesn't exist, overwrites if it does)
File.write("data.txt", "Hello, world!")

// Check if it exists
out File.exists("data.txt")   // → true

// Read the whole file as a string
let content = File.read("data.txt")
out content   // → Hello, world!

// Create an empty file (no-op if it already exists)
File.create("log.txt")

Binary files

// Read raw bytes — returns [int] where each value is 0-255
let bytes = File.read_asBinary("image.png")
out bytes.length   // number of bytes

// Write raw bytes
File.write_asBinary("copy.png", bytes)

Extended file system methods

// List directory contents
let entries = File.listDir("./src")
out entries   // → [main.sz, utils.sz, ...]

// Create a directory (including parent dirs)
File.mkdir("output/logs")

// File metadata
let stat = File.stat("data.txt")
out stat.size      // → bytes
out stat.isDir     // → false
out stat.modified  // → Unix ms timestamp

// Rename / move (requires unsafe)
unsafe {
    File.rename("old.txt", "new.txt")
}

// Delete file or directory (requires unsafe)
unsafe {
    File.delete("temp_dir")
}

Practical example — save and load JSON data

let data <string, any> = (
    {"name", "Sergio"},
    {"score", 42},
    {"active", true}
)

// Save
File.write("save.json", JSON.stringify(data))

// Load
let loaded = JSON.parse(File.read("save.json"))
out loaded["name"]   // → Sergio

OS

Process and operating system information. Requires use permissions { OS }.

use permissions { OS }

out OS.platform()   // → "windows" | "linux" | "macos"
out OS.pid()        // → current process ID

// Execute external command (requires unsafe)
let result = null
unsafe {
    result = OS.exec("git", ["log", "--oneline", "-5"])
}
out result.stdout   // command output
out result.code     // exit code (0 = success)

// Kill a process by PID (requires unsafe)
unsafe {
    OS.kill(1234)
}

Env

Environment variables and command-line arguments. Requires use permissions { Env }.

use permissions { Env }

out Env.get("HOME")     // → "/Users/sergio" or null if not set
out Env.get("PATH")     // → full PATH string

let args = Env.args()   // command-line args including program name
out args.length

// Set env var (requires unsafe — not thread-safe)
unsafe {
    Env.set("MY_VAR", "hello")
}
out Env.get("MY_VAR")   // → hello

System

Read-only system information. Requires use permissions { System }.

use permissions { System }

out System.cpuCount()      // → 15  (logical cores)
out System.totalMemory()   // → 34279034880  (bytes)
out System.freeMemory()    // → 13000000000  (bytes)
out System.hostname()      // → "DESKTOP-XYZ"
out System.uptime()        // → 168517  (seconds since boot)

Time

Timestamps and sleep. Requires use permissions { Time }.

use permissions { Time }

let t1 = Time.now()   // Unix timestamp in milliseconds
Time.sleep(500)       // pause 500ms
let t2 = Time.now()
out t2 - t1           // → ~500

DateTime

Immutable calendar date/time. DateTime.now() / utcNow() read the clock and require use permissions { Time }; from() / fromEpoch() and every field/arithmetic/format operation are pure and need no permission.

let d = DateTime.from(2026, 1, 31, 9, 30, 0)

// fields act as ints, but carry immutable add/reduce/remove
out d.day + 5            // 36
out d.month.add(1)       // 2026-02-28T09:30:00  (day clamped to month end)
out d.day.reduce(20)     // 2026-01-11T09:30:00

// formatting (moment.js-style; [text] is literal)
out d.format("YYYY-MM-DD HH:mm")   // 2026-01-31 09:30
out d.format("D/M/YYYY h:mm A")    // 31/1/2026 9:30 AM
out d.weekday                       // 6  (1=Mon … 7=Sun)

// object-destructuring exposes calendar fields as ints
const {day, month, year} = DateTime.from(2026, 6, 20)
out year + "-" + month + "-" + day  // 2026-6-20

Members: fields year month day hour minute second ms (each a DateField with .add/.reduce/.remove(n)), read-only weekday dayOfYear daysInMonth, and format(p) toString() iso() timestamp() isLeapYear() isUtc(). Two dates compare by instant.

Terminal

Interact with the terminal emulator — keyboard, mouse, cursor, raw mode. Requires use permissions { Terminal }.

use permissions { Terminal }

// Terminal size
let size = Terminal.getSize()
out "Cols: {size[0]}, Rows: {size[1]}"

// Clear screen and move cursor
Terminal.clear()
Terminal.setCursor(0, 0)

// Write raw byte to stdout (e.g. ANSI ESC = 27)
Terminal.writeByte(27)

// Raw mode + keyboard + mouse (all require unsafe)
unsafe {
    Terminal.setRawMode(true)
    Terminal.enableMouse(true)

    let evt = Terminal.readEvent()
    if (evt.type == "key") {
        out "Key: {evt.code}"         // "a", "Enter", "Esc", "F1", ...
        out "Mods: {evt.modifiers}"   // ["ctrl"], ["shift"], ...
    } else if (evt.type == "mouse") {
        out "Mouse {evt.kind} at {evt.col},{evt.row}"
        out "Button: {evt.button}"    // "left", "right", "middle"
    } else if (evt.type == "resize") {
        out "New size: {evt.cols}x{evt.rows}"
    }

    Terminal.enableMouse(false)
    Terminal.setRawMode(false)
}

Memory (raw allocation)

Manual byte-level allocation, for when you need a buffer with an exact layout. Allocating, freeing, reading, writing, copying and filling must happen inside an unsafe { } block; sizeof, size and offsetOf are safe to call anywhere. A single allocation is capped at 256 MiB.

let ptr = unsafe { Memory.alloc(Memory.sizeof("int64") * 4) }

unsafe {
    Memory.fill(ptr, 0)                      // zero the block
    Memory.write(ptr, 0, "int64", 42)        // handle, offset, type, value
    out Memory.read(ptr, 0, "int64")         // 42
    out Memory.size(ptr)                     // 32 — bytes in the allocation
    Memory.free(ptr)
}

out sizeof(int)                              // 8 — the global takes a TYPE, not a string

Note the two are different things. Memory.sizeof("int64") takes a layout name as a string; the global sizeof(int) takes a type keyword and nothing else — sizeof(5) or sizeof(x) is a parse error. See sizeof in the language reference.

The type names accepted by sizeof, read and write are bool, byte, int8, int16, int32, int64, int, uint8, uint16, uint32, uint64, float32, float64, decimal, ptr and str. Out-of-bounds offsets and unknown handles raise a catchable MemoryError.

MethodReturnsDescription
Memory.sizeof(type)intSize in bytes of a type name — safe outside unsafe
Memory.alloc(n)intAllocates n bytes (1 B – 256 MiB) → opaque handle — unsafe
Memory.free(handle)nullReleases the allocation — unsafe
Memory.size(handle)intBytes in the allocation — safe outside unsafe
Memory.read(handle, offset, type)anyReads a typed value at a byte offset — unsafe
Memory.write(handle, offset, type, value)nullWrites a typed value at a byte offset — unsafe
Memory.copy(src, dst, n)nullCopies n bytes between allocations — unsafe
Memory.fill(handle, byte)nullFills the block with a byte value (0–255) — unsafe
Memory.offsetOf(class, field)intByte offset of a field within a class — safe outside unsafe