// Top-level constructs CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI } Namespace = { "ns" ~ FullyQualifiedName } CommonDeclaration = { Interface | Class | Module | Function | OperatorFunction } ModuleLevelDeclaration = { Declare? ~ Public? ~ CommonDeclaration } InterfaceLevelDeclaration = { CommonDeclaration } ClassLevelDeclaration = { Declare? ~ Public? ~ ( CommonDeclaration | ClassMember ) } // Module Module = { "mod" ~ Identifier ~ "{" ~ ModuleLevelDeclaration* ~ "}" } // Interface Interface = { "int" ~ Identifier ~ GenericParameters? ~ ExtendsList? ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? } // Class Class = { "class" ~ Identifier ~ GenericParameters? ~ ClassConstructor? ~ ExtendsList? ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? } ClassMember = { Field? ~ Identifier ~ TypeAnnotation? } // Class Constructor ClassConstructor = { "(" ~ ClassMemberList? ~ ")" } ClassMemberList = { ClassMember ~ ( "," ~ ClassMember )* } // Various Keywords Declare = { "decl" } Public = { "pub" } Field = { "fld" } Implementation = { "impl" } Mutable = { "mut" } Consume = { "cons" } Reference = { "ref" } Define = { "def" } // Fqn and identifier FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* } Identifier = @{ IdentifierStartChar ~ IdentifierChar* } IdentifierStartChar = { 'a'..'z' | 'A'..'Z' | "_" } IdentifierChar = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" } // Type constructs ExtendsList = { ":" ~ TypeUse ~ ( "+" ~ TypeUse )* } TypeAnnotation = { ":" ~ TypeUse } TypeUse = { FullyQualifiedName ~ GenericArguments? } // Generic arguments given to a TypeUse or function calls GenericArguments = { "<" ~ FullyQualifiedName ~ ( "," ~ FullyQualifiedName )* ~ ">" } // Generic parameters (for when types are declared) GenericParameters = { "<" ~ Identifier ~ ( "," ~ Identifier )* ~ ">" } // Function Function = { ( Implementation | Define )? ~ ( Consume | Mutable )? ~ Reference? ~ "fn" ~ GenericParameters? ~ Identifier ~ "(" ~ Parameters? ~ ")" ~ ReturnType? ~ ( FunctionAlias | FunctionEqualsBody | BlockStatement )? } ReturnType = { "->" ~ Reference? ~ TypeUse } FunctionAlias = { "alias" ~ FullyQualifiedName } OperatorFunction = { ( Implementation | Define )? ~ ( Consume | Mutable )? ~ Reference? ~ "op" ~ Operator ~ "(" ~ Parameters? ~ ")" ~ ReturnType? ~ ( FunctionAlias | FunctionEqualsBody | BlockStatement )? } Operator = { Or | And | EqualTo | NotEqualTo | Greater | Less | GreaterEqual | LessEqual | Add | Subtract | Multiply | Divide | Modulo | CallOp } CallOp = { "()" } Parameters = { Parameter ~ ( "," ~ Parameter )* } Parameter = { Identifier ~ TypeAnnotation? } FunctionEqualsBody = { "=" ~ Expression } // Statements BlockStatement = { "{" ~ Statement* ~ "}" } Statement = { VariableDeclaration | CallExpression | AssignmentExpression } VariableDeclaration = { "let" ~ Mutable? ~ Identifier ~ TypeAnnotation? ~ ( "=" ~ Expression )? } // Expressions Expression = { OrExpression } OrExpression = { AndExpression ~ ( Or ~ AndExpression )* } AndExpression = { EqualityExpression ~ ( And ~ EqualityExpression )* } Or = { "||" } And = { "&&" } EqualityExpression = { ComparisonExpression ~ ( ( EqualTo | NotEqualTo ) ~ ComparisonExpression )* } EqualTo = { "==" } NotEqualTo = { "!=" } ComparisonExpression = { AdditiveExpression ~ ( ( Greater | Less | GreaterEqual | LessEqual ) ~ AdditiveExpression )* } Greater = { ">" } Less = { "<" } GreaterEqual = { ">=" } LessEqual = { "<=" } AdditiveExpression = { MultiplicativeExpression ~ ( ( Add | Subtract ) ~ MultiplicativeExpression )* } Add = { "+" } Subtract = { "-" } MultiplicativeExpression = { UnaryExpression ~ ( ( Multiply | Divide | Modulo ) ~ UnaryExpression )* } Multiply = { "*" } Divide = { "/" } Modulo = { "%" } UnaryExpression = { ( Not | Negative )* ~ PrimaryExpression ~ ( Call | ( PlusPlus | MinusMinus ) )* } Not = { "!" } Negative = { "-" } PlusPlus = { "++" } MinusMinus = { "--" } PrimaryExpression = { Literal | ObjectAccess | ParenthesizedExpression } ParenthesizedExpression = { "(" ~ Expression ~ ")" } // Call CallExpression = { PrimaryExpression ~ Call+ } Call = { GenericArguments? ~ CallArguments } ExpressionList = { Expression ~ ( "," ~ Expression )* } CallArguments = { ( "(" ~ ExpressionList? ~ ")" ) | ExpressionList } // Assignment AssignmentExpression = { ObjectAccess ~ "=" ~ Expression } // Object ObjectAccess = { FullyQualifiedName ~ ( "." ~ Identifier )* } // Literals Literal = { NumberLiteral | StringLiteral | BooleanLiteral | NullLiteral } NumberLiteral = { LongLiteral | IntLiteral } IntLiteral = { NumberBase } LongLiteral = ${ NumberBase ~ "L" } NumberBase = { DecimalBase | BinaryBase | HexadecimalBase } DecimalBase = @{ DecimalStartDigit ~ Digit* } BinaryBase = @{ "0b" ~ Digit* } DecimalStartDigit = { '1'..'9' } Digit = { '0'..'9'+ } HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ } HexadecimalDigit = { '0'..'9' | 'a'..'f' } StringLiteral = ${ "\"" ~ StringInner ~ "\"" } StringInner = @{ StringChar* } StringChar = { !( "\"" | "\\" ) ~ ANY | "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" ) | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) } BooleanLiteral = { "true" | "false" } NullLiteral = { "null" } WHITESPACE = _{ " " | "\t" | "\n" | "\r" }