1#[derive(Clone, Debug)]
2pub struct SeqApp {
3 pub title: String,
4
5 pub size: (f32, f32),
6
7 pub theme: ThemeName,
8
9 pub windows: Vec<SeqWindow>,
10
11 pub deferred: Vec<DeferredDecl>,
12
13 pub styles: Vec<StyleDecl>,
14
15 pub components: Vec<ComponentDef>,
16
17 pub states: Vec<StateDecl>,
18
19 pub fns: Vec<SeqFn>,
20
21 pub imports: Vec<ImportDecl>,
22
23 pub app_line: usize,
24
25 pub has_title: bool,
26
27 pub has_size: bool,
28}
29
30#[derive(Clone, Debug)]
31pub struct SeqFile {
32 pub imports: Vec<ImportDecl>,
33
34 pub components: Vec<ComponentDef>,
35
36 pub app: Option<SeqApp>,
37}
38
39#[derive(Clone, Debug)]
40pub struct ImportDecl {
41 pub path: String,
42
43 pub line: usize,
44}
45
46#[derive(Clone, Copy, Debug, PartialEq, Eq)]
47pub enum Visibility {
48 Pub,
49
50 Priv,
51}
52
53#[derive(Clone, Debug)]
54pub struct DeferredDecl {
55 pub kind: DeferredKind,
56
57 pub name: String,
58
59 pub line: usize,
60
61 pub sig: Vec<String>,
62}
63
64#[derive(Clone, Copy, Debug, PartialEq, Eq)]
65pub enum DeferredKind {
66 Prop,
67
68 On,
69
70 Style,
71}
72
73#[derive(Clone, Debug)]
74pub struct StyleDecl {
75 pub name: String,
76
77 pub line: usize,
78
79 pub target: String,
80
81 pub base: Option<String>,
82
83 pub args: Vec<SeqArg>,
84}
85
86#[derive(Clone, Debug)]
87pub struct CompParam {
88 pub name: String,
89
90 pub line: usize,
91
92 pub ty: String,
93}
94
95#[derive(Clone, Debug)]
96pub struct ComponentDef {
97 pub name: String,
98
99 pub line: usize,
100
101 pub params: Vec<CompParam>,
102
103 pub body: Vec<SeqNode>,
104
105 pub visibility: Visibility,
106
107 pub file: String,
108}
109
110#[derive(Clone, Debug, PartialEq, Eq)]
111pub enum ThemeName {
112 Dark,
113 Light,
114
115 File(String),
116}
117
118#[derive(Clone, Debug)]
119pub struct SeqWindow {
120 pub name: String,
121
122 pub line: usize,
123
124 pub size: Option<(f32, f32)>,
125
126 pub nodes: Vec<SeqNode>,
127}
128
129#[derive(Clone, Debug)]
130pub struct SeqNode {
131 pub kind: String,
132
133 pub line: usize,
134
135 pub label: Option<String>,
136
137 pub args: Vec<SeqArg>,
138
139 pub children: Vec<SeqNode>,
140}
141
142#[derive(Clone, Debug)]
143pub struct SeqArg {
144 pub name: String,
145
146 pub line: usize,
147
148 pub value: SeqValue,
149}
150
151#[derive(Clone, Debug)]
152pub enum SeqValue {
153 Str(String),
154
155 Num(f32),
156
157 Bool(bool),
158
159 Color(String),
160
161 Theme(String),
162
163 Length(LengthVal),
164
165 Ident(String),
166
167 Callback { action: String, args: Vec<SeqValue> },
168
169 CallSeq { name: String, args: Vec<SeqValue> },
170
171 Dynamic(String),
172
173 Env(String),
174
175 ItemField(String),
176
177 Tuple(Vec<SeqValue>),
178
179 Array(Vec<SeqValue>),
180}
181
182#[derive(Clone, Copy, Debug)]
183pub enum LengthVal {
184 Fill(f32),
185
186 Px(f32),
187
188 Fit,
189
190 Percent(f32),
191}
192
193#[derive(Clone, Debug)]
194pub struct StateDecl {
195 pub name: String,
196
197 pub line: usize,
198
199 pub ty: String,
200
201 pub init: SeqExpr,
202}
203
204#[derive(Clone, Debug)]
205pub struct FnParam {
206 pub name: String,
207
208 pub mutable: bool,
209
210 pub line: usize,
211
212 pub ty: String,
213}
214
215#[derive(Clone, Debug)]
216pub struct SeqFn {
217 pub name: String,
218
219 pub line: usize,
220
221 pub params: Vec<FnParam>,
222
223 pub ret: Option<String>,
224
225 pub body: Vec<SeqStmt>,
226}
227
228#[derive(Clone, Debug)]
229pub enum SeqStmt {
230 Let {
231 name: String,
232
233 mutable: bool,
234
235 value: SeqExpr,
236
237 line: usize,
238 },
239
240 Assign {
241 name: String,
242
243 value: SeqExpr,
244
245 line: usize,
246 },
247
248 If {
249 cond: SeqExpr,
250
251 then: Vec<SeqStmt>,
252
253 elifs: Vec<(SeqExpr, Vec<SeqStmt>)>,
254
255 els: Option<Vec<SeqStmt>>,
256
257 line: usize,
258 },
259
260 For {
261 var: String,
262
263 source: String,
264
265 body: Vec<SeqStmt>,
266
267 line: usize,
268 },
269
270 Match {
271 value: SeqExpr,
272
273 arms: Vec<SeqMatchArm>,
274
275 line: usize,
276 },
277
278 Return {
279 value: Option<SeqExpr>,
280
281 line: usize,
282 },
283
284 Expr(SeqExpr),
285}
286
287#[derive(Clone, Debug)]
288pub struct SeqMatchArm {
289 pub pattern: MatchPat,
290
291 pub body: Vec<SeqStmt>,
292
293 pub line: usize,
294}
295
296#[derive(Clone, Debug)]
297pub enum MatchPat {
298 Str(String),
299
300 Int(i64),
301
302 Bool(bool),
303
304 Wildcard,
305}
306
307#[derive(Clone, Debug)]
308pub struct SeqExpr {
309 pub line: usize,
310
311 pub kind: SeqExprKind,
312}
313
314#[derive(Clone, Debug)]
315pub enum SeqExprKind {
316 Int(i64),
317
318 Float(f64),
319
320 Str(String),
321
322 Bool(bool),
323
324 Var(String),
325
326 Field {
327 base: String,
328
329 field: String,
330 },
331
332 Tuple(Vec<SeqExpr>),
333
334 Unary {
335 op: UnOp,
336
337 expr: Box<SeqExpr>,
338 },
339
340 Binary {
341 op: BinOp,
342
343 lhs: Box<SeqExpr>,
344
345 rhs: Box<SeqExpr>,
346 },
347
348 Call {
349 name: String,
350
351 args: Vec<SeqExpr>,
352 },
353}
354
355#[derive(Clone, Copy, Debug, PartialEq, Eq)]
356pub enum UnOp {
357 Neg,
358
359 Not,
360}
361
362#[derive(Clone, Copy, Debug, PartialEq, Eq)]
363pub enum BinOp {
364 Add,
365
366 Sub,
367
368 Mul,
369
370 Div,
371
372 Rem,
373
374 Eq,
375
376 Ne,
377
378 Lt,
379
380 Le,
381
382 Gt,
383
384 Ge,
385
386 And,
387
388 Or,
389}
390
391#[must_use]
392pub fn resolve_seq_calls(mut app: SeqApp) -> SeqApp {
393 let fns: std::collections::HashSet<&str> = app.fns.iter().map(|f| f.name.as_str()).collect();
394 if fns.is_empty() {
395 return app;
396 }
397 for style in &mut app.styles {
398 for arg in &mut style.args {
399 resolve_value(&fns, &mut arg.value);
400 }
401 }
402 for window in &mut app.windows {
403 for node in &mut window.nodes {
404 resolve_node(&fns, node);
405 }
406 }
407 for comp in &mut app.components {
408 for node in &mut comp.body {
409 resolve_node(&fns, node);
410 }
411 }
412 app
413}
414
415fn resolve_node(fns: &std::collections::HashSet<&str>, node: &mut SeqNode) {
416 for arg in &mut node.args {
417 resolve_value(fns, &mut arg.value);
418 }
419 for child in &mut node.children {
420 resolve_node(fns, child);
421 }
422}
423
424fn resolve_value(fns: &std::collections::HashSet<&str>, value: &mut SeqValue) {
425 if let SeqValue::Callback { action, args } = value
426 && fns.contains(action.as_str())
427 {
428 let name = std::mem::take(action);
429 let mut taken = Vec::new();
430 std::mem::swap(args, &mut taken);
431 *value = SeqValue::CallSeq { name, args: taken };
432 }
433 match value {
434 SeqValue::Callback { args, .. } | SeqValue::CallSeq { args, .. } => {
435 for arg in args {
436 resolve_value(fns, arg);
437 }
438 }
439 SeqValue::Tuple(items) | SeqValue::Array(items) => {
440 for item in items {
441 resolve_value(fns, item);
442 }
443 }
444 _ => {}
445 }
446}