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
| # | Keyword | Category | Description |
|---|---|---|---|
| 1 | flux | Binding | Declare mutable variable |
| 2 | fix | Binding | Declare immutable variable |
| 3 | let | Binding | Declare variable (inferred phase) |
| 4 | freeze | Phase | Transition to crystal |
| 5 | thaw | Phase | Transition to fluid |
| 6 | forge | Phase | Controlled mutation block |
| 7 | clone | Phase | Deep copy a value |
| 8 | anneal | Phase | Thaw, transform, re-freeze |
| 9 | crystallize | Phase | Scoped crystallization |
| 10 | sublimate | Phase | Transition to sublimated |
| 11 | fn | Declaration | Function declaration |
| 12 | struct | Declaration | Struct declaration |
| 13 | enum | Declaration | Enum declaration |
| 14 | trait | Declaration | Trait declaration |
| 15 | impl | Declaration | Implementation block |
| 16 | test | Declaration | Test block |
| 17 | if | Control | Conditional expression |
| 18 | else | Control | Alternative branch |
| 19 | for | Control | For-in loop |
| 20 | in | Control | Iterator keyword |
| 21 | while | Control | While loop |
| 22 | loop | Control | Infinite loop |
| 23 | match | Control | Pattern matching |
| 24 | return | Jump | Return from function |
| 25 | break | Jump | Exit loop |
| 26 | continue | Jump | Next loop iteration |
| 27 | scope | Concurrency | Structured concurrency block |
| 28 | spawn | Concurrency | Launch concurrent task |
| 29 | try | Error | Exception handling block |
| 30 | catch | Error | Error handler |
| 31 | defer | Error | Deferred execution |
| 32 | import | Module | Import module |
| 33 | from | Module | Selective import source |
| 34 | as | Module | Import alias |
| 35 | true | Literal | Boolean true |
| 36 | false | Literal | Boolean false |
| 37 | nil | Literal | Nil value |
| 38 | print | Built-in | Output 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.
| Level | Operators | Associativity | Description |
|---|---|---|---|
| 1 | ?? | Left | Nil coalesce |
| 2 | || | Left | Logical OR |
| 3 | && | Left | Logical AND |
| 4 | | | Left | Bitwise OR |
| 5 | ^ | Left | Bitwise XOR |
| 6 | & | Left | Bitwise AND |
| 7 | == != | Left | Equality |
| 8 | < > <= >= | Left | Comparison |
| 9 | << >> | Left | Bit shift |
| 10 | .. | None | Range |
| 11 | + - | Left | Addition, subtraction |
| 12 | * / % | Left | Multiplication, 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:
| Limit | Value |
|---|---|
| Integer range | -263 to 263-1 (64-bit signed) |
| Float precision | IEEE 754 double (64-bit) |
| Max function parameters | 255 |
| Max local variables per scope | 256 |
| Max constants per chunk | 65,536 (16-bit index via wide opcodes) |
| Max call stack depth | 256 frames |
| Max upvalues per closure | 256 |
| String length | Limited by available memory |
| Array length | Limited by available memory |
E. Memory Architecture
The reference implementation uses a three-arena memory architecture to manage runtime allocations efficiently:
| Arena | Purpose | Lifecycle |
|---|---|---|
| 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.
Lattice