rtlola-parser 0.4.0

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

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

/// Allows for using a last(or:) function to access an element with offset -1.
///
/// Transforms:
/// a.last(or: x) => a.offset(by: -1).defaults(to: x)
#[derive(Debug, Clone)]
pub(crate) struct Last {}

impl Last {
    fn apply(&self, expr: &Expression, ast: &RtLolaAst) -> ChangeSet {
        match &expr.kind {
            ExpressionKind::Method(base, name, _types, arguments) => {
                if "last(or:)" != name.to_string() {
                    return ChangeSet::empty();
                };
                let target_stream = base.clone();
                assert_eq!(arguments.len(), 1);
                let default = arguments[0].clone();
                let builder = Builder::new(expr.span, ast);
                let new_expr = builder.default(
                    builder.offset(*target_stream, Offset::Discrete(-1)),
                    default,
                );
                ChangeSet::replace_current_expression(new_expr)
            }
            _ => ChangeSet::empty(),
        }
    }
}

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