chandeliers_san/ast/
mod.rs

1//! Internal representation of a program in Candle,
2//! before it is first translated to macros defined in `chandeliers-sem`
3//! and then expanded to Rust.
4//!
5//! You should construct elements defined in this file by going through
6//! the `translate` feature on the parent crate `chandeliers-syn`,
7//! and you can use them after performing the proper verifications by
8//! converting them into interpretable code using the methods from `codegen.rs`.
9
10use std::fmt;
11use std::hash::Hash;
12
13use chandeliers_err::EAccum;
14
15use crate::causality::depends::Depends;
16
17pub mod options;
18
19crate::sp::derive_with_span!(Tuple<T> where <T>);
20/// Generic wrapper for sequences of AST items.
21#[derive(Clone, Debug, PartialEq, Eq, Hash)]
22pub struct Tuple<T> {
23    /// Internals, intended to be interpreted as comma-separated.
24    elems: Vec<T>,
25}
26
27impl<T> Default for Tuple<T> {
28    // Not derivable because `T` is not necessarily `Default`.
29    fn default() -> Self {
30        Self {
31            elems: Vec::default(),
32        }
33    }
34}
35
36impl<T> Tuple<T> {
37    /// Map a function to a tuple.
38    pub fn map<F, U>(self, f: F) -> Tuple<U>
39    where
40        F: Fn(T) -> U,
41    {
42        Tuple {
43            elems: self.elems.into_iter().map(f).collect(),
44        }
45    }
46
47    /// Map a function by reference to a tuple.
48    pub fn map_ref<F, U>(&self, f: F) -> Tuple<U>
49    where
50        F: Fn(&T) -> U,
51    {
52        Tuple {
53            elems: self.elems.iter().map(f).collect(),
54        }
55    }
56
57    /// Map a faillible funciton by reference to a tuple.
58    /// # Errors
59    /// Fails if the function fails on any of the elements.
60    pub fn try_map<F, U>(&self, eaccum: &mut EAccum, mut f: F) -> Option<Tuple<U>>
61    where
62        F: FnMut(&mut EAccum, &T) -> Option<U>,
63    {
64        let mut elems = Vec::new();
65        for e in &self.elems {
66            elems.push(f(&mut *eaccum, e)?);
67        }
68        Some(Tuple { elems })
69    }
70
71    /// Iterate over elements of the tuple.
72    pub fn iter(&self) -> impl Iterator<Item = &T> {
73        self.elems.iter()
74    }
75
76    /// Iterate over elements of the tuple.
77    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
78        self.elems.iter_mut()
79    }
80
81    /// Number of elements in the tuple.
82    #[must_use]
83    pub fn len(&self) -> usize {
84        self.elems.len()
85    }
86
87    /// Whether this tuple is empty.
88    #[must_use]
89    pub fn is_empty(&self) -> bool {
90        self.elems.is_empty()
91    }
92
93    /// Append to the tuple.
94    pub fn push(&mut self, e: T) {
95        self.elems.push(e);
96    }
97}
98
99impl<T> IntoIterator for Tuple<T> {
100    type Item = T;
101    type IntoIter = <Vec<T> as IntoIterator>::IntoIter;
102    // This is pretty much transparent.
103    fn into_iter(self) -> Self::IntoIter {
104        self.elems.into_iter()
105    }
106}
107
108/// `Tuple` is a transparent wrapper, `Depends` recurses into all fieds.
109impl<T: Depends> Depends for Tuple<T> {
110    type Output = T::Output;
111    fn provides(&self, v: &mut Vec<Self::Output>) {
112        self.elems.provides(v);
113    }
114    fn requires(&self, v: &mut Vec<Self::Output>) {
115        self.elems.requires(v);
116    }
117}
118
119/// Timing primitives.
120pub mod past {
121    use std::fmt;
122
123    crate::sp::derive_with_span!(Depth);
124    /// The depth of a variable (how many `pre`/`fby` are in front)
125    #[derive(Debug, Clone, Copy)]
126    pub struct Depth {
127        /// How many instants in the past.
128        pub dt: usize,
129    }
130
131    impl fmt::Display for Depth {
132        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
133            write!(f, "{}", self.dt)
134        }
135    }
136}
137
138impl<T> fmt::Display for Tuple<T>
139where
140    T: fmt::Display,
141{
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        write!(f, "(")?;
144        let mut es = self.elems.iter();
145        if let Some(e) = es.next() {
146            write!(f, "{e}")?;
147        }
148        for e in es {
149            write!(f, ", {e}")?;
150        }
151        write!(f, ")")
152    }
153}
154
155/// Types of expressions.
156pub mod ty {
157    use std::fmt;
158
159    use crate::ast::past;
160    use crate::sp::Sp;
161
162    crate::sp::derive_with_span!(Base);
163    /// A basic scalar type or atomic type variable.
164    #[derive(Debug, Clone, PartialEq, Eq, Hash)]
165    pub enum Base {
166        /// Integer type (parsed from `int`, represented by `i64`)
167        Int,
168        /// Float type (parsed from `float`, represented by `f64`)
169        Float,
170        /// Bool type (parsed from `bool` represented by `bool`)
171        Bool,
172        /// Generic type variables
173        Other(Sp<String>),
174    }
175
176    crate::sp::derive_with_span!(Clock);
177    /// A clock type.
178    #[derive(Debug, Clone)]
179    pub enum Clock {
180        /// A clock written in the source code (e.g. `when b`).
181        Explicit {
182            /// Whether this clock is positive (when) or negative (whenot).
183            activation: bool,
184            /// Name of the boolean variable representing the clock.
185            id: Sp<String>,
186        },
187        /// The default clock of the node.
188        Implicit,
189        /// Any clock.
190        Adaptative,
191    }
192
193    impl fmt::Display for Base {
194        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195            match self {
196                Self::Int => write!(f, "int"),
197                Self::Float => write!(f, "float"),
198                Self::Bool => write!(f, "bool"),
199                Self::Other(t) => write!(f, "{t}"),
200            }
201        }
202    }
203
204    crate::sp::derive_with_span!(Clocked<T> where <T>);
205    /// A clock bound to an object (typically a `TyBase`).
206    #[derive(Debug, Clone)]
207    pub struct Clocked<T> {
208        /// Contents (the type).
209        pub inner: Sp<T>,
210        /// Attached clock.
211        pub clk: Sp<Clock>,
212    }
213
214    impl<T: fmt::Display> fmt::Display for Clocked<T> {
215        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
216            write!(f, "{}{}", self.inner, self.clk)
217        }
218    }
219
220    /// A scalar type with a clock becomes a fixed-size rotating stream
221    /// of values.
222    #[derive(Debug, Clone)]
223    pub struct Stream {
224        /// Inner type.
225        pub ty: Sp<Clocked<Base>>,
226        /// How many steps into the past this variable is used
227        /// (computed by `MakePositive`).
228        pub depth: Sp<past::Depth>,
229    }
230
231    impl fmt::Display for Stream {
232        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233            write!(f, "{}", self.ty)
234        }
235    }
236
237    crate::sp::derive_with_span!(Tuple);
238    /// A composite type of several values arbitrarily deeply nested.
239    #[derive(Debug, Clone)]
240    pub enum Tuple {
241        /// End of the nesting by a singleton element.
242        /// Covers both `x` and `(x)`.
243        Single(Sp<Base>),
244        /// A tuple of any number of elements.
245        /// E.g. `()`, `(x,)`, `(x, y, z)`, ...
246        Multiple(Sp<super::Tuple<Sp<Tuple>>>),
247    }
248
249    impl fmt::Display for Tuple {
250        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
251            match self {
252                Self::Single(t) => write!(f, "{t}"),
253                Self::Multiple(ts) => write!(f, "{ts}"),
254            }
255        }
256    }
257
258    impl fmt::Display for Clock {
259        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260            match self {
261                Self::Explicit { activation, id } => write!(
262                    f,
263                    " {when} {id}",
264                    when = if *activation { "when" } else { "whenot" }
265                ),
266                _ => Ok(()),
267            }
268        }
269    }
270}
271
272/// Variables and other kinds of referencese to external values.
273pub mod var {
274    use std::fmt;
275
276    use crate::sp::Sp;
277    use chandeliers_err::Transparent;
278
279    crate::sp::derive_with_span!(Local);
280    /// A local variable.
281    #[derive(Debug, Clone, PartialEq, Eq, Hash)]
282    pub struct Local {
283        /// Name.
284        pub repr: Sp<String>,
285    }
286
287    crate::sp::derive_with_span!(Global);
288    /// A global constant.
289    #[derive(Debug, Clone, PartialEq, Eq, Hash)]
290    pub struct Global {
291        /// Name.
292        pub repr: Sp<String>,
293        /// Number to generate unique identifiers.
294        pub run_uid: Transparent<usize>,
295    }
296
297    impl fmt::Display for Local {
298        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
299            write!(f, "{}", self.repr)
300        }
301    }
302
303    impl fmt::Display for Global {
304        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
305            write!(f, "{}", self.repr)
306        }
307    }
308
309    crate::sp::derive_with_span!(Past);
310    /// A past value of a variable.
311    #[derive(Debug, Clone)]
312    pub struct Past {
313        /// Variable.
314        pub var: Sp<Local>,
315        /// How many steps in the past.
316        pub depth: Sp<super::past::Depth>,
317    }
318
319    crate::sp::derive_with_span!(Node);
320    /// A subnode.
321    #[derive(Debug, Clone, PartialEq, Eq, Hash)]
322    pub struct Node {
323        /// Index in the `struct`'s `__node` field.
324        pub id: Sp<usize>,
325        /// Name of the call.
326        pub repr: Sp<String>,
327    }
328
329    crate::sp::derive_with_span!(Register);
330    /// A register for delayed values.
331    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
332    pub struct Register {
333        /// Unique identifier (this is the id'th register created for this node).
334        pub id: Sp<usize>,
335    }
336
337    impl fmt::Display for Register {
338        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339            write!(f, "reg{}", self.id)
340        }
341    }
342
343    crate::sp::derive_with_span!(Flip);
344    /// A register for delayed values.
345    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
346    pub struct Flip {
347        /// Unique identifier (this is the id'th flip created for this node).
348        pub id: Sp<usize>,
349    }
350
351    impl fmt::Display for Flip {
352        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353            write!(f, "flip{}", self.id)
354        }
355    }
356
357    impl fmt::Display for Past {
358        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
359            if self.depth.t.dt > 0 {
360                write!(f, "{}@{}", self.var, self.depth)
361            } else {
362                write!(f, "{}", self.var)
363            }
364        }
365    }
366
367    impl fmt::Display for Node {
368        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
369            write!(f, "{}", self.repr)
370        }
371    }
372
373    crate::sp::derive_with_span!(Reference);
374    /// An extern value, i.e. not composed of primitive literals
375    /// and operators.
376    #[derive(Debug, Clone)]
377    pub enum Reference {
378        /// A global variable.
379        Global(Sp<Global>),
380        /// A local variable, possibly in the past.
381        Var(Sp<Past>),
382    }
383
384    impl fmt::Display for Reference {
385        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
386            match self {
387                Self::Var(v) => write!(f, "{v}"),
388                Self::Global(g) => write!(f, "{g}"),
389            }
390        }
391    }
392}
393
394/// Operators.
395pub mod op {
396    use std::fmt;
397
398    /// A binary operator.
399    #[derive(Debug, Clone, Copy)]
400    pub enum Bin {
401        /// `+`
402        Add,
403        /// `*`
404        Mul,
405        /// `-` (binary)
406        Sub,
407        /// `/`
408        Div,
409        /// `%`
410        Rem,
411        /// `and`
412        BitAnd,
413        /// `or`
414        BitOr,
415        /// Not currently representable.
416        BitXor,
417    }
418
419    impl fmt::Display for Bin {
420        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
421            match self {
422                Self::Add => write!(f, "+"),
423                Self::Mul => write!(f, "*"),
424                Self::Sub => write!(f, "-"),
425                Self::Div => write!(f, "/"),
426                Self::Rem => write!(f, "%"),
427                Self::BitAnd => write!(f, "and"),
428                Self::BitOr => write!(f, "or"),
429                Self::BitXor => write!(f, "^"),
430            }
431        }
432    }
433
434    /// A unary operator.
435    #[derive(Debug, Clone, Copy)]
436    pub enum Un {
437        /// `-` (unary)
438        Neg,
439        /// `not`
440        Not,
441    }
442
443    impl fmt::Display for Un {
444        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
445            match self {
446                Self::Neg => write!(f, "-"),
447                Self::Not => write!(f, "not"),
448            }
449        }
450    }
451
452    /// A comparison operator.
453    #[derive(Debug, Clone, Copy)]
454    pub enum Cmp {
455        /// `<=`
456        Le,
457        /// `>=`
458        Ge,
459        /// `<`
460        Lt,
461        /// `>`
462        Gt,
463        /// `=`
464        Eq,
465        /// `<>`
466        Ne,
467    }
468
469    impl fmt::Display for Cmp {
470        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471            match self {
472                Self::Le => write!(f, "<="),
473                Self::Ge => write!(f, ">="),
474                Self::Lt => write!(f, "<"),
475                Self::Gt => write!(f, ">"),
476                Self::Eq => write!(f, "="),
477                Self::Ne => write!(f, "<>"),
478            }
479        }
480    }
481
482    crate::sp::derive_with_span!(Clock);
483    /// A clock operator applied to an expression.
484    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
485    pub enum Clock {
486        /// `when`
487        When,
488        /// `whenot`
489        Whenot,
490    }
491
492    impl fmt::Display for Clock {
493        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
494            match self {
495                Self::When => write!(f, "when"),
496                Self::Whenot => write!(f, "whenot"),
497            }
498        }
499    }
500}
501
502/// Definitions of expressions.
503pub mod expr {
504    use super::var;
505
506    use std::fmt;
507
508    use crate::ast::{op, past, Tuple};
509    use crate::sp::Sp;
510
511    crate::sp::derive_with_span!(Lit);
512    /// A literal.
513    #[derive(Debug, Clone, Copy)]
514    pub enum Lit {
515        /// Integer literal (parsed).
516        Int(i64),
517        /// Float literal (parsed).
518        Float(f64),
519        /// Bool literal (parsed).
520        Bool(bool),
521    }
522
523    impl fmt::Display for Lit {
524        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
525            match self {
526                Self::Int(i) => write!(f, "{i}"),
527                Self::Float(x) => write!(f, "{x}"),
528                Self::Bool(b) => write!(f, "{b}"),
529            }
530        }
531    }
532
533    crate::sp::derive_with_span!(Expr);
534    /// An expression.
535    #[derive(Debug, Clone)]
536    pub enum Expr {
537        /// Literals `1.0`, `42`, `true`, ...
538        Lit(Sp<Lit>),
539        /// External values `x`, `_0`, ...
540        Reference(Sp<super::var::Reference>),
541        /// Tuples `(1, 2.0, x)`.
542        Tuple(Sp<Tuple<Sp<Expr>>>),
543        /// We push `pre` to the variables so this is just a marker
544        /// of where a `pre` used to be.
545        DummyPre(Sp<Box<Expr>>),
546        /// Where parentheses used to be (useless for semantics but useful
547        /// for pretty-printing)
548        DummyParen(Sp<Box<Expr>>),
549        /// Application of a binary operator `a + b`.
550        Bin {
551            /// Binary operator (e.g. `+`).
552            op: op::Bin,
553            /// Left-hand-side (e.g. `a`).
554            lhs: Sp<Box<Expr>>,
555            /// Right-hand-side (e.g. `b`).
556            rhs: Sp<Box<Expr>>,
557        },
558        /// Application of a unary operator `not b`.
559        Un {
560            /// Unary operator (e.g. `not`).
561            op: op::Un,
562            /// Contents (e.g. `b`).
563            inner: Sp<Box<Expr>>,
564        },
565        /// Application of a comparison function `a <> b`.
566        Cmp {
567            /// Comparison operator (e.g. `<>`).
568            op: op::Cmp,
569            /// Left-hand-side (e.g. `a`).
570            lhs: Sp<Box<Expr>>,
571            /// Right-hand-side (e.g. `b`).
572            rhs: Sp<Box<Expr>>,
573        },
574        /// A when or whenot expression `e when b`.
575        Clock {
576            /// Clock operator (e.g. `when`).
577            op: op::Clock,
578            /// Expression being clocked (e.g. `e`).
579            inner: Sp<Box<Expr>>,
580            /// Clock variable (e.g. `b`).
581            activate: Sp<Box<Expr>>,
582        },
583        /// The special operator "later" in (Lustre `->`)
584        /// to perform case analysis on the current value of the clock.
585        Later {
586            /// Number of steps after which we read the `after` field.
587            delay: Sp<past::Depth>,
588            /// Value to evaluate before `delay`.
589            before: Sp<Box<Expr>>,
590            /// Value to evaluate after `delay`.
591            after: Sp<Box<Expr>>,
592        },
593        /// Alternative to `Fby` and `Pre`, provides a delay by enabling
594        /// a read before a write.
595        FetchRegister {
596            /// Unique identifier.
597            id: Sp<var::Register>,
598            /// Remember the init value for checking (ignored during codegen).
599            dummy_init: Option<Sp<Box<Expr>>>,
600            /// Remember the follow-up value for checking (ignored during codegen).
601            dummy_followed_by: Sp<Box<Expr>>,
602        },
603        /// Alternative to `Later`, provides an internal 0-then-1 not bound to
604        /// the global node clock.
605        Flip {
606            /// Unique identifier.
607            id: Sp<var::Flip>,
608            /// Expression to return on the first evaluation.
609            initial: Sp<Box<Expr>>,
610            /// Following values without unit delay.
611            continued: Sp<Box<Expr>>,
612        },
613        /// A conditional expression `if b then x else y`
614        Ifx {
615            /// Boolean condition.
616            cond: Sp<Box<Expr>>,
617            /// Evaluate if the condition holds.
618            yes: Sp<Box<Expr>>,
619            /// Evaluate if the condition does not hold.
620            no: Sp<Box<Expr>>,
621        },
622        /// Clock combinator
623        Merge {
624            /// Boolean condition.
625            switch: Sp<Box<Expr>>,
626            /// Evaluate if the condition holds.
627            on: Sp<Box<Expr>>,
628            /// Evaluate if the condition does not hold.
629            off: Sp<Box<Expr>>,
630        },
631        /// Advance a block.
632        Substep {
633            /// Number of steps to wait before activating for the first time.
634            delay: usize,
635            /// Index in the `struct`'s `__nodes` field.
636            id: Sp<super::var::Node>,
637            /// Arguments of the function call (parenthesized but not a tuple).
638            args: Sp<Box<Expr>>,
639        },
640    }
641
642    impl fmt::Display for Expr {
643        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
644            match self {
645                Self::Lit(l) => write!(f, "{l}"),
646                Self::Reference(r) => write!(f, "{r}"),
647                Self::Tuple(t) => write!(f, "{t}"),
648                Self::DummyParen(inner) => write!(f, "({inner})"),
649                Self::DummyPre(t) => write!(f, "{t}"),
650                Self::Bin { op, lhs, rhs } => write!(f, "{lhs} {op} {rhs}"),
651                Self::Un { op, inner } => write!(f, "{op} {inner}"),
652                Self::Cmp { op, lhs, rhs } => write!(f, "{lhs} {op} {rhs}"),
653                Self::FetchRegister { id, .. } => write!(f, "!{id}"),
654                Self::Flip {
655                    id,
656                    initial,
657                    continued,
658                } => write!(f, "{initial} ->@{id} {continued}"),
659                Self::Later {
660                    delay,
661                    before,
662                    after,
663                } => write!(f, "({before} ->{delay} {after})"),
664                Self::Ifx { cond, yes, no } => {
665                    write!(f, "if {cond} {{ {yes} }} else {{ {no} }}")
666                }
667                Self::Substep { delay, id, args } => {
668                    if *delay > 0 {
669                        write!(f, "{id}@{delay}{args}")
670                    } else {
671                        write!(f, "{id}{args}")
672                    }
673                }
674                Self::Clock {
675                    op,
676                    inner,
677                    activate,
678                } => write!(f, "({inner} {op} {activate})"),
679                Self::Merge { switch, on, off } => write!(f, "(merge {switch} {on} {off})"),
680            }
681        }
682    }
683}
684
685/// Statements and operations with side-effects.
686pub mod stmt {
687    use std::fmt;
688
689    use crate::ast::{expr, var, Tuple};
690    use crate::sp::Sp;
691
692    /// The target of an assignment `(x, y, z) = ...`.
693    /// May be abritrarily nested.
694    #[derive(Debug, Clone)]
695    pub enum VarTuple {
696        /// End of the recursion through a single variable.
697        Single(Sp<var::Local>),
698        /// Comma-separated tuple.
699        Multiple(Sp<Tuple<Sp<VarTuple>>>),
700    }
701
702    impl VarTuple {
703        /// Determine if this tuple binds any variables, or if it's a unit
704        /// assignment.
705        #[must_use]
706        pub fn is_empty(&self) -> bool {
707            match self {
708                Self::Single(_) => false,
709                Self::Multiple(tup) => tup.t.is_empty(),
710            }
711        }
712    }
713
714    impl fmt::Display for VarTuple {
715        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
716            match self {
717                Self::Single(v) => write!(f, "{v}"),
718                Self::Multiple(vs) => write!(f, "{vs}"),
719            }
720        }
721    }
722
723    crate::sp::derive_with_span!(Statement);
724    /// A statement.
725    #[derive(Debug, Clone)]
726    pub enum Statement {
727        /// Variable binding `let x = ...`
728        Let {
729            /// Variable tuple for destructuring the assignment.
730            target: Sp<VarTuple>,
731            /// Expression to compute.
732            source: Sp<expr::Expr>,
733        },
734        /// Perform an assertion.
735        Assert(Sp<expr::Expr>),
736        /// Set the initial value of a register.
737        InitRegister {
738            /// Unique identifier.
739            id: Sp<var::Register>,
740            /// Initial value.
741            val: Option<Sp<expr::Expr>>,
742            /// Clock of the node.
743            clk: Option<Sp<expr::Expr>>,
744        },
745        /// Perform the write to an already read register.
746        UpdateRegister {
747            /// Unique identifier.
748            id: Sp<var::Register>,
749            /// New value.
750            val: Sp<expr::Expr>,
751        },
752    }
753}
754
755/// Toplevel declarations.
756pub mod decl {
757    use std::fmt;
758
759    use crate::ast::{expr, options, stmt, ty, var, Tuple};
760    use crate::sp::Sp;
761    use chandeliers_err::Transparent;
762
763    /// A typed variable.
764    #[derive(Debug, Clone)]
765    pub struct TyVar {
766        /// Name of the variable.
767        pub name: Sp<var::Local>,
768        /// Type of the variable (including the temporal depth and clock).
769        pub ty: Sp<ty::Stream>,
770    }
771
772    impl fmt::Display for TyVar {
773        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
774            write!(f, "{}: {}", self.name, self.ty)
775        }
776    }
777
778    crate::sp::derive_with_span!(NodeName);
779    /// A node name (either for a declaration or for an invocation)
780    #[derive(Debug, Clone, PartialEq, Eq, Hash)]
781    pub struct NodeName {
782        /// Name of the node.
783        pub repr: Sp<String>,
784        /// Number to generate unique identifiers.
785        pub run_uid: Transparent<usize>,
786    }
787
788    impl fmt::Display for NodeName {
789        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
790            write!(f, "{}", self.repr)
791        }
792    }
793
794    /// Node template instantiated with concrete types.
795    #[derive(Debug, Clone)]
796    pub struct NodeInstance {
797        /// Node name.
798        pub name: Sp<NodeName>,
799        /// Instantiations of the generic type arguments.
800        pub generics: Option<Vec<Sp<ty::Base>>>,
801    }
802
803    /// Typed register.
804    #[derive(Debug, Clone)]
805    pub struct RegisterInstance {
806        /// Unique identifier.
807        pub id: Sp<var::Register>,
808        /// Registers can contain values of arbitrary types because they don't
809        /// need to be duplicated.
810        pub typ: Option<Sp<ty::Tuple>>,
811    }
812
813    /// 0-then-1 boolean to perform an initialization exactly once.
814    #[derive(Debug, Clone)]
815    pub struct FlipInstance {
816        /// Unique identifier.
817        pub id: Sp<var::Flip>,
818    }
819
820    /// A node declaration `node foo(x) returns (y); var z; let <body> tel`.
821    #[derive(Debug, Clone)]
822    pub struct Node {
823        /// Public name of the node (`foo`).
824        pub name: Sp<NodeName>,
825        /// Compilation options attached (in the form `#[...]` as per the standard Rust notation)
826        pub options: options::Node,
827        /// Input variables and types (`x`).
828        pub inputs: Sp<Tuple<Sp<TyVar>>>,
829        /// Output variables and types (`y`).
830        pub outputs: Sp<Tuple<Sp<TyVar>>>,
831        /// Local variables and types (`z`).
832        pub locals: Sp<Tuple<Sp<TyVar>>>,
833        /// Other nodes that are used by this one (function calls in `<body>`).
834        pub blocks: Vec<NodeInstance>,
835        /// Dependent types (useful for dead code analysis).
836        pub deptys: Vec<Sp<var::Local>>,
837        /// Body of the node declaration (`<body>`).
838        pub stmts: Vec<Sp<stmt::Statement>>,
839        /// Delayed values stored in registers.
840        pub registers: Vec<RegisterInstance>,
841        /// Performed initializations.
842        pub flips: Vec<FlipInstance>,
843    }
844
845    /// A global constant `const X : int = 0`.
846    #[derive(Debug, Clone)]
847    pub struct Const {
848        /// Public name of the constant (`X`).
849        pub name: Sp<var::Global>,
850        /// Compilation options attached (in the form `#[...]` as per the standard Rust notation)
851        pub options: options::Const,
852        /// Type of the constant (`int`).
853        pub ty: Sp<ty::Base>,
854        /// Const-computable value (`0`).
855        pub value: Sp<expr::Expr>,
856    }
857
858    /// A trusted node declaration `extern node foo(x) returns (y);`.
859    /// It does not have a body, and the rest of the program will
860    /// assume that it is well-defined.
861    #[derive(Debug, Clone)]
862    pub struct ExtNode {
863        /// Public name of the node (`foo`).
864        pub name: Sp<NodeName>,
865        /// Input variables and types (`x`).
866        pub inputs: Sp<Tuple<Sp<TyVar>>>,
867        /// Output variables and types (`y`).
868        pub outputs: Sp<Tuple<Sp<TyVar>>>,
869        /// Compilation options attached (in the form `#[...]` as per the standard Rust notation)
870        pub options: options::ExtNode,
871    }
872
873    /// A trusted constant declaration `extern const X : int;`.
874    /// It does not have a value, and the rest of the program will
875    /// asusme that it is well-defined.
876    #[derive(Debug, Clone)]
877    pub struct ExtConst {
878        /// Public name of the constant (`X`).
879        pub name: Sp<var::Global>,
880        /// Type of the constant (`int`).
881        pub ty: Sp<ty::Base>,
882        /// Compilation options attached (in the form `#[...]` as per the standard Rust notation)
883        pub options: options::ExtConst,
884    }
885
886    /// A toplevel declaration.
887    #[derive(Debug, Clone)]
888    pub enum Decl {
889        /// `const X : int = 0`
890        Const(Sp<Const>),
891        /// `node foo() returns (); let tel`
892        Node(Sp<Node>),
893        /// `extern const X : int`.
894        ExtConst(Sp<ExtConst>),
895        /// `extern node foo() returns ();`
896        ExtNode(Sp<ExtNode>),
897    }
898
899    /// A Lustre program is a sequence of declarations.
900    #[derive(Debug, Clone)]
901    pub struct Prog {
902        /// Sequence of declarations.
903        pub decls: Vec<Sp<Decl>>,
904    }
905}