/ Specification
Playground Docs Performance GitHub
Chapter 2

Lexical Structure

This chapter defines the lexical grammar of Lattice: the rules by which a sequence of characters is broken into tokens. The lexer processes source code left-to-right, producing a stream of tokens that the parser consumes.

Source Encoding

Lattice source files are encoded in UTF-8. String literals may contain arbitrary UTF-8 sequences. Identifiers are restricted to ASCII letters, digits, and underscores.

Whitespace and Line Breaks

Whitespace characters (space, tab, carriage return, newline) serve as token separators and are otherwise insignificant. Lattice does not use significant whitespace for block structure; blocks are delimited by braces { }.

Comments

Lattice supports two forms of comments:

// This is a line comment

/* This is a
   block comment */

/* Block comments /* can be */ nested */

Keywords

The following 38 identifiers are reserved as keywords and cannot be used as variable or function names:

CategoryKeywords
Bindingsflux fix let
Phasefreeze thaw forge clone anneal crystallize sublimate
Declarationsfn struct enum trait impl test
Control flowif else for in while loop match
Jumpreturn break continue
Concurrencyscope spawn
Error handlingtry catch defer
Modulesimport from as
Literalstrue false nil
Built-inprint

Contextual Identifiers

The following identifiers are not reserved but have special meaning in certain syntactic positions. They may be used as variable names elsewhere:

IdentifierContext
selectChannel multiplexing expression
defaultDefault arm in select
timeoutTimeout arm in select
whereContract clause in freeze()
exceptException list in freeze()
requireFunction precondition
ensureFunction postcondition
fluidPhase qualifier in match patterns
crystalPhase qualifier in match patterns

Identifiers

identifier  ::= (letter | "_") { letter | digit | "_" }
letter      ::= "a".."z" | "A".."Z"
digit       ::= "0".."9"

Identifiers begin with a letter or underscore, followed by any combination of letters, digits, and underscores. Identifiers are case-sensitive.

Literals

Integer Literals

int_literal  ::= digit { digit }

Integer literals are sequences of decimal digits. They represent 64-bit signed integers (int64_t). Negative integer literals are formed by applying the unary negation operator to a positive literal.

Float Literals

float_literal  ::= digit { digit } "." digit { digit }

Float literals contain a decimal point with digits on both sides. They represent 64-bit IEEE 754 double-precision floating point values.

String Literals

Lattice supports three forms of string literals:

Double-Quoted Strings

double_string  ::= '"' { string_char | escape | interpolation } '"'

Double-quoted strings support escape sequences and string interpolation with ${...}.

Single-Quoted Strings

single_string  ::= "'" { string_char | escape } "'"

Single-quoted strings support escape sequences but not interpolation.

Triple-Quoted Strings

triple_string  ::= '"""' { any_char | interpolation } '"""'

Triple-quoted strings span multiple lines, support interpolation, and auto-dedent based on the minimum indentation of non-empty lines.

Escape Sequences

EscapeCharacter
\nNewline (LF)
\tTab
\rCarriage return
\0Null byte
\\Backslash
\"Double quote
\'Single quote
\$Dollar sign (escape interpolation)
\xHHHex byte value

String Interpolation

interpolation  ::= "${" expression "}"

Within double-quoted and triple-quoted strings, ${...} embeds an expression whose value is converted to a string at runtime. The expression may be any valid Lattice expression, including method calls and nested interpolations.

let name = "world"
print("hello ${name}")          // hello world
print("2 + 2 = ${2 + 2}")       // 2 + 2 = 4
print("upper: ${name.to_upper()}") // upper: WORLD

Boolean Literals

The keywords true and false are boolean literals.

Nil Literal

The keyword nil represents the absence of a value.

Operators and Punctuation

Lattice defines the following operator and punctuation tokens:

CategoryTokens
Arithmetic+ - * / %
Comparison== != < > <= >=
Logical&& || !
Bitwise& | ^ ~ << >>
Assignment= += -= *= /= %= &= |= ^= <<= >>=
Range..
Spread...
Arrow-> =>
Optional?. ?[ ?? ?
Dot.
Delimiters( ) { } [ ]
Punctuation, : :: ;
Phase prefix~ (fluid) * (crystal)

Mode Directive

mode_directive  ::= "#mode" ("casual" | "strict")

A mode directive, if present, must appear at the beginning of the source file (before any statements or items). It controls the strictness of phase checking.