1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use super::*;
use crate::ast::print::write_delim_list;
use std::fmt::{Display, Formatter, Result};

impl Display for Expression {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match &self.kind {
            ExpressionKind::LoadConstant(c) => write!(f, "{}", c),
            ExpressionKind::Function(name, args, ty) => {
                write!(f, "{}(", name)?;
                if let Type::Function(arg_tys, res) = ty {
                    let zipped: Vec<(&Type, &Expression)> = arg_tys.iter().zip(args.iter()).collect();
                    if let Some((last, prefix)) = zipped.split_last() {
                        prefix.iter().fold(Ok(()), |accu, (t, a)| accu.and_then(|()| write!(f, "{}: {}, ", a, t)))?;
                        write!(f, "{}: {}", last.1, last.0)?;
                    }
                    write!(f, ") -> {}", res)
                } else {
                    unreachable!("The type of a function needs to be a function.")
                }
            }
            ExpressionKind::Convert { from, to, expr } => write!(f, "cast<{},{}>({})", from, to, expr),
            ExpressionKind::Tuple(elems) => write_delim_list(f, elems, "(", ")", ","),
            ExpressionKind::Ite { condition, consequence, alternative, .. } => {
                write!(f, "if {} then {} else {}", condition, consequence, alternative)
            }
            ExpressionKind::ArithLog(op, args, ty) => {
                write_delim_list(f, args, &format!("{}(", op), &format!(") : [{}]", ty), ",")
            }
            ExpressionKind::DiscreteWindowLookup(wr) => write!(f, "{}", wr),
            ExpressionKind::WindowLookup(wr) => write!(f, "{}", wr),
            ExpressionKind::Default { expr, default, .. } => write!(f, "{}.default({})", expr, default),
            ExpressionKind::OffsetLookup { target, offset } => write!(f, "{}.offset({})", target, offset),
            ExpressionKind::StreamAccess(sr, access) => match access {
                StreamAccessKind::Sync => write!(f, "{}", sr),
                StreamAccessKind::Hold => write!(f, "{}.hold()", sr),
                StreamAccessKind::Optional => write!(f, "{}.get()", sr),
            },
            ExpressionKind::TupleAccess(expr, num) => write!(f, "{}.{}", expr, num),
        }
    }
}

impl Display for Constant {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match self {
            Constant::Bool(b) => write!(f, "{}", b),
            Constant::UInt(u) => write!(f, "{}", u),
            Constant::Int(i) => write!(f, "{}", i),
            Constant::Float(fl) => write!(f, "{}", fl),
            Constant::Str(s) => write!(f, "{}", s),
        }
    }
}

impl Display for Offset {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match self {
            Offset::PastDiscreteOffset(u) => write!(f, "{}", u),
            _ => unimplemented!(),
        }
    }
}

impl Display for ArithLogOp {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        use ArithLogOp::*;
        match self {
            Not => write!(f, "!"),
            Neg => write!(f, "~"),
            Add => write!(f, "+"),
            Sub => write!(f, "-"),
            Mul => write!(f, "*"),
            Div => write!(f, "/"),
            Rem => write!(f, "%"),
            Pow => write!(f, "^"),
            And => write!(f, "∧"),
            Or => write!(f, "∨"),
            Eq => write!(f, "="),
            Lt => write!(f, "<"),
            Le => write!(f, "≤"),
            Ne => write!(f, "≠"),
            Ge => write!(f, "≥"),
            Gt => write!(f, ">"),
            BitNot => write!(f, "~"),
            BitAnd => write!(f, "&"),
            BitOr => write!(f, "|"),
            BitXor => write!(f, "^"),
            Shl => write!(f, "<<"),
            Shr => write!(f, ">>"),
        }
    }
}

impl Display for Type {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match self {
            Type::Float(_) => write!(f, "Float{}", self.size().expect("Floats are sized.").0 * 8),
            Type::UInt(_) => write!(f, "UInt{}", self.size().expect("UInts are sized.").0 * 8),
            Type::Int(_) => write!(f, "Int{}", self.size().expect("Ints are sized.").0 * 8),
            Type::Function(args, res) => write_delim_list(f, args, "(", &format!(") -> {}", res), ","),
            Type::Tuple(elems) => write_delim_list(f, elems, "(", ")", ","),
            Type::String => write!(f, "String"),
            Type::Bytes => write!(f, "Bytes"),
            Type::Option(inner) => write!(f, "Option<{}>", inner),
            Type::Bool => write!(f, "Bool"),
        }
    }
}

impl Display for WindowReference {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match self {
            WindowReference::SlidingWindow(x) => write!(f, "Win({})", x),
            WindowReference::DiscreteWindow(x) => write!(f, "DisWin({})", x),
        }
    }
}

impl Display for StreamReference {
    fn fmt(&self, f: &mut Formatter<'_>) -> Result {
        match self {
            StreamReference::OutRef(ix) => write!(f, "Out({})", ix),
            StreamReference::InRef(ix) => write!(f, "In({})", ix),
        }
    }
}