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}