rocks_lang/
expr.rs

1use crate::token::Token;
2use crate::literal::Literal;
3
4/// Represents a [`logical`](Expr::Logical) expression's data in the language.
5#[derive(Debug, PartialEq, Eq, Clone)]
6pub struct LogicalData {
7    pub left: Box<Expr>,
8    pub operator: Token,
9    pub right: Box<Expr>,
10}
11
12/// Represents an [`unary`](Expr::Unary) expression's data in the language.
13#[derive(Debug, PartialEq, Eq, Clone)]
14pub struct UnaryData {
15    pub operator: Token,
16    pub expr: Box<Expr>,
17}
18
19/// Represents a [`binary`](Expr::Binary) expression's data in the language.
20#[derive(Debug, PartialEq, Eq, Clone)]
21pub struct BinaryData {
22    pub left: Box<Expr>,
23    pub operator: Token,
24    pub right: Box<Expr>,
25}
26
27/// Represents a [`grouping`](Expr::Grouping) expression's data in the language.
28#[derive(Debug, PartialEq, Eq, Clone)]
29pub struct GroupingData {
30    pub expr: Box<Expr>,
31}
32
33/// Represents a [`variable`](Expr::Variable) expression's data in the language.
34#[derive(Debug, PartialEq, Eq, Clone)]
35pub struct VariableData {
36    pub name: Token,
37}
38
39/// Represents an [`assign`](Expr::Assign) expression's data in the language.
40#[derive(Debug, PartialEq, Eq, Clone)]
41pub struct AssignData {
42    pub name: Token,
43    pub value: Box<Expr>,
44}
45
46/// Represents a [`call`](Expr::Call) expression's data in the language.
47#[derive(Debug, PartialEq, Eq, Clone)]
48pub struct CallData {
49    pub callee: Box<Expr>,
50    pub paren: Token,
51    pub arguments: Vec<Expr>,
52}
53
54/// Represents a [`get`](Expr::Get) expression's data in the language.
55#[derive(Debug, PartialEq, Eq, Clone)]
56pub struct GetData {
57    pub object: Box<Expr>,
58    pub name: Token,
59}
60
61/// Represents a [`set`](Expr::Set) expression's data in the language.
62#[derive(Debug, PartialEq, Eq, Clone)]
63pub struct SetData {
64    pub object: Box<Expr>,
65    pub name: Token,
66    pub value: Box<Expr>,
67}
68
69/// Represents a [`this`](Expr::This) expression's data in the language.
70#[derive(Debug, PartialEq, Eq, Clone)]
71pub struct ThisData {
72    pub keyword: Token,
73}
74
75/// Represents a [`super`](Expr::Super) expression's data in the language.
76#[derive(Debug, PartialEq, Eq, Clone)]
77pub struct SuperData {
78    pub keyword: Token,
79    pub method: Token,
80}
81
82/// Represents an expression in the language.
83#[derive(Debug, PartialEq, Eq, Clone)]
84pub enum Expr {
85    /// A [`literal`](crate::literal::Literal) value.
86    /// - `1`
87    /// - `"hello"`
88    /// - `true`
89    /// - `null`
90    Literal(Literal),
91
92    /// A logical expression.
93    /// - `true and false`
94    /// - `1 or "hello"`
95    Logical(LogicalData),
96
97    /// An unary expression.
98    /// - `-1`
99    /// - `!true`
100    Unary(UnaryData),
101
102    /// A binary expression.
103    /// - `1 + 2`
104    /// - `1 != 2`
105    /// - `1 <= 2`
106    /// - `1 / 2`
107    Binary(BinaryData),
108
109    /// A grouping expression.
110    /// - `(1 + 2)`
111    /// - `(true and false) or (1 <= 2)`
112    /// - `((1 + 2) * 3) / 4`
113    Grouping(GroupingData),
114
115    /// A variable expression.
116    /// - `x`
117    Variable(VariableData),
118
119    /// An assignment expression.
120    /// - `x = 1`
121    /// - `x = "hello"`
122    /// - `x = func()`
123    Assign(AssignData),
124
125    /// A call expression.
126    /// - `func()`
127    /// - `func(arg1, 23)`
128    /// - `instance.method()`
129    Call(CallData),
130
131    /// A get expression.
132    /// - `instance.property`
133    /// - `instance.property.method()`
134    Get(GetData),
135
136    /// A set expression.
137    /// - `instance.property = 1`
138    /// - `instance.property = "hello"`
139    Set(SetData),
140
141    /// A this expression.
142    /// - `this`
143    /// - `this.property`
144    This(ThisData),
145
146    /// A super expression.
147    /// - `super.method()`
148    /// - `super.method(arg1, 23)`
149    Super(SuperData),
150}
151
152impl Expr {
153    /// Accepts a visitor and returns the result of the visit.
154    /// This is used to implement the visitor pattern.
155    pub fn accept<T>(&self, visitor: &mut impl ExprVisitor<T>) -> T {
156        use Expr::*;
157
158        match self {
159            Literal(_) => visitor.visit_literal_expr(self),
160            Logical(_) => visitor.visit_logical_expr(self),
161            Unary(_) => visitor.visit_unary_expr(self),
162            Binary(_) => visitor.visit_binary_expr(self),
163            Grouping(_) => visitor.visit_grouping_expr(self),
164            Variable(_) => visitor.visit_variable_expr(self),
165            Assign(_) => visitor.visit_assign_expr(self),
166            Call(_) => visitor.visit_call_expr(self),
167            Get(_) => visitor.visit_get_expr(self),
168            Set(_) => visitor.visit_set_expr(self),
169            This(_) => visitor.visit_this_expr(self),
170            Super(_) => visitor.visit_super_expr(self),
171        }
172    }
173}
174
175/// A visitor for expressions.
176pub trait ExprVisitor<T> {
177    fn visit_literal_expr(&mut self, expr: &Expr) -> T;
178    fn visit_logical_expr(&mut self, expr: &Expr) -> T;
179    fn visit_unary_expr(&mut self, expr: &Expr) -> T;
180    fn visit_binary_expr(&mut self, expr: &Expr) -> T;
181    fn visit_grouping_expr(&mut self, expr: &Expr) -> T;
182    fn visit_variable_expr(&mut self, expr: &Expr) -> T;
183    fn visit_assign_expr(&mut self, expr: &Expr) -> T;
184    fn visit_call_expr(&mut self, expr: &Expr) -> T;
185    fn visit_get_expr(&mut self, expr: &Expr) -> T;
186    fn visit_set_expr(&mut self, expr: &Expr) -> T;
187    fn visit_this_expr(&mut self, expr: &Expr) -> T;
188    fn visit_super_expr(&mut self, expr: &Expr) -> T;
189}