use pest::Parser; pub mod build; pub mod unparse; // Operators #[derive(Debug)] pub enum Operator { Binary(BinaryOperator), PrefixUnary(PrefixUnaryOperator), SuffixUnary(SuffixUnaryOperator), } #[derive(Debug)] pub enum BinaryOperator { Or, And, EqualTo, NotEqualTo, Greater, Less, GreaterEqual, LessEqual, Add, Subtract, Multiply, Divide, Modulo, LeftShift, RightShift, } #[derive(Debug)] pub enum PrefixUnaryOperator { Spread, Borrow, BorrowMut, Not, Negative, } #[derive(Debug)] pub enum SuffixUnaryOperator { PlusPlus, MinusMinus, } /* Names */ #[derive(Debug, Clone)] pub struct Identifier { pub name: String, } #[derive(Debug)] pub struct FullyQualifiedName { pub identifiers: Vec, } /* Type Use */ #[derive(Debug)] pub enum TypeUse { InterfaceOrClass(InterfaceOrClassTypeUse), Tuple(TupleTypeUse), Function(FunctionTypeUse), } #[derive(Debug)] pub struct InterfaceOrClassTypeUse { pub borrow_count: usize, pub is_mut: bool, pub fqn: FullyQualifiedName, pub generics: GenericArguments, } #[derive(Debug)] pub struct TupleTypeUse { pub borrow_count: usize, pub is_mut: bool, pub type_uses: Vec, } #[derive(Debug)] pub struct FunctionTypeUse { pub borrow_count: usize, pub function_modifier: Option, pub generics: GenericParameters, pub parameters: FunctionTypeParameters, pub inputs: InputArguments, pub return_type: ReturnType, } // Generic arguments #[derive(Debug)] pub struct GenericArguments(pub Vec); impl GenericArguments { pub fn is_empty(&self) -> bool { self.0.is_empty() } } #[derive(Debug)] 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); impl GenericParameters { pub fn is_empty(&self) -> bool { self.0.is_empty() } } #[derive(Debug)] pub struct GenericParameter(Identifier); /* Function Type Parameters */ #[derive(Debug)] pub struct FunctionTypeParameters(pub Vec); /* Input Arguments */ #[derive(Debug)] pub struct InputArguments(pub Vec); 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 #[derive(Debug)] pub struct Parameters(pub Vec); impl Parameters { pub fn is_empty(&self) -> bool { self.0.is_empty() } } #[derive(Debug)] pub struct Parameter { identifier: Identifier, type_use: TypeUse, } #[derive(Debug)] pub struct ReturnType { pub declared_type: VoidOrTypeUse, pub references: References, } #[derive(Debug)] pub enum VoidOrTypeUse { Void, TypeUse(Box), } #[derive(Debug)] pub struct References(pub Vec); impl References { pub fn is_empty(&self) -> bool { self.0.is_empty() } } #[derive(Debug)] pub struct Reference(pub Identifier); /* Input Parameters */ #[derive(Debug)] pub struct InputParameters(pub Vec); #[derive(Debug)] pub struct InputParameter(pub TypeUse); // Implements #[derive(Debug)] pub struct ImplementsList(pub Vec); impl ImplementsList { pub fn is_empty(&self) -> bool { self.0.is_empty() } } // Top-level construct #[derive(Debug)] pub struct CompilationUnit { pub namespace: Option, pub declarations: Vec, } // Declarations allowed in each level #[derive(Debug)] pub enum ModuleLevelDeclaration { Type(TypeDeclaration), Module(ModuleDeclaration), Interface(InterfaceDeclaration), Class(ClassDeclaration), Function(FunctionDeclaration), PlatformFunction(PlatformFunctionDeclaration), } #[derive(Debug)] pub enum InterfaceLevelDeclaration { Type(TypeDeclaration), Module(ModuleDeclaration), Interface(InterfaceDeclaration), Class(ClassDeclaration), Function(InterfaceFunctionDeclaration), OperatorFunction(InterfaceOperatorFunctionDeclaration), } #[derive(Debug)] pub enum ClassLevelDeclaration { Type(TypeDeclaration), Module(ModuleDeclaration), Interface(InterfaceDeclaration), Class(ClassDeclaration), Function(FunctionDeclaration), OperatorFunction(OperatorFunctionDeclaration), PlatformFunction(PlatformFunctionDeclaration), Field(FieldDeclaration), } // Declarations #[derive(Debug)] pub struct TypeDeclaration { pub is_public: bool, pub identifier: Identifier, pub lhs: TypeUse, pub where_guards: TypeWhereGuards, pub rhs: TypeUse, } #[derive(Debug)] pub struct ModuleDeclaration { pub is_public: bool, pub identifier: Identifier, pub declarations: Vec, } #[derive(Debug)] pub struct InterfaceDeclaration { pub is_public: bool, pub identifier: Identifier, pub generics: GenericParameters, pub inputs: InputParameters, pub return_type: Option, pub implements: ImplementsList, pub declarations: Vec, } #[derive(Debug)] pub struct ClassDeclaration { pub is_public: bool, pub identifier: Identifier, pub generics: GenericParameters, pub class_constructor: Option, pub implements: ImplementsList, pub declarations: Vec, } // Type components #[derive(Debug)] pub struct TypeWhereGuards(pub Vec); #[derive(Debug)] pub struct TypeWhereGuard { pub identifier: Identifier, pub implements: TypeImplementsList, } #[derive(Debug)] pub struct TypeImplementsList(pub Vec); #[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); #[derive(Debug)] pub enum TypeGenericArgument { Underscore, FullyQualifiedName(FullyQualifiedName), Infer(Identifier), } #[derive(Debug)] pub struct TypeTupleArguments(pub Vec); #[derive(Debug)] pub enum TypeTupleArgument { Underscore, FullyQualifiedName(FullyQualifiedName), Infer(Identifier), EllipsisUnderscore, EllipsisInfer(Identifier), } #[derive(Debug)] pub struct TypeFunctionArguments { pub generics: TypeGenericArguments, pub parameters: TypeTupleArguments, pub return_type: ReturnType, } // Function declarations and components #[derive(Debug)] pub struct FunctionDeclaration { pub is_public: bool, pub modifier: Option, pub generics: GenericParameters, pub identifier: Identifier, pub parameters: Parameters, pub return_type: Option, pub body: FunctionBody, } #[derive(Debug)] pub struct OperatorFunctionDeclaration { pub is_public: bool, pub modifier: Option, pub generics: GenericParameters, pub operator: Operator, pub parameters: Parameters, pub return_type: Option, pub body: FunctionBody, } #[derive(Debug)] pub struct PlatformFunctionDeclaration { pub is_public: bool, pub modifier: Option, pub generics: GenericParameters, pub identifier: Identifier, pub parameters: Parameters, pub return_type: TypeUse, } #[derive(Debug)] pub struct InterfaceFunctionDeclaration { pub modifier: Option, pub generics: GenericParameters, pub identifier: Identifier, pub parameters: Parameters, pub return_type: ReturnType, pub body: Option, } #[derive(Debug)] pub struct InterfaceOperatorFunctionDeclaration { pub modifier: Option, pub generics: GenericParameters, pub operator: Operator, pub parameters: Parameters, pub return_type: ReturnType, pub body: Option, } #[derive(Debug)] pub enum FunctionBody { Equals(Expression), Block(BlockStatement), Alias(Identifier), } // Class components #[derive(Debug)] pub struct ClassConstructor(pub Vec); #[derive(Debug)] pub struct ClassConstructorParameter { pub is_field: bool, pub identifier: Identifier, pub declared_type: TypeUse, } #[derive(Debug)] pub struct FieldDeclaration { pub is_mutable: bool, pub identifier: Identifier, pub declared_type: TypeUse, } // Statements #[derive(Debug)] pub struct BlockStatement(pub Vec); #[derive(Debug)] pub enum Statement { BlockStatement(BlockStatement), VariableDeclarationStatement(VariableDeclarationStatement), AssignStatement(AssignStatement), CallStatement(CallExpression), ReturnStatement(ReturnStatement), IfStatement(IfStatement), IfElseStatement(IfElseStatement), WhileStatement(WhileStatement), ForStatement(ForStatement), } #[derive(Debug)] pub struct VariableDeclarationStatement { is_mutable: bool, identifier: Identifier, declared_type: Option, initializer: Option, } #[derive(Debug)] pub struct AssignStatement(pub AssignmentExpression); #[derive(Debug)] pub struct ReturnStatement(pub Option); #[derive(Debug)] pub struct IfStatement { pub condition: Expression, pub then_block: BlockStatement, } #[derive(Debug)] pub struct IfElseStatement { pub condition: Expression, pub then_block: BlockStatement, pub else_ifs: ElseIfs, pub else_block: BlockStatement, } #[derive(Debug)] pub struct ElseIfs(pub Vec); #[derive(Debug)] pub struct WhileStatement { pub condition: Expression, pub body: BlockStatement, } #[derive(Debug)] pub struct ForStatement { pub variable: Identifier, pub iterator: Expression, pub body: BlockStatement, } // Expressions #[derive(Debug)] pub enum Expression { Ternary(TernaryExpression), Binary(BinaryExpression), Unary(UnaryExpression), Assignment(Box), Call(CallExpression), Literal(Literal), } #[derive(Debug)] pub struct TernaryExpression { pub condition: Box, pub true_block: Box, pub false_block: Box, } #[derive(Debug)] pub struct BinaryExpression { pub left: Box, pub operator: BinaryOperator, pub right: Box, } #[derive(Debug)] pub struct UnaryExpression { pub lhs_operators: Vec, pub expression: Box, pub rhs_operators: Vec, } #[derive(Debug)] pub struct AssignmentExpression { identifier: Identifier, expression: Expression, } #[derive(Debug)] pub struct CallExpression { pub callee: Box, pub arguments: CallArguments, } #[derive(Debug)] pub struct CallArguments(pub Vec); #[derive(Debug)] pub struct CallArgument(pub Box); #[derive(Debug)] pub enum Literal { IntegerLiteral(i32), LongLiteral(i64), DoubleLiteral(f64), USizeLiteral(usize), StringLiteral(String), BooleanLiteral(bool), }