Zynx Language Grammar
A readable map of the current grammar shape.
This readable grammar guide follows the current 0.0.0-dev language surface.
It is a guide, not a full formal grammar. Current Language Surface
records the current public source boundaries.
source_file = top_level_item*
top_level_item =
attribute* ("extern" | "export" | "intrinsic")*
(function | struct | union | enum | error | interface | type | test | import | export | statement)
| foreign_decl
foreign_decl =
"foreign" string ("fn" foreign_fn | ("let" | "const") declaration ";")
| "foreign" "library" string "{" foreign_item* "}"
module declarations are not part of current source. Module identities are
derived from file paths and import requests.
function = ("async" | "unsafe")* "fn" identifier generics? "(" parameters? ")" (throws_clause? "->" type)? block
struct = "struct" identifier generics? (":" type_list)? "{" fields? "}"
interface = "interface" identifier generics? (":" type_list)? (";" | "{" members? "}")
enum = "enum" identifier generics? "{" variants? "}"
type = "type" identifier generics? "=" "distinct"? type ";"
Generic declarations can contain type parameters, interface bounds, const
integer parameters such as N: usize, and one final type pack such as T....
Generic argument lists can contain type arguments or integer literals for const
generic parameters.
expression =
assignment
| conditional
| binary
| unary
| postfix
| primary
postfix = primary (call | member_access | index_access)*
member_access = ("." | "?.") identifier generic_arguments?
condition = expression | identifier ":=" expression
See Operators for precedence and associativity.
type = "const"? ("&" | "*"+)? type_atom type_pack? nullable? throws_clause?
type_atom = base_type | named_type | tuple_type | callable_type | array_type
array_type = "[" type ("," number)? "]"
nullable = "?"
throws_clause = "throws" "(" identifier ("|" identifier)* ")"
Array and slice types use bracket-first syntax: [T] for slice-shaped array
values and [T, N] for fixed-size arrays.
throws(...) belongs after the nullable suffix on value types, as in
T? throws(E). Function declarations and callable types put the thrown error
set before the return arrow, as in fn load() throws(IOError) -> Data.
Dynamic require(...), user-defined decorators, atomics, runtime interface
objects, and broad foreign ABI forms are outside normal source. See
Current Language Surface for those
boundaries.