1use core::range::Range;
2use serde::{Deserialize, Serialize};
3
4pub type RubyAst = ProgramNode;
6
7#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
9pub struct ProgramNode {
10 pub statements: Vec<StatementNode>,
11 #[serde(with = "oak_core::serde_range")]
12 pub span: Range<usize>,
13}
14
15#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
17pub enum StatementNode {
18 Expression(ExpressionNode),
20 MethodDef {
22 name: String,
23 params: Vec<String>,
24 body: Vec<StatementNode>,
25 #[serde(with = "oak_core::serde_range")]
26 span: Range<usize>,
27 },
28 ClassDef {
30 name: String,
31 superclass: Option<String>,
32 body: Vec<StatementNode>,
33 #[serde(with = "oak_core::serde_range")]
34 span: Range<usize>,
35 },
36 Assignment {
38 target: String,
39 value: ExpressionNode,
40 #[serde(with = "oak_core::serde_range")]
41 span: Range<usize>,
42 },
43 If {
45 condition: ExpressionNode,
46 then_body: Vec<StatementNode>,
47 else_body: Option<Vec<StatementNode>>,
48 #[serde(with = "oak_core::serde_range")]
49 span: Range<usize>,
50 },
51 While {
53 condition: ExpressionNode,
54 body: Vec<StatementNode>,
55 #[serde(with = "oak_core::serde_range")]
56 span: Range<usize>,
57 },
58 Return {
60 value: Option<ExpressionNode>,
61 #[serde(with = "oak_core::serde_range")]
62 span: Range<usize>,
63 },
64}
65
66#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
68pub enum ExpressionNode {
69 Identifier {
71 name: String,
72 #[serde(with = "oak_core::serde_range")]
73 span: Range<usize>,
74 },
75 Literal(LiteralNode),
77 MethodCall {
79 receiver: Option<Box<ExpressionNode>>,
80 method: String,
81 args: Vec<ExpressionNode>,
82 #[serde(with = "oak_core::serde_range")]
83 span: Range<usize>,
84 },
85 BinaryOp {
87 left: Box<ExpressionNode>,
88 operator: String,
89 right: Box<ExpressionNode>,
90 #[serde(with = "oak_core::serde_range")]
91 span: Range<usize>,
92 },
93 UnaryOp {
95 operator: String,
96 operand: Box<ExpressionNode>,
97 #[serde(with = "oak_core::serde_range")]
98 span: Range<usize>,
99 },
100 Array {
102 elements: Vec<ExpressionNode>,
103 #[serde(with = "oak_core::serde_range")]
104 span: Range<usize>,
105 },
106 Hash {
108 pairs: Vec<(ExpressionNode, ExpressionNode)>,
109 #[serde(with = "oak_core::serde_range")]
110 span: Range<usize>,
111 },
112}
113
114#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
116pub enum LiteralNode {
117 Integer {
119 value: i64,
120 #[serde(with = "oak_core::serde_range")]
121 span: Range<usize>,
122 },
123 Float {
125 value: f64,
126 #[serde(with = "oak_core::serde_range")]
127 span: Range<usize>,
128 },
129 String {
131 value: String,
132 #[serde(with = "oak_core::serde_range")]
133 span: Range<usize>,
134 },
135 Symbol {
137 value: String,
138 #[serde(with = "oak_core::serde_range")]
139 span: Range<usize>,
140 },
141 Boolean {
143 value: bool,
144 #[serde(with = "oak_core::serde_range")]
145 span: Range<usize>,
146 },
147 Nil {
149 #[serde(with = "oak_core::serde_range")]
150 span: Range<usize>,
151 },
152}
153
154pub trait RubyAstVisitor {
156 fn visit_program(&mut self, node: &ProgramNode);
157 fn visit_statement(&mut self, stmt: &StatementNode);
158 fn visit_expression(&mut self, expr: &ExpressionNode);
159 fn visit_literal(&mut self, literal: &LiteralNode);
160}