Language Reference

Nine keywords: circuit, hold, memory, when, but, emit, append, through, wire. Grammar, condition operators, and comments.

Keywords

Sanguis has 9 keywords.

KeywordPurpose
circuitDeclare a body, a collection of holds and routes
holdDeclare a named value (scalar or text)
memoryDeclare the layer type of a hold (persistent state)
whenDeclare a route trigger
butGate a route with a condition
emitSend a value to a target (replaces current content)
appendAppend a value to a text hold (accumulates)
throughIterate through text, one character per tick
wireConnect 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:

OperatorMeaning
<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

BuiltinSignatureReturnsDescription
concatconcat(a, b)textConcatenate two strings
lenlen(s)scalarLength of string
extractextract(s, start, end)textSubstring from start to end
trimtrim(s)textRemove leading/trailing whitespace
replacereplace(s, old, new)textReplace all occurrences of old with new
splitsplit(s, delim)textSplit on delimiter, return first field
split_atsplit_at(s, delim, n)textSplit on delimiter, return nth field (0-indexed)
cropcrop(s)textReturn text after first | character
joinjoin(template, arg1, ...)textFill {} placeholders in template with args
starts_withstarts_with(s, prefix)textReturns "true" or "false"

Comparison Builtins

BuiltinSignatureReturnsDescription
matchmatch(a, b)"1" or "0"Exact string equality
containscontains(haystack, needle)"true" or "false"Substring check

Conversion Builtins

BuiltinSignatureReturnsDescription
to_numberto_number(s)scalarParse string to number
to_textto_text(n)textFormat number as string

File I/O Builtins

BuiltinSignatureReturnsDescription
read_fileread_file(path)textRead file contents as text
write_filewrite_file(path, content)"1" or "0"Write text to file

Output Builtins

BuiltinSignatureReturnsDescription
printprint(s)textPass-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 success

Nested 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_body

Arguments are evaluated recursively. Up to 8 arguments per call are supported.