// Keywords Ns = { "ns" } TypeKw = { "type" } Mod = { "mod" } Int = { "int" } ClassKw = { "class" } Platform = { "platform" } Pub = { "pub" } Fld = { "fld" } Impl = { "impl" } Mut = { "mut" } Cons = { "cons" } Static = { "static" } Ref = { "ref" } Def = { "def" } Where = { "where" } Infer = { "infer" } Void = { "Void" } Delegate = { "delegate" } Let = { "let" } Fn = { "fn" } Op = { "op" } Return = { "return" } If = { "if" } Else = { "else" } While = { "while" } For = { "for" } In = { "in" } Move = { "move" } Alias = { "alias" } True = { "true" } False = { "false" } // Keywords as a rule (for preventing identifiers with keywords, etc.) Keyword = { Ns | TypeKw | Mod | Int | ClassKw | Platform | Pub | Fld | Impl | Mut | Cons | Static | Ref | Def | Where | Infer | Void | Delegate | Let | Fn | Op | Return | If | Else | While | For | In | Move | Alias | True | False } // Symbols Ellipsis = { "..." } Underscore = { "_" } Semicolon = { ";" } // Operators Or = { "||" } And = { "&&" } EqualTo = { "==" } NotEqualTo = { "!=" } Greater = { ">" } Less = { "<" } GreaterEqual = { ">=" } LessEqual = { "<=" } Add = { "+" } Subtract = { "-" } Multiply = { "*" } Divide = { "/" } Modulo = { "%" } Not = { "!" } Negative = { "-" } PlusPlus = { "++" } MinusMinus = { "--" } CallOp = { "()" } Spread = { Ellipsis } Borrow = { "&" } Star = { "*" } LeftShift = { "<<" } RightShift = { ">>" } Index = { "[]" } Operator = { Or | And | EqualTo | NotEqualTo | Greater | Less | GreaterEqual | LessEqual | Add | Subtract | Multiply | Divide | Modulo | Not | Negative | PlusPlus | MinusMinus | CallOp | Spread | Borrow | Star | LeftShift | RightShift | Index } // Names Identifier = @{ ( Keyword ~ IdentifierChar | !Keyword ~ IdentifierStartChar ) ~ IdentifierChar* } IdentifierStartChar = { 'a'..'z' | 'A'..'Z' | "_" } IdentifierChar = { 'a'..'z' | 'A'..'Z' | '0'..'9' | "_" } FullyQualifiedName = { Identifier ~ ( "::" ~ Identifier )* } // Common lists TypeUseList = { TypeUse ~ ( "," ~ TypeUse )* } IdentifierList = { Identifier ~ ( "," ~ Identifier )* } ParenthesesTypeUseList = { "(" ~ TypeUseList ~ ")" } ParenthesesOptionalTypeUseList = { "(" ~ TypeUseList? ~ ")" } // In general: // Arguments = usage // Parameters = declaration TypeUse = { Void | InterfaceOrClassTypeUse | TupleTypeUse | FunctionTypeUse } InterfaceOrClassTypeUse = { Borrow* ~ Mut? ~ FullyQualifiedName ~ GenericArguments? } TupleTypeUse = { Borrow* ~ Mut? ~ TupleArguments } FunctionTypeUse = { Borrow* ~ FunctionTypeModifier? ~ Fn ~ GenericParameters? ~ Parameters ~ ReturnType } // Generic Arguments GenericArguments = { "<" ~ TypeUseList ~ ">" } // Generic Parameters GenericParameters = { "<" ~ IdentifierList ~ ">" } // Tuple Arguments TupleArguments = { ParenthesesOptionalTypeUseList } // Implements list ImplementsList = { ":" ~ TypeUse ~ ( "+" ~ TypeUse )* } // Function type modifier FunctionTypeModifier = { Cons | Mut ~ Ref | Mut | Ref } // Parameters Parameters = { "(" ~ ( Parameter ~ ( "," ~ Parameter )* )? ~ ")" } Parameter = { Identifier ~ ":" ~ TypeUse } // Return type ReturnType = { "->" ~ TypeUse ~ RefList? } RefList = { Ref ~ Identifier ~ ( "," ~ Identifier ) } // Top-level constructs CompilationUnit = { SOI ~ Namespace? ~ ModuleLevelDeclaration* ~ EOI } Namespace = { Ns ~ FullyQualifiedName } // Organizational declarations ModuleLevelDeclaration = { Module | Interface | Class | FunctionDefinition | PlatformFunction } InterfaceLevelDeclaration = { Module | Interface | Class | InterfaceFunction | InterfaceDefaultFunction | InterfaceOperatorFunction | InterfaceDefaultOperatorFunction } ClassLevelDeclaration = { Module | Interface | Class | FunctionDefinition | OperatorFunctionDefinition | PlatformFunction | Property | Field } // Main organizational constructs Module = { Pub? ~ Mod ~ Identifier ~ "{" ~ ModuleLevelDeclaration* ~ "}" } Interface = { Pub? ~ Int ~ Identifier ~ GenericParameters? ~ ImplementsList? ~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )? } Class = { Pub? ~ ClassKw ~ Identifier ~ GenericParameters? ~ ClassConstructor? ~ ImplementsList? ~ ( "{" ~ ClassLevelDeclaration* ~ "}" )? } // Function constructs FunctionDefinition = { Pub? ~ FunctionModifier? ~ Fn ~ GenericParameters? ~ Identifier ~ Parameters ~ ReturnType? ~ FunctionBody } OperatorFunctionDefinition = { Pub? ~ FunctionModifier? ~ Op ~ GenericParameters? ~ Operator ~ Parameters ~ ReturnType? ~ FunctionBody } PlatformFunction = { Pub? ~ FunctionModifier? ~ Platform ~ Fn ~ GenericParameters? ~ Identifier ~ Parameters ~ ReturnType } InterfaceFunction = { FunctionModifier? ~ Fn ~ GenericParameters? ~ Identifier ~ Parameters ~ ReturnType } InterfaceDefaultFunction = { Def ~ FunctionModifier? ~ Fn ~ GenericParameters? ~ Identifier ~ Parameters ~ ReturnType ~ FunctionBody } InterfaceOperatorFunction = { FunctionModifier? ~ Op ~ GenericParameters? ~ Operator ~ Parameters ~ ReturnType } InterfaceDefaultOperatorFunction = { Def ~ FunctionModifier? ~ Op ~ Operator ~ Parameters ~ ReturnType ~ RefList? ~ FunctionBody } FunctionModifier = { Static | Cons | Mut ~ Ref | Mut | Ref } FunctionBody = { FunctionAliasBody | FunctionEqualsBody | BlockStatement } FunctionEqualsBody = { "=" ~ Expression } FunctionAliasBody = { Alias ~ Identifier } // Class constructs ClassConstructor = { "(" ~ DataMember ~ ( "," ~ DataMember )* ~ ")" } DataMember = { Property | Field } Property = { Mut? ~ Identifier ~ ":" ~ TypeUse } Field = { Mut? ~ Fld ~ Identifier ~ ":" ~ TypeUse } // Statements BlockStatement = { "{" ~ Statement* ~ Expression? ~ "}" } Statement = { ( VariableDeclaration | AssignmentStatement | CallStatement | ReturnStatement ) ~ Semicolon | ( BlockStatement | IfElseStatement | IfStatement | WhileStatement | ForStatement ) } VariableDeclaration = { Let ~ Mut? ~ Identifier ~ ( ":" ~ TypeUse )? ~ ( "=" ~ Expression )? } AssignmentStatement = { Expression ~ "=" ~ Expression } CallStatement = { PrimaryExpression ~ ObjectAccess? ~ ParenthesesCall ~ ( ObjectAccess | ParenthesesCall | PlusPlus | MinusMinus )* } ReturnStatement = { Return ~ Expression? } IfStatement = { If ~ "(" ~ Expression ~ ")" ~ BlockStatement } IfElseStatement = { IfStatement ~ ElseIf* ~ ElseBlock? } ElseIf = { Else ~ IfStatement } ElseBlock = { Else ~ BlockStatement } WhileStatement = { While ~ "(" ~ Expression ~ ")" ~ BlockStatement } ForStatement = { For ~ "(" ~ Identifier ~ In ~ Expression ~ ")" ~ BlockStatement } // Expressions Expression = { TernaryExpression } TernaryExpression = { OrExpression ~ ( "?" ~ Expression ~ ":" ~ Expression )? } OrExpression = { AndExpression ~ ( Or ~ Expression )? } AndExpression = { ComparisonExpression ~ ( And ~ Expression )? } ComparisonExpression = { ShiftExpression ~ ( ( Greater | Less | GreaterEqual | LessEqual | EqualTo | NotEqualTo ) ~ Expression )? } ShiftExpression = { AdditiveExpression ~ ( ( LeftShift | RightShift ) ~ Expression )? } AdditiveExpression = { MultiplicativeExpression ~ ( ( Add | Subtract ) ~ Expression )? } MultiplicativeExpression = { PrefixExpression ~ ( ( Multiply | Divide | Modulo ) ~ Expression )? } PrefixExpression = { ( Spread | BorrowMut | Borrow | Mut | Not | Negative )* ~ SuffixExpression } BorrowMut = { Borrow ~ Mut } SuffixExpression = { PrimaryExpression ~ ( ObjectAccess | ParenthesesCall | PlusPlus | MinusMinus )* } PrimaryExpression = { Literal | FullyQualifiedName | Closure | ParenthesizedExpression } ParenthesizedExpression = { "(" ~ Expression ~ ")" } ObjectAccess = { ( ObjectProperty | ObjectIndex )+ } ObjectProperty = { "." ~ Identifier } ObjectIndex = { "[" ~ Expression ~ "]" } // Calls ParenthesesCall = { TurboFish? ~ "(" ~ ExpressionList? ~ ")" ~ Closure? } TurboFish = { "::" ~ GenericArguments } ExpressionList = { Expression ~ ( "," ~ Expression )* } // Closure Closure = { ( Cons | Mut )? ~ Move? ~ ClosureCaptures? ~ "{" ~ ( ClosureParameters? ~ "->" )? ~ Statement* ~ Expression? ~ "}" } ClosureParameters = { ClosureParameter ~ ( "," ~ ClosureParameter )* } ClosureParameter = { Identifier ~ ( ":" ~ TypeUse )? } ClosureCaptures = { "|" ~ ClosureCapture ~ ( "," ~ ClosureCapture )* ~ "|" } ClosureCapture = { Borrow* ~ Mut? ~ Identifier } // Literals Literal = { NumberLiteral | StringLiteral | BooleanLiteral } NumberLiteral = { DoubleLiteral | LongLiteral | IntLiteral } IntLiteral = { NumberBase } LongLiteral = ${ NumberBase ~ "L" } DoubleLiteral = ${ DecimalBase ~ "." ~ Digit+ } NumberBase = { BinaryBase | HexadecimalBase | DecimalBase } DecimalBase = @{ "0" | DecimalStartDigit ~ Digit* } BinaryBase = @{ "0b" ~ Digit+ } DecimalStartDigit = { '1'..'9' } Digit = @{ '0'..'9'+ } HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ } HexadecimalDigit = { '0'..'9' | 'a'..'f' } StringLiteral = { SingleQuoteString | DoubleQuoteString | BacktickString } SingleQuoteString = { "'" ~ StringInner? ~ "'" } DoubleQuoteString = { "\"" ~ ( DStringInner? ~ DStringExpression )* ~ DStringInner? ~ "\"" } StringInner = @{ StringChar+ } StringChar = { !( "\'" | "\\" ) ~ ANY | "\\" ~ ( "'" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" ) | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) } DStringInner = @{ DStringChar+ } DStringChar = { !( "\"" | "\\" | "${" ) ~ ANY | "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" ) | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) } DStringExpression = { "${" ~ Expression ~ "}" } BacktickString = { "`" ~ ( BacktickInner? ~ DStringExpression )* ~ BacktickInner? ~ "`" } BacktickInner = @{ BacktickStringChar+ } BacktickStringChar = { !( "\\`" | "\\" | "${" ) ~ ANY | "\\" ~ ( "`" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" | "$" ) | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) } BooleanLiteral = { True | False } WHITESPACE = _{ " " | "\t" | "\n" | "\r" }