Annex A (normative) — Formal grammar
This annex defines the complete formal grammar of the Ori language in Extended Backus-Naur Form (EBNF). The notation conventions are defined in Clause 5.
// ============================================================================
// Ori Language Grammar
// Version: 2026
//
// This is the unified formal grammar for the Ori programming language.
// All productions are authoritative and take precedence over prose descriptions.
//
// Notation:
// production = expression . Production definition
// "keyword" Literal token
// | Alternation
// [ ] Optional (0 or 1)
// { } Repetition (0 or more)
// ( ) Grouping
// /* comment */ Informative note
//
// Cross-references to detailed explanations are provided in comments.
// ============================================================================
// ============================================================================
// LEXICAL GRAMMAR
// See: 06-source-code.md, 07-lexical-elements.md
// ============================================================================
// --- Characters ---
// See: 06-source-code.md § 6.1 Characters, § 6.1.2 Letters and digits
unicode_char = /* any Unicode code point except NUL (U+0000) */ .
letter = 'A' … 'Z' | 'a' … 'z' .
digit = '0' … '9' .
hex_digit = digit | 'A' … 'F' | 'a' … 'f' .
bin_digit = '0' | '1' .
newline = /* U+000A */ .
whitespace = ' ' | '\t' | '\r' | newline .
// --- Tokens ---
token = identifier | keyword | literal | operator | delimiter .
// --- Comments ---
// See: 07-lexical-elements.md § 7.1 Comments
comment = "//" { unicode_char - newline } newline .
doc_comment = "//" [ " " ] [ doc_marker ] { unicode_char - newline } newline .
doc_marker = "*" | "!" | ">" .
member_doc = "//" " " "*" " " identifier ":" [ " " { unicode_char - newline } ] .
warning_doc = "//" " " "!" " " { unicode_char - newline } .
example_doc = "//" " " ">" " " { unicode_char - newline } .
// --- Identifiers ---
// See: 07-lexical-elements.md § 7.2 Identifiers
identifier = ( letter | "_" ) { letter | digit | "_" } .
// --- Keywords ---
// See: 07-lexical-elements.md § 7.3 Keywords
//
// Reserved (36): as, break, continue, def, div, do, else, extend, extension, extern,
// false, for, if, impl, in, let, loop, match, Never, pub, self, Self, suspend,
// tests, then, trait, true, type, unsafe, use, uses, void, where, while, with, yield
// Reserved (future, 5): asm, inline, static, union, view
// Context-sensitive (patterns, 9): cache, catch, handler, nursery, parallel, recurse, spawn,
// timeout, try
// Context-sensitive (pattern args, 10): body, buffer, default, expr, map, on_error, over,
// pre, post, state
// Context-sensitive (imports, 2): from (extern blocks), without (import items, before "def")
// Context-sensitive (other, 3): args (@main params), by (after range), max (fixed-capacity lists)
// Context-sensitive (embed, 2): embed (file embedding), has_embed (file existence check)
// Context-sensitive (type names, 5): bool, byte, float, int, str
// Built-in constructors (4): channel, channel_all, channel_in, channel_out
// --- Operators ---
// See: 07-lexical-elements.md § 7.4 Operators
arith_op = "+" | "-" | "*" | "/" | "%" | "div" | "**" .
comp_op = "==" | "!=" | "<" | ">" | "<=" | ">=" .
logic_op = "&&" | "||" | "!" .
bit_op = "&" | "|" | "^" | "~" | "<<" | ">>" .
unary_op = "!" | "-" | "~" .
other_op = ".." | "..=" | "??" | "?" | "->" | "=>" | "|>" .
// --- Delimiters ---
delimiter = "(" | ")" | "[" | "]" | "{" | "}"
| "," | ":" | "." | "@" | "$" | ";" .
// --- Literals ---
// See: 07-lexical-elements.md § 7.7 Literals
literal = int_literal | float_literal | string_literal | template_literal | char_literal
| byte_literal | bool_literal | duration_literal | size_literal .
// Integer literals
// See: 07-lexical-elements.md § 7.7.1 Integer literals
int_literal = decimal_lit | hex_lit | bin_lit .
decimal_lit = "0" | non_zero_digit { [ "_" ] digit } .
non_zero_digit = "1" … "9" .
hex_lit = "0" ( "x" | "X" ) hex_digit { [ "_" ] hex_digit } .
bin_lit = "0" ( "b" | "B" ) bin_digit { [ "_" ] bin_digit } .
// Float literals
// See: 07-lexical-elements.md § 7.7.2 Float literals
float_literal = decimal_digits "." decimal_digits [ exponent ]
| decimal_digits exponent .
decimal_digits = digit { [ "_" ] digit } .
exponent = ( "e" | "E" ) [ "+" | "-" ] decimal_digits .
// String literals
// See: 07-lexical-elements.md § 7.7.3 String literals
string_literal = '"' { string_char | escape_seq } '"' .
string_char = unicode_char - ( '"' | '\' | newline ) .
escape_seq = '\' ( '"' | '\' | 'n' | 't' | 'r' | '0' )
| unicode_escape
| hex_escape .
unicode_escape = '\' 'u' '{' hex_digit { hex_digit } '}' . /* 1-6 hex digits */
hex_escape = '\' 'x' hex_digit hex_digit . /* \x00-\xFF */
// Template string literals (with interpolation)
// See: 07-lexical-elements.md § 7.7.4 Template strings
template_literal = '`' { template_char | template_escape | unicode_escape | template_brace | interpolation } '`' .
template_char = unicode_char - ( '`' | '\' | '{' | '}' ) .
template_escape = '\' ( '`' | '\' | 'n' | 't' | 'r' | '0' ) .
template_brace = "{{" | "}}" .
interpolation = '{' expression [ ':' format_spec ] '}' .
// Format specifiers for template strings
// See: 07-properties-of-types.md § Format Spec Syntax
// Syntax: [[fill]align][sign][#][0][width][.precision][type]
format_spec = [ [ fill ] align ] [ sign ] [ alt_form ] [ zero_pad ] [ width ] [ '.' precision ] [ format_type ] .
fill = unicode_char - ( align | sign ) .
align = '<' | '>' | '^' .
sign = '+' | '-' | ' ' .
alt_form = '#' .
zero_pad = '0' .
width = decimal_lit .
precision = decimal_lit .
format_type = 'b' | 'o' | 'x' | 'X' | 'e' | 'E' | 'f' | '%' .
// Character literals
// See: 07-lexical-elements.md § 7.7.5 Character literals
char_literal = "'" ( char_char | char_escape ) "'" .
char_char = unicode_char - ( "'" | '\' | newline ) .
char_escape = '\' ( "'" | '\' | 'n' | 't' | 'r' | '0' )
| unicode_escape
| char_hex_escape .
char_hex_escape = '\' 'x' hex_digit hex_digit . /* \x00-\x7F only; \x80-\xFF is an error */
// Byte literals
// See: 07-lexical-elements.md § 7.7.6 Byte literals
byte_literal = "b'" ( byte_char | byte_escape ) "'" .
byte_char = ascii_char - ( "'" | '\' ) . /* U+0020-U+007E, excluding ' and \ */
byte_escape = '\' ( "'" | '\' | 'n' | 't' | 'r' | '0' )
| hex_escape . /* \x00-\xFF; no \u{} or \" */
ascii_char = '\x20' … '\x7E' . /* printable ASCII */
// Boolean literals
bool_literal = "true" | "false" .
// Duration literals
// See: 07-lexical-elements.md § 7.7.8 Duration literals
// Decimal syntax (e.g., 0.5s) is compile-time sugar computed via integer arithmetic
duration_literal = duration_number duration_unit .
duration_number = decimal_lit | decimal_lit "." digit { digit } .
duration_unit = "ns" | "us" | "ms" | "s" | "m" | "h" .
// Size literals
// See: 07-lexical-elements.md § 7.7.9 Size literals
// Decimal syntax (e.g., 1.5kb) is compile-time sugar computed via integer arithmetic
size_literal = size_number size_unit .
size_number = decimal_lit | decimal_lit "." digit { digit } .
size_unit = "b" | "kb" | "mb" | "gb" | "tb" .
// ============================================================================
// SOURCE STRUCTURE
// See: 06-source-code.md, 18-modules.md
// ============================================================================
source_file = [ file_attribute ] { import | reexport | extension_import } { declaration } .
// File-level attribute (conditional compilation)
// See: 24-conditional-compilation.md § File-Level Conditions
file_attribute = "#!" identifier "(" [ attribute_arg { "," attribute_arg } ] ")" .
// --- Imports ---
// See: 12-modules.md § Imports
import = "use" import_path [ import_list | "as" identifier ] ";" .
import_path = string_literal | identifier { "." identifier } .
import_list = "{" import_item { "," import_item } "}" .
import_item = [ "::" ] identifier [ "without" "def" ] [ "as" identifier ] | "$" identifier .
// --- Re-exports ---
reexport = "pub" "use" import_path import_list ";" .
// --- Extensions ---
// See: 12-modules.md § Extensions
extension_def = "extend" [ generics ] type [ where_clause ] "{" { method } "}" .
extension_import = [ "pub" ] "extension" import_path "{" extension_item { "," extension_item } "}" .
extension_item = identifier "." identifier .
// --- FFI (Foreign Function Interface) ---
// See: spec/24-ffi.md
extern_block = [ "pub" ] "extern" string_literal [ "from" string_literal ]
{ block_attribute } "{" { extern_item } "}" .
extern_item = "@" identifier extern_params "->" [ ownership ] type
[ "as" string_literal ]
{ item_attribute } .
extern_params = "(" [ extern_param { "," extern_param } ] [ c_variadic ] ")" .
extern_param = [ param_modifier ] identifier ":" [ ownership ] type .
c_variadic = "," "..." . /* C-style variadic - only valid in extern "c" blocks */
// Deep FFI annotations (see: proposals/approved/deep-ffi-proposal.md)
param_modifier = "out" | "mut" .
ownership = "owned" | "borrowed" .
block_attribute = "#" identifier "(" { attribute_arg } ")" . /* #error(...), #free(...) */
item_attribute = "#" identifier "(" { attribute_arg } ")" . /* per-function overrides */
// Parametric FFI capability
ffi_capability = "FFI" [ "(" string_literal ")" ] .
// ============================================================================
// DECLARATIONS
// See: 08-declarations.md
// ============================================================================
declaration = { attribute } [ "pub" ] ( function | type_def | trait_def | impl_block | extension_def | test | constant_decl | extern_block | capset_decl ) .
// --- Attributes ---
// See: 08-declarations.md § Attributes, 24-conditional-compilation.md
// Item-level: #derive(...), #skip(...), #target(...), #cfg(...)
attribute = "#" identifier [ "(" [ attribute_arg { "," attribute_arg } ] ")" ] .
attribute_arg = expression | identifier ":" expression | array_literal .
array_literal = "[" [ string_literal { "," string_literal } ] "]" .
// --- Functions ---
// See: 08-declarations.md § Functions
function = "@" identifier [ generics ] clause_params "->" type [ uses_clause ] [ where_clause ] [ guard_clause ] { contract } "=" expression [ ";" ] .
/* Semicolon rule: ";" is required when the body expression does not end with "}".
When the body is a block_expr (ending with "}"), ";" is omitted — same as Rust's fn. */
clause_params = "(" [ clause_param { "," clause_param } ] ")" .
clause_param = match_pattern [ ":" type ] [ "=" expression ] . /* pattern with optional type and default */
guard_clause = "if" expression .
// --- Generics ---
// See: 06-types.md § Const Generic Parameters
generics = "<" generic_param { "," generic_param } ">" .
generic_param = type_param | const_param .
type_param = identifier [ ":" bounds ] [ "=" type ] .
const_param = "$" identifier ":" const_type [ "=" const_expr ] .
const_type = "int" | "bool" .
bounds = type_path { "+" type_path } .
where_clause = "where" constraint { "," constraint } .
constraint = type_constraint | const_constraint .
type_constraint = identifier ":" bounds .
const_constraint = const_bound_expr .
// Const bound expressions (for where clauses)
// See: 06-types.md § Const Bounds
const_bound_expr = const_or_expr .
const_or_expr = const_and_expr { "||" const_and_expr } .
const_and_expr = const_not_expr { "&&" const_not_expr } .
const_not_expr = "!" const_not_expr | const_cmp_expr .
const_cmp_expr = const_expr comparison_op const_expr
| "(" const_bound_expr ")" .
comparison_op = ">" | "<" | ">=" | "<=" | "==" | "!=" .
// --- Capabilities ---
// See: 14-capabilities.md
uses_clause = "uses" identifier { "," identifier } .
capset_decl = "capset" identifier "=" identifier { "," identifier } ";" .
// --- Type Definitions ---
// See: 08-declarations.md § Types, 06-types.md § User-Defined Types
type_def = "type" identifier [ generics ] [ where_clause ] "=" type_body [ ";" ] .
/* Semicolon rule: ";" required for sum types and newtypes (no "}"); omitted for struct types (end with "}") */
type_body = struct_body | sum_body | type .
struct_body = "{" [ field { "," field } ] "}" .
sum_body = variant { "|" variant } .
variant = identifier [ "(" [ field { "," field } ] ")" ] .
field = identifier ":" type .
// --- Traits ---
// See: 08-declarations.md § Traits
trait_def = "trait" identifier [ generics ] [ ":" bounds ] "{" { trait_item } "}" .
trait_item = method_sig | default_method | assoc_type .
method_sig = "@" identifier params "->" type ";" .
default_method = "@" identifier params "->" type "=" expression [ ";" ] .
/* Semicolon rule: same as function — ";" required unless body ends with "}" */
assoc_type = "type" identifier [ ":" bounds ] [ "=" type ] .
params = "(" [ param { "," param } ] ")" .
param = identifier ":" type | variadic_param .
variadic_param = identifier ":" "..." type .
// --- Implementations ---
// See: 08-declarations.md § Implementations
impl_block = inherent_impl | trait_impl | def_impl .
inherent_impl = "impl" [ generics ] type_path [ where_clause ] "{" { method } "}" .
trait_impl = "impl" [ generics ] type ":" type_path [ where_clause ] "{" { method } "}" .
def_impl = "def" "impl" identifier "{" { def_impl_method } "}" .
method = "@" identifier params "->" type [ uses_clause ] "=" expression [ ";" ] .
def_impl_method = "@" identifier params "->" type "=" expression [ ";" ] . /* no self, no uses */
/* Semicolon rule: same as function — ";" required unless body ends with "}" */
// --- Tests ---
// See: 13-testing.md
test = "@" identifier "tests" test_targets "()" "->" "void" "=" expression [ ";" ] .
/* Semicolon rule: same as function — ";" required unless body ends with "}" */
test_targets = "_" | test_target { "tests" test_target } .
test_target = "@" identifier .
// --- Constants (Immutable Bindings) ---
// See: 04-constants.md
constant_decl = "let" "$" identifier [ ":" type ] "=" expression ";" .
// ============================================================================
// TYPES
// See: 06-types.md
// ============================================================================
type = type_path [ type_args ]
| trait_object_bounds /* Printable + Hashable */
| list_type | fixed_list_type | map_type | tuple_type | function_type
| impl_trait_type .
type_path = identifier { "." identifier } .
// --- Bounded Trait Objects ---
// See: 06-types.md § Bounded Trait Objects
// Multiple trait bounds as a type: `@store (item: Printable + Hashable) -> void`
trait_object_bounds = type_path "+" type_path { "+" type_path } .
// --- Existential Types (impl Trait) ---
// See: 06-types.md § Existential Types
impl_trait_type = "impl" trait_bounds [ impl_where_clause ] .
trait_bounds = type_path { "+" type_path } .
impl_where_clause = "where" assoc_constraint { "," assoc_constraint } .
assoc_constraint = identifier "==" type .
type_args = "<" type_or_const { "," type_or_const } ">" .
type_or_const = type | const_expr .
list_type = "[" type "]" .
fixed_list_type = "[" type "," "max" const_expr "]" .
map_type = "{" type ":" type "}" .
tuple_type = "(" type { "," type } ")" | "()" .
function_type = "(" [ type { "," type } ] ")" "->" type .
/* const_expr is defined in § CONSTANT EXPRESSIONS below */
// ============================================================================
// EXPRESSIONS
// See: 09-expressions.md
// ============================================================================
expression = with_expr | let_expr | if_expr | for_expr | while_expr | loop_expr | lambda | break_expr | continue_expr | unsafe_expr | block_expr | match_expr | try_expr | binary_expr .
// --- Primary Expressions ---
primary = literal | identifier | "self" | "Self"
| "(" expression ")"
| "#" /* length in index context */
| list_literal | map_literal | struct_literal
| block_expr /* { expr \n expr \n result } */
| match_expr /* match expr { arms } */
| try_expr /* try { block_body } */
| pattern_expr /* parallel, spawn, etc. */
| unsafe_expr
| embed_expr | has_embed_expr .
// --- Block Expression ---
// See: proposals/approved/block-expression-syntax.md
// Semicolons terminate statements inside blocks. The last expression without ";"
// is the block's value. A block where every expression has ";" returns void.
block_expr = "{" { statement } [ expression ] "}" .
statement = ( let_expr | assignment | expression ) ";" .
// --- Unsafe Expression ---
// See: spec/24-ffi.md § Unsafe Blocks
unsafe_expr = "unsafe" block_expr .
// --- Embed Expressions ---
// See: 11-built-in-functions.md § embed, § has_embed
// See: proposals/approved/embed-expression-proposal.md
embed_expr = "embed" "(" expression ")" .
has_embed_expr = "has_embed" "(" expression ")" .
// List literals with spread support
// See: 09-expressions.md § Spread Operator
list_literal = "[" [ list_element { "," list_element } ] "]" .
list_element = "..." expression | expression .
// Map literals with spread support
// See: computed-map-keys-proposal.md for key semantics
map_literal = "{" [ map_element { "," map_element } ] "}" .
map_element = "..." expression | map_entry .
map_entry = map_key ":" expression .
map_key = "[" expression "]" /* computed key: evaluates expression */
| identifier /* literal string key: "foo" from foo */
| string_literal . /* literal string key */
// Struct literals with spread support
struct_literal = type_path "{" [ struct_element { "," struct_element } ] "}" .
struct_element = "..." expression | field_init .
field_init = identifier [ ":" expression ] .
// --- Postfix Expressions ---
// See: 09-expressions.md § Postfix Expressions
postfix_expr = primary { postfix_op } .
postfix_op = "." member_name [ call_args ] /* field/method access */
| "." match_method /* method-style match */
| "[" expression "]" /* index access */
| call_args /* function call */
| "?" /* error propagation */
| "as" type /* infallible type conversion */
| "as?" type . /* fallible type conversion */
member_name = identifier | keyword | int_literal . /* keywords/ints valid after "." (tuple: t.0) */
match_method = "match" "(" match_arm { "," match_arm } ")" .
call_args = "(" [ call_arg { "," call_arg } ] ")" .
call_arg = named_arg | positional_arg | spread_arg .
named_arg = identifier ":" [ expression ] . /* punned when expression omitted: f(x:) = f(x: x) */
positional_arg = expression .
spread_arg = "..." expression . /* spread into variadic position only */
// --- Unary Expressions ---
// See: 09-expressions.md § Unary Expressions
unary_expr = [ "!" | "-" | "~" ] power_expr .
// --- Power Expression ---
// See: operator-rules.md § Power
// ** binds tighter than unary: -x ** 2 = -(x ** 2)
power_expr = postfix_expr [ "**" power_expr ] . /* right-associative */
// --- Binary Expressions ---
// See: 09-expressions.md § Binary Expressions
// Precedence (lowest to highest): |>, ??, ||, &&, |, ^, &, ==, cmp, range, shift, add, mul, unary, power
binary_expr = pipe_expr .
pipe_expr = coalesce_expr { "|>" pipe_step } .
pipe_step = "." member_name [ call_args ] /* method on piped value */
| postfix_expr [ call_args ] /* function call with implicit fill */
| lambda . /* expression-level operation */
coalesce_expr = or_expr [ "??" coalesce_expr ] . /* right-associative */
or_expr = and_expr { "||" and_expr } .
and_expr = bit_or_expr { "&&" bit_or_expr } .
bit_or_expr = bit_xor_expr { "|" bit_xor_expr } .
bit_xor_expr = bit_and_expr { "^" bit_and_expr } .
bit_and_expr = eq_expr { "&" eq_expr } .
eq_expr = cmp_expr { ( "==" | "!=" ) cmp_expr } .
cmp_expr = range_expr { ( "<" | ">" | "<=" | ">=" ) range_expr } .
range_expr = shift_expr [ ( ".." | "..=" ) [ shift_expr ] [ "by" shift_expr ] ] .
shift_expr = add_expr { ( "<<" | ">>" ) add_expr } .
add_expr = mul_expr { ( "+" | "-" ) mul_expr } .
mul_expr = unary_expr { ( "*" | "/" | "%" | "div" | "@" ) unary_expr } .
// --- With Expression ---
// See: 09-expressions.md § With Expression, 14-capabilities.md § Providing Capabilities
with_expr = "with" capability_binding { "," capability_binding } "in" expression .
capability_binding = identifier "=" ( handler_expr | expression ) .
// --- Handler Expression (Stateful Effect Handlers) ---
// See: 14-capabilities.md § Stateful Handlers, proposals/approved/stateful-mock-testing-proposal.md
// `handler` is context-sensitive: valid only in the expression position of a capability_binding.
handler_expr = "handler" "(" "state" ":" expression ")" "{" handler_operations "}" .
handler_operations = handler_operation { "," handler_operation } .
handler_operation = identifier ":" expression .
// --- Let Binding ---
// See: 09-expressions.md § Let Binding, 05-variables.md
let_expr = "let" binding_pattern [ ":" type ] "=" expression .
assignment = assignment_target "=" expression
| assignment_target compound_op expression .
assignment_target = identifier { "[" expression "]" | "." identifier } .
compound_op = "+=" | "-=" | "*=" | "/=" | "%=" | "**=" | "@="
| "&=" | "|=" | "^=" | "<<=" | ">>="
| "&&=" | "||=" .
binding = let_expr | assignment . /* convenience grouping; not currently referenced */
// --- Conditional ---
// See: 09-expressions.md § Conditional
if_expr = "if" expression "then" expression
{ "else" "if" expression "then" expression }
[ "else" expression ] .
// --- For Expression ---
// See: 09-expressions.md § For Expression, 19-control-flow.md § Labeled Loops
for_expr = "for" [ label ] binding_pattern "in" expression [ "if" expression ] { for_clause } ( "do" | "yield" ) expression .
for_clause = "for" binding_pattern "in" expression [ "if" expression ] .
// --- Loop Expression ---
// See: 09-expressions.md § Loop Expression, 19-control-flow.md § Labeled Loops
loop_expr = "loop" [ label ] block_expr .
// --- While Expression ---
// See: 16-control-flow.md § While Loop
// Desugars to: loop { if !condition then break; body }
while_expr = "while" [ label ] expression "do" expression .
// --- Labels ---
// See: 19-control-flow.md § Labeled Loops
label = ":" identifier . /* no space around colon */
// --- Lambda ---
// See: 09-expressions.md § Lambda
lambda = simple_lambda | typed_lambda .
simple_lambda = lambda_params "->" expression .
typed_lambda = "(" [ typed_param { "," typed_param } ] ")" "->" type "=" expression .
lambda_params = identifier | "(" [ identifier { "," identifier } ] ")" .
typed_param = identifier ":" type .
// --- Control Flow ---
// See: 19-control-flow.md
break_expr = "break" [ label ] [ expression ] .
continue_expr = "continue" [ label ] [ expression ] .
// ============================================================================
// PATTERNS (COMPILER CONSTRUCTS)
// See: 10-patterns.md
// ============================================================================
// --- Pattern Categories ---
pattern_expr = function_exp | function_val | channel_expr | for_pattern | catch_expr | nursery_expr .
function_exp = pattern_name "(" pattern_arg { "," pattern_arg } ")" .
pattern_name = "recurse" | "parallel" | "spawn" | "timeout" | "cache" | "with" . /* nursery has explicit nursery_expr */
pattern_arg = identifier ":" expression .
// Type conversion patterns (call position only)
function_val = ( "int" | "float" | "str" | "byte" ) "(" expression ")" .
// --- Block-Based Expressions ---
// See: proposals/approved/block-expression-syntax.md
// match: Pattern matching with scrutinee before block
match_expr = "match" expression "{" match_arms "}" .
match_arms = [ match_arm { "," match_arm } [ "," ] ] .
match_arm = match_pattern [ "if" expression ] "->" expression .
// try: Error-propagating block (returns early on Err)
try_expr = "try" block_expr .
// --- Function-Level Contracts ---
// See: proposals/approved/block-expression-syntax.md § Function-Level Contracts
// Contracts sit between the return type and the "=" in function declarations.
contract = pre_contract | post_contract .
pre_contract = "pre" "(" check_expr ")" .
post_contract = "post" "(" postcheck_expr ")" .
check_expr = expression [ "|" string_literal ] .
postcheck_expr = lambda_params "->" check_expr .
// for pattern: First-match iteration
// See: 10-patterns.md § for Pattern
for_pattern = "for" "(" for_pattern_args ")" .
for_pattern_args = "over" ":" expression "," "match" ":" match_pattern "->" expression "," "default" ":" expression
| "over" ":" expression "," "map" ":" expression "," "match" ":" match_pattern "->" expression "," "default" ":" expression .
// catch: Panic recovery
// See: 20-errors-and-panics.md § Catching Panics
catch_expr = "catch" "(" "expr" ":" expression ")" .
// nursery: Structured concurrency
// See: 10-patterns.md § Concurrency
nursery_expr = "nursery" "(" nursery_args ")" .
nursery_args = "body" ":" lambda "," "on_error" ":" expression [ "," "timeout" ":" expression ] .
// --- Channel Constructors ---
// See: 06-types.md § Channel Types
channel_expr = channel_constructor "(" "buffer" ":" expression ")" .
channel_constructor = "channel" [ type_args ] | "channel_in" [ type_args ] | "channel_out" [ type_args ] | "channel_all" [ type_args ] .
// --- Match Patterns ---
// See: 10-patterns.md § Match Patterns
match_pattern = literal_pattern
| identifier_pattern
| wildcard_pattern
| variant_pattern
| struct_pattern
| tuple_pattern
| list_pattern
| range_pattern
| or_pattern
| at_pattern .
literal_pattern = [ "-" ] int_literal | string_literal | char_literal | byte_literal | bool_literal .
identifier_pattern = identifier .
wildcard_pattern = "_" .
variant_pattern = type_path [ "(" [ variant_field { "," variant_field } ] ")" ] .
variant_field = identifier ":" [ match_pattern ] /* named; punned if pattern omitted */
| match_pattern . /* positional */
struct_pattern = [ type_path ] "{" [ field_pattern { "," field_pattern } ] [ ".." ] "}" .
field_pattern = identifier [ ":" match_pattern ] .
tuple_pattern = "(" [ match_pattern { "," match_pattern } ] ")" .
list_pattern = "[" [ list_pattern_elems ] "]" .
list_pattern_elems = match_pattern { "," match_pattern } [ "," ".." [ identifier ] ]
| ".." [ identifier ] .
range_pattern = literal_pattern ( ".." | "..=" ) literal_pattern .
or_pattern = match_pattern "|" match_pattern .
at_pattern = identifier "@" match_pattern .
// --- Binding Patterns ---
// See: 05-variables.md § Destructuring
// The "$" prefix marks immutable bindings; without "$", bindings are mutable.
binding_pattern = [ "$" ] identifier
| "_"
| "{" [ field_binding { "," field_binding } ] "}"
| "(" [ binding_pattern { "," binding_pattern } ] ")"
| "[" [ binding_pattern { "," binding_pattern } [ ".." [ "$" ] identifier ] ] "]" .
field_binding = [ "$" ] identifier [ ":" binding_pattern ] .
// ============================================================================
// CONSTANT EXPRESSIONS
// See: 04-constants.md, 21-constant-expressions.md
// ============================================================================
const_expr = literal
| "$" identifier
| const_expr ( arith_op | comp_op | "&&" | "||" | "&" | "|" | "^" | "<<" | ">>" ) const_expr
| unary_op const_expr
| "(" const_expr ")" .
// ============================================================================
// PROGRAM ENTRY
// See: 18-program-execution.md
// ============================================================================
main_function = "@main" main_params "->" main_return "=" expression [ ";" ] .
main_params = "()" | "(" "args" ":" "[" "str" "]" ")" .
main_return = "void" | "int" | "Never" .
// ============================================================================
// END OF GRAMMAR
// ============================================================================