Skip to main content

oak_erlang/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2use core::range::Range;
3use std::{boxed::Box, string::String, vec::Vec};
4
5use crate::lexer::token_type::ErlangTokenType;
6
7/// Erlang AST root.
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9#[derive(Debug, PartialEq, Clone)]
10pub struct ErlangRoot {
11    /// Items in the module.
12    pub items: Vec<Item>,
13}
14
15/// An identifier in Erlang.
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17#[derive(Debug, PartialEq, Eq, Clone)]
18pub struct Identifier {
19    /// Name of the identifier.
20    pub name: String,
21    /// Source span of the identifier.
22    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
23    pub span: Range<usize>,
24}
25
26/// Top-level items: modules, functions, attributes, etc.
27#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
28#[derive(Debug, PartialEq, Clone)]
29pub enum Item {
30    /// Module declaration.
31    Module(Module),
32    /// Function declaration.
33    Function(Function),
34    /// Attribute declaration.
35    Attribute(Attribute),
36    /// Export declaration.
37    Export(Export),
38}
39
40/// A module declaration.
41#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
42#[derive(Debug, PartialEq, Clone)]
43pub struct Module {
44    /// Name of the module.
45    pub name: Identifier,
46    /// Source span of the module declaration.
47    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
48    pub span: Range<usize>,
49}
50
51/// An export declaration.
52#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
53#[derive(Debug, PartialEq, Clone)]
54pub struct Export {
55    /// Exported functions.
56    pub functions: Vec<Identifier>,
57    /// Source span of the export declaration.
58    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
59    pub span: Range<usize>,
60}
61
62/// An attribute declaration.
63#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
64#[derive(Debug, PartialEq, Clone)]
65pub struct Attribute {
66    /// Name of the attribute.
67    pub name: Identifier,
68    /// Value of the attribute.
69    pub value: String,
70    /// Source span of the attribute declaration.
71    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
72    pub span: Range<usize>,
73}
74
75/// A function declaration.
76#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
77#[derive(Debug, PartialEq, Clone)]
78pub struct Function {
79    /// Name of the function.
80    pub name: Identifier,
81    /// Arity of the function.
82    pub arity: usize,
83    /// Clauses of the function.
84    pub clauses: Vec<FunctionClause>,
85    /// Source span of the function declaration.
86    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
87    pub span: Range<usize>,
88}
89
90/// A clause of a function.
91#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
92#[derive(Debug, PartialEq, Clone)]
93pub struct FunctionClause {
94    /// Patterns for the clause.
95    pub patterns: Vec<Pattern>,
96    /// Optional guard for the clause.
97    pub guard: Option<Expr>,
98    /// Body of the clause.
99    pub body: Vec<Statement>,
100    /// Source span of the function clause.
101    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
102    pub span: Range<usize>,
103}
104
105/// A pattern matching expression.
106#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
107#[derive(Debug, PartialEq, Clone)]
108pub enum Pattern {
109    /// Variable pattern.
110    Variable(Identifier),
111    /// Atom pattern.
112    Atom(String),
113    /// Number pattern.
114    Number(String),
115    /// String pattern.
116    String(String),
117    /// List pattern.
118    List(Vec<Pattern>),
119    /// Tuple pattern.
120    Tuple(Vec<Pattern>),
121    /// Record pattern.
122    Record(RecordPattern),
123    /// Wildcard pattern.
124    Wildcard,
125}
126
127/// A record pattern.
128#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
129#[derive(Debug, PartialEq, Clone)]
130pub struct RecordPattern {
131    /// Name of the record.
132    pub name: Identifier,
133    /// Fields of the record pattern.
134    pub fields: Vec<(Identifier, Pattern)>,
135    /// Source span of the record pattern.
136    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
137    pub span: Range<usize>,
138}
139
140/// A statement in Erlang.
141#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
142#[derive(Debug, PartialEq, Clone)]
143pub enum Statement {
144    /// Expression statement.
145    Expr(Expr),
146    /// Match statement.
147    Match {
148        /// Pattern to match.
149        pattern: Pattern,
150        /// Expression to match against.
151        expr: Expr,
152        /// Source span of the match statement.
153        #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
154        span: Range<usize>,
155    },
156    /// Case statement.
157    Case(CaseExpr),
158    /// If statement.
159    If(IfExpr),
160    /// Try statement.
161    Try(TryExpr),
162}
163
164/// An expression in Erlang.
165#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
166#[derive(Debug, PartialEq, Clone)]
167pub enum Expr {
168    /// Variable expression.
169    Variable(Identifier),
170    /// Atom expression.
171    Atom(String),
172    /// Number expression.
173    Number(String),
174    /// String expression.
175    String(String),
176    /// Binary expression.
177    Binary(BinaryExpr),
178    /// List expression.
179    List(Vec<Expr>),
180    /// Tuple expression.
181    Tuple(Vec<Expr>),
182    /// Record expression.
183    Record(RecordExpr),
184    /// Function call expression.
185    Call(CallExpr),
186    /// Fun expression.
187    Fun(FunExpr),
188    /// Case expression.
189    Case(CaseExpr),
190    /// If expression.
191    If(IfExpr),
192    /// Try expression.
193    Try(TryExpr),
194    /// Receive expression.
195    Receive(ReceiveExpr),
196}
197
198/// A binary expression.
199#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
200#[derive(Debug, PartialEq, Clone)]
201pub struct BinaryExpr {
202    /// Left-hand side expression.
203    pub left: Box<Expr>,
204    /// Operator.
205    pub op: ErlangTokenType,
206    /// Right-hand side expression.
207    pub right: Box<Expr>,
208    /// Source span of the binary expression.
209    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
210    pub span: Range<usize>,
211}
212
213/// A function call expression.
214#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
215#[derive(Debug, PartialEq, Clone)]
216pub struct CallExpr {
217    /// Callee expression.
218    pub callee: Box<Expr>,
219    /// Arguments for the call.
220    pub args: Vec<Expr>,
221    /// Source span of the call expression.
222    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
223    pub span: Range<usize>,
224}
225
226/// A fun expression.
227#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
228#[derive(Debug, PartialEq, Clone)]
229pub struct FunExpr {
230    /// Clauses of the fun expression.
231    pub clauses: Vec<FunctionClause>,
232    /// Source span of the fun expression.
233    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
234    pub span: Range<usize>,
235}
236
237/// A case expression.
238#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
239#[derive(Debug, PartialEq, Clone)]
240pub struct CaseExpr {
241    /// Expression to match.
242    pub expr: Box<Expr>,
243    /// Clauses of the case expression.
244    pub clauses: Vec<CaseClause>,
245    /// Source span of the case expression.
246    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
247    pub span: Range<usize>,
248}
249
250/// A clause in a case expression.
251#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
252#[derive(Debug, PartialEq, Clone)]
253pub struct CaseClause {
254    /// Pattern for the clause.
255    pub pattern: Pattern,
256    /// Optional guard for the clause.
257    pub guard: Option<Expr>,
258    /// Body of the clause.
259    pub body: Vec<Statement>,
260    /// Source span of the case clause.
261    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
262    pub span: Range<usize>,
263}
264
265/// An if expression.
266#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
267#[derive(Debug, PartialEq, Clone)]
268pub struct IfExpr {
269    /// Clauses of the if expression.
270    pub clauses: Vec<IfClause>,
271    /// Source span of the if expression.
272    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
273    pub span: Range<usize>,
274}
275
276/// A clause in an if expression.
277#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
278#[derive(Debug, PartialEq, Clone)]
279pub struct IfClause {
280    /// Guard for the clause.
281    pub guard: Expr,
282    /// Body of the clause.
283    pub body: Vec<Statement>,
284    /// Source span of the if clause.
285    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
286    pub span: Range<usize>,
287}
288
289/// A try expression.
290#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
291#[derive(Debug, PartialEq, Clone)]
292pub struct TryExpr {
293    /// Body of the try expression.
294    pub body: Vec<Statement>,
295    /// Catch clauses.
296    pub catch_clauses: Vec<CatchClause>,
297    /// Optional after clause.
298    pub after_clause: Option<Box<Expr>>,
299    /// Source span of the try expression.
300    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
301    pub span: Range<usize>,
302}
303
304/// A catch clause.
305#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
306#[derive(Debug, PartialEq, Clone)]
307pub struct CatchClause {
308    /// Pattern for the clause.
309    pub pattern: Pattern,
310    /// Optional guard for the clause.
311    pub guard: Option<Expr>,
312    /// Body of the clause.
313    pub body: Vec<Statement>,
314    /// Source span of the catch clause.
315    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
316    pub span: Range<usize>,
317}
318
319/// A receive expression.
320#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
321#[derive(Debug, PartialEq, Clone)]
322pub struct ReceiveExpr {
323    /// Clauses of the receive expression.
324    pub clauses: Vec<ReceiveClause>,
325    /// Optional after clause.
326    pub after_clause: Option<Box<Expr>>,
327    /// Source span of the receive expression.
328    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
329    pub span: Range<usize>,
330}
331
332/// A clause in a receive expression.
333#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
334#[derive(Debug, PartialEq, Clone)]
335pub struct ReceiveClause {
336    /// Pattern for the clause.
337    pub pattern: Pattern,
338    /// Optional guard for the clause.
339    pub guard: Option<Expr>,
340    /// Body of the clause.
341    pub body: Vec<Statement>,
342    /// Source span of the receive clause.
343    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
344    pub span: Range<usize>,
345}
346
347/// A record expression.
348#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
349#[derive(Debug, PartialEq, Clone)]
350pub struct RecordExpr {
351    /// Name of the record.
352    pub name: Identifier,
353    /// Fields of the record expression.
354    pub fields: Vec<(Identifier, Expr)>,
355    /// Source span of the record expression.
356    #[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
357    pub span: Range<usize>,
358}