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

View File

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

View File

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