1#![doc = include_str!("readme.md")]
2use core::range::Range;
3use serde::{Deserialize, Serialize};
4
5pub type RubyAst = RubyRoot;
7
8#[derive(Debug, Clone, PartialEq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11pub struct RubyRoot {
12 pub statements: Vec<StatementNode>,
14 #[serde(with = "oak_core::serde_range")]
16 pub span: Range<usize>,
17}
18
19#[derive(Debug, Clone, PartialEq)]
21#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
22pub enum StatementNode {
23 Expression(ExpressionNode),
25 MethodDef {
27 name: String,
29 params: Vec<String>,
31 body: Vec<StatementNode>,
33 #[serde(with = "oak_core::serde_range")]
35 span: Range<usize>,
36 },
37 ClassDef {
39 name: String,
41 superclass: Option<String>,
43 body: Vec<StatementNode>,
45 #[serde(with = "oak_core::serde_range")]
47 span: Range<usize>,
48 },
49 Assignment {
51 target: String,
53 value: ExpressionNode,
55 #[serde(with = "oak_core::serde_range")]
57 span: Range<usize>,
58 },
59 If {
61 condition: ExpressionNode,
63 then_body: Vec<StatementNode>,
65 else_body: Option<Vec<StatementNode>>,
67 #[serde(with = "oak_core::serde_range")]
69 span: Range<usize>,
70 },
71 While {
73 condition: ExpressionNode,
75 body: Vec<StatementNode>,
77 #[serde(with = "oak_core::serde_range")]
79 span: Range<usize>,
80 },
81 Return {
83 value: Option<ExpressionNode>,
85 #[serde(with = "oak_core::serde_range")]
87 span: Range<usize>,
88 },
89}
90
91#[derive(Debug, Clone, PartialEq)]
93#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
94pub enum ExpressionNode {
95 Identifier {
97 name: String,
99 #[serde(with = "oak_core::serde_range")]
101 span: Range<usize>,
102 },
103 Literal(LiteralNode),
105 MethodCall {
107 receiver: Option<Box<ExpressionNode>>,
109 method: String,
111 args: Vec<ExpressionNode>,
113 #[serde(with = "oak_core::serde_range")]
115 span: Range<usize>,
116 },
117 BinaryOp {
119 left: Box<ExpressionNode>,
121 operator: String,
123 right: Box<ExpressionNode>,
125 #[serde(with = "oak_core::serde_range")]
127 span: Range<usize>,
128 },
129 UnaryOp {
131 operator: String,
133 operand: Box<ExpressionNode>,
135 #[serde(with = "oak_core::serde_range")]
137 span: Range<usize>,
138 },
139 Array {
141 elements: Vec<ExpressionNode>,
143 #[serde(with = "oak_core::serde_range")]
145 span: Range<usize>,
146 },
147 Hash {
149 pairs: Vec<(ExpressionNode, ExpressionNode)>,
151 #[serde(with = "oak_core::serde_range")]
153 span: Range<usize>,
154 },
155}
156
157#[derive(Debug, Clone, PartialEq)]
159#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
160pub enum LiteralNode {
161 Integer {
163 value: i64,
165 #[serde(with = "oak_core::serde_range")]
167 span: Range<usize>,
168 },
169 Float {
171 value: f64,
173 #[serde(with = "oak_core::serde_range")]
175 span: Range<usize>,
176 },
177 String {
179 value: String,
181 #[serde(with = "oak_core::serde_range")]
183 span: Range<usize>,
184 },
185 Symbol {
187 value: String,
189 #[serde(with = "oak_core::serde_range")]
191 span: Range<usize>,
192 },
193 Boolean {
195 value: bool,
197 #[serde(with = "oak_core::serde_range")]
199 span: Range<usize>,
200 },
201 Nil {
203 #[serde(with = "oak_core::serde_range")]
205 span: Range<usize>,
206 },
207}
208
209pub trait RubyAstVisitor {
211 fn visit_program(&mut self, node: &RubyRoot);
213 fn visit_statement(&mut self, stmt: &StatementNode);
215 fn visit_expression(&mut self, expr: &ExpressionNode);
217 fn visit_literal(&mut self, literal: &LiteralNode);
219}