# Zeta Grammar #### Version 0.0.1 ## Contents - [Todo](#todo) - [Grammar Notation](#grammar-notation) - [Definitions](#definitions) + [Lexical](#lexical) + [Primary](#primary) + [Intermediate](#intermediate) + [Type Expression](#type-expression) + [Expression](#expression) + [Pattern](#pattern) + [Statement](#statement) ## Todo + Generics > e.g. `fn: gen_func (x: T) -> T { x + Y }` + `extern` label for functions and variables > Escape name mangling system for C FFI + Metaprogramming syntax > e.g. `meta for`, `emit`, `quotes`?, `meta` variables? + Macros? > Something like a `meta` function with `meta` variables as parameters? + CTFE syntax > e.g. `#some_func(constants)` + Annotation syntax > e.g. `#[inline]`, `#[packed]` ## Grammar Notation * `(element_a element_b etc)` > Grouping `element_a` and `element_b` and `etc` * `element_a | element_b | etc` > One of `element_a` or `element_b` or `etc` * `element+` > One or more repetitions of `element` * `element*` > Zero or more repetitions of `element` * `element~` > Zero or one of `element` * `element{n,N}` > Repetitions of `element` between `n` and `N` times * `'a'...'z'` > Any character between and including `a` and `z` > (`between` in terms of [numerical representation](http://www.asciitable.com/), e.g. `a` is `97` and `z` is `122`) ## Definitions ### Lexical ```ebnf LETTER = 'a'...'z' | 'A'...'Z' ; DIGIT = '0'...'9' ; HEX_DIGIT = 'a'...'f' | 'A'...'F' | DIGIT ; BIN_DIGIT = '0' | '1' ; UNICODE = '\u{0}'...'\u{10FFFF}' ; SIMPLE_ESCAPE = '\\' ('\\' | "'" | '"' | 'r' | 'n' | 't' | '0') ; ASCII_ESCAPE = "\\a" '{' HEX_DIGIT{1,2} '}' ; UNICODE_ESCAPE = "\\u" '{' HEX_DIGIT{1,6} '}' ; CHAR_ESCAPE = SIMPLE_ESCAPE | ASCII_ESCAPE | UNICODE_ESCAPE ; ``` ### Primary ```ebnf ignore = '_' ; identifier = ((LETTER | ignore) (LETTER | DIGIT)+) | (LETTER (LETTER | DIGIT)*) ; nil = "nil" ; bool = "true" | "false"; decimal = (DIGIT (DIGIT | ignore)* '.')~ DIGIT (DIGIT | ignore)* ('e' ('+' | '-')~ DIGIT (DIGIT | ignore)*)~ ; hexadecimal = "0x" (HEX_DIGIT | ignore)+ ; binary = "0b" (BIN_DIGIT | ignore)+ ; char = "'" (UNICODE | CHAR_ESCAPE) "'" ; constant = "nan" | "inf" ; number = decimal | hexadecimal | binary | char | constant ; string = '"' (UNICODE | CHAR_ESCAPE)* '"' ; literal = nil | bool | number | string ; primary = identifier | literal ; ``` ### Intermediate ```ebnf struct_field = identifier ':' type_expression ; enum_field = identifer ('=' expression)~ ; sum_tuple_variant = '(' type_expression (, type_expression)* ')' ; sum_struct_variant = '[' struct_field (, struct_field)* ']' ; sum_field = identifier (sum_tuple_variant | sum_struct_variant)~ ; ident_chain = identifier ('.' identifier)* ; patt_tuple_field = (identifier '=' expression) | pattern ; patt_struct_field = identifier ((('as' identifier)~ ('=' expression)~) | (':' pattern)) ; overloadable_operator = '^' | '@' | "not" | '!' | '+' | '-' | '+' | '-' | '*' | '/' | '%' | "!=" | "==" | "<" | ">" | "<=" | ">=" | "and" | "or" | "xor" | "&" | "|" | "~" | "lshift" | "rshift" | ".." | "..." | "->" | '.' | "[]" | "as" | "()" | '=' ; function_param = pattern ':' type_expression ; match_branch = ((identifier '=' expression) | pattern) '=>' statement ; label = ":<" identifier '>' ; ``` ### Type Expression ```ebnf texpr_name = identifier ; texpr_pointer = '^' type_expression ; texpr_array = '[' expression ']' type_expression ; texpr_tuple = '(' (type_expression (',' type_expression)*)~ ')' ; texpr_struct = "struct" '[' (struct_field (',' struct_field)*)~ ']' ; texpr_union = "union" '[' (struct_field (',' struct_field)*)~ ']' ; texpr_enum = "enum" '[' (enum_field (',' enum_field)*)~ ']' ; texpr_sum = "sum" '[' (sum_field (',' sum_field)*)~ ']' ; texpr_function = "fn" texpr_tuple ("->" type_expression)~ ; type_expression = texpr_name | texpr_pointer | texpr_array | texpr_tuple | texpr_struct | texpr_union | texpr_enum | texpr_sum | texpr_function ; ``` ### Expression ```ebnf expr_primary = primary ; expr_sem_group = '(' expression ')' ; expr_unary = ('^' | '@' | "not" | '!' | '+' | '-' | "sizeof" | "alignof" | "offsetof") expression ; expr_binary = expression ('+' | '-' | '*' | '/' | '%' | "!=" | "==" | "<" | ">" | "<=" | ">=" | "and" | "or" | "xor" | "&" | "|" | "~" | "lshift" | "rshift" | ".." | "..." | "else") expression ; expr_call = expression '(' (expression (',' expression)*)~ ')' ; expr_member = expression '.' identifier ; expr_subscript = expression '[' expression ']' ; expr_cast = expression 'as' type_expression ; expr_compound = (':' type_expression ':')~ '[' (compound_field (',' compound_field)*)~ ']' ; expr_block = stmt_block | stmt_conditional | stmt_match ; expression = expr_primary | expr_sem_group | expr_unary | expr_binary | expr_call | expr_member | expr_subscript | expr_cast | expr_compound | expr_block ; ``` ### Pattern ```ebnf patt_ignore = ignore ; patt_name = ident_chain ; patt_expr = '=' expression ; patt_tuple = '(' patt_tuple_field (',' '...')~ (',' patt_tuple_field)* ')' ; patt_sum = ident_chain patt_tuple ; patt_struct = ident_chain '[' ('...' | (patt_struct_field (',' patt_struct_field)* (',' '...')~)) ']' ; patt_else = pattern else pattern ; patt_enums = ident_chain '{' expression '}' ; pattern = patt_ignore | patt_name | patt_expr | patt_tuple | patt_sum | patt_struct | patt_else | patt_enums ; ``` ### Statement ```ebnf stmt_block = '{' statement* expression~ '}' ; stmt_mod = "mod" identifier (stmt_block | ';') ; stmt_import = "import" string ('as' identifier)~ ';' ; stmt_export = "export" statement ; stmt_use = "use" ident_chain ('as' identifier)~ ';' ; stmt_type_alias = "type" identifier ':' type_expression ';' ; stmt_struct = "struct" identifier '[' (struct_field (',' struct_field)*)~ ']' ; stmt_union = "union" identifier '[' (struct_field (',' struct_field)*)~ ']' ; stmt_enum = "enum" identifier '[' (enum_field (',' enum_field)*)~ ']' ; stmt_sum = "sum" identifier '[' (sum_field (',' sum_field)*)~ ']' ; stmt_impl = "impl" type_expression stmt_block ; stmt_function = "fn" (overloadable_operator | identifier) '(' (function_param (',' function_param)*)~ ')' ("->" type_expression)~ (stmt_block | ';') ; stmt_declaration = "let" pattern (':' type_expression)~ ('=' expression)~ ';' ; stmt_assign = expression '=' expression ';' ; stmt_mod_assign = expression ("+=" | "-=" | "*=" | "/=" | "%=") expression ';' ; stmt_loop_control = ("break" | "continue") identifier ';' ; stmt_return = "return" expression ';' ; stmt_conditional = "if" expression stmt_block ("else" "if" expression stmt_block)* ("else" stmt_block)~ ; stmt_match = "match" expression '{' (match_branch (',' match_branch)*)~ '}' ; stmt_for = "for" label~ pattern "in" expression stmt_block ; stmt_while = "while" label~ expression stmt_block ; stmt_loop = "loop" label~ stmt_block ("until" expression ';') ; stmt_expression = expression ';' ; statement = stmt_block | stmt_mod | stmt_import | stmt_export | stmt_use | stmt_type_alias | stmt_struct | stmt_union | stmt_enum | stmt_sum | stmt_impl | stmt_function | stmt_declaration | stmt_assign | stmt_mod_assign | stmt_loop_control | stmt_return | stmt_conditional | stmt_match | stmt_for | stmt_while | stmt_loop | stmt_expression ; ``` [^](#zeta-grammar)