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!("({})", params.iter().map(|e| e.pretty_string(names)).join(", "))
21                    } else {
22                        "".into()
23                    },
24                    match kind {
25                        StreamAccessKind::Offset(o) => format!(".offset(by: {o})"),
26                        StreamAccessKind::Hold => ".hold()".into(),
27                        StreamAccessKind::SlidingWindow(r) | StreamAccessKind::DiscreteWindow(r) => {
28                            format!(".aggregate(ref: {r})")
29                        },
30                        _ => "".into(),
31                    }
32                )
33            },
34            LoadConstant(c) => format!("{c}"),
35            Function(FnExprKind { name, args, .. }) => {
36                format!("{}({})", name, args.iter().map(|e| e.pretty_string(names)).join(", "))
37            },
38            Tuple(elems) => format!("({})", elems.iter().map(|e| e.pretty_string(names)).join(", ")),
39            Ite {
40                condition,
41                consequence,
42                alternative,
43                ..
44            } => {
45                format!(
46                    "if {} then {} else {}",
47                    condition.pretty_string(names),
48                    consequence.pretty_string(names),
49                    alternative.pretty_string(names)
50                )
51            },
52            ArithLog(op, args) => {
53                if args.len() == 1 {
54                    format!("{}{}", op, args.first().unwrap().pretty_string(names))
55                } else {
56                    format!(
57                        "({})",
58                        args.iter().map(|e| e.pretty_string(names)).join(&format!(" {op} "))
59                    )
60                }
61            },
62            Default { expr, default } => {
63                format!(
64                    "{}.default({})",
65                    expr.pretty_string(names),
66                    default.pretty_string(names)
67                )
68            },
69            Widen(WidenExprKind { expr: e, ty }) => format!("{}({})", ty, e.pretty_string(names)),
70            TupleAccess(e, idx) => format!("{}.{}", e.pretty_string(names), idx),
71            ParameterAccess(sref, idx) => format!("Param({}, {})", names[sref], idx),
72        }
73    }
74}
75
76impl Display for Expression {
77    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
78        use crate::hir::expression::ExpressionKind::*;
79        match &self.kind {
80            LoadConstant(c) => write!(f, "{c}"),
81            Function(FnExprKind { name, args, .. }) => {
82                write!(f, "{}({})", name, args.iter().map(|e| format!("{e}")).join(", "))
83            },
84            Tuple(elems) => write!(f, "({})", elems.iter().map(|e| format!("{e}")).join(", ")),
85            Ite {
86                condition,
87                consequence,
88                alternative,
89                ..
90            } => {
91                write!(f, "if {condition} then {consequence} else {alternative}")
92            },
93            ArithLog(op, args) => {
94                if args.len() == 1 {
95                    write!(f, "{}{}", op, args.first().unwrap())
96                } else {
97                    write!(f, "({})", args.iter().map(|e| format!("{e}")).join(&format!(" {op} ")))
98                }
99            },
100            Default { expr, default: dft } => write!(f, "{expr}.default({dft})"),
101            Widen(WidenExprKind { expr: e, ty }) => write!(f, "{ty}({e})"),
102            TupleAccess(e, idx) => write!(f, "{e}.{idx}",),
103            ParameterAccess(sref, idx) => write!(f, "Param(ref: {sref}, idx: {idx})"),
104            StreamAccess(sref, kind, params) => {
105                write!(
106                    f,
107                    "Stream(ref: {}, params: ({}))",
108                    sref,
109                    params.iter().map(|e| format!("{e}")).join(", ")
110                )?;
111                match kind {
112                    StreamAccessKind::Offset(o) => write!(f, ".offset(by: {o})"),
113                    StreamAccessKind::Hold => write!(f, ".hold()"),
114                    StreamAccessKind::SlidingWindow(r) | StreamAccessKind::DiscreteWindow(r) => {
115                        write!(f, ".aggregate(ref: {r})")
116                    },
117                    _ => Ok(()),
118                }
119            },
120        }
121    }
122}
123
124impl Display for Constant {
125    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
126        let lit = match self {
127            Constant::Inlined(Inlined { lit, .. }) => lit,
128            Constant::Basic(c) => c,
129        };
130        match lit {
131            Literal::SInt(v) => write!(f, "{v}"),
132            Literal::Integer(v) => write!(f, "{v}"),
133            Literal::Float(v) => write!(f, "{v}"),
134            Literal::Bool(v) => write!(f, "{v}"),
135            Literal::Str(v) => write!(f, "{v}"),
136        }
137    }
138}
139
140impl Display for ArithLogOp {
141    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
142        use ArithLogOp::*;
143        match self {
144            Not => write!(f, "!"),
145            Neg => write!(f, "~"),
146            Add => write!(f, "+"),
147            Sub => write!(f, "-"),
148            Mul => write!(f, "*"),
149            Div => write!(f, "/"),
150            Rem => write!(f, "%"),
151            Pow => write!(f, "^"),
152            And => write!(f, "∧"),
153            Or => write!(f, "∨"),
154            Eq => write!(f, "="),
155            Lt => write!(f, "<"),
156            Le => write!(f, "≤"),
157            Ne => write!(f, "≠"),
158            Ge => write!(f, "≥"),
159            Gt => write!(f, ">"),
160            BitNot => write!(f, "~"),
161            BitAnd => write!(f, "&"),
162            BitOr => write!(f, "|"),
163            BitXor => write!(f, "^"),
164            Shl => write!(f, "<<"),
165            Shr => write!(f, ">>"),
166        }
167    }
168}
169
170impl Display for Offset {
171    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
172        match self {
173            Offset::PastDiscrete(u) => write!(f, "{u}"),
174            _ => unimplemented!(),
175        }
176    }
177}
178
179impl Display for WindowReference {
180    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
181        match self {
182            WindowReference::Sliding(u) => write!(f, "SlidingWin({u})"),
183            WindowReference::Discrete(u) => write!(f, "DiscreteWin({u})"),
184            WindowReference::Instance(u) => write!(f, "InstanceAggr({u})"),
185        }
186    }
187}
188
189impl Display for StreamReference {
190    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
191        match self {
192            StreamReference::Out(ox) => write!(f, "Out({ox})"),
193            StreamReference::In(ix) => write!(f, "In({ix})"),
194        }
195    }
196}
197
198impl Display for AnnotatedType {
199    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
200        use AnnotatedType::*;
201        match self {
202            Int(s) => write!(f, "Int{s}"),
203            Float(s) => write!(f, "Float{s}"),
204            UInt(s) => write!(f, "UInt{s}"),
205            Bool => write!(f, "Bool"),
206            String => write!(f, "String"),
207            Bytes => write!(f, "Bytes"),
208            Option(t) => write!(f, "Option<{t}>"),
209            Tuple(tys) => write!(f, "({})", tys.iter().map(|t| format!("{t}")).join(",")),
210            //Used in function declaration
211            Numeric => write!(f, "Numeric"),
212            Signed => write!(f, "Signed"),
213            Sequence => write!(f, "Sequence"),
214            Param(idx, name) => write!(f, "FunctionParam({idx}, {name})"),
215            Any => write!(f, "Any"),
216        }
217    }
218}