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 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}