1#![doc = include_str!("readme.md")]
2use core::range::Range;
3
4pub type RubyAst = RubyRoot;
6
7#[derive(Debug, Clone, PartialEq)]
9#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
10pub struct RubyRoot {
11 pub statements: Vec<StatementNode>,
13 #[serde(with = "oak_core::serde_range")]
15 pub span: Range<usize>,
16}
17
18#[derive(Debug, Clone, PartialEq)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub enum StatementNode {
22 Expression(ExpressionNode),
24 MethodDef {
26 name: String,
28 params: Vec<String>,
30 body: Vec<StatementNode>,
32 #[serde(with = "oak_core::serde_range")]
34 span: Range<usize>,
35 },
36 ClassDef {
38 name: String,
40 superclass: Option<String>,
42 body: Vec<StatementNode>,
44 #[serde(with = "oak_core::serde_range")]
46 span: Range<usize>,
47 },
48 Assignment {
50 target: String,
52 value: ExpressionNode,
54 #[serde(with = "oak_core::serde_range")]
56 span: Range<usize>,
57 },
58 If {
60 condition: ExpressionNode,
62 then_body: Vec<StatementNode>,
64 else_body: Option<Vec<StatementNode>>,
66 #[serde(with = "oak_core::serde_range")]
68 span: Range<usize>,
69 },
70 While {
72 condition: ExpressionNode,
74 body: Vec<StatementNode>,
76 #[serde(with = "oak_core::serde_range")]
78 span: Range<usize>,
79 },
80 Return {
82 value: Option<ExpressionNode>,
84 #[serde(with = "oak_core::serde_range")]
86 span: Range<usize>,
87 },
88}
89
90#[derive(Debug, Clone, PartialEq)]
92#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
93pub enum ExpressionNode {
94 Identifier {
96 name: String,
98 #[serde(with = "oak_core::serde_range")]
100 span: Range<usize>,
101 },
102 Literal(LiteralNode),
104 MethodCall {
106 receiver: Option<Box<ExpressionNode>>,
108 method: String,
110 args: Vec<ExpressionNode>,
112 #[serde(with = "oak_core::serde_range")]
114 span: Range<usize>,
115 },
116 BinaryOp {
118 left: Box<ExpressionNode>,
120 operator: String,
122 right: Box<ExpressionNode>,
124 #[serde(with = "oak_core::serde_range")]
126 span: Range<usize>,
127 },
128 UnaryOp {
130 operator: String,
132 operand: Box<ExpressionNode>,
134 #[serde(with = "oak_core::serde_range")]
136 span: Range<usize>,
137 },
138 Array {
140 elements: Vec<ExpressionNode>,
142 #[serde(with = "oak_core::serde_range")]
144 span: Range<usize>,
145 },
146 Hash {
148 pairs: Vec<(ExpressionNode, ExpressionNode)>,
150 #[serde(with = "oak_core::serde_range")]
152 span: Range<usize>,
153 },
154}
155
156#[derive(Debug, Clone, PartialEq)]
158#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
159pub enum LiteralNode {
160 Integer {
162 value: i64,
164 #[serde(with = "oak_core::serde_range")]
166 span: Range<usize>,
167 },
168 Float {
170 value: f64,
172 #[serde(with = "oak_core::serde_range")]
174 span: Range<usize>,
175 },
176 String {
178 value: String,
180 #[serde(with = "oak_core::serde_range")]
182 span: Range<usize>,
183 },
184 Symbol {
186 value: String,
188 #[serde(with = "oak_core::serde_range")]
190 span: Range<usize>,
191 },
192 Boolean {
194 value: bool,
196 #[serde(with = "oak_core::serde_range")]
198 span: Range<usize>,
199 },
200 Nil {
202 #[serde(with = "oak_core::serde_range")]
204 span: Range<usize>,
205 },
206}
207
208pub trait RubyAstVisitor {
210 fn visit_program(&mut self, node: &RubyRoot);
212 fn visit_statement(&mut self, stmt: &StatementNode);
214 fn visit_expression(&mut self, expr: &ExpressionNode);
216 fn visit_literal(&mut self, literal: &LiteralNode);
218}