deimos-lang/src/ast/mod.rs
2025-05-14 10:04:31 -05:00

563 lines
11 KiB
Rust

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<Identifier>,
}
/* 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<TypeUse>,
}
#[derive(Debug)]
pub struct FunctionTypeUse {
pub borrow_count: usize,
pub function_modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub parameters: FunctionTypeParameters,
pub inputs: InputArguments,
pub return_type: ReturnType,
}
// 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: 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);
/* Function Type Parameters */
#[derive(Debug)]
pub struct FunctionTypeParameters(pub Vec<TypeUse>);
/* 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
#[derive(Debug)]
pub struct Parameters(pub Vec<Parameter>);
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<TypeUse>),
}
#[derive(Debug)]
pub struct References(pub Vec<Reference>);
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<InputParameter>);
#[derive(Debug)]
pub struct InputParameter(pub TypeUse);
// Implements
#[derive(Debug)]
pub struct ImplementsList(pub Vec<TypeUse>);
impl ImplementsList {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
// Top-level construct
#[derive(Debug)]
pub struct CompilationUnit {
pub namespace: Option<FullyQualifiedName>,
pub declarations: Vec<ModuleLevelDeclaration>,
}
// 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<ModuleLevelDeclaration>,
}
#[derive(Debug)]
pub struct InterfaceDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub generics: GenericParameters,
pub inputs: InputParameters,
pub return_type: Option<ReturnType>,
pub implements: ImplementsList,
pub declarations: Vec<InterfaceLevelDeclaration>,
}
#[derive(Debug)]
pub struct ClassDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub generics: GenericParameters,
pub class_constructor: Option<ClassConstructor>,
pub implements: ImplementsList,
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: TypeGenericArguments,
pub parameters: TypeTupleArguments,
pub return_type: ReturnType,
}
// Function declarations and components
#[derive(Debug)]
pub struct FunctionDeclaration {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: Option<ReturnType>,
pub body: FunctionBody,
}
#[derive(Debug)]
pub struct OperatorFunctionDeclaration {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub operator: Operator,
pub parameters: Parameters,
pub return_type: Option<ReturnType>,
pub body: FunctionBody,
}
#[derive(Debug)]
pub struct PlatformFunctionDeclaration {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: TypeUse,
}
#[derive(Debug)]
pub struct InterfaceFunctionDeclaration {
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: ReturnType,
pub body: Option<FunctionBody>,
}
#[derive(Debug)]
pub struct InterfaceOperatorFunctionDeclaration {
pub modifier: Option<FunctionModifier>,
pub generics: GenericParameters,
pub operator: Operator,
pub parameters: Parameters,
pub return_type: ReturnType,
pub body: Option<FunctionBody>,
}
#[derive(Debug)]
pub enum FunctionBody {
Equals(Expression),
Block(BlockStatement),
Alias(Identifier),
}
// Class components
#[derive(Debug)]
pub struct ClassConstructor(pub Vec<ClassConstructorParameter>);
#[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<Statement>);
#[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<TypeUse>,
initializer: Option<Expression>,
}
#[derive(Debug)]
pub struct AssignStatement(pub AssignmentExpression);
#[derive(Debug)]
pub struct ReturnStatement(pub Option<Expression>);
#[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<IfStatement>);
#[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<AssignmentExpression>),
Call(CallExpression),
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>,
pub operator: BinaryOperator,
pub right: Box<Expression>,
}
#[derive(Debug)]
pub struct UnaryExpression {
pub lhs_operators: Vec<PrefixUnaryOperator>,
pub expression: Box<Expression>,
pub rhs_operators: Vec<SuffixUnaryOperator>,
}
#[derive(Debug)]
pub struct AssignmentExpression {
identifier: Identifier,
expression: Expression,
}
#[derive(Debug)]
pub struct CallExpression {
pub callee: Box<Expression>,
pub arguments: CallArguments,
}
#[derive(Debug)]
pub struct CallArguments(pub Vec<CallArgument>);
#[derive(Debug)]
pub struct CallArgument(pub Box<Expression>);
#[derive(Debug)]
pub enum Literal {
IntegerLiteral(i32),
LongLiteral(i64),
DoubleLiteral(f64),
USizeLiteral(usize),
StringLiteral(String),
BooleanLiteral(bool),
}