rtlola_parser/
ast.rs

1//! This module contains the [RtLolaAst] data structures for the RTLola Language.
2//!
3//! Every node in the abstract syntax tree is assigned a unique id and has a span referencing the node's location in the specification.
4
5use std::cell::RefCell;
6use std::convert::TryFrom;
7use std::hash::Hash;
8
9use serde::{Deserialize, Serialize};
10
11mod conversion;
12mod print;
13
14use std::rc::Rc;
15
16use num::rational::Rational64 as Rational;
17use rtlola_reporting::Span;
18
19/// The root of a RTLola specification, consisting of stream and trigger declarations.
20/// Each declaration contains the id of the Ast node, a span, and declaration-specific components.
21///
22/// # Ast Node Kinds
23/// * [Import] represents an import statement for a module.
24/// * [Constant] represents a constant stream.
25/// * [Input] represents an input stream.
26/// * [Output] represents an regular output stream or trigger.
27/// * [Mirror] represents mirror streams, a syntactic sugar for an output stream.
28/// * [TypeDeclaration] captures a user given type declaration.
29///
30/// # Related Data Structures
31/// * A [NodeId] is a unique identifier given to every node of the [RtLolaAst]
32/// * A [Span] links an Ast node to its code location.
33#[derive(Debug, Default, Clone)]
34pub struct RtLolaAst {
35    /// The imports of additional modules
36    pub imports: Vec<Import>,
37    /// The constant stream declarations
38    pub constants: Vec<Rc<Constant>>,
39    /// The input stream declarations
40    pub inputs: Vec<Rc<Input>>,
41    /// The output stream declarations
42    pub outputs: Vec<Rc<Output>>,
43    /// The mirror stream declarations
44    pub mirrors: Vec<Rc<Mirror>>,
45    /// The user-defined type declarations
46    pub type_declarations: Vec<TypeDeclaration>,
47    /// Next highest NodeId
48    pub next_node_id: RefCell<NodeId>,
49}
50
51impl RtLolaAst {
52    /// Creates a new and empty [RtLolaAst]
53    pub(crate) fn empty() -> RtLolaAst {
54        RtLolaAst {
55            imports: Vec::new(),
56            constants: Vec::new(),
57            inputs: Vec::new(),
58            outputs: Vec::new(),
59            mirrors: Vec::new(),
60            type_declarations: Vec::new(),
61            next_node_id: RefCell::new(NodeId::default()),
62        }
63    }
64
65    pub(crate) fn next_id(&self) -> NodeId {
66        let res = *self.next_node_id.borrow();
67        self.next_node_id.borrow_mut().id += 1;
68        self.next_node_id.borrow_mut().prime_counter = 0;
69        res
70    }
71
72    /// Creates a deep clone of the Ast. I.e. clones the underlying data not the RCs.
73    pub fn clone_deep(&self) -> RtLolaAst {
74        let RtLolaAst {
75            imports,
76            constants,
77            inputs,
78            outputs,
79            mirrors,
80            type_declarations,
81            next_node_id,
82        } = self;
83
84        RtLolaAst {
85            imports: imports.clone(),
86            constants: constants.iter().map(|c| Rc::new(c.as_ref().clone())).collect(),
87            inputs: inputs.iter().map(|c| Rc::new(c.as_ref().clone())).collect(),
88            outputs: outputs.iter().map(|c| Rc::new(c.as_ref().clone())).collect(),
89            mirrors: mirrors.iter().map(|c| Rc::new(c.as_ref().clone())).collect(),
90            type_declarations: type_declarations.clone(),
91            next_node_id: next_node_id.clone(),
92        }
93    }
94}
95
96/// An Ast node representing the import of a module, which brings additional implemented functionality to a specification.
97/// The 'math' module, for example, adds pre-defined mathematical functions as the sine or cosine function.
98#[derive(Debug, Clone)]
99pub struct Import {
100    /// The name of the module
101    pub name: Ident,
102    /// The id of the node in the Ast
103    pub id: NodeId,
104    /// The span in the specification declaring the module
105    pub span: Span,
106}
107
108/// An Ast node representing the declaration of a constant.
109#[derive(Debug, Clone)]
110pub struct Constant {
111    /// The name of the constant stream
112    pub name: Ident,
113    /// The value type of the constant stream
114    pub ty: Option<Type>,
115    /// The literal defining the constant
116    pub literal: Literal,
117    /// The id of the node in the Ast
118    pub id: NodeId,
119    /// The span in the specification declaring the constant stream
120    pub span: Span,
121}
122
123/// An Ast node representing the declaration of an input stream.
124#[derive(Debug, Clone)]
125pub struct Input {
126    /// The name of the input stream
127    pub name: Ident,
128    ///  The value type of the input stream
129    pub ty: Type,
130    /// The parameters of a parameterized input stream; The vector is empty in non-parametrized streams.
131    pub params: Vec<Rc<Parameter>>,
132    /// The id of the node in the Ast
133    pub id: NodeId,
134    /// The span in the specification declaring the input stream
135    pub span: Span,
136}
137
138/// The kind of an output stream
139/// Can be either a regular output stream with a name or a trigger
140#[derive(Debug, Clone, Eq, PartialEq, Hash)]
141pub enum OutputKind {
142    /// The output stream represents a regular named output stream
143    NamedOutput(Ident),
144    /// The output stream represents a trigger
145    Trigger,
146}
147
148/// An Ast node representing the declaration of an output stream.
149#[derive(Debug, Clone, Eq, PartialEq, Hash)]
150pub struct Output {
151    /// The kind of the output stream
152    pub kind: OutputKind,
153    /// An optional value type annotation of the output stream
154    pub annotated_type: Option<Type>,
155    /// The parameters of a parameterized output stream; The vector is empty in non-parametrized streams
156    pub params: Vec<Rc<Parameter>>,
157    /// The spawn declaration of a parameterized stream
158    pub spawn: Option<SpawnSpec>,
159    /// The eval declaration of a stream,
160    pub eval: Vec<EvalSpec>,
161    ///  The close declaration of parametrized stream
162    pub close: Option<CloseSpec>,
163    /// The id of the node in the Ast
164    pub id: NodeId,
165    /// The span in the specification declaring the output stream
166    pub span: Span,
167}
168
169impl Output {
170    /// Returns the name of the output stream if it has any
171    pub fn name(&self) -> Option<&Ident> {
172        match &self.kind {
173            OutputKind::NamedOutput(n) => Some(n),
174            OutputKind::Trigger => None,
175        }
176    }
177}
178
179/// Represents an output stream that mirrors another but filters them.
180#[derive(Debug, Clone, Eq, PartialEq, Hash)]
181pub struct Mirror {
182    /// The name of the mirror stream.
183    pub name: Ident,
184    /// The condition under which values of the target will be propagated.
185    pub filter: Expression,
186    /// The stream that is supposed to be mirrored.
187    pub target: Ident,
188    /// The id of the node in the Ast
189    pub id: NodeId,
190    /// The span in the specification declaring the parameter
191    pub span: Span,
192}
193
194/// An Ast node representing the declaration of a parameter of a parametrized stream.
195#[derive(Debug, Clone, Eq, PartialEq, Hash)]
196pub struct Parameter {
197    /// The name of the parameter
198    pub name: Ident,
199    /// An optional value type annotation of the parameter
200    pub ty: Option<Type>,
201    /// The index of this parameter in the list of parameter of the respective output stream
202    pub param_idx: usize,
203    /// The id of the node in the Ast
204    pub id: NodeId,
205    /// The span in the specification declaring the parameter
206    pub span: Span,
207}
208
209/// An Ast node representing the declaration of a spawn condition and expression of a stream.
210#[derive(Debug, Clone, Eq, PartialEq, Hash)]
211pub struct SpawnSpec {
212    /// The expression defining the parameter instances. If the stream has more than one parameter, the expression needs to return a tuple, with one element for each parameter
213    pub expression: Option<Expression>,
214    /// The pacing type describing when a new instance is created.
215    pub annotated_pacing: AnnotatedPacingType,
216    /// An additional condition for the creation of an instance, i.e., an instance is only created if the condition is true.
217    pub condition: Option<Expression>,
218    /// The id of the node in the Ast
219    pub id: NodeId,
220    /// The span in the specification declaring the invoke declaration
221    pub span: Span,
222}
223
224/// An Ast node representing the evaluation condition and expression of a stream
225#[derive(Debug, Clone, Eq, PartialEq, Hash)]
226pub struct EvalSpec {
227    /// The pacing type describing when a new value is computed.
228    pub annotated_pacing: AnnotatedPacingType,
229    /// The boolean expression defining the condition, if a stream instance is evaluated.
230    pub condition: Option<Expression>,
231    /// The evaluated expression, defining the value of the stream.
232    pub eval_expression: Option<Expression>,
233    /// The id of the node in the Ast
234    pub id: NodeId,
235    /// The span in the specification declaring the extend declaration
236    pub span: Span,
237}
238
239/// An Ast node representing the declaration of a close condition of a stream
240#[derive(Debug, Clone, Eq, PartialEq, Hash)]
241pub struct CloseSpec {
242    /// The boolean expression defining the condition, if a stream instance is closed.
243    pub condition: Expression,
244    /// The pacing type describing when the close condition is evaluated.
245    pub annotated_pacing: AnnotatedPacingType,
246    /// The id of the node in the Ast
247    pub id: NodeId,
248    /// The span in the specification declaring the extend declaration
249    pub span: Span,
250}
251
252/// An Ast node representing the declaration of a user-defined type.
253#[allow(clippy::vec_box)]
254#[derive(Debug, Clone)]
255pub struct TypeDeclaration {
256    /// The name of the new type.
257    pub name: Option<Ident>,
258    /// The components of the new type, e.g. a GPS type might consist of a type for the latitude and for the longitude
259    pub fields: Vec<Box<TypeDeclField>>,
260    /// The id of the node in the Ast
261    pub id: NodeId,
262    /// The span in the specification declaring the type declaration
263    pub span: Span,
264}
265
266/// An Ast node representing the declaration of a field of a user-defined type.
267#[derive(Debug, Clone)]
268pub struct TypeDeclField {
269    /// The type of a field of a user-defined type
270    pub ty: Type,
271    /// The name of a field of a user-defined type
272    pub name: String,
273    /// The id of the node in the Ast
274    pub id: NodeId,
275    /// The span in the specification declaring the type declaration
276    pub span: Span,
277}
278
279/// An Ast node representing an opening or closing parenthesis.
280#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
281pub struct Parenthesis {
282    /// The id of the node in the Ast
283    pub id: NodeId,
284    /// The span in the specification declaring the extend declaration
285    pub span: Span,
286}
287
288impl Parenthesis {
289    /// Creates a new Parenthesis
290    pub(crate) fn new(id: NodeId, span: Span) -> Parenthesis {
291        Parenthesis { id, span }
292    }
293}
294
295/// An Ast node representing the declaration of a value type
296#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
297pub struct Type {
298    /// The kind of the type, e.g., a tuple
299    pub kind: TypeKind,
300    /// The id of the node in the Ast
301    pub id: NodeId,
302    /// The span in the specification declaring the extend declaration
303    pub span: Span,
304}
305
306impl Type {
307    /// Creates a new non-recursive type like `Int` or `Bool`
308    pub(crate) fn new_simple(id: NodeId, name: String, span: Span) -> Type {
309        Type {
310            id,
311            kind: TypeKind::Simple(name),
312            span,
313        }
314    }
315
316    /// Creates a new tuple type
317    pub(crate) fn new_tuple(id: NodeId, tuple: Vec<Type>, span: Span) -> Type {
318        Type {
319            id,
320            kind: TypeKind::Tuple(tuple),
321            span,
322        }
323    }
324
325    /// Creates a new optional type
326    pub(crate) fn new_optional(id: NodeId, name: Type, span: Span) -> Type {
327        Type {
328            id,
329            kind: TypeKind::Optional(name.into()),
330            span,
331        }
332    }
333}
334
335/// Ast representation of the value type of a stream
336#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, Hash)]
337pub enum TypeKind {
338    /// A simple type, e.g., `Int`
339    Simple(String),
340    /// A tuple type, e.g., `(Int32, Float32)`
341    Tuple(Vec<Type>),
342    /// An optional type, e.g., `Int?`
343    Optional(Box<Type>),
344}
345
346/// The Ast representation of a stream expression
347#[derive(Debug, Clone, Eq, PartialEq, Hash)]
348pub struct Expression {
349    /// The kind of the root expression, e.g., stream access
350    pub kind: ExpressionKind,
351    /// The id of the node in the Ast
352    pub id: NodeId,
353    /// The span in the specification declaring the extend declaration
354    pub span: Span,
355}
356
357impl Expression {
358    /// Creates a new expression
359    pub(crate) fn new(id: NodeId, kind: ExpressionKind, span: Span) -> Expression {
360        Expression { kind, id, span }
361    }
362}
363
364#[allow(clippy::large_enum_variant, clippy::vec_box)]
365#[derive(Debug, Clone, Hash, Eq, PartialEq)]
366/// The Ast representation of a single expression
367pub enum ExpressionKind {
368    /// A literal, e.g., `1`, `"foo"`
369    Lit(Literal),
370    /// An identifier, e.g., `foo`
371    Ident(Ident),
372    /// Accessing a stream
373    StreamAccess(Box<Expression>, StreamAccessKind),
374    /// A default expression, e.g., `a.defaults(to: 0) `
375    Default(Box<Expression>, Box<Expression>),
376    /// An offset expression, e.g., `a.offset(by: -1)`
377    Offset(Box<Expression>, Offset),
378    /// A discrete window with a duration `duration` as an integer constant and aggregation function `aggregation`
379    DiscreteWindowAggregation {
380        /// The accesses stream
381        expr: Box<Expression>,
382        /// The duration of the window
383        duration: Box<Expression>,
384        /// Flag to mark that the window returns only a value if the complete duration has passed
385        wait: bool,
386        /// The aggregation function
387        aggregation: WindowOperation,
388    },
389    /// A sliding window with duration `duration` and aggregation function `aggregation`
390    SlidingWindowAggregation {
391        /// The accesses stream
392        expr: Box<Expression>,
393        /// The duration of the window
394        duration: Box<Expression>,
395        /// Flag to mark that the window returns only a value if the complete duration has passed
396        wait: bool,
397        /// The aggregation function
398        aggregation: WindowOperation,
399    },
400    /// A aggregation over stream-instances with instances `instances` and aggregation function `aggregation`
401    InstanceAggregation {
402        /// The accesses stream
403        expr: Box<Expression>,
404        /// Flag to indicate which instances are part of the aggregation
405        selection: InstanceSelection,
406        /// The aggregation function
407        aggregation: InstanceOperation,
408    },
409    /// A binary operation (For example: `a + b`, `a * b`)
410    Binary(BinOp, Box<Expression>, Box<Expression>),
411    /// A unary operation (For example: `!x`, `*x`)
412    Unary(UnOp, Box<Expression>),
413    /// An if-then-else expression
414    Ite(Box<Expression>, Box<Expression>, Box<Expression>),
415    /// An expression enveloped in parentheses
416    ParenthesizedExpression(Option<Box<Parenthesis>>, Box<Expression>, Option<Box<Parenthesis>>),
417    /// An expression was expected, e.g., after an operator like `*`
418    MissingExpression,
419    /// A tuple expression
420    Tuple(Vec<Expression>),
421    /// Access of a named (`obj.foo`) or unnamed (`obj.0`) struct field
422    Field(Box<Expression>, Ident),
423    /// A method call, e.g., `foo.bar(-1)`
424    Method(Box<Expression>, FunctionName, Vec<Type>, Vec<Expression>),
425    /// A function call
426    Function(FunctionName, Vec<Type>, Vec<Expression>),
427}
428
429#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
430/// The Ast representation of the different aggregation functions
431pub enum WindowOperation {
432    /// Aggregation function to count the number of updated values on the accessed stream
433    Count,
434    /// Aggregation function to return the minimum
435    Min,
436    /// Aggregation function to return the minimum
437    Max,
438    /// Aggregation function to return the addition
439    Sum,
440    /// Aggregation function to return the product
441    Product,
442    /// Aggregation function to return the average
443    Average,
444    /// Aggregation function to return the integral
445    Integral,
446    /// Aggregation function to return the conjunction, i.e., the sliding window returns true iff ALL values on the accessed stream inside a window are assigned to true
447    Conjunction,
448    /// Aggregation function to return the disjunction, i.e., the sliding window returns true iff AT LEAst ONE value on the accessed stream inside a window is assigned to true
449    Disjunction,
450    /// Aggregation function to return the last value, a time bounded hold
451    Last,
452    /// Aggregation function to return the variance of all values, assumes equal probability.
453    Variance,
454    /// Aggregation function to return the covariance of all values in a tuple stream, assumes equal probability.
455    Covariance,
456    /// Aggregation function to return the standard deviation of all values, assumes equal probability.
457    StandardDeviation,
458    /// Aggregation function to return the Nth-Percentile
459    NthPercentile(u8),
460}
461
462#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
463/// A subset of the window operations that are suitable to be performed over a set of instances.
464pub enum InstanceOperation {
465    /// Aggregation function to count the number of instances of the accessed stream
466    Count,
467    /// Aggregation function to return the minimum
468    Min,
469    /// Aggregation function to return the minimum
470    Max,
471    /// Aggregation function to return the addition
472    Sum,
473    /// Aggregation function to return the product
474    Product,
475    /// Aggregation function to return the average
476    Average,
477    /// Aggregation function to return the conjunction, i.e., the instances aggregation returns true iff ALL current values of the instances of the accessed stream are assigned to true
478    Conjunction,
479    /// Aggregation function to return the disjunction, i.e., the instances aggregation returns true iff ANY current values of the instances of the accessed stream are assigned to true
480    Disjunction,
481    /// Aggregation function to return the variance of all values, assumes equal probability.
482    Variance,
483    /// Aggregation function to return the covariance of all values in a tuple stream, assumes equal probability.
484    Covariance,
485    /// Aggregation function to return the standard deviation of all values, assumes equal probability.
486    StandardDeviation,
487    /// Aggregation function to return the Nth-Percentile
488    NthPercentile(u8),
489}
490
491impl TryFrom<WindowOperation> for InstanceOperation {
492    type Error = String;
493
494    fn try_from(value: WindowOperation) -> Result<Self, Self::Error> {
495        match value {
496            WindowOperation::Count => Ok(InstanceOperation::Count),
497            WindowOperation::Min => Ok(InstanceOperation::Min),
498            WindowOperation::Max => Ok(InstanceOperation::Max),
499            WindowOperation::Sum => Ok(InstanceOperation::Sum),
500            WindowOperation::Product => Ok(InstanceOperation::Product),
501            WindowOperation::Average => Ok(InstanceOperation::Average),
502            WindowOperation::Conjunction => Ok(InstanceOperation::Conjunction),
503            WindowOperation::Disjunction => Ok(InstanceOperation::Disjunction),
504            WindowOperation::Variance => Ok(InstanceOperation::Variance),
505            WindowOperation::Covariance => Ok(InstanceOperation::Covariance),
506            WindowOperation::StandardDeviation => Ok(InstanceOperation::StandardDeviation),
507            WindowOperation::NthPercentile(x) => Ok(InstanceOperation::NthPercentile(x)),
508            WindowOperation::Integral | WindowOperation::Last => {
509                Err(format!("Operation {value} not supported over instances."))
510            },
511        }
512    }
513}
514
515impl From<InstanceOperation> for WindowOperation {
516    fn from(val: InstanceOperation) -> Self {
517        match val {
518            InstanceOperation::Count => WindowOperation::Count,
519            InstanceOperation::Min => WindowOperation::Min,
520            InstanceOperation::Max => WindowOperation::Max,
521            InstanceOperation::Sum => WindowOperation::Sum,
522            InstanceOperation::Product => WindowOperation::Product,
523            InstanceOperation::Average => WindowOperation::Average,
524            InstanceOperation::Conjunction => WindowOperation::Conjunction,
525            InstanceOperation::Disjunction => WindowOperation::Disjunction,
526            InstanceOperation::Variance => WindowOperation::Variance,
527            InstanceOperation::Covariance => WindowOperation::Covariance,
528            InstanceOperation::StandardDeviation => WindowOperation::StandardDeviation,
529            InstanceOperation::NthPercentile(x) => WindowOperation::NthPercentile(x),
530        }
531    }
532}
533
534/// Describes the operation used to access a stream
535#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
536pub enum StreamAccessKind {
537    /// Synchronous access
538    Sync,
539    /// Hold access for *incompatible* stream types, returns previous known value
540    Hold,
541    /// Optional access, returns value if it exists, called by `.get()`
542    Get,
543    /// Boolean Typed access, returning true if the target stream received a new value at the current timestamp. Called with `.is_fresh()`.
544    Fresh,
545}
546
547/// Describes the operation used to access a stream with a offset
548#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
549pub enum Offset {
550    /// Discrete offset
551    Discrete(i16),
552    /// Real-time offset
553    RealTime(Rational, TimeUnit),
554}
555
556/// Supported time unit for real time expressions
557#[allow(missing_docs)]
558#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
559pub enum TimeUnit {
560    Nanosecond,
561    Microsecond,
562    Millisecond,
563    Second,
564    Minute,
565    Hour,
566    Day,
567    Week,
568    /// Note: A year is always, *always*, 365 days long.
569    Year,
570}
571
572/// An Ast node representing the declaration of a literal
573#[derive(Debug, Clone, Eq, PartialEq, Hash)]
574pub struct Literal {
575    /// The kind of the literal, e.g., boolean, string, numeric, ...
576    pub kind: LitKind,
577    /// The id of the node in the Ast
578    pub id: NodeId,
579    /// The span in the specification declaring the extend declaration
580    pub span: Span,
581}
582
583impl Literal {
584    /// Creates a new bool literal
585    pub(crate) fn new_bool(id: NodeId, val: bool, span: Span) -> Literal {
586        Literal {
587            id,
588            kind: LitKind::Bool(val),
589            span,
590        }
591    }
592
593    /// Creates a new numeric literal
594    pub(crate) fn new_numeric(id: NodeId, val: &str, unit: Option<String>, span: Span) -> Literal {
595        Literal {
596            id,
597            kind: LitKind::Numeric(val.to_string(), unit),
598            span,
599        }
600    }
601
602    /// Creates a new string literal
603    pub(crate) fn new_str(id: NodeId, val: &str, span: Span) -> Literal {
604        Literal {
605            id,
606            kind: LitKind::Str(val.to_string()),
607            span,
608        }
609    }
610
611    /// Creates a new raw string literal
612    pub(crate) fn new_raw_str(id: NodeId, val: &str, span: Span) -> Literal {
613        Literal {
614            id,
615            kind: LitKind::RawStr(val.to_string()),
616            span,
617        }
618    }
619}
620
621#[derive(Debug, Clone, Eq, PartialEq, Hash)]
622/// The Ast representation of literals
623pub enum LitKind {
624    /// A string literal (`"foo"`)
625    Str(String),
626    /// A raw string literal (`r#" x " a \ff "#`)
627    RawStr(String),
628    /// A numeric value with optional postfix part (`42`, `1.3`, `1Hz`, `100sec`)
629    /// Stores as a string to have lossless representation
630    Numeric(String, Option<String>),
631    /// A boolean literal (`true`)
632    Bool(bool),
633}
634
635/// An Ast node representing a binary operator.
636#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
637pub enum BinOp {
638    /// The `+` operator (addition)
639    Add,
640    /// The `-` operator (subtraction)
641    Sub,
642    /// The `*` operator (multiplication)
643    Mul,
644    /// The `/` operator (division)
645    Div,
646    /// The `%` operator (modulus)
647    Rem,
648    /// The `**` operator (power)
649    Pow,
650    /// The `&&` operator (logical and)
651    And,
652    /// The `||` operator (logical or)
653    Or,
654    /// The `->` operator (logical implication)
655    Implies,
656    /// The `^` operator (bitwise xor)
657    BitXor,
658    /// The `&` operator (bitwise and)
659    BitAnd,
660    /// The `|` operator (bitwise or)
661    BitOr,
662    /// The `<<` operator (shift left)
663    Shl,
664    /// The `>>` operator (shift right)
665    Shr,
666    /// The `==` operator (equality)
667    Eq,
668    /// The `<` operator (less than)
669    Lt,
670    /// The `<=` operator (less than or equal to)
671    Le,
672    /// The `!=` operator (not equal to)
673    Ne,
674    /// The `>=` operator (greater than or equal to)
675    Ge,
676    /// The `>` operator (greater than)
677    Gt,
678}
679
680/// An Ast node representing an unary operator.
681#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
682pub enum UnOp {
683    /// The `!` operator for logical inversion
684    Not,
685    /// The `-` operator for negation
686    Neg,
687    /// The `~` operator for one's complement
688    BitNot,
689}
690
691/// An Ast node representing the name of a called function and also the names of the arguments.
692#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
693pub struct FunctionName {
694    /// The name of the function
695    pub name: Ident,
696    /// A list containing the name of each argument.  If the argument is unnamed, it is represented by `None`.
697    pub arg_names: Vec<Option<Ident>>,
698}
699
700#[derive(Debug, Clone, Eq, Serialize, Deserialize)]
701/// This struct represents an identifier in the specification.
702/// For example the name of an [Output] or [Input].
703pub struct Ident {
704    /// The name of the identifier
705    pub name: String,
706    /// The span in the specification declaring the identifier
707    pub span: Span,
708}
709
710impl Ident {
711    /// Creates a new identifier.
712    pub(crate) fn new(name: String, span: Span) -> Ident {
713        Ident { name, span }
714    }
715}
716
717/// In the equality definition of `Ident`, we only compare the string values
718/// and ignore the `Span` info
719impl PartialEq for Ident {
720    fn eq(&self, other: &Self) -> bool {
721        self.name == other.name
722    }
723}
724
725impl Hash for Ident {
726    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
727        self.name.hash(state);
728    }
729}
730
731#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
732/// Enum to indicate which instances are part of the aggregation
733pub enum InstanceSelection {
734    /// Only instances that are updated in this evaluation cycle are part of the aggregation
735    Fresh,
736    /// All instances are part of the aggregation
737    All,
738}
739
740#[derive(Debug, Clone, PartialEq, Eq, Hash)]
741/// Enum to indicate which annotated pacing type the stream has
742pub enum AnnotatedPacingType {
743    /// No annotated Pacing
744    NotAnnotated,
745    /// Annotated Pacing refers to the global clock
746    Global(Expression),
747    /// Annotated Pacing refers to the local clock
748    Local(Expression),
749    /// Annotated Pacing is unspecified if it refers the local or global clock
750    Unspecified(Expression),
751}
752
753/// Every node in the Ast gets a unique id, represented by a 32bit unsigned integer.
754/// They are used in the later analysis phases to store information about Ast nodes.
755#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
756pub struct NodeId {
757    /// The actual unique id.
758    pub id: u32,
759    /// Counter to track transformations on this node. Increased during syntactic sugar removal.
760    pub prime_counter: u32,
761}
762
763impl NodeId {
764    /// Creates a new NodeId
765    pub fn new(x: usize) -> NodeId {
766        assert!(x < (u32::MAX as usize));
767        NodeId {
768            id: x as u32,
769            prime_counter: 0u32,
770        }
771    }
772
773    /// Creates a copy NodeId with incremented prime counter, which indicates a applied transformation for desugarization.
774    pub fn primed(&self) -> Self {
775        let NodeId { id, prime_counter } = *self;
776        NodeId {
777            id,
778            prime_counter: prime_counter + 1,
779        }
780    }
781}