Skip to main content

sequoia_seq/
ir.rs

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