deimos-lang/src/ast/mod.rs
2025-05-14 19:24:59 -05:00

535 lines
10 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 Vec<Identifier>);
/* 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<FunctionTypeModifier>,
pub generics: GenericParameters,
pub parameters: Parameters,
pub return_type: ReturnType,
}
// Generic arguments
#[derive(Debug)]
pub struct GenericArguments(pub Vec<TypeUse>);
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<GenericParameter>);
impl GenericParameters {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for GenericParameters {
fn default() -> Self {
GenericParameters(Vec::new())
}
}
#[derive(Debug)]
pub struct GenericParameter(pub Identifier);
/* Tuple Arguments */
#[derive(Debug)]
pub struct TupleArguments(pub Vec<TypeUse>);
/* Implements List */
#[derive(Debug)]
pub struct ImplementsList(pub Vec<TypeUse>);
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 and Function Modifier */
#[derive(Debug)]
pub enum FunctionTypeModifier {
Cons,
MutRef,
Mut,
Ref,
}
/* Function Parameters */
#[derive(Debug)]
pub struct Parameters(pub Vec<Parameter>);
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 {
identifier: Identifier,
type_use: TypeUse,
}
/* Return Type */
#[derive(Debug)]
pub struct ReturnType {
pub declared_type: Box<TypeUse>,
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<Reference>);
impl References {
pub fn is_empty(&self) -> bool {
self.0.is_empty()
}
}
impl Default for References {
fn default() -> Self {
References(Vec::new())
}
}
#[derive(Debug)]
pub struct Reference(pub Identifier);
/* 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 {
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<ModuleLevelDeclaration>,
}
#[derive(Debug)]
pub struct InterfaceDeclaration {
pub is_public: bool,
pub identifier: Identifier,
pub generics: GenericParameters,
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>,
}
// Function declarations and components
#[derive(Debug)]
pub struct FunctionDefinition {
pub is_public: bool,
pub modifier: Option<FunctionModifier>,
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<FunctionModifier>,
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<FunctionModifier>,
pub generics: GenericParameters,
pub identifier: Identifier,
pub parameters: Parameters,
pub return_type: ReturnType,
}
#[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 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<ClassConstructorParameter>);
#[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<Statement>,
pub expression: Option<Expression>,
}
#[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 {
is_mutable: bool,
identifier: Identifier,
declared_type: Option<TypeUse>,
initializer: Option<Expression>,
}
#[derive(Debug)]
pub struct AssignStatement {
pub lhs: Expression,
pub rhs: Expression,
}
#[derive(Debug)]
pub struct CallStatement {
pub callee: Expression,
pub arguments: CallArguments
}
#[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),
Call(CallExpression),
FullyQualifiedName(FullyQualifiedName),
Closure(Closure),
ObjectAccess(ObjectAccess),
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 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 struct Closure {
}
#[derive(Debug)]
pub struct ObjectAccess {
pub receiver: Box<Expression>,
pub navigations: ObjectNavigations
}
#[derive(Debug)]
pub struct ObjectNavigations(pub Vec<ObjectNavigation>);
#[derive(Debug)]
pub enum ObjectNavigation {
Index(Box<Expression>),
Identifier(Box<Identifier>)
}
#[derive(Debug)]
pub enum Literal {
IntegerLiteral(i32),
LongLiteral(i64),
DoubleLiteral(f64),
USizeLiteral(usize),
StringLiteral(String),
BooleanLiteral(bool),
}