Skip to main content

oak_ruby/ast/
mod.rs

1#![doc = include_str!("readme.md")]
2use core::range::Range;
3use serde::{Deserialize, Serialize};
4
5/// Ruby AST root node
6pub type RubyAst = RubyRoot;
7
8/// Program node
9#[derive(Debug, Clone, PartialEq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct RubyRoot {
12    /// List of statements
13    pub statements: Vec<StatementNode>,
14    /// Source code span
15    #[serde(with = "oak_core::serde_range")]
16    pub span: Range<usize>,
17}
18
19/// Ruby statement node
20#[derive(Debug, Clone, PartialEq)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub enum StatementNode {
23    /// Expression statement
24    Expression(ExpressionNode),
25    /// Method definition
26    MethodDef {
27        /// Method name
28        name: String,
29        /// Parameter list
30        params: Vec<String>,
31        /// Method body
32        body: Vec<StatementNode>,
33        /// Source code span
34        #[serde(with = "oak_core::serde_range")]
35        span: Range<usize>,
36    },
37    /// Class definition
38    ClassDef {
39        /// Class name
40        name: String,
41        /// Superclass name
42        superclass: Option<String>,
43        /// Class body
44        body: Vec<StatementNode>,
45        /// Source code span
46        #[serde(with = "oak_core::serde_range")]
47        span: Range<usize>,
48    },
49    /// Assignment statement
50    Assignment {
51        /// Assignment target
52        target: String,
53        /// Assignment value
54        value: ExpressionNode,
55        /// Source code span
56        #[serde(with = "oak_core::serde_range")]
57        span: Range<usize>,
58    },
59    /// Conditional statement
60    If {
61        /// Condition expression
62        condition: ExpressionNode,
63        /// then branch
64        then_body: Vec<StatementNode>,
65        /// else branch
66        else_body: Option<Vec<StatementNode>>,
67        /// Source code span
68        #[serde(with = "oak_core::serde_range")]
69        span: Range<usize>,
70    },
71    /// Loop statement
72    While {
73        /// Condition expression
74        condition: ExpressionNode,
75        /// Loop body
76        body: Vec<StatementNode>,
77        /// Source code span
78        #[serde(with = "oak_core::serde_range")]
79        span: Range<usize>,
80    },
81    /// Return statement
82    Return {
83        /// Return value
84        value: Option<ExpressionNode>,
85        /// Source code span
86        #[serde(with = "oak_core::serde_range")]
87        span: Range<usize>,
88    },
89}
90
91/// Ruby expression node
92#[derive(Debug, Clone, PartialEq)]
93#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
94pub enum ExpressionNode {
95    /// Identifier
96    Identifier {
97        /// Identifier name
98        name: String,
99        /// Source code span
100        #[serde(with = "oak_core::serde_range")]
101        span: Range<usize>,
102    },
103    /// Literal
104    Literal(LiteralNode),
105    /// Method call
106    MethodCall {
107        /// Receiver
108        receiver: Option<Box<ExpressionNode>>,
109        /// Method name
110        method: String,
111        /// Argument list
112        args: Vec<ExpressionNode>,
113        /// Source code span
114        #[serde(with = "oak_core::serde_range")]
115        span: Range<usize>,
116    },
117    /// Binary operation
118    BinaryOp {
119        /// Left operand
120        left: Box<ExpressionNode>,
121        /// Operator
122        operator: String,
123        /// Right operand
124        right: Box<ExpressionNode>,
125        /// Source code span
126        #[serde(with = "oak_core::serde_range")]
127        span: Range<usize>,
128    },
129    /// Unary operation
130    UnaryOp {
131        /// Operator
132        operator: String,
133        /// Operand
134        operand: Box<ExpressionNode>,
135        /// Source code span
136        #[serde(with = "oak_core::serde_range")]
137        span: Range<usize>,
138    },
139    /// Array
140    Array {
141        /// Array element list
142        elements: Vec<ExpressionNode>,
143        /// Source code span
144        #[serde(with = "oak_core::serde_range")]
145        span: Range<usize>,
146    },
147    /// Hash
148    Hash {
149        /// The key-value pairs in the hash.
150        pairs: Vec<(ExpressionNode, ExpressionNode)>,
151        /// The source span of the hash.
152        #[serde(with = "oak_core::serde_range")]
153        span: Range<usize>,
154    },
155}
156
157/// Literal node
158#[derive(Debug, Clone, PartialEq)]
159#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
160pub enum LiteralNode {
161    /// Integer literal
162    Integer {
163        /// The integer value.
164        value: i64,
165        /// The source span of the integer.
166        #[serde(with = "oak_core::serde_range")]
167        span: Range<usize>,
168    },
169    /// Float literal
170    Float {
171        /// The floating-point value.
172        value: f64,
173        /// The source span of the float.
174        #[serde(with = "oak_core::serde_range")]
175        span: Range<usize>,
176    },
177    /// String literal
178    String {
179        /// The string value.
180        value: String,
181        /// The source span of the string.
182        #[serde(with = "oak_core::serde_range")]
183        span: Range<usize>,
184    },
185    /// Symbol literal
186    Symbol {
187        /// The symbol value.
188        value: String,
189        /// The source span of the symbol.
190        #[serde(with = "oak_core::serde_range")]
191        span: Range<usize>,
192    },
193    /// Boolean literal
194    Boolean {
195        /// The boolean value.
196        value: bool,
197        /// The source span of the boolean.
198        #[serde(with = "oak_core::serde_range")]
199        span: Range<usize>,
200    },
201    /// nil
202    Nil {
203        /// The source span of the nil literal.
204        #[serde(with = "oak_core::serde_range")]
205        span: Range<usize>,
206    },
207}
208
209/// Ruby AST visitor trait
210pub trait RubyAstVisitor {
211    /// Visits the root program node.
212    fn visit_program(&mut self, node: &RubyRoot);
213    /// Visits a statement node.
214    fn visit_statement(&mut self, stmt: &StatementNode);
215    /// Visits an expression node.
216    fn visit_expression(&mut self, expr: &ExpressionNode);
217    /// Visits a literal node.
218    fn visit_literal(&mut self, literal: &LiteralNode);
219}