mod conversion;
mod print;
use std::rc::Rc;
use num::rational::Rational64 as Rational;
use rtlola_reporting::Span;
#[derive(Debug, Default, Clone)]
pub struct RtLolaAst {
pub imports: Vec<Import>,
pub constants: Vec<Rc<Constant>>,
pub inputs: Vec<Rc<Input>>,
pub outputs: Vec<Rc<Output>>,
pub trigger: Vec<Rc<Trigger>>,
pub type_declarations: Vec<TypeDeclaration>,
}
impl RtLolaAst {
pub(crate) fn empty() -> RtLolaAst {
RtLolaAst {
imports: Vec::new(),
constants: Vec::new(),
inputs: Vec::new(),
outputs: Vec::new(),
trigger: Vec::new(),
type_declarations: Vec::new(),
}
}
}
#[derive(Debug, Clone)]
pub struct Import {
pub name: Ident,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct Constant {
pub name: Ident,
pub ty: Option<Type>,
pub literal: Literal,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct Input {
pub name: Ident,
pub ty: Type,
pub params: Vec<Rc<Parameter>>,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct Output {
pub name: Ident,
pub ty: Option<Type>,
pub extend: ActivationCondition,
pub params: Vec<Rc<Parameter>>,
pub spawn: Option<SpawnSpec>,
pub filter: Option<FilterSpec>,
pub close: Option<CloseSpec>,
pub expression: Expression,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct Parameter {
pub name: Ident,
pub ty: Option<Type>,
pub param_idx: usize,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct ActivationCondition {
pub expr: Option<Expression>,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct SpawnSpec {
pub target: Option<Expression>,
pub pacing: ActivationCondition,
pub condition: Option<Expression>,
pub is_if: bool,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct FilterSpec {
pub target: Expression,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct CloseSpec {
pub target: Expression,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct Trigger {
pub expression: Expression,
pub extend: ActivationCondition,
pub message: Option<String>,
pub info_streams: Vec<Ident>,
pub id: NodeId,
pub span: Span,
}
#[allow(clippy::vec_box)]
#[derive(Debug, Clone)]
pub struct TypeDeclaration {
pub name: Option<Ident>,
pub fields: Vec<Box<TypeDeclField>>,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct TypeDeclField {
pub ty: Type,
pub name: String,
pub id: NodeId,
pub span: Span,
}
#[derive(Debug, Clone)]
pub struct Parenthesis {
pub id: NodeId,
pub span: Span,
}
impl Parenthesis {
pub(crate) fn new(id: NodeId, span: Span) -> Parenthesis {
Parenthesis { id, span }
}
}
#[derive(Debug, Clone)]
pub struct Type {
pub kind: TypeKind,
pub id: NodeId,
pub span: Span,
}
impl Type {
pub(crate) fn new_simple(id: NodeId, name: String, span: Span) -> Type {
Type {
id,
kind: TypeKind::Simple(name),
span,
}
}
pub(crate) fn new_tuple(id: NodeId, tuple: Vec<Type>, span: Span) -> Type {
Type {
id,
kind: TypeKind::Tuple(tuple),
span,
}
}
pub(crate) fn new_optional(id: NodeId, name: Type, span: Span) -> Type {
Type {
id,
kind: TypeKind::Optional(name.into()),
span,
}
}
}
#[derive(Debug, Clone)]
pub enum TypeKind {
Simple(String),
Tuple(Vec<Type>),
Optional(Box<Type>),
}
#[derive(Debug, Clone)]
pub struct Expression {
pub kind: ExpressionKind,
pub id: NodeId,
pub span: Span,
}
impl Expression {
pub(crate) fn new(id: NodeId, kind: ExpressionKind, span: Span) -> Expression {
Expression { kind, id, span }
}
}
#[allow(clippy::large_enum_variant, clippy::vec_box)]
#[derive(Debug, Clone)]
pub enum ExpressionKind {
Lit(Literal),
Ident(Ident),
StreamAccess(Box<Expression>, StreamAccessKind),
Default(Box<Expression>, Box<Expression>),
Offset(Box<Expression>, Offset),
DiscreteWindowAggregation {
expr: Box<Expression>,
duration: Box<Expression>,
wait: bool,
aggregation: WindowOperation,
},
SlidingWindowAggregation {
expr: Box<Expression>,
duration: Box<Expression>,
wait: bool,
aggregation: WindowOperation,
},
Binary(BinOp, Box<Expression>, Box<Expression>),
Unary(UnOp, Box<Expression>),
Ite(Box<Expression>, Box<Expression>, Box<Expression>),
ParenthesizedExpression(Option<Box<Parenthesis>>, Box<Expression>, Option<Box<Parenthesis>>),
MissingExpression,
Tuple(Vec<Expression>),
Field(Box<Expression>, Ident),
Method(Box<Expression>, FunctionName, Vec<Type>, Vec<Expression>),
Function(FunctionName, Vec<Type>, Vec<Expression>),
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum WindowOperation {
Count,
Min,
Max,
Sum,
Product,
Average,
Integral,
Conjunction,
Disjunction,
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum StreamAccessKind {
Sync,
Hold,
Optional,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Offset {
Discrete(i16),
RealTime(Rational, TimeUnit),
}
#[allow(missing_docs)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum TimeUnit {
Nanosecond,
Microsecond,
Millisecond,
Second,
Minute,
Hour,
Day,
Week,
Year,
}
#[derive(Debug, Clone)]
pub struct Literal {
pub kind: LitKind,
pub id: NodeId,
pub span: Span,
}
impl Literal {
pub(crate) fn new_bool(id: NodeId, val: bool, span: Span) -> Literal {
Literal {
id,
kind: LitKind::Bool(val),
span,
}
}
pub(crate) fn new_numeric(id: NodeId, val: &str, unit: Option<String>, span: Span) -> Literal {
Literal {
id,
kind: LitKind::Numeric(val.to_string(), unit),
span,
}
}
pub(crate) fn new_str(id: NodeId, val: &str, span: Span) -> Literal {
Literal {
id,
kind: LitKind::Str(val.to_string()),
span,
}
}
pub(crate) fn new_raw_str(id: NodeId, val: &str, span: Span) -> Literal {
Literal {
id,
kind: LitKind::RawStr(val.to_string()),
span,
}
}
}
#[derive(Debug, Clone)]
pub enum LitKind {
Str(String),
RawStr(String),
Numeric(String, Option<String>),
Bool(bool),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum BinOp {
Add,
Sub,
Mul,
Div,
Rem,
Pow,
And,
Or,
BitXor,
BitAnd,
BitOr,
Shl,
Shr,
Eq,
Lt,
Le,
Ne,
Ge,
Gt,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum UnOp {
Not,
Neg,
BitNot,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FunctionName {
pub name: Ident,
pub arg_names: Vec<Option<Ident>>,
}
#[derive(Debug, Clone, Eq)]
pub struct Ident {
pub name: String,
pub span: Span,
}
impl Ident {
pub(crate) fn new(name: String, span: Span) -> Ident {
Ident { name, span }
}
}
impl PartialEq for Ident {
fn eq(&self, other: &Self) -> bool {
self.name == other.name
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeId(pub(crate) u32);
impl NodeId {
pub fn new(x: usize) -> NodeId {
assert!(x < (u32::max_value() as usize));
NodeId(x as u32)
}
}