Skip to main content

skullbrain_parser/ast/
mod.rs

1use cstree::{
2    interning::{Resolver, TokenKey},
3    text::TextRange,
4};
5
6mod _ast;
7mod span;
8
9pub use span::Span;
10
11/// Converts a concrete syntax tree (CST) node to its corresponding abstract syntax tree (AST) representation.
12pub trait ToAst {
13    /// The target AST type that this CST node converts to.
14    type Output;
15
16    /// Attempts to convert this CST node to its corresponding AST representation.
17    ///
18    /// Returns `Some(ast_node)` if the conversion is successful, or `None` if the
19    /// CST node cannot be represented in the AST (e.g., due to syntax errors or
20    /// unsupported constructs).
21    fn to_ast<I>(self, resolver: &I) -> Option<Self::Output>
22    where
23        I: Resolver<TokenKey> + ?Sized;
24}
25
26/// Core AST expression enum - simplified and semantic.
27#[derive(Debug, Clone, PartialEq)]
28pub enum Expr {
29    // Literals and identifiers
30    /// Literal value (numbers, strings, booleans)
31    Literal(Literal),
32    /// Variable or function identifier
33    Ident(Ident),
34
35    // Operators
36    /// Binary operation between two expressions (e.g., `a + b`, `x == y`)
37    Binary(BinaryExpr),
38    /// Unary operation on a single expression (e.g., `-x`, `!condition`)
39    Unary(UnaryExpr),
40
41    // Method chaining
42    /// Method call or property access (e.g., `obj.method()`, `obj.field`)
43    Chain(ChainExpr),
44
45    // Grouping
46    /// Parenthesized expression for precedence (e.g., `(a + b)`)
47    Paren(ParenExpr),
48    /// Block of statements/expressions (e.g., `{ stmt1; stmt2; expr }`)
49    Block(BlockExpr),
50
51    // Control flow
52    /// Break statement, optionally with a value (e.g., `break;`, `break value;`)
53    Break(Break),
54    /// Continue statement (e.g., `continue;`)
55    Continue(Continue),
56    /// Return statement, optionally with a value (e.g., `return;`, `return value;`)
57    Return(Return),
58    /// Throw statement with an exception value (e.g., `throw error;`)
59    Throw(Throw),
60
61    // Loops
62    /// While loop with condition and body (e.g., `while (condition) { body }`)
63    While(While),
64    /// For loop with iterator and body (e.g., `for (iterator) { body }`)
65    For(ForLoop),
66
67    // Conditionals
68    /// If/else conditional expression (e.g., `if (cond) { then } else { else }`)
69    If(IfElse),
70    /// MatchPat matching expression (e.g., `match expr { MatchPat => body }`)
71    Match(Match),
72
73    // Exception handling
74    /// Try-catch expression for exception handling (e.g., `try { code } catch (e) { handler }`)
75    TryCatch(TryCatch),
76
77    // Declarations (when used as expressions)
78    /// Variable declaration/definition (e.g., `let x: int = value;`)
79    Variable(VariableStmt),
80    /// Function declaration/definition (e.g., `fn add(a: int, b: int) -> int { a + b }`)
81    Function(Function),
82    /// Class declaration/definition (e.g., `class MyClass { fields, methods }`)
83    Class(Class),
84    /// Trait declaration/definition (e.g., `trait Drawable { fn draw(&self); }`)
85    Trait(Trait),
86    /// Trait implementation block (e.g., `impl Drawable for MyClass { ... }`)
87    TraitImpl(TraitImpl),
88    /// Enum declaration/definition (e.g., `enum Option<T> { Some(T), None }`)
89    Enum(Enum),
90    /// Type alias declaration (e.g., `type UserId = u64;`)
91    TypeAlias(TypeAlias),
92    /// Import statement (e.g., `import { items } from "module";`)
93    Import(ImportStmt),
94}
95
96/// Simplified literal representation in the abstract syntax tree.
97///
98/// Represents the basic literal values that can appear in expressions,
99#[derive(Debug, Clone, PartialEq)]
100pub struct Literal {
101    ///
102    span: TextRange,
103    ///
104    pub value: Value,
105}
106
107///
108#[derive(Debug, Clone, PartialEq)]
109pub enum Value {
110    /// Boolean literal (`true` or `false`)
111    Bool(bool),
112    /// Signed integer literal
113    Int(i64),
114    /// Double-precision floating point literal
115    Double(f64),
116    /// String literal
117    Str(String),
118}
119/// An identifier in the abstract syntax tree.
120///
121/// Represents a named identifier such as variable names, function names,
122/// or other symbolic references in the source code.
123#[derive(Debug, Clone, PartialEq)]
124pub struct Ident {
125    ///
126    span: TextRange,
127    /// The name of the identifier
128    pub name: String,
129}
130
131/// Binary operation expression in the abstract syntax tree.
132///
133/// Represents an expression with two operands and a binary operator,
134/// such as `a + b`, `x == y`, or `foo && bar`.
135#[derive(Debug, Clone, PartialEq)]
136pub struct BinaryExpr {
137    /// The left and right operands, boxed to reduce memory usage
138    operand: Box<(Expr, Expr)>,
139    /// The binary operator applied to the operands
140    pub op: BinaryOp,
141}
142
143impl BinaryExpr {
144    /// Returns a reference to the left operand of the binary expression.
145    pub const fn left(&self) -> &Expr {
146        &self.operand.0
147    }
148
149    /// Returns a reference to the right operand of the binary expression.
150    pub const fn right(&self) -> &Expr {
151        &self.operand.1 // Note: This should be .1, not .0
152    }
153
154    /// Returns a mutable reference to the left operand of the binary expression.
155    pub const fn left_mut(&mut self) -> &mut Expr {
156        &mut self.operand.0
157    }
158
159    /// Returns a mutable reference to the right operand of the binary expression.
160    pub const fn right_mut(&mut self) -> &mut Expr {
161        &mut self.operand.1
162    }
163}
164/// Binary operators available in expressions.
165///
166/// Represents the various binary operations that can be performed between two operands,
167/// organized by category for clarity.
168#[derive(Debug, Clone, PartialEq)]
169pub enum BinaryOp {
170    // Arithmetic operators
171    /// Addition operator (`+`)
172    Add,
173    /// Subtraction operator (`-`)
174    Sub,
175    /// Multiplication operator (`*`)
176    Mul,
177    /// Division operator (`/`)
178    Div,
179    /// Modulo operator (`%`)
180    Mod,
181
182    // Comparison operators
183    /// Equality operator (`==`)
184    Eq,
185    /// Inequality operator (`!=`)
186    NotEq,
187    /// Less than operator (`<`)
188    Lt,
189    /// Greater than operator (`>`)
190    Gt,
191    /// Less than or equal operator (`<=`)
192    LtEq,
193    /// Greater than or equal operator (`>=`)
194    GtEq,
195
196    // Logical operators
197    /// Logical AND operator (`&&`)
198    And,
199    /// Logical OR operator (`||`)
200    Or,
201}
202
203/// Unary operation expression in the abstract syntax tree.
204///
205/// Represents an expression with a single operand and a unary operator,
206/// such as `-x` (negation) or `!condition` (logical not).
207#[derive(Debug, Clone, PartialEq)]
208pub struct UnaryExpr {
209    /// The unary operator to apply
210    pub op: UnaryOp,
211    /// The operand expression, boxed to reduce memory usage
212    pub expr: Box<Expr>,
213}
214
215/// Unary operators available in expressions.
216///
217/// Represents the unary operations that can be performed on a single operand.
218#[derive(Debug, Clone, PartialEq)]
219pub enum UnaryOp {
220    /// Arithmetic negation operator (`-`)
221    Minus,
222    /// Logical NOT operator (`!`)
223    Not,
224}
225
226/// Method chaining expression in the abstract syntax tree.
227///
228/// Represents method invocation or property access on an object,
229/// such as `obj.method()` or `obj.property`.
230#[derive(Debug, Clone, PartialEq)]
231pub struct ChainExpr {
232    /// The object and method/property pair, boxed to reduce memory usage
233    data: Box<(Expr, Expr)>,
234}
235
236impl ChainExpr {
237    /// Returns a reference to the object being accessed.
238    pub const fn object(&self) -> &Expr {
239        &self.data.0
240    }
241
242    /// Returns a reference to the method or property being accessed.
243    pub const fn method(&self) -> &Expr {
244        &self.data.1 // Note: This should be .1, not .0
245    }
246
247    /// Returns a mutable reference to the object being accessed.
248    pub const fn object_mut(&mut self) -> &mut Expr {
249        &mut self.data.0
250    }
251
252    /// Returns a mutable reference to the method or property being accessed.
253    pub const fn method_mut(&mut self) -> &mut Expr {
254        &mut self.data.1 // Note: This should be .1, not .0
255    }
256}
257/// Parenthesized expression in the abstract syntax tree.
258///
259/// Represents an expression wrapped in parentheses, such as `(x + y)`.
260/// While parentheses don't change the semantic meaning, they can affect
261/// operator precedence and are sometimes preserved for clarity.
262#[derive(Debug, Clone, PartialEq)]
263pub struct ParenExpr {
264    ///
265    span: TextRange,
266
267    /// The expression contained within the parentheses
268    pub expr: Box<Expr>,
269}
270
271/// Block expression in the abstract syntax tree.
272///
273/// Represents a sequence of statements or expressions enclosed in braces,
274/// such as `{ stmt1; stmt2; expr }`. The last expression in the block
275/// is typically the block's value.
276#[derive(Debug, Clone, PartialEq)]
277pub struct BlockExpr {
278    ///
279    pub span: TextRange,
280    /// The statements and expressions within the block
281    pub statements: Box<[Expr]>,
282}
283
284/// Break statement in the abstract syntax tree.
285///
286/// Represents a break statement that exits from a loop, optionally
287/// with a value, such as `break;` or `break value;`.
288#[derive(Debug, Clone, PartialEq)]
289pub struct Break {
290    ///
291    span: TextRange,
292    /// Optional value to break with
293    pub value: Option<Box<Expr>>,
294}
295
296/// Continue statement in the abstract syntax tree.
297///
298/// Represents a continue statement that skips to the next iteration
299/// of a loop, such as `continue;`.
300#[derive(Debug, Clone, PartialEq)]
301pub struct Continue {
302    ///
303    span: TextRange,
304}
305
306/// Return statement in the abstract syntax tree.
307///
308/// Represents a return statement that exits from a function, optionally
309/// with a value, such as `return;` or `return value;`.
310#[derive(Debug, Clone, PartialEq)]
311pub struct Return {
312    ///
313    span: TextRange,
314    /// Optional value to return
315    pub value: Option<Box<Expr>>,
316}
317
318/// Throw statement in the abstract syntax tree.
319///
320/// Represents a throw statement that raises an exception with the given value,
321/// such as `throw error;`.
322#[derive(Debug, Clone, PartialEq)]
323pub struct Throw {
324    ///
325    span: TextRange,
326    /// The value/exception to throw
327    pub value: Box<Expr>,
328}
329
330/// While loop expression in the abstract syntax tree.
331///
332/// Represents a while loop with a condition and body, such as
333/// `while (condition) { body }`.
334#[derive(Debug, Clone, PartialEq)]
335pub struct While {
336    ///
337    span: TextRange,
338    /// The loop condition wrapped in parentheses
339    pub condition: ParenExpr,
340    /// The loop body
341    pub body: BlockExpr,
342}
343
344/// For loop expression in the abstract syntax tree.
345///
346/// Represents a for loop with an iterator expression and body, such as
347/// `for (iterator) { body }`.
348#[derive(Debug, Clone, PartialEq)]
349pub struct ForLoop {
350    ///
351    span: TextRange,
352    /// The iterator expression wrapped in parentheses
353    pub iterator: ParenExpr,
354    /// The loop body
355    pub body: BlockExpr,
356}
357
358/// If expression in the abstract syntax tree.
359///
360/// Represents conditional branching with if/else if/else chains, such as
361/// `if (condition) { then_branch } else if (condition2) { branch2 } else { final_branch }`.
362#[derive(Debug, Clone, PartialEq)]
363pub struct IfElse {
364    ///
365    span: TextRange,
366
367    /// The primary condition wrapped in parentheses
368    pub condition: ParenExpr,
369    /// The block to execute when the condition is true
370    pub then_branch: BlockExpr,
371    /// Optional chain of else-if and else branches
372    pub else_branches: Option<Box<[ElseBranch]>>,
373}
374
375/// A single else or else-if branch in an if expression.
376///
377/// Represents either an `else if (condition) { block }` branch (when condition is Some)
378/// or a final `else { block }` branch (when condition is None).
379#[derive(Debug, Clone, PartialEq)]
380pub struct ElseBranch {
381    ///
382    span: TextRange,
383
384    /// The condition for else-if branches, None for final else branch
385    pub condition: Option<ParenExpr>,
386    /// The block to execute for this branch
387    pub then_branch: BlockExpr,
388}
389
390/// Match expression in the abstract syntax tree.
391///
392/// Represents MatchPat matching against an expression with multiple arms,
393/// such as `match expr { MatchPat1 => body1, MatchPat2 => body2 }`.
394#[derive(Debug, Clone, PartialEq)]
395pub struct Match {
396    ///
397    span: TextRange,
398
399    /// The expression being matched against
400    pub expr: ParenExpr,
401    /// The match arms containing MatchPats and their corresponding bodies
402    pub arms: Box<[MatchArm]>,
403}
404
405/// A single arm in a match expression.
406///
407/// Represents one MatchPat-body pair in a match expression,
408/// such as `MatchPat => body`.
409#[derive(Debug, Clone, PartialEq)]
410pub struct MatchArm {
411    /// The MatchPat to match against
412    pub pat: Option<MatchPat>,
413    /// The expression to evaluate when the MatchPat matches
414    pub body: BlockExpr,
415}
416/// MatchPat for matching in match expressions and other MatchPat contexts.
417///
418/// Represents the various MatchPats that can be used to match against values
419/// in MatchPat matching constructs like match expressions.
420#[derive(Debug, Clone, PartialEq)]
421pub enum MatchPat {
422    /// Literal MatchPat that matches a specific literal value
423    Literal(Literal),
424    ///
425    Ident(Ident),
426}
427
428/// Try-catch expression in the abstract syntax tree.
429///
430/// Represents exception handling with a try block and optional catch arms,
431/// such as `try { risky_code } catch (ErrorType e) { handle_error }`.
432#[derive(Debug, Clone, PartialEq)]
433pub struct TryCatch {
434    ///
435    span: TextRange,
436    /// The block of code that might throw an exception
437    pub try_block: BlockExpr,
438    /// Optional catch arms for handling different exception types
439    pub catch_arms: Option<Box<[CatchArm]>>,
440}
441
442/// A single catch arm in a try-catch expression.
443///
444/// Represents one exception handler that catches a specific type of exception
445/// and executes a corresponding block of code.
446#[derive(Debug, Clone, PartialEq)]
447pub struct CatchArm {
448    ///
449    span: TextRange,
450    /// The type of exception this arm catches
451    pub catch_ty: Option<CatchType>,
452    /// The block of code to execute when this exception is caught
453    pub body: BlockExpr,
454}
455
456/// Exception type specification for catch arms.
457///
458/// Specifies both the type of exception to catch and the variable name
459/// to bind the caught exception to within the catch block.
460#[derive(Debug, Clone, PartialEq)]
461pub struct CatchType {
462    ///
463    span: TextRange,
464    /// The type of exception to catch
465    pub ty: Type,
466    /// The variable name to bind the caught exception to
467    pub name: Ident,
468}
469
470/// Type representation in the abstract syntax tree.
471///
472/// Represents the various types that can appear in type annotations,
473/// function signatures, and other type contexts.
474#[derive(Debug, Clone, PartialEq)]
475pub enum Type {
476    /// A simple identifier type (e.g., `String`, `MyClass`)
477    Ident(Ident),
478    /// A function type with its signature (e.g., `(int, string) -> bool`)
479    Function(FunctionSignature),
480}
481
482/// Variable declaration/expression in the abstract syntax tree.
483///
484/// Represents variable declarations with optional type annotations and initializers,
485/// such as `let mut x: int = { compute_value() }`.
486#[derive(Debug, Clone, PartialEq)]
487pub struct VariableStmt {
488    ///
489    span: TextRange,
490
491    /// Whether the variable is mutable
492    pub is_mutable: bool,
493    /// Access modifiers (public, private, etc.)
494    pub modifiers: Modifiers,
495    /// The variable name
496    pub name: Ident,
497    /// Optional type annotation
498    pub ty_annotation: Option<Type>,
499    /// The initialization expression
500    pub initializer: BlockExpr,
501}
502
503/// Function declaration/expression in the abstract syntax tree.
504///
505/// Represents function definitions with their signature, modifiers, and body,
506/// such as `pub fn add(a: int, b: int) -> int { a + b }`.
507#[derive(Debug, Clone, PartialEq)]
508pub struct Function {
509    ///
510    span: TextRange,
511
512    /// Access modifiers (public, private, static, etc.)
513    pub modifiers: Modifiers,
514    /// The function name
515    pub name: Ident,
516    /// The function signature (parameters and return type)
517    pub signature: FunctionSignature,
518    /// The function body
519    pub body: BlockExpr,
520}
521
522/// Function signature specification.
523///
524/// Defines the parameters and return type of a function without the body.
525#[derive(Debug, Clone, PartialEq)]
526pub struct FunctionSignature {
527    ///
528    span: TextRange,
529    /// The function parameters
530    pub parameters: Box<[Parameter]>,
531    /// Optional return type (None for void functions)
532    pub return_type: Option<Box<Type>>,
533}
534
535/// Function parameter specification.
536///
537/// Represents a single parameter in a function signature with its name and type.
538#[derive(Debug, Clone, PartialEq)]
539pub struct Parameter {
540    /// The parameter name
541    pub name: Ident,
542    /// The parameter type
543    pub ty: Type,
544}
545
546/// Class declaration/expression in the abstract syntax tree.
547///
548/// Represents class definitions with their members and nested implementations,
549/// such as `pub class MyClass { fields, methods, etc. }`.
550#[derive(Debug, Clone, PartialEq)]
551pub struct Class {
552    ///
553    span: TextRange,
554
555    /// Access modifiers (public, abstract, etc.)
556    pub modifiers: Modifiers,
557    /// The class name
558    pub name: Ident,
559    /// The class members (fields, methods, etc.)
560    pub members: MemberConstructions,
561    /// Nested trait implementations within the class
562    pub nested_impls: Box<[TraitImpl]>,
563}
564
565/// Collection of member constructions for classes, traits, and enums.
566///
567/// Groups together all the different types of members that can appear
568/// within a class, trait, or enum definition.
569#[derive(Debug, Clone, PartialEq)]
570pub struct MemberConstructions<T = Function> {
571    /// Implicit initialization expressions
572    pub implicit_inits: Box<[Expr]>,
573    /// Method definitions
574    pub methods: Box<[T]>,
575    /// Field declarations
576    pub fields: Box<[VariableStmt]>,
577    /// Type aliases defined within this scope
578    pub aliasz: Box<[TypeAlias]>,
579}
580
581/// Trait declaration/expression in the abstract syntax tree.
582///
583/// Represents trait definitions that specify a contract of methods and types,
584/// such as `pub trait Drawable { fn draw(&self); }`.
585#[derive(Debug, Clone, PartialEq)]
586pub struct Trait {
587    ///
588    span: TextRange,
589
590    /// Access modifiers (public, etc.)
591    pub modifiers: Modifiers,
592    /// The trait name
593    pub name: Ident,
594    /// The trait members (method signatures, associated types, etc.)
595    pub members: MemberConstructions<FunctionItem>,
596}
597
598/// Function declaration/expression in the abstract syntax tree.
599#[derive(Debug, Clone, PartialEq)]
600pub struct FunctionItem {
601    ///
602    span: TextRange,
603
604    /// Access modifiers (public, private, static, etc.)
605    pub modifiers: Modifiers,
606    /// The function name
607    pub name: Ident,
608    /// The function signature (parameters and return type)
609    pub signature: FunctionSignature,
610    /// The function body
611    pub body: Option<BlockExpr>,
612}
613
614/// Trait implementation block.
615///
616/// Represents the implementation of trait methods and associated items,
617/// providing concrete implementations for trait requirements.
618#[derive(Debug, Clone, PartialEq)]
619pub struct TraitImpl {
620    ///
621    span: TextRange,
622
623    /// The implemented members (method bodies, type definitions, etc.)
624    pub members: MemberConstructions,
625}
626
627/// Enum declaration/expression in the abstract syntax tree.
628///
629/// Represents enumeration types with variants and associated members,
630/// such as `pub enum Option<T> { Some(T), None }`.
631#[derive(Debug, Clone, PartialEq)]
632pub struct Enum {
633    ///
634    span: TextRange,
635
636    /// Access modifiers (public, etc.)
637    pub modifiers: Modifiers,
638    /// The enum name
639    pub name: Ident,
640    /// The enum variants
641    pub variants: Box<[EnumVariant]>,
642    /// Associated members (methods, constants, etc.)
643    pub members: MemberConstructions,
644    /// Nested trait implementations for the enum
645    pub nested_impls: Box<[TraitImpl]>,
646}
647
648/// A single variant in an enum definition.
649///
650/// Represents one possible value of an enumeration, optionally with associated data,
651/// such as `Some(T)` or `Error { code: int, message: string }`.
652#[derive(Debug, Clone, PartialEq)]
653pub struct EnumVariant {
654    /// The variant name
655    pub name: Ident,
656    /// Optional fields associated with this variant
657    pub fields: Option<Box<[EnumVariantField]>>,
658}
659
660/// A named field within an enum variant.
661#[derive(Debug, Clone, PartialEq)]
662pub struct EnumVariantField {
663    /// The name of the field
664    pub name: Ident,
665    /// The type of the field
666    pub ty: Type,
667}
668
669/// Type alias declaration/expression in the abstract syntax tree.
670///
671/// Represents type aliases that create alternative names for existing types,
672/// such as `pub type UserId = u64;`.
673#[derive(Debug, Clone, PartialEq)]
674pub struct TypeAlias {
675    ///
676    span: TextRange,
677
678    /// Access modifiers (public, etc.)
679    pub modifiers: Modifiers,
680    /// The alias name
681    pub name: Ident,
682    /// The type being aliased
683    pub aliased_type: Type,
684}
685
686/// Import statement in the abstract syntax tree.
687///
688/// Represents module imports that bring external items into scope,
689/// such as `import { foo, bar } from "module";`.
690#[derive(Debug, Clone, PartialEq)]
691pub struct ImportStmt {
692    ///
693    span: TextRange,
694
695    /// The source module or file path
696    pub source: String,
697    /// The specific items to import from the source
698    pub items: Box<[Ident]>,
699}
700
701bitflags::bitflags! {
702    /// Represents various modifiers that can be applied to functions, classes, variables,
703    /// and other declarations to control their visibility, accessibility, and behavior.
704
705    #[derive(Debug, Clone, PartialEq)]
706    pub struct Modifiers : u8 {
707        /// Public visibility modifier.
708        ///
709        /// Makes the declaration accessible from outside its defining module
710        const Public = 0b00000001;
711
712          /// Instance access modifier.
713        ///
714        /// Indicates that the declaration requires instance access (non-static).
715        const InstanceAccess = 0b00000010;
716    }
717}