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}