rtlola_hir/hir/
print.rs

1use std::collections::HashMap;
2use std::fmt::{Display, Formatter, Result};
3
4use itertools::Itertools;
5
6use super::{AnnotatedType, Offset, WindowReference};
7use crate::hir::expression::{ArithLogOp, Constant, Expression, Literal};
8use crate::hir::{FnExprKind, Inlined, StreamAccessKind, StreamReference, WidenExprKind};
9
10impl Expression {
11    /// Produces a prettified string representation of the expression given the names of the streams
12    pub(crate) fn pretty_string(&self, names: &HashMap<StreamReference, String>) -> String {
13        use crate::hir::expression::ExpressionKind::*;
14        match &self.kind {
15            StreamAccess(sref, kind, params) => {
16                format!(
17                    "{}{}{}",
18                    names[sref],
19                    if !params.is_empty() {
20                        format!(
21                            "({})",
22                            params.iter().map(|e| e.pretty_string(names)).join(", ")
23                        )
24                    } else {
25                        "".into()
26                    },
27                    match kind {
28                        StreamAccessKind::Offset(o) => format!(".offset(by: {o})"),
29                        StreamAccessKind::Hold => ".hold()".into(),
30                        StreamAccessKind::SlidingWindow(r)
31                        | StreamAccessKind::DiscreteWindow(r)
32                        | StreamAccessKind::InstanceAggregation(r) => {
33                            format!(".aggregate(ref: {r})")
34                        }
35                        StreamAccessKind::Fresh => ".is_fresh()".into(),
36                        StreamAccessKind::Get => ".get()".into(),
37                        StreamAccessKind::Sync => "".into(),
38                    }
39                )
40            }
41            LoadConstant(c) => format!("{c}"),
42            Function(FnExprKind { name, args, .. }) => {
43                format!(
44                    "{}({})",
45                    name,
46                    args.iter().map(|e| e.pretty_string(names)).join(", ")
47                )
48            }
49            Tuple(elems) => format!(
50                "({})",
51                elems.iter().map(|e| e.pretty_string(names)).join(", ")
52            ),
53            Ite {
54                condition,
55                consequence,
56                alternative,
57                ..
58            } => {
59                format!(
60                    "if {} then {} else {}",
61                    condition.pretty_string(names),
62                    consequence.pretty_string(names),
63                    alternative.pretty_string(names)
64                )
65            }
66            ArithLog(op, args) => {
67                if args.len() == 1 {
68                    format!("{}{}", op, args.first().unwrap().pretty_string(names))
69                } else {
70                    format!(
71                        "({})",
72                        args.iter()
73                            .map(|e| e.pretty_string(names))
74                            .join(&format!(" {op} "))
75                    )
76                }
77            }
78            Default { expr, default } => {
79                format!(
80                    "{}.default({})",
81                    expr.pretty_string(names),
82                    default.pretty_string(names)
83                )
84            }
85            Widen(WidenExprKind { expr: e, ty }) => format!("{}({})", ty, e.pretty_string(names)),
86            TupleAccess(e, idx) => format!("{}.{}", e.pretty_string(names), idx),
87            ParameterAccess(sref, idx) => format!("Param({}, {})", names[sref], idx),
88            LambdaParameterAccess { wref, pref } => {
89                format!("LambdaParam{{wref:{wref}, pref:{pref}}}")
90            }
91        }
92    }
93}
94
95impl Display for Expression {
96    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
97        use crate::hir::expression::ExpressionKind::*;
98        match &self.kind {
99            LoadConstant(c) => write!(f, "{c}"),
100            Function(FnExprKind { name, args, .. }) => {
101                write!(
102                    f,
103                    "{}({})",
104                    name,
105                    args.iter().map(|e| format!("{e}")).join(", ")
106                )
107            }
108            Tuple(elems) => write!(f, "({})", elems.iter().map(|e| format!("{e}")).join(", ")),
109            Ite {
110                condition,
111                consequence,
112                alternative,
113                ..
114            } => {
115                write!(f, "if {condition} then {consequence} else {alternative}")
116            }
117            ArithLog(op, args) => {
118                if args.len() == 1 {
119                    write!(f, "{}{}", op, args.first().unwrap())
120                } else {
121                    write!(
122                        f,
123                        "({})",
124                        args.iter().map(|e| format!("{e}")).join(&format!(" {op} "))
125                    )
126                }
127            }
128            Default { expr, default: dft } => write!(f, "{expr}.default({dft})"),
129            Widen(WidenExprKind { expr: e, ty }) => write!(f, "{ty}({e})"),
130            TupleAccess(e, idx) => write!(f, "{e}.{idx}",),
131            ParameterAccess(sref, idx) => write!(f, "Param(ref: {sref}, idx: {idx})"),
132            LambdaParameterAccess { wref, pref } => {
133                write!(f, "LambdaParam{{ wref: {wref}, pref: {pref}}}")
134            }
135            StreamAccess(sref, kind, params) => {
136                write!(
137                    f,
138                    "Stream(ref: {}, params: ({}))",
139                    sref,
140                    params.iter().map(|e| format!("{e}")).join(", ")
141                )?;
142                match kind {
143                    StreamAccessKind::Offset(o) => write!(f, ".offset(by: {o})"),
144                    StreamAccessKind::Hold => write!(f, ".hold()"),
145                    StreamAccessKind::SlidingWindow(r)
146                    | StreamAccessKind::DiscreteWindow(r)
147                    | StreamAccessKind::InstanceAggregation(r) => {
148                        write!(f, ".aggregate(ref: {r})")
149                    }
150                    StreamAccessKind::Fresh => write!(f, ".is_fresh()"),
151                    StreamAccessKind::Get => write!(f, ".get()"),
152                    StreamAccessKind::Sync => Ok(()),
153                }
154            }
155        }
156    }
157}
158
159impl Display for Literal {
160    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
161        match self {
162            Literal::SInt(v) => write!(f, "{v}"),
163            Literal::Integer(v) => write!(f, "{v}"),
164            Literal::Decimal(v) => write!(f, "{v}"),
165            Literal::Bool(v) => write!(f, "{v}"),
166            Literal::Str(v) => write!(f, "{v}"),
167        }
168    }
169}
170
171impl Display for Constant {
172    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
173        let lit = match self {
174            Constant::Inlined(Inlined { lit, .. }) => lit,
175            Constant::Basic(c) => c,
176        };
177        write!(f, "{lit}")
178    }
179}
180
181impl Display for ArithLogOp {
182    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
183        use ArithLogOp::*;
184        match self {
185            Not => write!(f, "!"),
186            Neg => write!(f, "~"),
187            Add => write!(f, "+"),
188            Sub => write!(f, "-"),
189            Mul => write!(f, "*"),
190            Div => write!(f, "/"),
191            Rem => write!(f, "%"),
192            Pow => write!(f, "^"),
193            And => write!(f, "∧"),
194            Or => write!(f, "∨"),
195            Eq => write!(f, "="),
196            Lt => write!(f, "<"),
197            Le => write!(f, "≤"),
198            Ne => write!(f, "≠"),
199            Ge => write!(f, "≥"),
200            Gt => write!(f, ">"),
201            BitNot => write!(f, "~"),
202            BitAnd => write!(f, "&"),
203            BitOr => write!(f, "|"),
204            BitXor => write!(f, "^"),
205            Shl => write!(f, "<<"),
206            Shr => write!(f, ">>"),
207        }
208    }
209}
210
211impl Display for Offset {
212    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
213        match self {
214            Offset::PastDiscrete(u) => write!(f, "-{u}"),
215            _ => unimplemented!(),
216        }
217    }
218}
219
220impl Display for WindowReference {
221    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
222        match self {
223            WindowReference::Sliding(u) => write!(f, "SlidingWin({u})"),
224            WindowReference::Discrete(u) => write!(f, "DiscreteWin({u})"),
225            WindowReference::Instance(u) => write!(f, "InstanceAggr({u})"),
226        }
227    }
228}
229
230impl Display for StreamReference {
231    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
232        match self {
233            StreamReference::Out(ox) => write!(f, "Out({ox})"),
234            StreamReference::In(ix) => write!(f, "In({ix})"),
235        }
236    }
237}
238
239impl Display for AnnotatedType {
240    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
241        use AnnotatedType::*;
242        match self {
243            Int(s) => write!(f, "Int{s}"),
244            Float(s) => write!(f, "Float{s}"),
245            UInt(s) => write!(f, "UInt{s}"),
246            Bool => write!(f, "Bool"),
247            String => write!(f, "String"),
248            Bytes => write!(f, "Bytes"),
249            Option(t) => write!(f, "Option<{t}>"),
250            Tuple(tys) => write!(f, "({})", tys.iter().map(|t| format!("{t}")).join(",")),
251            //Used in function declaration
252            Numeric => write!(f, "Numeric"),
253            Signed => write!(f, "Signed"),
254            Sequence => write!(f, "Sequence"),
255            Param(idx, name) => write!(f, "FunctionParam({idx}, {name})"),
256            Any => write!(f, "Any"),
257            Fixed(total, fractional) => write!(f, "Fixed{total}_{fractional}"),
258            UFixed(total, fractional) => write!(f, "UFixed{total}_{fractional}"),
259            Fractional => write!(f, "Fractional"),
260        }
261    }
262}