1use jrsonnet_gc::{unsafe_empty_trace, Finalize, Trace};
2use jrsonnet_interner::IStr;
3#[cfg(feature = "deserialize")]
4use serde::Deserialize;
5#[cfg(feature = "serialize")]
6use serde::Serialize;
7use std::{
8 fmt::{Debug, Display},
9 ops::Deref,
10 path::{Path, PathBuf},
11 rc::Rc,
12};
13
14#[cfg_attr(feature = "serialize", derive(Serialize))]
15#[cfg_attr(feature = "deserialize", derive(Deserialize))]
16#[derive(Debug, PartialEq, Trace)]
17#[trivially_drop]
18pub enum FieldName {
19 Fixed(IStr),
21 Dyn(LocExpr),
23}
24
25#[cfg_attr(feature = "serialize", derive(Serialize))]
26#[cfg_attr(feature = "deserialize", derive(Deserialize))]
27#[derive(Debug, Clone, Copy, PartialEq, Trace)]
28#[trivially_drop]
29pub enum Visibility {
30 Normal,
32 Hidden,
34 Unhide,
36}
37
38impl Visibility {
39 pub fn is_visible(&self) -> bool {
40 matches!(self, Self::Normal | Self::Unhide)
41 }
42}
43
44#[cfg_attr(feature = "serialize", derive(Serialize))]
45#[cfg_attr(feature = "deserialize", derive(Deserialize))]
46#[derive(Clone, Debug, PartialEq, Trace)]
47#[trivially_drop]
48pub struct AssertStmt(pub LocExpr, pub Option<LocExpr>);
49
50#[cfg_attr(feature = "serialize", derive(Serialize))]
51#[cfg_attr(feature = "deserialize", derive(Deserialize))]
52#[derive(Debug, PartialEq, Trace)]
53#[trivially_drop]
54pub struct FieldMember {
55 pub name: FieldName,
56 pub plus: bool,
57 pub params: Option<ParamsDesc>,
58 pub visibility: Visibility,
59 pub value: LocExpr,
60}
61
62#[cfg_attr(feature = "serialize", derive(Serialize))]
63#[cfg_attr(feature = "deserialize", derive(Deserialize))]
64#[derive(Debug, PartialEq, Trace)]
65#[trivially_drop]
66pub enum Member {
67 Field(FieldMember),
68 BindStmt(BindSpec),
69 AssertStmt(AssertStmt),
70}
71
72#[cfg_attr(feature = "serialize", derive(Serialize))]
73#[cfg_attr(feature = "deserialize", derive(Deserialize))]
74#[derive(Debug, Clone, Copy, PartialEq, Trace)]
75#[trivially_drop]
76pub enum UnaryOpType {
77 Plus,
78 Minus,
79 BitNot,
80 Not,
81}
82
83impl Display for UnaryOpType {
84 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
85 use UnaryOpType::*;
86 write!(
87 f,
88 "{}",
89 match self {
90 Plus => "+",
91 Minus => "-",
92 BitNot => "~",
93 Not => "!",
94 }
95 )
96 }
97}
98
99#[cfg_attr(feature = "serialize", derive(Serialize))]
100#[cfg_attr(feature = "deserialize", derive(Deserialize))]
101#[derive(Debug, Clone, Copy, PartialEq, Trace)]
102#[trivially_drop]
103pub enum BinaryOpType {
104 Mul,
105 Div,
106
107 Mod,
109
110 Add,
111 Sub,
112
113 Lhs,
114 Rhs,
115
116 Lt,
117 Gt,
118 Lte,
119 Gte,
120
121 BitAnd,
122 BitOr,
123 BitXor,
124
125 Eq,
126 Neq,
127
128 And,
129 Or,
130
131 In,
133}
134
135impl Display for BinaryOpType {
136 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137 use BinaryOpType::*;
138 write!(
139 f,
140 "{}",
141 match self {
142 Mul => "*",
143 Div => "/",
144 Mod => "%",
145 Add => "+",
146 Sub => "-",
147 Lhs => "<<",
148 Rhs => ">>",
149 Lt => "<",
150 Gt => ">",
151 Lte => "<=",
152 Gte => ">=",
153 BitAnd => "&",
154 BitOr => "|",
155 BitXor => "^",
156 Eq => "==",
157 Neq => "!=",
158 And => "&&",
159 Or => "||",
160 In => "in",
161 }
162 )
163 }
164}
165
166#[cfg_attr(feature = "serialize", derive(Serialize))]
168#[cfg_attr(feature = "deserialize", derive(Deserialize))]
169#[derive(Debug, PartialEq, Trace)]
170#[trivially_drop]
171pub struct Param(pub IStr, pub Option<LocExpr>);
172
173#[cfg_attr(feature = "serialize", derive(Serialize))]
175#[cfg_attr(feature = "deserialize", derive(Deserialize))]
176#[derive(Debug, Clone, PartialEq)]
177pub struct ParamsDesc(pub Rc<Vec<Param>>);
178
179unsafe impl Trace for ParamsDesc {
182 unsafe_empty_trace!();
183}
184impl Finalize for ParamsDesc {}
185
186impl Deref for ParamsDesc {
187 type Target = Vec<Param>;
188 fn deref(&self) -> &Self::Target {
189 &self.0
190 }
191}
192
193#[cfg_attr(feature = "serialize", derive(Serialize))]
194#[cfg_attr(feature = "deserialize", derive(Deserialize))]
195#[derive(Debug, PartialEq, Trace)]
196#[trivially_drop]
197pub struct Arg(pub Option<String>, pub LocExpr);
198
199#[cfg_attr(feature = "serialize", derive(Serialize))]
200#[cfg_attr(feature = "deserialize", derive(Deserialize))]
201#[derive(Debug, PartialEq, Trace)]
202#[trivially_drop]
203pub struct ArgsDesc(pub Vec<Arg>);
204
205impl Deref for ArgsDesc {
206 type Target = Vec<Arg>;
207 fn deref(&self) -> &Self::Target {
208 &self.0
209 }
210}
211
212#[cfg_attr(feature = "serialize", derive(Serialize))]
213#[cfg_attr(feature = "deserialize", derive(Deserialize))]
214#[derive(Debug, Clone, PartialEq, Trace)]
215#[trivially_drop]
216pub struct BindSpec {
217 pub name: IStr,
218 pub params: Option<ParamsDesc>,
219 pub value: LocExpr,
220}
221
222#[cfg_attr(feature = "serialize", derive(Serialize))]
223#[cfg_attr(feature = "deserialize", derive(Deserialize))]
224#[derive(Debug, PartialEq, Trace)]
225#[trivially_drop]
226pub struct IfSpecData(pub LocExpr);
227
228#[cfg_attr(feature = "serialize", derive(Serialize))]
229#[cfg_attr(feature = "deserialize", derive(Deserialize))]
230#[derive(Debug, PartialEq, Trace)]
231#[trivially_drop]
232pub struct ForSpecData(pub IStr, pub LocExpr);
233
234#[cfg_attr(feature = "serialize", derive(Serialize))]
235#[cfg_attr(feature = "deserialize", derive(Deserialize))]
236#[derive(Debug, PartialEq, Trace)]
237#[trivially_drop]
238pub enum CompSpec {
239 IfSpec(IfSpecData),
240 ForSpec(ForSpecData),
241}
242
243#[cfg_attr(feature = "serialize", derive(Serialize))]
244#[cfg_attr(feature = "deserialize", derive(Deserialize))]
245#[derive(Debug, PartialEq, Trace)]
246#[trivially_drop]
247pub struct ObjComp {
248 pub pre_locals: Vec<BindSpec>,
249 pub key: LocExpr,
250 pub value: LocExpr,
251 pub post_locals: Vec<BindSpec>,
252 pub compspecs: Vec<CompSpec>,
253}
254
255#[cfg_attr(feature = "serialize", derive(Serialize))]
256#[cfg_attr(feature = "deserialize", derive(Deserialize))]
257#[derive(Debug, PartialEq, Trace)]
258#[trivially_drop]
259pub enum ObjBody {
260 MemberList(Vec<Member>),
261 ObjComp(ObjComp),
262}
263
264#[cfg_attr(feature = "serialize", derive(Serialize))]
265#[cfg_attr(feature = "deserialize", derive(Deserialize))]
266#[derive(Debug, PartialEq, Clone, Copy, Trace)]
267#[trivially_drop]
268pub enum LiteralType {
269 This,
270 Super,
271 Dollar,
272 Null,
273 True,
274 False,
275}
276
277#[cfg_attr(feature = "serialize", derive(Serialize))]
278#[cfg_attr(feature = "deserialize", derive(Deserialize))]
279#[derive(Debug, PartialEq, Trace)]
280#[trivially_drop]
281pub struct SliceDesc {
282 pub start: Option<LocExpr>,
283 pub end: Option<LocExpr>,
284 pub step: Option<LocExpr>,
285}
286
287#[cfg_attr(feature = "serialize", derive(Serialize))]
289#[cfg_attr(feature = "deserialize", derive(Deserialize))]
290#[derive(Debug, PartialEq, Trace)]
291#[trivially_drop]
292pub enum Expr {
293 Literal(LiteralType),
294
295 Str(IStr),
297 Num(f64),
299 Var(IStr),
301
302 Arr(Vec<LocExpr>),
304 ArrComp(LocExpr, Vec<CompSpec>),
316
317 Obj(ObjBody),
319 ObjExtend(LocExpr, ObjBody),
321
322 Parened(LocExpr),
324
325 UnaryOp(UnaryOpType, LocExpr),
327 BinaryOp(LocExpr, BinaryOpType, LocExpr),
329 AssertExpr(AssertStmt, LocExpr),
331 LocalExpr(Vec<BindSpec>, LocExpr),
333
334 Import(PathBuf),
336 ImportStr(PathBuf),
338 ErrorStmt(LocExpr),
340 Apply(LocExpr, ArgsDesc, bool),
342 Index(LocExpr, LocExpr),
344 Function(ParamsDesc, LocExpr),
346 Intrinsic(IStr),
348 IfElse {
350 cond: IfSpecData,
351 cond_then: LocExpr,
352 cond_else: Option<LocExpr>,
353 },
354 Slice(LocExpr, SliceDesc),
355}
356
357#[cfg_attr(feature = "serialize", derive(Serialize))]
359#[cfg_attr(feature = "deserialize", derive(Deserialize))]
360#[derive(Clone, PartialEq, Trace)]
361#[trivially_drop]
362pub struct ExprLocation(pub Rc<Path>, pub usize, pub usize);
363
364impl Debug for ExprLocation {
365 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
366 write!(f, "{:?}:{:?}-{:?}", self.0, self.1, self.2)
367 }
368}
369
370#[cfg_attr(feature = "serialize", derive(Serialize))]
372#[cfg_attr(feature = "deserialize", derive(Deserialize))]
373#[derive(Clone, PartialEq)]
374pub struct LocExpr(pub Rc<Expr>, pub Option<ExprLocation>);
375unsafe impl Trace for LocExpr {
378 unsafe_empty_trace!();
379}
380impl Finalize for LocExpr {}
381
382impl Debug for LocExpr {
383 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
384 if f.alternate() {
385 write!(f, "{:#?}", self.0)?;
386 } else {
387 write!(f, "{:?}", self.0)?;
388 }
389 if let Some(loc) = &self.1 {
390 write!(f, " from {:?}", loc)?;
391 }
392 Ok(())
393 }
394}
395
396#[macro_export]
398macro_rules! loc_expr {
399 ($expr:expr, $need_loc:expr,($name:expr, $start:expr, $end:expr)) => {
400 LocExpr(
401 std::rc::Rc::new($expr),
402 if $need_loc {
403 Some(ExprLocation($name, $start, $end))
404 } else {
405 None
406 },
407 )
408 };
409}
410
411#[macro_export]
413macro_rules! loc_expr_todo {
414 ($expr:expr) => {
415 LocExpr(Rc::new($expr), None)
416 };
417}