Language Reference
Nine keywords: circuit, hold, memory, when, but, emit, append, through, wire. Grammar, condition operators, and comments.
Keywords
Sanguis has 9 keywords.
| Keyword | Purpose |
|---|---|
| circuit | Declare a body, a collection of holds and routes |
| hold | Declare a named value (scalar or text) |
| memory | Declare the layer type of a hold (persistent state) |
| when | Declare a route trigger |
| but | Gate a route with a condition |
| emit | Send a value to a target (replaces current content) |
| append | Append a value to a text hold (accumulates) |
| through | Iterate through text, one character per tick |
| wire | Connect a hold in one circuit to a hold in another |
Grammar
program := (circuit | wire)*
circuit := "circuit" IDENT "{" (hold | when)* "}"
hold := "hold" IDENT ":" "memory" ("scalar" | "text") ("=" value)?
when := "when" IDENT "{" ("but" condition)* ("through" IDENT)? (emit | append)* "}"
wire := "wire" IDENT "." IDENT "to" IDENT "." IDENT
condition := IDENT ("<" | ">" | "=" | "<=" | ">=") (number | IDENT)
emit := "emit" expr "to" target
append := "append" expr "to" IDENT
target := IDENT | "screen"
value := number | string
expr := number | string | IDENT | IDENT ("+" | "-" | "*" | "/") expr | builtin "(" args ")"
Condition Operators
Sanguis supports five comparison operators:
| Operator | Meaning |
|---|---|
| < | Less than |
| > | Greater than |
| = | Equal to |
| <= | Less than or equal to |
| >= | Greater than or equal to |
Operands are either a hold name and a number, or a hold name and another hold name:
but x < 5.0 // hold vs number but x > y // hold vs hold but x = 0.0 // hold vs number (equality) but x >= 3.0 // hold vs number (greater or equal) but x <= 10.0 // hold vs number (less or equal)
Arithmetic
Arithmetic is supported inside emit expressions:
emit a + b to sum // addition emit a - b to diff // subtraction emit a * b to prod // multiplication emit a / b to quot // division (returns 0.0 if b is 0) emit pos + 1.0 to pos // increment
Only +, -, *, and / are supported. Division by zero returns 0.0. Arithmetic is evaluated left to right. Operands can be numbers, hold names, or builtin results.
Comments
// Comments start with // and run to end of line.
Comments are ignored by the parser. Use them freely.
Builtins
Sanguis provides 17 builtins for string manipulation, file I/O, comparison, and conversion. Builtins run on the GPU. Text operations happen in VRAM.
String Builtins
| Builtin | Signature | Returns | Description |
|---|---|---|---|
| concat | concat(a, b) | text | Concatenate two strings |
| len | len(s) | scalar | Length of string |
| extract | extract(s, start, end) | text | Substring from start to end |
| trim | trim(s) | text | Remove leading/trailing whitespace |
| replace | replace(s, old, new) | text | Replace all occurrences of old with new |
| split | split(s, delim) | text | Split on delimiter, return first field |
| split_at | split_at(s, delim, n) | text | Split on delimiter, return nth field (0-indexed) |
| crop | crop(s) | text | Return text after first | character |
| join | join(template, arg1, ...) | text | Fill {} placeholders in template with args |
| starts_with | starts_with(s, prefix) | text | Returns "true" or "false" |
Comparison Builtins
| Builtin | Signature | Returns | Description |
|---|---|---|---|
| match | match(a, b) | "1" or "0" | Exact string equality |
| contains | contains(haystack, needle) | "true" or "false" | Substring check |
Conversion Builtins
| Builtin | Signature | Returns | Description |
|---|---|---|---|
| to_number | to_number(s) | scalar | Parse string to number |
| to_text | to_text(n) | text | Format number as string |
File I/O Builtins
| Builtin | Signature | Returns | Description |
|---|---|---|---|
| read_file | read_file(path) | text | Read file contents as text |
| write_file | write_file(path, content) | "1" or "0" | Write text to file |
Output Builtins
| Builtin | Signature | Returns | Description |
|---|---|---|---|
| print(s) | text | Pass-through (prints to screen) |
Builtin Examples
emit concat("Hello", " World!") to screen // "Hello World!"
emit len("hello") to screen // 5.0000
emit extract("hello", 0, 3) to screen // "hel"
emit trim(" hi ") to screen // "hi"
emit replace("a.b.c", ".", "_") to screen // "a_b_c"
emit match("abc", "abc") to screen // "1"
emit contains("hello world", "world") to screen // "true"
emit starts_with("hello", "he") to screen // "true"
emit split_at("a,b,c", ",", 1) to screen // "b"
emit join("{} + {} = {}", "1", "2", "3") to screen // "1 + 2 = 3"
emit read_file("input.txt") to buffer // file contents
emit write_file("out.txt", "data") to result // "1" on successNested Builtin Calls
Builtins can be nested:
emit concat(genome, concat("BODY|", concat(trim(name), "\n"))) to genome
emit match(extract(line, 0, 4), "body") to f_bodyArguments are evaluated recursively. Up to 8 arguments per call are supported.