// 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" } // 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 } // 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 = { ">>" } Operator = { Or | And | EqualTo | NotEqualTo | Greater | Less | GreaterEqual | LessEqual | Add | Subtract | Multiply | Divide | Modulo | Not | Negative | PlusPlus | MinusMinus | CallOp | Spread | Borrow | Star } // 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 = { FunctionEqualsBody | BlockStatement | FunctionAliasBody } 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 = { ( BlockStatement | VariableDeclaration | AssignmentStatement | CallStatement | ReturnStatement | IfStatement | IfElseStatement | WhileStatement | ForStatement )? ~ Semicolon } VariableDeclaration = { Let ~ Mut? ~ Identifier ~ ( ":" ~ TypeUse )? ~ ( "=" ~ Expression )? } AssignmentStatement = { Expression ~ "=" ~ Expression } CallStatement = { ( Literal | FullyQualifiedName | Closure | ParenthesizedExpression ) ~ ( ObjectAccess? ~ ParenthesesCall )+ } ReturnStatement = { Return ~ Expression? } IfStatement = { If ~ Expression ~ BlockStatement } IfElseStatement = { If ~ Expression ~ BlockStatement ~ ( Else ~ IfStatement )* ~ Else ~ BlockStatement } WhileStatement = { While ~ Expression ~ BlockStatement } ForStatement = { For ~ Expression ~ In ~ Expression ~ BlockStatement } // Expressions Expression = { TernaryExpression | OrExpression } TernaryExpression = { ( OrExpression | ParenthesizedExpression ) ~ "?" ~ Expression ~ ":" ~ Expression } OrExpression = { AndExpression ~ ( Or ~ Expression )? } AndExpression = { EqualityExpression ~ ( And ~ Expression )? } EqualityExpression = { ComparisonExpression ~ ( ( EqualTo | NotEqualTo ) ~ Expression )? } ComparisonExpression = { AdditiveExpression ~ ( ( Greater | Less | GreaterEqual | LessEqual ) ~ Expression )? } ShiftExpression = { AdditiveExpression ~ ( ( LeftShift | RightShift ) ~ Expression )? } AdditiveExpression = { MultiplicativeExpression ~ ( ( Add | Subtract ) ~ Expression )? } MultiplicativeExpression = { UnaryExpression ~ ( ( Multiply | Divide | Modulo ) ~ Expression )? } UnaryExpression = { ( Spread | ( Borrow ~ Mut ) | Borrow | Mut | Not | Negative )* ~ PrimaryExpression ~ ( PlusPlus | MinusMinus )* } PrimaryExpression = { ( Literal | FullyQualifiedName | Closure | ParenthesizedExpression ) ~ ExpressionSuffix? } ParenthesizedExpression = { "(" ~ Expression ~ ")" } ExpressionSuffix = { ObjectAccess ~ ( ParenthesesCall ~ ObjectAccess? )* | ( ParenthesesCall ~ ObjectAccess? )+ } ObjectAccess = { "." ~ Identifier ~ ( "." ~ Identifier )* } // 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 = { ( Mut | ( 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 = ${ "\"" ~ StringInner ~ "\"" } StringInner = @{ StringChar* } StringChar = { !( "\"" | "\\" ) ~ ANY | "\\" ~ ( "\"" | "\\" | "/" | "b" | "f" | "n" | "r" | "t" ) | "\\" ~ ( "u" ~ ASCII_HEX_DIGIT{4} ) } BooleanLiteral = { "true" | "false" } WHITESPACE = _{ " " | "\t" | "\n" | "\r" }