use crate::name_analysis::symbol::Symbol; use pest::Parser; use std::range::Range; pub mod build; pub mod named; pub mod pretty_print; 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, BorrowMut, Borrow, Mut, Not, Negative, } #[derive(Debug)] pub enum SuffixUnaryOperator { PlusPlus, MinusMinus, } /* Names */ #[derive(Debug, Clone)] pub struct Identifier { pub name: String, pub file_id: usize, pub range: Range, scope_id: Option, symbol: Option, } impl Identifier { pub fn new(name: &str, file_id: usize, range: Range) -> Self { Identifier { name: name.to_string(), file_id, range, scope_id: None, symbol: None, } } pub fn set_scope_id(&mut self, id: usize) { self.scope_id = Some(id); } pub fn scope_id(&self) -> Option { self.scope_id } pub fn set_symbol(&mut self, symbol: Symbol) { self.symbol = Some(symbol); } pub fn symbol(&self) -> &Option { &self.symbol } } #[derive(Debug)] pub struct FullyQualifiedName { pub identifiers: Vec, pub file_id: usize, pub range: Range, scope_id: Option, symbol: Option, } impl FullyQualifiedName { pub fn new(identifiers: Vec, file_id: usize, range: Range) -> Self { FullyQualifiedName { identifiers, range, file_id, scope_id: None, symbol: None, } } pub fn set_scope_id(&mut self, scope_id: usize) { self.scope_id = Some(scope_id); } pub fn scope_id(&self) -> Option { self.scope_id } pub fn set_symbol(&mut self, symbol: Symbol) { self.symbol = Some(symbol); } pub fn symbol(&self) -> &Option { &self.symbol } } /* Type Use */ #[derive(Debug)] pub enum TypeUse { Void, InterfaceOrClass(InterfaceOrClassTypeUse), Tuple(TupleTypeUse), Function(FunctionTypeUse), } #[derive(Debug)] pub struct InterfaceOrClassTypeUse { pub borrow_count: usize, pub is_mutable: bool, pub fqn: FullyQualifiedName, pub generics: GenericArguments, } #[derive(Debug)] pub struct TupleTypeUse { pub borrow_count: usize, pub is_mutable: bool, pub arguments: TupleArguments, } #[derive(Debug)] pub struct FunctionTypeUse { pub borrow_count: usize, pub function_modifier: Option, pub generics: GenericParameters, pub parameters: Parameters, 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() } } impl Default for GenericArguments { fn default() -> Self { GenericArguments(Vec::new()) } } /* Generic parameters */ #[derive(Debug)] pub struct GenericParameters(pub Vec); impl GenericParameters { pub fn is_empty(&self) -> bool { self.0.is_empty() } } impl Default for GenericParameters { fn default() -> Self { GenericParameters(Vec::new()) } } /* Tuple Arguments */ #[derive(Debug)] pub struct TupleArguments(pub Vec); /* Implements List */ #[derive(Debug)] pub struct ImplementsList(pub Vec); impl ImplementsList { pub fn is_empty(&self) -> bool { self.0.is_empty() } } impl Default for ImplementsList { fn default() -> Self { ImplementsList(Vec::new()) } } /* Function Type Modifier */ #[derive(Debug)] pub enum FunctionTypeModifier { Cons, MutRef, Mut, Ref, } /* Function Parameters */ #[derive(Debug)] pub struct Parameters(pub Vec); impl Parameters { pub fn is_empty(&self) -> bool { self.0.is_empty() } } impl Default for Parameters { fn default() -> Self { Parameters(Vec::new()) } } #[derive(Debug)] pub struct Parameter { pub identifier: Identifier, pub type_use: TypeUse, } /* Return Type */ #[derive(Debug)] pub struct ReturnType { pub declared_type: Box, pub references: References, } impl ReturnType { pub fn void() -> Self { ReturnType { declared_type: Box::new(TypeUse::Void), references: References::default(), } } } /* References */ #[derive(Debug)] pub struct References(pub Vec); impl References { pub fn is_empty(&self) -> bool { self.0.is_empty() } } impl Default for References { fn default() -> Self { References(Vec::new()) } } /* Top-level construct */ #[derive(Debug)] pub struct CompilationUnit { pub namespace: Option, pub declarations: Vec, } // Declarations allowed in each level #[derive(Debug)] pub enum ModuleLevelDeclaration { Module(ModuleDeclaration), Interface(InterfaceDeclaration), Class(ClassDeclaration), Function(FunctionDefinition), PlatformFunction(PlatformFunctionDeclaration), } #[derive(Debug)] pub enum InterfaceLevelDeclaration { Module(ModuleDeclaration), Interface(InterfaceDeclaration), Class(ClassDeclaration), Function(InterfaceFunctionDeclaration), OperatorFunction(InterfaceOperatorFunctionDeclaration), } #[derive(Debug)] pub enum ClassLevelDeclaration { Module(ModuleDeclaration), Interface(InterfaceDeclaration), Class(ClassDeclaration), Function(FunctionDefinition), OperatorFunction(OperatorFunctionDefinition), PlatformFunction(PlatformFunctionDeclaration), Property(PropertyDeclaration), Field(FieldDeclaration), } // Declarations #[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 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, } // Function declarations and components #[derive(Debug)] pub struct FunctionDefinition { pub is_public: bool, pub modifier: Option, pub generics: GenericParameters, pub identifier: Identifier, pub parameters: Parameters, pub return_type: ReturnType, pub body: FunctionBody, } #[derive(Debug)] pub struct OperatorFunctionDefinition { pub is_public: bool, pub modifier: Option, pub generics: GenericParameters, pub operator: Operator, pub parameters: Parameters, pub return_type: ReturnType, 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: ReturnType, } #[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 FunctionModifier { Static, Cons, Mut, Ref, MutRef, } #[derive(Debug)] pub enum FunctionBody { Equals(Expression), Block(BlockStatement), Alias(Identifier), } // Class components #[derive(Debug)] pub struct ClassConstructor(pub Vec); #[derive(Debug)] pub enum ClassConstructorParameter { Property(PropertyDeclaration), Field(FieldDeclaration), } #[derive(Debug)] pub struct PropertyDeclaration { pub is_mutable: 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 statements: Vec, pub expression: Option, } #[derive(Debug)] pub enum Statement { BlockStatement(BlockStatement), VariableDeclarationStatement(VariableDeclarationStatement), AssignStatement(AssignStatement), CallStatement(CallStatement), ReturnStatement(ReturnStatement), IfStatement(IfStatement), IfElseStatement(IfElseStatement), WhileStatement(WhileStatement), ForStatement(ForStatement), } #[derive(Debug)] pub struct VariableDeclarationStatement { pub is_mutable: bool, pub identifier: Identifier, pub declared_type: Option, pub initializer: Option, } #[derive(Debug)] pub struct AssignStatement { pub lhs: Expression, pub rhs: Expression, } #[derive(Debug)] pub struct CallStatement(pub Expression); #[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 if_statement: IfStatement, pub else_ifs: ElseIfs, pub else_block: Option, } #[derive(Debug, Default)] pub struct ElseIfs(pub Vec); #[derive(Debug)] pub struct ElseBlock(pub BlockStatement); #[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), UnaryPrefix(PrefixExpression), UnarySuffix(SuffixExpression), Call(CallExpression), ObjectAccess(ObjectAccess), Literal(Literal), FullyQualifiedName(FullyQualifiedName), Closure(Closure), } #[derive(Debug)] pub struct TernaryExpression { pub condition: Box, pub true_expression: Box, pub false_expression: Box, } #[derive(Debug)] pub struct BinaryExpression { pub left: Box, pub operator: BinaryOperator, pub right: Box, } #[derive(Debug)] pub struct PrefixExpression { pub operator: PrefixUnaryOperator, pub expression: Box, } #[derive(Debug)] pub struct SuffixExpression { expression: Box, operator: SuffixUnaryOperator, } #[derive(Debug)] pub struct CallExpression { pub callee: Box, pub turbo_fish: Option, pub arguments: CallArguments, } #[derive(Debug)] pub struct TurboFish(pub GenericArguments); #[derive(Debug)] pub struct CallArguments(pub Vec); #[derive(Debug)] pub struct CallArgument(pub Box); #[derive(Debug)] pub struct Closure { pub modifier: Option, pub is_move: bool, pub captures: ClosureCaptures, pub parameters: ClosureParameters, pub statements: Vec, pub expression: Option>, } #[derive(Debug)] pub enum ClosureModifier { Cons, Mut, } #[derive(Debug, Default)] pub struct ClosureCaptures(pub Vec); impl ClosureCaptures { pub fn is_empty(&self) -> bool { self.0.is_empty() } } #[derive(Debug)] pub struct ClosureCapture { pub borrow_count: usize, pub is_mutable: bool, pub identifier: Box, } #[derive(Debug, Default)] pub struct ClosureParameters(pub Vec); impl ClosureParameters { pub fn is_empty(&self) -> bool { self.0.is_empty() } } #[derive(Debug)] pub struct ClosureParameter { pub identifier: Identifier, pub type_use: Option, } #[derive(Debug)] pub struct ObjectAccess { pub receiver: Box, pub navigations: ObjectNavigations, } #[derive(Debug)] pub struct ObjectNavigations(pub Vec); #[derive(Debug)] pub enum ObjectNavigation { Index(Box), Identifier(Box), } #[derive(Debug)] pub enum Literal { Integer(i32), Long(i64), Double(f64), USize(usize), String(String), DString(DString), BacktickString(DString), Boolean(bool), } #[derive(Debug)] pub struct DString(pub Vec); #[derive(Debug)] pub enum DStringPart { String(String), Expression(Box), } impl DStringPart { pub fn from_string(s: &str) -> DStringPart { DStringPart::String(String::from(s)) } pub fn from_expression(e: Expression) -> DStringPart { DStringPart::Expression(Box::new(e)) } pub fn is_string(&self) -> bool { match self { DStringPart::String(_) => true, _ => false, } } pub fn unwrap_string(self) -> String { match self { DStringPart::String(s) => s, _ => panic!(), } } pub fn is_expression(&self) -> bool { match self { DStringPart::Expression(_) => true, _ => false, } } }