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