Work on grammar and reorganize src/ast/mod.rs.

This commit is contained in:
Jesse Brault 2025-05-13 19:00:14 -05:00
parent e4c93f319d
commit 16e180180b
3 changed files with 499 additions and 431 deletions

View File

@ -1,8 +1,8 @@
use crate::ast::{
CompilationUnit, DelegateOrIdentifier, Fqn, FunctionModifier, FunctionTypeUse, GenericArgument,
GenericArguments, GenericParameter, GenericParameters, Identifier, InputArgument,
InputArguments, InterfaceOrClassTypeUse, Reference, References, ReturnType, TupleTypeUse,
TypeUse, VoidOrTypeUse,
CompilationUnit, DelegateOrIdentifier, FullyQualifiedName, FunctionModifier, FunctionTypeUse,
GenericArgument, GenericArguments, GenericParameter, GenericParameters, Identifier,
InputArgument, InputArguments, InterfaceOrClassTypeUse, Reference, References, ReturnType,
TupleTypeUse, TypeUse, VoidOrTypeUse,
};
use crate::parser::Rule;
use pest::iterators::Pair;
@ -24,7 +24,7 @@ fn build_identifier(identifier_pair: Pair<Rule>) -> Identifier {
}
}
fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
fn build_fqn(fqn_pair: Pair<Rule>) -> FullyQualifiedName {
let mut identifiers: Vec<Identifier> = vec![];
for identifier_pair in fqn_pair.into_inner() {
identifiers.push(expect_and_use(
@ -33,7 +33,7 @@ fn build_fqn(fqn_pair: Pair<Rule>) -> Fqn {
build_identifier,
));
}
Fqn { identifiers }
FullyQualifiedName { identifiers }
}
fn build_type_use(type_use_pair: Pair<Rule>) -> TypeUse {

View File

@ -8,7 +8,8 @@ pub mod unparse;
#[derive(Debug)]
pub enum Operator {
Binary(BinaryOperator),
Unary(UnaryOperator),
PrefixUnary(PrefixUnaryOperator),
SuffixUnary(SuffixUnaryOperator),
}
#[derive(Debug)]
@ -31,16 +32,21 @@ pub enum BinaryOperator {
}
#[derive(Debug)]
pub enum UnaryOperator {
pub enum PrefixUnaryOperator {
Spread,
Borrow,
BorrowMut,
Not,
Negative,
PlusPlus,
MinusMinus,
CallOp,
Spread,
}
// Names
#[derive(Debug)]
pub enum SuffixUnaryOperator {
PlusPlus,
MinusMinus,
}
/* Names */
#[derive(Debug, Clone)]
pub struct Identifier {
@ -48,48 +54,11 @@ pub struct Identifier {
}
#[derive(Debug)]
pub struct Fqn {
pub struct FullyQualifiedName {
pub identifiers: Vec<Identifier>,
}
// Generic parameters
#[derive(Debug)]
pub struct GenericParameters(pub Vec<GenericParameter>);
impl GenericParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct GenericParameter(Identifier);
// Generic arguments
#[derive(Debug)]
pub struct GenericArguments(pub Vec<GenericArgument>);
impl GenericArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct GenericArgument {
pub fqn: Fqn,
}
// Type-use and components
// #[derive(Debug)]
// pub struct TypeUse {
// pub fqn: Fqn,
// pub arguments: Option<TypeArguments>,
// pub inputs: Option<InputArguments>,
// }
/* Type Use */
#[derive(Debug)]
pub enum TypeUse {
@ -100,7 +69,7 @@ pub enum TypeUse {
#[derive(Debug)]
pub struct InterfaceOrClassTypeUse {
pub fqn: Fqn,
pub fqn: FullyQualifiedName,
pub generics: GenericArguments,
}
@ -116,26 +85,68 @@ pub struct FunctionTypeUse {
pub return_type: ReturnType,
}
#[derive(Debug)]
pub enum TypeArguments {
Generics(GenericArguments),
Tuple(TupleArguments),
Function(FunctionTypeArguments),
}
// Generic arguments
#[derive(Debug)]
pub struct TupleArguments(pub Vec<Fqn>);
pub struct GenericArguments(pub Vec<GenericArgument>);
impl TupleArguments {
impl GenericArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct FunctionTypeArguments {
pub parameters: TupleParameters,
pub return_type: Box<TypeUse>,
pub struct GenericArgument {
pub fqn: FullyQualifiedName,
}
/* Function Modifier */
#[derive(Debug)]
pub enum FunctionModifier {
Static,
Cons,
Mut,
Ref,
MutRef,
}
/* Generic parameters */
#[derive(Debug)]
pub struct GenericParameters(pub Vec<GenericParameter>);
impl GenericParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct GenericParameter(Identifier);
/* Input Arguments */
#[derive(Debug)]
pub struct InputArguments(pub Vec<InputArgument>);
impl InputArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct InputArgument {
pub lhs: DelegateOrIdentifier,
pub rhs: Identifier,
}
#[derive(Debug)]
pub enum DelegateOrIdentifier {
Delegate,
Identifier(Identifier),
}
// Function components
@ -179,54 +190,13 @@ impl References {
#[derive(Debug)]
pub struct Reference(pub Identifier);
// Inputs
/* Input Parameters */
#[derive(Debug)]
pub enum DelegateOrIdentifier {
Delegate,
Identifier(Identifier),
}
pub struct InputParameters(pub Vec<InputParameter>);
#[derive(Debug)]
pub struct InputParameters(pub Vec<DelegateOrIdentifier>);
impl InputParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct InputArguments(pub Vec<InputArgument>);
impl InputArguments {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct InputArgument {
pub lhs: DelegateOrIdentifier,
pub rhs: Identifier,
}
// Where guards
#[derive(Debug)]
pub struct WhereGuards(pub Vec<WhereGuard>);
impl WhereGuards {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
#[derive(Debug)]
pub struct WhereGuard {
pub identifier: Identifier,
pub implements: ImplementsList,
}
pub struct InputParameter(pub TypeUse);
// Implements
@ -243,7 +213,7 @@ impl ImplementsList {
#[derive(Debug)]
pub struct CompilationUnit {
pub namespace: Option<Fqn>,
pub namespace: Option<FullyQualifiedName>,
pub declarations: Vec<ModuleLevelDeclaration>,
}
@ -287,8 +257,8 @@ pub enum ClassLevelDeclaration {
pub struct TypeDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub parameters: Option<TypeParameters>,
pub where_guards: WhereGuards,
pub lhs: TypeUse,
pub where_guards: TypeWhereGuards,
pub rhs: TypeUse,
}
@ -305,8 +275,8 @@ pub struct InterfaceDeclaration {
pub identifier: Identifier,
pub generics: GenericParameters,
pub inputs: InputParameters,
pub return_type: Option<ReturnType>,
pub implements: ImplementsList,
pub where_guards: WhereGuards,
pub declarations: Vec<InterfaceLevelDeclaration>,
}
@ -316,30 +286,68 @@ pub struct ClassDeclaration {
pub identifier: Identifier,
pub generics: GenericParameters,
pub class_constructor: Option<ClassConstructor>,
pub inputs: InputArguments,
pub implements: ImplementsList,
pub where_guards: WhereGuards,
pub declarations: Vec<ClassLevelDeclaration>,
}
// Type components
#[derive(Debug)]
pub struct TypeWhereGuards(pub Vec<TypeWhereGuard>);
#[derive(Debug)]
pub struct TypeWhereGuard {
pub identifier: Identifier,
pub implements: TypeImplementsList,
}
#[derive(Debug)]
pub struct TypeImplementsList(pub Vec<TypeImplements>);
#[derive(Debug)]
pub struct TypeImplements {
pub fqn: FullyQualifiedName,
pub arguments: TypeImplementsArguments,
}
#[derive(Debug)]
pub enum TypeImplementsArguments {
Generic(TypeGenericArguments),
Tuple(TypeTupleArguments),
Function(TypeFunctionArguments),
}
#[derive(Debug)]
pub struct TypeGenericArguments(pub Vec<TypeGenericArgument>);
#[derive(Debug)]
pub enum TypeGenericArgument {
Underscore,
FullyQualifiedName(FullyQualifiedName),
Infer(Identifier),
}
#[derive(Debug)]
pub struct TypeTupleArguments(pub Vec<TypeTupleArgument>);
#[derive(Debug)]
pub enum TypeTupleArgument {
Underscore,
FullyQualifiedName(FullyQualifiedName),
Infer(Identifier),
EllipsisUnderscore,
EllipsisInfer(Identifier),
}
#[derive(Debug)]
pub struct TypeFunctionArguments {
pub generics: GenericArguments,
pub parameters: TypeTupleArguments,
pub return_type: ReturnType,
}
// Function declarations and components
#[derive(Debug)]
pub enum FunctionModifier {
Static,
Cons,
Mut,
Ref,
MutRef,
}
#[derive(Debug)]
pub enum FunctionBody {
EqualsBody(Expression),
BlockBody(BlockStatement),
AliasBody(Identifier),
}
#[derive(Debug)]
pub struct FunctionDeclaration {
pub is_public: bool,
@ -390,22 +398,13 @@ pub struct InterfaceOperatorFunctionDeclaration {
pub return_type: ReturnType,
}
// Type components
// TODO: default interface functions
#[derive(Debug)]
pub enum TypeParameters {
Generic(GenericParameters),
Tuple(TupleParameters),
Function(FunctionTypeParameters),
}
#[derive(Debug)]
pub struct TupleParameters(pub Vec<Identifier>);
#[derive(Debug)]
pub struct FunctionTypeParameters {
pub parameters: Parameters,
pub return_type: TypeUse,
pub enum FunctionBody {
Equals(Expression),
Block(BlockStatement),
Alias(Identifier),
}
// Class components
@ -435,9 +434,9 @@ pub struct BlockStatement(pub Vec<Statement>);
#[derive(Debug)]
pub enum Statement {
BlockStatement(BlockStatement),
CallStatement(CallExpression),
VariableDeclarationStatement(VariableDeclarationStatement),
AssignStatement(AssignStatement),
CallStatement(CallExpression),
ReturnStatement(ReturnStatement),
IfStatement(IfStatement),
IfElseStatement(IfElseStatement),
@ -462,15 +461,15 @@ pub struct ReturnStatement(pub Option<Expression>);
#[derive(Debug)]
pub struct IfStatement {
pub condition: Expression,
pub then_branch: BlockStatement,
pub then_block: BlockStatement,
}
#[derive(Debug)]
pub struct IfElseStatement {
pub condition: Expression,
pub then_branch: BlockStatement,
pub then_block: BlockStatement,
pub else_ifs: ElseIfs,
pub else_branch: BlockStatement,
pub else_block: BlockStatement,
}
#[derive(Debug)]
@ -493,6 +492,7 @@ pub struct ForStatement {
#[derive(Debug)]
pub enum Expression {
Ternary(TernaryExpression),
Binary(BinaryExpression),
Unary(UnaryExpression),
Assignment(Box<AssignmentExpression>),
@ -500,6 +500,13 @@ pub enum Expression {
Literal(Literal),
}
#[derive(Debug)]
pub struct TernaryExpression {
pub condition: Box<Expression>,
pub true_block: Box<Expression>,
pub false_block: Box<Expression>,
}
#[derive(Debug)]
pub struct BinaryExpression {
pub left: Box<Expression>,
@ -509,8 +516,9 @@ pub struct BinaryExpression {
#[derive(Debug)]
pub struct UnaryExpression {
pub operator: UnaryOperator,
pub lhs_operators: Vec<PrefixUnaryOperator>,
pub expression: Box<Expression>,
pub rhs_operators: Vec<SuffixUnaryOperator>,
}
#[derive(Debug)]

View File

@ -20,6 +20,13 @@ Delegate = { "delegate" }
Let = { "let" }
Fn = { "fn" }
Op = { "op" }
Return = { "return" }
If = { "if" }
Else = { "else" }
While = { "while" }
For = { "for" }
In = { "in" }
Move = { "move" }
// Keywords as a rule (for preventing identifiers with keywords, etc.)
Keyword = {
@ -44,11 +51,19 @@ Keyword = {
| Let
| Fn
| Op
| Return
| If
| Else
| While
| For
| In
| Move
}
// Symbols
Ellipsis = { "..." }
Underscore = { "_" }
Semicolon = { ";" }
// Operators
Or = { "||" }
@ -70,6 +85,10 @@ PlusPlus = { "++" }
MinusMinus = { "--" }
CallOp = { "()" }
Spread = { Ellipsis }
Borrow = { "&" }
Star = { "*" }
LeftShift = { "<<" }
RightShift = { ">>" }
Operator = {
Or
@ -91,15 +110,12 @@ Operator = {
| MinusMinus
| CallOp
| Spread
| Borrow
| Star
}
// Commonly shared constructs
FullyQualifiedName = {
Identifier
~ ( "::" ~ Identifier )*
}
Identifier = @{
( Keyword ~ IdentifierChar | !Keyword ~ IdentifierStartChar )
~ IdentifierChar*
@ -118,14 +134,25 @@ IdentifierChar = {
| "_"
}
FullyQualifiedName = {
Identifier
~ ( "::" ~ Identifier )*
}
// In general:
// Arguments = usage
// Parameters = declaration
TypeUse = {
(
Mut
| ( Borrow ~ Mut? )*
)?
~ (
InterfaceOrClassTypeUse
| TupleTypeUse
| FunctionTypeUse
)
}
InterfaceOrClassTypeUse = {
@ -151,12 +178,7 @@ FunctionTypeUse = {
~ ReturnType
}
FunctionTypeModifier = {
Cons
| Mut ~ Ref
| Mut
| Ref
}
// Generic Arguments
GenericArguments = {
"<"
@ -165,40 +187,6 @@ GenericArguments = {
~ ">"
}
InputArguments = {
"|"
~ (
InputArgument
~ ( "," ~ InputArgument )*
)?
~ "|"
}
InputArgument = {
Identifier
~ ( "=" ~ Identifier )
}
RefList = {
Ref
~ Identifier
~ ( "," ~ Identifier )*
}
FunctionInputArguments = {
"|"
~ (
FunctionInputArgument
~ ( "," ~ FunctionInputArgument )*
)?
~ "|"
}
FunctionInputArgument = {
( Delegate | Identifier )
~ ( "=" ~ Identifier )
}
// Generic Parameters
GenericParameters = {
@ -208,67 +196,75 @@ GenericParameters = {
~ ">"
}
InputParameters = {
// Function Input Arguments
FunctionInputArguments = {
"|"
~ InputParameter
~ ( "," ~ InputParameter )*
~ (
FunctionInputArgument
~ ( "," ~ FunctionInputArgument )*
)?
~ "|"
}
InputParameter = {
Identifier
~ ":"
~ TypeUse
FunctionInputArgument = {
( Delegate ~ "=" ~ Identifier )
| Identifier
}
TupleGenericParameters = {
// Function type components
FunctionTypeModifier = {
Cons
| Mut ~ Ref
| Mut
| Ref
}
Parameters = {
"("
~ (
Identifier
~ ( "," ~ Identifier )*
Parameter
~ ( "," ~ Parameter )*
)?
~ ")"
}
FunctionGenericParameters = {
TupleGenericParameters
~ FunctionGenericParameterReturnType
}
FunctionGenericParameterReturnType = {
"->"
~ ( Void | Identifier )
~ RefList?
}
FunctionInputParameters = {
"|"
~ FunctionInputParameter
~ ( "," ~ FunctionInputParameter )*
~ "|"
}
FunctionInputParameter = {
( Delegate | Identifier )
Parameter = {
Identifier
~ ":"
~ TypeUse
}
ReturnType = {
"->"
~ ( Void | TypeUse )
~ RefList?
}
RefList = {
Ref
~ Identifier
~ ( "," ~ Identifier )*
}
// Input Parameters
InputParameters = {
"("
~ (
TypeUse
~ ( "," ~ TypeUse )*
)?
~ ")"
}
// Implements list
ImplementsList = {
":"
~ TypeUse
~ ( "+" ~ TypeUse )
}
WhereGuards = {
Where
~ WhereGuard
~ ( "," ~ WhereGuard )*
}
WhereGuard = {
Identifier
~ ImplementsList
~ ( "+" ~ TypeUse )*
}
// Top-level constructs
@ -324,7 +320,7 @@ Type = {
Pub?
~ TypeKw
~ Identifier
~ GenericParameters?
~ TypeUse
~ TypeWhereGuards?
~ "="
~ TypeUse
@ -341,9 +337,10 @@ Interface = {
Pub?
~ Int
~ Identifier
~ InterfaceGenericParametersAndInputs?
~ GenericParameters?
~ InputParameters?
~ ReturnType?
~ ImplementsList?
~ WhereGuards?
~ ( "{" ~ InterfaceLevelDeclaration* ~ "}" )?
}
@ -354,8 +351,6 @@ Class = {
~ GenericParameters?
~ ClassConstructor?
~ ImplementsList?
~ InputArguments?
~ WhereGuards?
~ ( "{" ~ ClassLevelDeclaration* ~ "}" )?
}
@ -370,19 +365,23 @@ TypeWhereGuards = {
TypeWhereGuard = {
Identifier
~ ":"
~ TypeTypeUse
~ ( "+" ~ TypeTypeUse )*
~ TypeImplementsList
}
TypeTypeUse = {
TypeImplementsList = {
TypeImplements
~ ( "+" ~ TypeImplements )*
}
TypeImplements = {
FullyQualifiedName
~ TypeTypeArguments?
~ TypeImplementsArguments?
}
TypeTypeArguments = {
TypeImplementsArguments = {
TypeGenericArguments
| TypeGenericFunctionArguments
| TypeGenericTupleArguments
| TypeTupleArguments
| TypeFunctionArguments
}
TypeGenericArguments = {
@ -398,16 +397,16 @@ TypeGenericArgument = {
| ( Infer ~ Identifier )
}
TypeGenericTupleArguments = {
TypeTupleArguments = {
"("
~ (
TypeGenericTupleArgument
~ ( "," ~ TypeGenericTupleArgument )*
TypeTupleArgument
~ ( "," ~ TypeTupleArgument )*
)?
~ ")"
}
TypeGenericTupleArgument = {
TypeTupleArgument = {
Underscore
| FullyQualifiedName
| ( Infer ~ Identifier )
@ -415,120 +414,13 @@ TypeGenericTupleArgument = {
| ( Ellipsis ~ Infer ~ Identifier )
}
TypeGenericFunctionArguments = {
TypeGenericTupleArguments
~ TypeGenericArguments?
~ TypeFunctionReturnType
}
TypeFunctionReturnType = {
"->"
~ ( Void | FullyQualifiedName )
~ RefList?
}
// Interface
InterfaceGenericParametersAndInputs = {
GenericParameters ~ InputParameters?
| TupleGenericParameters
| FunctionGenericParameters ~ FunctionInputParameters?
| InputParameters
}
InterfaceFunction = {
(
Static
| Cons
| ( Mut ~ Ref? )
)?
~ Fn
~ GenericParameters?
~ Identifier
~ Parameters
TypeFunctionArguments = {
TypeGenericArguments?
~ TypeTupleArguments
~ ReturnType
~ WhereGuards?
}
InterfaceDefaultFunction = {
Def
~ (
Static
| Cons
| ( Mut ~ Ref? )
)?
~ Fn
~ GenericParameters?
~ Identifier
~ Parameters
~ ReturnType
~ WhereGuards?
~ FunctionBody
}
InterfaceOperatorFunction = {
(
Cons
| ( Mut ~ Ref? )
)?
~ Op
~ Operator
~ Parameters
~ ReturnType
~ RefList?
~ WhereGuards? // TODO: decide if we want this for interface op functions
}
InterfaceDefaultOperatorFunction = {
Def
~ (
Cons
| ( Mut ~ Ref? )
)?
~ Op
~ Operator
~ Parameters
~ ReturnType
~ RefList?
~ WhereGuards?
~ FunctionBody
}
// Class constructs
ClassConstructor = {
"("
~ DataMember
~ ( "," ~ DataMember )*
~ ")"
}
DataMember = {
Property
| Field
}
Property = {
Mut?
~ Identifier
~ ":"
~ TypeUse
}
Field = {
Mut?
~ Fld
~ Identifier
~ ":"
~ TypeUse
}
// Function constructs
FunctionModifier = {
Static
| Cons
| Mut? ~ Ref?
}
FunctionDefinition = {
Pub?
@ -562,30 +454,68 @@ PlatformFunction = {
~ ReturnType
}
Parameters = {
"("
~ (
Parameter
~ ( "," ~ Parameter )*
InterfaceFunction = {
(
Static
| Cons
| ( Mut ~ Ref? )
)?
~ ")"
~ Fn
~ GenericParameters?
~ Identifier
~ Parameters
~ ReturnType
}
Parameter = {
Identifier
~ ":"
~ TypeUse
InterfaceDefaultFunction = {
Def
~ (
Static
| Cons
| ( Mut ~ Ref? )
)?
~ Fn
~ GenericParameters?
~ Identifier
~ Parameters
~ ReturnType
~ FunctionBody
}
ReturnType = {
"->"
~ ( Void | TypeUse )
InterfaceOperatorFunction = {
(
Cons
| ( Mut ~ Ref? )
)?
~ Op
~ Operator
~ Parameters
~ ReturnType
}
InterfaceDefaultOperatorFunction = {
Def
~ (
Cons
| ( Mut ~ Ref? )
)?
~ Op
~ Operator
~ Parameters
~ ReturnType
~ RefList?
~ FunctionBody
}
FunctionModifier = {
Static
| Cons
| Mut? ~ Ref?
}
FunctionBody = {
FunctionEqualsBody
| FunctionBlockBody
| BlockStatement
| FunctionAliasBody
}
@ -594,29 +524,62 @@ FunctionEqualsBody = {
~ Expression
}
FunctionBlockBody = {
"{"
~ Statement*
~ "}"
}
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
| AssignmentExpression
| AssignmentStatement
| CallStatement
| ReturnStatement
| IfStatement
| IfElseStatement
| WhileStatement
| ForStatement
)?
~ Semicolon
}
VariableDeclaration = {
@ -627,26 +590,76 @@ VariableDeclaration = {
~ ( "=" ~ Expression )?
}
AssignmentStatement = {
Expression
~ "="
~ Expression
}
CallStatement = { PrimaryExpression }
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 = { OrExpression }
Expression = {
TernaryExpression
| OrExpression
}
TernaryExpression = {
( OrExpression | ParenthesizedExpression )
~ "?"
~ Expression
~ ":"
~ Expression
}
OrExpression = {
AndExpression
~ ( Or ~ Expression )*
~ ( Or ~ Expression )?
}
AndExpression = {
EqualityExpression
~ ( And ~ Expression )*
~ ( And ~ Expression )?
}
EqualityExpression = {
ComparisonExpression
~ (
( EqualTo | NotEqualTo )
~ Expression
)*
~ ( ( EqualTo | NotEqualTo ) ~ Expression )?
}
ComparisonExpression = {
@ -654,7 +667,12 @@ ComparisonExpression = {
~ (
( Greater | Less | GreaterEqual | LessEqual )
~ Expression
)*
)?
}
ShiftExpression = {
AdditiveExpression
~ ( ( LeftShift | RightShift ) ~ Expression )?
}
AdditiveExpression = {
@ -662,33 +680,38 @@ AdditiveExpression = {
~ (
( Add | Subtract )
~ Expression
)*
)?
}
MultiplicativeExpression = {
SpreadExpression
UnaryExpression
~ (
( Multiply | Divide | Modulo )
~ Expression
)*
}
SpreadExpression = {
UnaryExpression
~ Spread
~ Expression
)?
}
UnaryExpression = {
( Not | Negative )*
(
Spread
| ( Borrow ~ Mut )
| Borrow
| Mut
| Not
| Negative
)*
~ PrimaryExpression
~ ( ( NoParenthesesCall | ParenthesesCall )+ | ( PlusPlus | MinusMinus ) )?
~ ( PlusPlus | MinusMinus )*
}
PrimaryExpression = {
(
Literal
| ObjectAccess
| FullyQualifiedName
| Closure
| ParenthesizedExpression
)
~ ExpressionSuffix?
}
ParenthesizedExpression = {
@ -697,6 +720,18 @@ ParenthesizedExpression = {
~ ")"
}
ExpressionSuffix = {
ObjectAccess
~ ( ParenthesesCall ~ ObjectAccess? )*
| ( ParenthesesCall ~ ObjectAccess? )+
}
ObjectAccess = {
"."
~ Identifier
~ ( "." ~ Identifier )*
}
// Calls
ParenthesesCall = {
@ -704,11 +739,7 @@ ParenthesesCall = {
~ "("
~ ExpressionList?
~ ")"
}
NoParenthesesCall = {
TurboFish?
~ ExpressionList
~ Closure?
}
TurboFish = {
@ -721,20 +752,46 @@ ExpressionList = {
~ ( "," ~ Expression )*
}
// Assignment
AssignmentExpression = {
ObjectAccess
~ "="
~ Expression
// Closure
Closure = {
( Cons | Mut )?
~ Move?
~ ClosureCaptures?
~ "{"
~ ( ClosureParameters? ~ "->" )?
~ Statement*
~ Expression?
~ "}"
}
// Object
ObjectAccess = {
FullyQualifiedName
~ ( "." ~ Identifier )*
ClosureParameters = {
ClosureParameter
~ ( "," ~ ClosureParameter )*
}
ClosureParameter = {
Identifier
~ ( ":" ~ TypeUse )?
}
ClosureCaptures = {
"|"
~ ClosureCapture
~ ( "," ~ ClosureCapture )*
~ "|"
}
ClosureCapture = {
(
Mut
| ( Borrow ~ Mut? )*
)?
~ Identifier
}
// Literals
Literal = {
NumberLiteral
| StringLiteral
@ -742,9 +799,9 @@ Literal = {
}
NumberLiteral = {
LongLiteral
DoubleLiteral
| LongLiteral
| IntLiteral
| DoubleLiteral
}
IntLiteral = { NumberBase }
@ -754,18 +811,21 @@ LongLiteral = ${ NumberBase ~ "L" }
DoubleLiteral = ${ DecimalBase ~ "." ~ Digit+ }
NumberBase = {
DecimalBase
| BinaryBase
BinaryBase
| HexadecimalBase
| DecimalBase
}
DecimalBase = @{ DecimalStartDigit ~ Digit* }
DecimalBase = @{
"0"
| DecimalStartDigit ~ Digit*
}
BinaryBase = @{ "0b" ~ Digit* }
BinaryBase = @{ "0b" ~ Digit+ }
DecimalStartDigit = { '1'..'9' }
Digit = { '0'..'9'+ }
Digit = @{ '0'..'9'+ }
HexadecimalBase = @{ "0x" ~ HexadecimalDigit+ }