rtlola-parser 0.4.0

A parser for RTLola specifications.
Documentation
use rtlola_reporting::RtLolaError;

use super::{builder::Builder, ChangeSet, ExprOrigin, SynSugar};
use crate::ast::{Expression, ExpressionKind, Offset, RtLolaAst};

/// Allows for using a delta(x,dft: 0)  function to compute the difference between the current and last value of x; defaults to 0.
///
/// Transforms:
/// delta(x,dft:0.0) → x - x.last(or: 0.0)
#[derive(Debug, Clone)]
pub(crate) struct Delta {}

impl Delta {
    fn apply(&self, expr: &Expression, ast: &RtLolaAst) -> ChangeSet {
        match &expr.kind {
            // Function(FunctionName, Vec<Type>, Vec<Expression>),
            ExpressionKind::Function(name, _types, args) => {
                let f_name = name.name.name.clone();
                /* currently not parsable but intended: , "δ", "Δ" */
                if !["delta"].contains(&f_name.as_str()) {
                    return ChangeSet::empty();
                }
                let arg_names = name.arg_names.clone();
                if arg_names.len() != 2 {
                    return ChangeSet::empty();
                }
                if arg_names[0].is_some() || arg_names[1].is_none() {
                    return ChangeSet::empty();
                }
                if !["dft", "default", "or"].contains(&arg_names[1].as_ref().unwrap().name.as_str())
                {
                    return ChangeSet::empty();
                }
                let target_stream = args[0].clone();
                let default_expr = args[1].clone();
                let builder = Builder::new(expr.span, ast);
                let new_expr = builder.sub(
                    target_stream.clone(),
                    builder.default(
                        builder.offset(target_stream, Offset::Discrete(-1)),
                        default_expr,
                    ),
                );
                ChangeSet::replace_current_expression(new_expr)
            }
            _ => ChangeSet::empty(),
        }
    }
}

impl SynSugar for Delta {
    fn desugarize_expr<'a>(
        &self,
        exp: &'a Expression,
        ast: &'a RtLolaAst,
        _stream: usize,
        _origin: ExprOrigin,
    ) -> Result<ChangeSet, RtLolaError> {
        Ok(self.apply(exp, ast))
    }
}