Foundations
Lexical & Literals
How Leviathan source text is spelled: what a comment, an identifier, and a keyword look like, and every literal form the lexer recognizes — from binary integers to triple-quoted strings.
Comments
Two forms, exactly as in C-family languages. Block comments do not nest.
// a line comment runs to end of line
/* a block comment
spans multiple lines */Identifiers
An identifier matches [A-Za-z_][A-Za-z0-9_]*. The house style
is camelCase: each internal word boundary capitalizes the
stem after the first — subString, not substring.
Keywords
The reserved words that may not be used as bare identifiers at statement or declaration start:
namespace class struct enum interface public private new mutating
distinct const get set return var let await bind inject use uses
if else while for in match is this true false
break continue do using try catch throwThe primitive type names int, string,
bool, float, and void are
not keywords — they are ordinary names resolved to
prelude declarations. And attribute, comptime,
rule, macro, and as are
contextual: ordinary identifiers except at the
declaration positions that give them meaning. Keywords like
get/is/in may still be used as
member names after . or ::.
Literal forms
Every literal the language recognizes, at a glance:
| Form | Examples | Type |
|---|---|---|
| integer | 42, 0, 0xFF, 0b1010 | int |
| float | 3.14 | float |
| string | "hello", 'hi' | string |
| boolean | true, false | bool |
| array | [1, 2, 3], [], [1..5] | Array<T> |
| range | 1..10 (inclusive) | Range |
A Range element inside an array literal spreads: [1..3, 7] is [1, 2, 3, 7].
Integer literals
Decimal, hex (0x/0X), or binary
(0b/0B) — there is no octal. An underscore
_ separates digits for readability in any base, including a
float's fractional digits; it may not lead, trail, or double up.
int million = 1_000_000;
int mask = 0x1_FF; // 511
int flags = 0b1010; // 10
float pi = 1_000.000_5; // separators allowed in fractional digits too
A hex/binary literal is always an int — 0x1.5
(a dot followed by a digit) is a compile error, not a fractional part,
while 0xA..0xF is the .. range operator applied
to two hex ints. Hex/binary literals reinterpret their full 64-bit
pattern, so 0x8000000000000000 prints the same as
1 << 63.
String literals
Both quote styles lex to string literals and are otherwise identical —
' and " differ only in which character ends the
token.
Escapes
Strings are byte-clean through the floor, so an embedded NUL survives rather than terminating the string.
| Escape | Meaning |
|---|---|
\n \t \r \0 | newline, tab, carriage-return, NUL |
\xNN | exactly two hex digits → that byte |
\u{H+} | 1–6 hex digits → the UTF-8 encoding of that Unicode scalar |
\" \\ \' | the literal quote, backslash, apostrophe |
\<other> | an unrecognized escape passes the character through (\q is just q) |
A surrogate or out-of-range \u{...} scalar decodes to
U+FFFD rather than throwing — a compile-time literal has
nothing to catch. A malformed \x or \u{...} is
left alone: the leading letter passes through as ordinary content.
Interpolation
"...${expr}..." (either quote style) desugars in the parser to
concatenation with .toString():
string msg = "code=${resp.status}!";
// exactly equivalent to:
string msg = "code=" + (resp.status).toString() + "!";
\${ escapes a literal ${; a bare $
with no { stays literal (there is no $name
shorthand — that syntax belongs to quasiquote holes). An empty or
unterminated hole is a compile error. A hole may nest a string literal as
long as it uses the opposite quote style from the outer literal.
Raw strings
r"..." / r'...' — a r immediately
before a quote opens a literal where backslash is an ordinary character.
No escape processing and no ${...} interpolation happen
inside. Single-line only; there is no way to embed the delimiter quote.
Ideal for regex patterns, Windows paths, and embedded JSON/HTML fixtures.
string pattern = r"\d+\.\d+"; // backslashes are literal
string path = r"C:\Users\me";Multiline strings
"""...""" / '''...''' — a literal delimited by
three quotes may contain raw newlines and lone embedded quotes (only three
in a row closes it). Unlike a raw string, ordinary escape processing
and ${...} interpolation still apply inside.
string doc = """
Dear ${name},
Welcome aboard.
""";Char literals are target-typed
A single-quoted literal is a string by default, but it
re-types to char when — and only when — the
expected type in context is char and its decoded
content is exactly one Unicode scalar. See
Types and
Strings & Chars for the full rule.
char c = 'a'; // char — the context expects one
var s = 'a'; // stays string — no char context
bool ok = (c == 'a'); // 'a' re-types to char to match c
string d = "a"; // double-quoted is never a charCall-argument position does not (yet) target-type a bare
'x' to a char parameter — a char-typed
value binds fine, but a bare literal argument stays
string. This is a deferred surface.
Operators & punctuation
The symbolic tokens the lexer produces:
:: : ; , . .. ( ) { } [ ]
=> = == != ! < > <= >= + - * / %
+= -= *= /= %= << >> && || & | ^ ~ ? ?? ?. @
@ introduces an attribute.
A backtick-delimited `...` lexes as a
quasiquote literal, and inside
one $name is a hole. See
Expressions for operator
precedence.