normalize_surface_syntax/ir/
expr.rs1use super::Span;
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub enum Expr {
9 Literal(Literal),
11
12 Ident(String),
14
15 Binary {
17 left: Box<Expr>,
18 op: BinaryOp,
19 right: Box<Expr>,
20 #[serde(skip_serializing_if = "Option::is_none")]
22 span: Option<Span>,
23 },
24
25 Unary {
27 op: UnaryOp,
28 expr: Box<Expr>,
29 #[serde(skip_serializing_if = "Option::is_none")]
31 span: Option<Span>,
32 },
33
34 Call {
36 callee: Box<Expr>,
37 args: Vec<Expr>,
38 #[serde(skip_serializing_if = "Option::is_none")]
40 span: Option<Span>,
41 },
42
43 Member {
45 object: Box<Expr>,
46 property: Box<Expr>,
47 computed: bool,
49 #[serde(skip_serializing_if = "Option::is_none")]
51 span: Option<Span>,
52 },
53
54 Array(Vec<Expr>),
56
57 Object(Vec<(String, Expr)>),
59
60 Function(Box<crate::Function>),
62
63 Conditional {
65 test: Box<Expr>,
66 consequent: Box<Expr>,
67 alternate: Box<Expr>,
68 #[serde(skip_serializing_if = "Option::is_none")]
70 span: Option<Span>,
71 },
72
73 Assign {
75 target: Box<Expr>,
76 value: Box<Expr>,
77 #[serde(skip_serializing_if = "Option::is_none")]
79 span: Option<Span>,
80 },
81
82 TemplateLiteral(Vec<TemplatePart>),
88}
89
90#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
92pub enum TemplatePart {
93 Text(String),
95 Expr(Box<Expr>),
97}
98
99#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
101pub enum Literal {
102 Null,
103 Bool(bool),
104 Number(f64),
105 String(String),
106}
107
108#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
110pub enum BinaryOp {
111 Add,
113 Sub,
114 Mul,
115 Div,
116 Mod,
117
118 Eq,
120 Ne,
121 Lt,
122 Le,
123 Gt,
124 Ge,
125
126 And,
128 Or,
129
130 Concat,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
136pub enum UnaryOp {
137 Neg,
138 Not,
139}
140
141impl Expr {
143 pub fn null() -> Self {
144 Expr::Literal(Literal::Null)
145 }
146
147 pub fn bool(v: bool) -> Self {
148 Expr::Literal(Literal::Bool(v))
149 }
150
151 pub fn number(v: impl Into<f64>) -> Self {
152 Expr::Literal(Literal::Number(v.into()))
153 }
154
155 pub fn string(v: impl Into<String>) -> Self {
156 Expr::Literal(Literal::String(v.into()))
157 }
158
159 pub fn ident(name: impl Into<String>) -> Self {
160 Expr::Ident(name.into())
161 }
162
163 pub fn binary(left: Expr, op: BinaryOp, right: Expr) -> Self {
164 Expr::Binary {
165 left: Box::new(left),
166 op,
167 right: Box::new(right),
168 span: None,
169 }
170 }
171
172 pub fn unary(op: UnaryOp, expr: Expr) -> Self {
173 Expr::Unary {
174 op,
175 expr: Box::new(expr),
176 span: None,
177 }
178 }
179
180 pub fn call(callee: Expr, args: Vec<Expr>) -> Self {
181 Expr::Call {
182 callee: Box::new(callee),
183 args,
184 span: None,
185 }
186 }
187
188 pub fn member(object: Expr, property: impl Into<String>) -> Self {
189 Expr::Member {
190 object: Box::new(object),
191 property: Box::new(Expr::string(property)),
192 computed: false,
193 span: None,
194 }
195 }
196
197 pub fn index(object: Expr, index: Expr) -> Self {
198 Expr::Member {
199 object: Box::new(object),
200 property: Box::new(index),
201 computed: true,
202 span: None,
203 }
204 }
205
206 pub fn array(items: Vec<Expr>) -> Self {
207 Expr::Array(items)
208 }
209
210 pub fn object(pairs: Vec<(String, Expr)>) -> Self {
211 Expr::Object(pairs)
212 }
213
214 pub fn conditional(test: Expr, consequent: Expr, alternate: Expr) -> Self {
215 Expr::Conditional {
216 test: Box::new(test),
217 consequent: Box::new(consequent),
218 alternate: Box::new(alternate),
219 span: None,
220 }
221 }
222
223 pub fn assign(target: Expr, value: Expr) -> Self {
224 Expr::Assign {
225 target: Box::new(target),
226 value: Box::new(value),
227 span: None,
228 }
229 }
230
231 pub fn template_literal(parts: Vec<TemplatePart>) -> Self {
232 Expr::TemplateLiteral(parts)
233 }
234
235 pub fn with_span(self, span: Span) -> Self {
237 match self {
238 Expr::Binary {
239 left, op, right, ..
240 } => Expr::Binary {
241 left,
242 op,
243 right,
244 span: Some(span),
245 },
246 Expr::Unary { op, expr, .. } => Expr::Unary {
247 op,
248 expr,
249 span: Some(span),
250 },
251 Expr::Call { callee, args, .. } => Expr::Call {
252 callee,
253 args,
254 span: Some(span),
255 },
256 Expr::Member {
257 object,
258 property,
259 computed,
260 ..
261 } => Expr::Member {
262 object,
263 property,
264 computed,
265 span: Some(span),
266 },
267 Expr::Conditional {
268 test,
269 consequent,
270 alternate,
271 ..
272 } => Expr::Conditional {
273 test,
274 consequent,
275 alternate,
276 span: Some(span),
277 },
278 Expr::Assign { target, value, .. } => Expr::Assign {
279 target,
280 value,
281 span: Some(span),
282 },
283 other => other,
284 }
285 }
286}