Skip to main content

oak_elixir/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2use core::range::Range;
3
4use std::{boxed::Box, string::String, vec::Vec};
5
6use crate::ElixirTokenType;
7
8/// Represents an identifier in the Elixir AST.
9///
10/// An identifier is a name used to refer to variables, functions, modules, or other entities.
11#[derive(Debug, PartialEq, Eq, Clone)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct Identifier {
14    /// The name of the identifier.
15    pub name: String,
16    /// The source code span where this identifier appears.
17    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
18    pub span: Range<usize>,
19}
20
21/// The root node of the Elixir AST.
22#[derive(Debug, PartialEq, Clone)]
23#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
24pub struct ElixirRoot {
25    /// The collection of top-level items in the Elixir source.
26    pub items: Vec<Item>,
27}
28
29/// Top-level item: Module, function, or statement
30#[derive(Debug, PartialEq, Clone)]
31#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
32pub enum Item {
33    /// A module definition containing nested items.
34    Module(Module),
35    /// A function definition.
36    Function(Function),
37    /// A standalone statement.
38    Statement(Statement),
39}
40
41/// Represents an Elixir module definition.
42///
43/// A module is a container for functions, types, and other items.
44#[derive(Debug, PartialEq, Clone)]
45#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
46pub struct Module {
47    /// The name of the module.
48    pub name: Identifier,
49    /// The items contained within the module.
50    pub items: Vec<Item>,
51    /// The source code span where this module appears.
52    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
53    pub span: Range<usize>,
54}
55
56/// Represents an Elixir function definition.
57///
58/// A function consists of a name, parameters, and a body.
59#[derive(Debug, PartialEq, Clone)]
60#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
61pub struct Function {
62    /// The name of the function.
63    pub name: Identifier,
64    /// The parameters accepted by the function.
65    pub params: Vec<Param>,
66    /// The body of the function.
67    pub body: Block,
68    /// The source code span where this function appears.
69    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
70    pub span: Range<usize>,
71}
72
73/// Represents a function parameter.
74///
75/// A parameter has a name and an optional type specification.
76#[derive(Debug, PartialEq, Clone)]
77#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
78pub struct Param {
79    /// The name of the parameter.
80    pub name: Identifier,
81    /// The optional type annotation for the parameter.
82    pub ty: Option<String>,
83    /// The source code span where this parameter appears.
84    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
85    pub span: Range<usize>,
86}
87
88/// Represents a block of statements.
89///
90/// A block is a sequence of statements that are executed in order.
91#[derive(Debug, PartialEq, Clone)]
92#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
93pub struct Block {
94    /// The statements contained in this block.
95    pub statements: Vec<Statement>,
96    /// The source code span where this block appears.
97    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
98    pub span: Range<usize>,
99}
100
101/// Represents a statement in the Elixir AST.
102///
103/// A statement is an executable unit of code that does not produce a value.
104#[derive(Debug, PartialEq, Clone)]
105#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
106pub enum Statement {
107    /// A variable binding statement (let binding).
108    Let {
109        /// The name of the variable being bound.
110        name: Identifier,
111        /// The expression whose value is bound to the variable.
112        expr: Expr,
113        /// The source code span where this statement appears.
114        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
115        span: Range<usize>,
116    },
117    /// An expression statement.
118    ExprStmt {
119        /// The expression being evaluated.
120        expr: Expr,
121        /// The source code span where this statement appears.
122        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
123        span: Range<usize>,
124    },
125}
126
127/// Represents an expression in the Elixir AST.
128///
129/// An expression is a unit of code that produces a value when evaluated.
130#[derive(Debug, PartialEq, Clone)]
131#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
132pub enum Expr {
133    /// An identifier expression.
134    Ident(Identifier),
135    /// An atom literal.
136    Atom {
137        /// The value of the atom.
138        value: String,
139        /// The source code span where this atom appears.
140        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
141        span: Range<usize>,
142    },
143    /// A numeric literal.
144    Number {
145        /// The value of the number as a string.
146        value: String,
147        /// The source code span where this number appears.
148        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
149        span: Range<usize>,
150    },
151    /// A string literal.
152    String {
153        /// The value of the string.
154        value: String,
155        /// The source code span where this string appears.
156        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
157        span: Range<usize>,
158    },
159    /// A boolean literal.
160    Bool {
161        /// The boolean value.
162        value: bool,
163        /// The source code span where this boolean appears.
164        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
165        span: Range<usize>,
166    },
167    /// A unary expression.
168    Unary {
169        /// The unary operator.
170        op: ElixirTokenType,
171        /// The operand expression.
172        expr: Box<Expr>,
173        /// The source code span where this expression appears.
174        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
175        span: Range<usize>,
176    },
177    /// A binary expression.
178    Binary {
179        /// The left operand.
180        left: Box<Expr>,
181        /// The binary operator.
182        op: ElixirTokenType,
183        /// The right operand.
184        right: Box<Expr>,
185        /// The source code span where this expression appears.
186        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
187        span: Range<usize>,
188    },
189    /// A pattern match expression.
190    Match {
191        /// The left-hand side pattern.
192        left: Box<Expr>,
193        /// The right-hand side expression.
194        right: Box<Expr>,
195        /// The source code span where this expression appears.
196        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
197        span: Range<usize>,
198    },
199    /// A function call expression.
200    Call {
201        /// The expression being called.
202        callee: Box<Expr>,
203        /// The arguments passed to the function.
204        args: Vec<Expr>,
205        /// The source code span where this expression appears.
206        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
207        span: Range<usize>,
208    },
209    /// A field access expression.
210    Field {
211        /// The receiver expression.
212        receiver: Box<Expr>,
213        /// The field being accessed.
214        field: Identifier,
215        /// The source code span where this expression appears.
216        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
217        span: Range<usize>,
218    },
219    /// A module attribute expression.
220    Attribute {
221        /// The name of the attribute.
222        name: Identifier,
223        /// The source code span where this attribute appears.
224        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
225        span: Range<usize>,
226    },
227    /// An index access expression.
228    Index {
229        /// The receiver expression.
230        receiver: Box<Expr>,
231        /// The index expression.
232        index: Box<Expr>,
233        /// The source code span where this expression appears.
234        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
235        span: Range<usize>,
236    },
237    /// A parenthesized expression.
238    Paren {
239        /// The inner expression.
240        expr: Box<Expr>,
241        /// The source code span where this expression appears.
242        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
243        span: Range<usize>,
244    },
245    /// A list literal.
246    List {
247        /// The elements of the list.
248        items: Vec<Expr>,
249        /// The source code span where this list appears.
250        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
251        span: Range<usize>,
252    },
253    /// A tuple literal.
254    Tuple {
255        /// The elements of the tuple.
256        items: Vec<Expr>,
257        /// The source code span where this tuple appears.
258        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
259        span: Range<usize>,
260    },
261    /// A map literal.
262    Map {
263        /// The key-value pairs of the map.
264        items: Vec<Expr>,
265        /// The source code span where this map appears.
266        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
267        span: Range<usize>,
268    },
269    /// A block expression.
270    Block(Block),
271}