(* Conlang Expression Grammar *) Start = File ; Mutability = "mut"? ; Visibility = "pub"? ; File = Item* EOI ; Item = Visibility ItemKind ; ItemKind = Const | Static | Module | Function | Struct | Enum | Alias | Impl ; (* item *) Const = "const" Identifier ':' Type = Expr ';' ; Static = "static" Mutability Identifier ':' Type = Expr ';' ; Module = "mod" Identifier ModuleKind ; ModuleKind = '{' Item* '}' | ';' ; Function = "fn" Identifier '(' (Param ',')* Param? ')' ('->' Type)? Block? ; Param = Mutability Identifier ':' Type ; Struct = "struct" Identifier (StructTuple | StructBody)?; StructBody = '{' (StructMember ',')* StructMember? '}' ; StructTuple = TyTuple ; StructMember = Visibility Identifier ':' Type ; Enum = "enum" Identifier '{' (Variant ',')* Variant? '}' ; Variant = Identifier (VarStruct | VarTuple | VarCLike)? ; VarStruct = '{' (StructMember ',')* StructMember? '}' ; VarTuple = TyTuple ; VarCLike = '=' INTEGER ; Alias = "type" Ty ('=' Ty)? ';' ; Impl = "impl" Path '{' Item* '}' ; (* TODO: Impl Trait for Target*) (* type *) Ty = Never | Empty | Path | TyTuple | TyRef | TyFn ; Never = '!' ; Empty = '(' ')' ; TyTuple = '(' (Ty ',')* Ty? ')' ; TyRef = ('&' | '&&')* Path ; TyFn = "fn" TyTuple (-> Ty)? ; (* path *) Path = '::'? PathPart ('::' PathPart)* ; PathPart = "super" | "self" | Identifier ; Identifier = IDENTIFIER ; (* statement *) Stmt = ';' | (Let | Item | Expr) Semi ; Semi = ';'? ; Let = "let" Mutability Identifier (':' Ty)? ('=' Expr)? ; (* TODO: Closure syntax *) (* Closure = "cl" '(' Param* ')' Block ; *) (* literal *) Bool = "true" | "false" ; (* expr *) ExprKind = Assign | Compare | Range | Logic | Bitwise | Shift | Factor | Term | Unary | Member | Call | Index | Path | Literal | Array | ArrayRep | AddrOf | Block | Group | While | If | For | Break | Return | Continue ; Expr = Assign ; Assign = Path (AssignKind Assign ) | Compare ; Binary = Compare | Range | Logic | Bitwise | Shift | Factor | Term ; Compare = Range (CompareOp Range )* ; Range = Logic (RangeOp Logic )* ; Logic = Bitwise (LogicOp Bitwise)* ; Bitwise = Shift (BitwiseOp Shift )* ; Shift = Factor (ShiftOp Factor )* ; Factor = Term (FactorOp Term )* ; Term = Unary (FactorOp Unary )* ; Unary = (UnaryKind)* Member ; Member = Call ('.' Call)* ; Call = Index ('(' Tuple? ')')* ; Index = Primary ('[' Indices ']')* ; Indices = (Expr ',')* Expr? ; Primary = Literal | Path | Array | ArrayRep | AddrOf | Block | Group | If | While | For | Break | Return | Continue; Literal = STRING | CHARACTER | FLOAT | INTEGER | Bool ; Array = '[' (Expr ',')* Expr? ']' ; ArrayRep = '[' Expr ';' Expr ']' ; AddrOf = ('&' | '&&')* Mutability? Expr ; Block = '{' Stmt* '}'; Group = '(' (Empty | Expr | Tuple) ')' ; Tuple = (Expr ',')* Expr? ; Empty = ; While = "while" Expr Block Else ; If = "if" Expr Block Else ; For = "for" Identifier "in" Expr Block Else ; Else = ("else" Expr)? ; Break = "break" Expr ; Return = "return" Expr ; Continue = "continue" ; AssignKind = '=' | '+=' | '-=' | '*=' | '/=' | '&=' | '|=' | '^=' |'<<=' |'>>=' ; BinaryKind = CompareOp | RangeOp | LogicOp | BitwiseOp | ShiftOp | TermOp | FactorOp ; CompareOp = '<' | '<=' | '==' | '!=' | '>=' | '>' ; RangeOp = '..' | '..=' ; LogicOp = '&&' | '||' | '^^' ; BitwiseOp = '&' | '|' | '^' ; ShiftOp = '<<' | '>>'; TermOp = '+' | '-' ; FactorOp = '*' | '/' | '%' ; UnaryKind = '*' | '-' | '!' | '@' | '~' ;