/ Specification
Playground Docs Architecture Performance GitHub
Chapter 13

Appendices

A. Full EBNF Grammar

Programs and Items

program      ::= [ mode_directive ] { item }
item         ::= function | struct_decl | enum_decl | trait_decl
             |   impl_block | test_block | statement

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

function     ::= "fn" IDENT "(" [ param_list ] ")" [ "->" type_expr ]
                 { contract } block
param_list   ::= param { "," param }
param        ::= [ "..." ] IDENT ":" type_expr [ "=" expression ]
contract     ::= "require" expression [ "," STRING ]
             |   "ensure" closure [ "," STRING ]

struct_decl  ::= "struct" IDENT "{" field_decl { "," field_decl } "}"
field_decl   ::= IDENT ":" type_expr

enum_decl    ::= "enum" IDENT "{" variant { "," variant } "}"
variant      ::= IDENT [ "(" type_expr { "," type_expr } ")" ]

trait_decl   ::= "trait" IDENT "{" { trait_method } "}"
trait_method ::= "fn" IDENT "(" [ param_list ] ")" [ "->" type_expr ]

impl_block   ::= "impl" IDENT "for" IDENT "{" { function } "}"

test_block   ::= "test" STRING block

Types

type_expr    ::= [ phase_prefix ] type_name
             |   "[" type_expr "]"
phase_prefix ::= "~" | "*"
type_name    ::= "Int" | "Float" | "Bool" | "String" | "Array"
             |   "Map" | "Tuple" | "Set" | "Fn" | "Channel"
             |   "Range" | IDENT

Statements

statement    ::= binding | assignment | destructure | return_stmt
             |   break_stmt | continue_stmt | defer_stmt
             |   import_stmt | expr_stmt

binding      ::= phase_kw IDENT [ ":" type_expr ] "=" expression
phase_kw     ::= "flux" | "fix" | "let"

assignment   ::= lvalue "=" expression
             |   lvalue compound_op expression
lvalue       ::= IDENT | expression "." IDENT | expression "[" expression "]"
compound_op  ::= "+=" | "-=" | "*=" | "/=" | "%="
             |   "&=" | "|=" | "^=" | "<<=" | ">>="

destructure  ::= phase_kw "[" array_pat "]" "=" expression
             |   phase_kw "{" struct_pat "}" "=" expression
array_pat    ::= IDENT { "," IDENT } [ "," "..." IDENT ]
struct_pat   ::= IDENT { "," IDENT }

return_stmt  ::= "return" [ expression ]
break_stmt   ::= "break"
continue_stmt ::= "continue"
defer_stmt   ::= "defer" block

import_stmt  ::= "import" STRING [ "as" IDENT ]
             |   "import" "{" import_list "}" "from" STRING
import_list  ::= IDENT { "," IDENT }

Expressions

expression   ::= nil_coalesce
nil_coalesce ::= or_expr { "??" or_expr }
or_expr      ::= and_expr { "||" and_expr }
and_expr     ::= bit_or { "&&" bit_or }
bit_or       ::= bit_xor { "|" bit_xor }
bit_xor      ::= bit_and { "^" bit_and }
bit_and      ::= equality { "&" equality }
equality     ::= comparison { ("==" | "!=") comparison }
comparison   ::= shift { ("<" | ">" | "<=" | ">=") shift }
shift        ::= range_expr { ("<<" | ">>") range_expr }
range_expr   ::= addition [ ".." addition ]
addition     ::= multiply { ("+" | "-") multiply }
multiply     ::= unary { ("*" | "/" | "%") unary }
unary        ::= ("-" | "!" | "~") unary | postfix
postfix      ::= primary { postfix_op }
postfix_op   ::= "." IDENT [ "(" [ arg_list ] ")" ]
             |   "?." IDENT [ "(" [ arg_list ] ")" ]
             |   "[" expression "]"
             |   "?[" expression "]"
             |   "(" [ arg_list ] ")"
             |   "?"

primary      ::= INT | FLOAT | STRING | "true" | "false" | "nil"
             |   IDENT [ "::" IDENT [ "(" [ arg_list ] ")" ] ]
             |   IDENT "{" field_init { "," field_init } "}"
             |   "(" expression [ "," expression { "," expression } ] ")"
             |   "[" [ expression { "," expression } ] "]"
             |   closure | if_expr | match_expr
             |   for_expr | while_expr | loop_expr
             |   forge_expr | scope_expr | spawn_expr | select_expr
             |   try_catch | freeze_expr | thaw_expr | clone_expr
             |   anneal_expr | sublimate_expr | crystallize_expr
             |   print_expr | "..." expression
             |   block

closure      ::= "|" [ closure_params ] "|" ( expression | block )
closure_params ::= closure_param { "," closure_param }
closure_param  ::= [ "..." ] IDENT [ "=" expression ]
block        ::= "{" { statement } [ expression ] "}"
arg_list     ::= expression { "," expression }
field_init   ::= IDENT ":" expression

Match and Select

match_expr   ::= "match" expression "{" { match_arm } "}"
match_arm    ::= [ phase_qual ] pattern [ "if" expression ] "=>" ( expression | block ) [ "," ]
phase_qual   ::= "fluid" | "crystal"
pattern      ::= INT | ["-"] INT | FLOAT | ["-"] FLOAT
             |   STRING | "true" | "false" | "nil"
             |   "_" | IDENT
             |   INT ".." INT

select_expr  ::= "select" "{" { select_arm } "}"
select_arm   ::= IDENT "from" expression "=>" block [ "," ]
             |   "default" "=>" block [ "," ]
             |   "timeout" "(" expression ")" "=>" block [ "," ]

Lexical Grammar

IDENT        ::= (letter | "_") { letter | digit | "_" }
INT          ::= digit { digit }
FLOAT        ::= digit { digit } "." digit { digit }
STRING       ::= '"' { str_char | escape | interp } '"'
             |   "'" { str_char | escape } "'"
             |   '"""' { any | interp } '"""'
interp       ::= "${" expression "}"
escape       ::= "\n" | "\t" | "\r" | "\0" | "\\" | "\""
             |   "\'" | "\$" | "\x" hex hex
comment      ::= "//" { any_except_newline }
             |   "/*" { any | comment } "*/"

B. Keyword Table

#KeywordCategoryDescription
1fluxBindingDeclare mutable variable
2fixBindingDeclare immutable variable
3letBindingDeclare variable (inferred phase)
4freezePhaseTransition to crystal
5thawPhaseTransition to fluid
6forgePhaseControlled mutation block
7clonePhaseDeep copy a value
8annealPhaseThaw, transform, re-freeze
9crystallizePhaseScoped crystallization
10sublimatePhaseTransition to sublimated
11fnDeclarationFunction declaration
12structDeclarationStruct declaration
13enumDeclarationEnum declaration
14traitDeclarationTrait declaration
15implDeclarationImplementation block
16testDeclarationTest block
17ifControlConditional expression
18elseControlAlternative branch
19forControlFor-in loop
20inControlIterator keyword
21whileControlWhile loop
22loopControlInfinite loop
23matchControlPattern matching
24returnJumpReturn from function
25breakJumpExit loop
26continueJumpNext loop iteration
27scopeConcurrencyStructured concurrency block
28spawnConcurrencyLaunch concurrent task
29tryErrorException handling block
30catchErrorError handler
31deferErrorDeferred execution
32importModuleImport module
33fromModuleSelective import source
34asModuleImport alias
35trueLiteralBoolean true
36falseLiteralBoolean false
37nilLiteralNil value
38printBuilt-inOutput to stdout

C. Operator Precedence

Operators are listed from lowest precedence (loosest binding) to highest precedence (tightest binding). Operators on the same level have equal precedence.

LevelOperatorsAssociativityDescription
1??LeftNil coalesce
2||LeftLogical OR
3&&LeftLogical AND
4|LeftBitwise OR
5^LeftBitwise XOR
6&LeftBitwise AND
7== !=LeftEquality
8< > <= >=LeftComparison
9<< >>LeftBit shift
10..NoneRange
11+ -LeftAddition, subtraction
12* / %LeftMultiplication, division, modulo
13- ! ~Right (prefix)Negation, logical NOT, bitwise NOT
14. ?. [] ?[] () ?Left (postfix)Access, call, try-propagate

D. Implementation Limits

The reference implementation (C, bytecode VM) has the following practical limits:

LimitValue
Integer range-263 to 263-1 (64-bit signed)
Float precisionIEEE 754 double (64-bit)
Max function parameters255
Max local variables per scope256
Max constants per chunk65,536 (16-bit index via wide opcodes)
Max call stack depth256 frames
Max upvalues per closure256
String lengthLimited by available memory
Array lengthLimited by available memory

E. Memory Architecture

The reference implementation uses a three-arena memory architecture to manage runtime allocations efficiently:

ArenaPurposeLifecycle
Fluid Heap General-purpose malloc/free allocations for mutable values, locals, globals, and data structure backing stores. Individual deallocation via value_free or mark-sweep GC.
Crystal Regions Arena-based allocator for frozen (fix-phase) values. Each freeze() creates a new region; deep-cloning into the arena provides cache locality. Bulk O(1) deallocation when region becomes unreachable.
Ephemeral Bump Arena Page-linked bump allocator for short-lived string temporaries produced by concatenation and interpolation in the bytecode VM. Bulk O(1) reset at each statement boundary via OP_RESET_EPHEMERAL. Pages are retained across resets for reuse.

Values track their arena via a region_id field: REGION_NONE for the fluid heap, a numeric ID for crystal regions, and REGION_EPHEMERAL for the bump arena. The value_free function skips any value whose region_id is not REGION_NONE, preventing double-free of arena-managed memory. When an ephemeral value escapes its statement (e.g., stored into a global or pushed into an array), it is automatically promoted to the fluid heap via deep-clone.