1use serde::{Deserialize, Serialize};
2
3pub mod visitor;
4pub use visitor::{walk_block, walk_expr, walk_program, walk_stmt, Visitor};
5
6fn is_false(b: &bool) -> bool {
8 !b
9}
10
11fn skip_none<T>(opt: &Option<T>) -> bool {
13 opt.is_none()
14}
15
16fn is_zero_u32(n: &u32) -> bool {
18 *n == 0
19}
20
21#[derive(Debug, Clone, Copy, Default)]
28pub struct Loc {
29 pub line: u32,
30 pub column: u32,
31}
32
33impl Loc {
34 pub fn new(line: u32, column: u32) -> Self {
35 Self { line, column }
36 }
37
38 pub fn position(&self) -> Option<(u32, u32)> {
40 (self.line != 0).then_some((self.line, self.column))
41 }
42
43 pub fn line(&self) -> Option<u32> {
45 (self.line != 0).then_some(self.line)
46 }
47}
48
49impl PartialEq for Loc {
52 fn eq(&self, _other: &Self) -> bool {
53 true
54 }
55}
56
57#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
60pub enum TypeQualifier {
61 Const,
62 Input,
63 Simple,
64 Series,
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)]
69pub enum VarKind {
70 #[default]
72 Plain,
73 Var,
75 Varip,
77}
78
79impl VarKind {
80 pub fn is_persistent(self) -> bool {
82 !matches!(self, VarKind::Plain)
83 }
84
85 fn is_plain(&self) -> bool {
87 matches!(self, VarKind::Plain)
88 }
89}
90
91#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
93pub enum Argument {
94 Positional(Expr),
95 Named { name: String, value: Expr },
96}
97
98#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
100pub enum Expr {
101 Literal(Literal),
102 Variable(String),
103 Binary {
104 left: Box<Expr>,
105 op: BinOp,
106 right: Box<Expr>,
107 #[serde(skip)]
108 loc: Loc,
109 },
110 Unary {
111 op: UnOp,
112 expr: Box<Expr>,
113 },
114 Call {
115 callee: Box<Expr>,
116 #[serde(default, skip_serializing_if = "Vec::is_empty")]
117 type_args: Vec<String>, args: Vec<Argument>,
119 #[serde(default, skip_serializing_if = "is_zero_u32")]
120 id: u32,
121 #[serde(skip)]
122 loc: Loc,
123 },
124 Index {
125 expr: Box<Expr>,
126 index: Box<Expr>,
127 },
128 MemberAccess {
129 object: Box<Expr>,
130 member: String,
131 },
132 Ternary {
133 condition: Box<Expr>,
134 then_expr: Box<Expr>,
135 else_expr: Box<Expr>,
136 },
137 Function {
138 params: Vec<FunctionParam>,
139 body: Vec<Stmt>,
140 },
141 Array(Vec<Expr>),
142 Switch {
143 value: Box<Expr>,
144 cases: Vec<(Expr, Expr)>, },
146 IfExpr {
147 condition: Box<Expr>,
148 then_expr: Box<Expr>,
149 else_if_branches: Vec<(Expr, Expr)>, else_expr: Option<Box<Expr>>, },
152}
153
154#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
155pub enum Literal {
156 Int(i64),
157 Number(f64),
158 String(String),
159 Bool(bool),
160 Na, HexColor(String), }
163
164#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
165pub enum BinOp {
166 Add,
167 Sub,
168 Mul,
169 Div,
170 Mod,
171 Eq,
172 NotEq,
173 Less,
174 Greater,
175 LessEq,
176 GreaterEq,
177 And,
178 Or,
179}
180
181#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
182pub enum UnOp {
183 Neg,
184 Not,
185}
186
187#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
188pub enum Stmt {
189 VarDecl {
190 name: String,
191 #[serde(skip_serializing_if = "skip_none")]
192 type_qualifier: Option<TypeQualifier>,
193 type_annotation: Option<String>,
194 initializer: Option<Expr>,
195 #[serde(default, skip_serializing_if = "VarKind::is_plain")]
196 var_kind: VarKind,
197 },
198 Assignment {
199 target: Expr, value: Expr,
201 },
202 TupleAssignment {
203 names: Vec<String>,
204 value: Expr,
205 },
206 Expression(Expr),
207 If {
208 condition: Expr,
209 then_branch: Vec<Stmt>,
210 else_if_branches: Vec<(Expr, Vec<Stmt>)>, else_branch: Option<Vec<Stmt>>,
212 },
213 For {
214 var_name: String,
215 from: Expr,
216 to: Expr,
217 body: Vec<Stmt>,
218 },
219 ForIn {
220 index_var: Option<String>, item_var: String,
224 collection: Expr,
225 body: Vec<Stmt>,
226 },
227 While {
228 condition: Expr,
229 body: Vec<Stmt>,
230 },
231 Break,
232 Continue,
233 TypeDecl {
234 name: String,
235 fields: Vec<TypeField>,
236 #[serde(default, skip_serializing_if = "is_false")]
237 export: bool,
238 },
239 MethodDecl {
240 name: String,
241 params: Vec<MethodParam>,
242 body: Vec<Stmt>,
243 #[serde(default, skip_serializing_if = "is_false")]
244 export: bool,
245 },
246 EnumDecl {
247 name: String,
248 fields: Vec<EnumField>,
249 #[serde(default, skip_serializing_if = "is_false")]
250 export: bool,
251 },
252 FunctionDecl {
253 name: String,
254 params: Vec<FunctionParam>,
255 body: Vec<Stmt>,
256 #[serde(default, skip_serializing_if = "is_false")]
257 export: bool,
258 },
259 Export {
260 item: ExportItem,
261 },
262 Import {
263 path: String, alias: String, },
266}
267
268#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
270pub enum ExportItem {
271 Type(String), Function(String), }
274
275#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
277pub struct EnumField {
278 pub name: String,
279 pub title: Option<String>, }
281
282#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
284pub struct MethodParam {
285 #[serde(skip_serializing_if = "skip_none")]
286 pub type_qualifier: Option<TypeQualifier>,
287 pub type_annotation: Option<String>, pub name: String,
289 pub default_value: Option<Expr>,
290}
291
292#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
294pub struct FunctionParam {
295 #[serde(skip_serializing_if = "skip_none")]
296 pub type_qualifier: Option<TypeQualifier>,
297 #[serde(skip_serializing_if = "skip_none")]
298 pub type_annotation: Option<String>,
299 pub name: String,
300 #[serde(skip_serializing_if = "skip_none")]
301 pub default_value: Option<Expr>,
302}
303
304#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
306pub struct TypeField {
307 pub name: String,
308 #[serde(skip_serializing_if = "skip_none")]
309 pub type_qualifier: Option<TypeQualifier>,
310 pub type_annotation: String,
311 pub default_value: Option<Expr>,
312}
313
314#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
316pub struct Program {
317 pub statements: Vec<Stmt>,
318}
319
320impl Program {
321 pub fn new(statements: Vec<Stmt>) -> Self {
322 Self { statements }
323 }
324}