//! //! The AST module contains all structs and enums for the abstract syntax tree generated by the parser //! //! All AST nodes are bump allocated into the lifetime `'ast` use crate::{errors::Span, runtime::gc::Symbol}; #[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Ident { pub sym: Symbol, pub span: Span, } pub type Program<'ast> = Block<'ast>; #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Block<'ast> { pub stmts: &'ast [Stmt<'ast>], pub span: Span, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Stmt<'ast> { Declaration(Declaration<'ast>), Assignment(Assignment<'ast>), FnDecl(FnDecl<'ast>), If(IfStmt<'ast>), Loop(Block<'ast>, Span), While(WhileStmt<'ast>), Break(Span), Return(Option>, Span), Block(Block<'ast>), Expr(Expr<'ast>), Print(Expr<'ast>, Span), } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Declaration<'ast> { pub span: Span, pub name: Ident, pub init: Expr<'ast>, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Assignment<'ast> { pub span: Span, pub lhs: Expr<'ast>, pub rhs: Expr<'ast>, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct FnDecl<'ast> { pub span: Span, pub name: Ident, pub params: &'ast [Ident], pub body: Block<'ast>, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct IfStmt<'ast> { pub span: Span, pub cond: Expr<'ast>, pub body: Block<'ast>, pub else_part: Option<&'ast ElsePart<'ast>>, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum ElsePart<'ast> { Else(Block<'ast>, Span), ElseIf(IfStmt<'ast>, Span), } impl ElsePart<'_> { pub fn span(&self) -> Span { match self { ElsePart::Else(_, span) | ElsePart::ElseIf(_, span) => *span, } } } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct WhileStmt<'ast> { pub span: Span, pub cond: Expr<'ast>, pub body: Block<'ast>, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Expr<'ast> { Ident(Ident), Literal(Literal<'ast>), UnaryOp(&'ast UnaryOp<'ast>), BinaryOp(&'ast BinaryOp<'ast>), Call(&'ast Call<'ast>), } impl Expr<'_> { pub fn span(&self) -> Span { match self { Expr::Literal(lit) => lit.span(), Expr::UnaryOp(unary) => unary.span, Expr::BinaryOp(binary) => binary.span, Expr::Ident(Ident { span, .. }) => *span, Expr::Call(call) => call.span, } } } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum Literal<'ast> { String(Symbol, Span), Number(f64, Span), Array(&'ast [Expr<'ast>], Span), Object(Span), Boolean(bool, Span), Null(Span), } impl Literal<'_> { pub fn span(&self) -> Span { match self { Literal::String(_, span) | Literal::Number(_, span) | Literal::Array(_, span) | Literal::Object(span) | Literal::Boolean(_, span) | Literal::Null(span) => *span, } } } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct UnaryOp<'ast> { pub span: Span, pub expr: Expr<'ast>, pub kind: UnaryOpKind, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum UnaryOpKind { Not, Neg, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct BinaryOp<'ast> { pub span: Span, pub lhs: Expr<'ast>, pub rhs: Expr<'ast>, pub kind: BinaryOpKind, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum BinaryOpKind { And, Or, Equal, GreaterEqual, Greater, LessEqual, Less, NotEqual, Add, Sub, Mul, Div, Mod, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub struct Call<'ast> { pub callee: Expr<'ast>, pub span: Span, pub kind: CallKind<'ast>, } #[derive(Debug, PartialEq)] #[cfg_attr(feature = "_debug", derive(dbg_pls::DebugPls))] pub enum CallKind<'ast> { Field(Ident), Fn(&'ast [Expr<'ast>]), }