prqlc_ast/
expr.rs

1pub mod generic;
2mod ident;
3mod ops;
4
5use std::collections::HashMap;
6
7use enum_as_inner::EnumAsInner;
8use serde::{Deserialize, Serialize};
9
10pub use self::ident::Ident;
11pub use self::ops::{BinOp, UnOp};
12pub use self::token::{Literal, ValueAndUnit};
13use super::token;
14use crate::span::Span;
15use crate::Ty;
16
17impl Expr {
18    pub fn new<K: Into<ExprKind>>(kind: K) -> Self {
19        Expr {
20            kind: kind.into(),
21            span: None,
22            alias: None,
23        }
24    }
25}
26
27// The following code is tested by the tests_misc crate to match expr.rs in prqlc.
28
29/// Expr is anything that has a value and thus a type.
30/// Most of these can contain other [Expr] themselves; literals should be [ExprKind::Literal].
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct Expr {
33    #[serde(flatten)]
34    pub kind: ExprKind,
35
36    #[serde(skip)]
37    pub span: Option<Span>,
38
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub alias: Option<String>,
41}
42
43#[derive(Debug, EnumAsInner, PartialEq, Clone, Serialize, Deserialize, strum::AsRefStr)]
44pub enum ExprKind {
45    Ident(String),
46    Indirection {
47        base: Box<Expr>,
48        field: IndirectionKind,
49    },
50    #[cfg_attr(
51        feature = "serde_yaml",
52        serde(with = "serde_yaml::with::singleton_map")
53    )]
54    Literal(token::Literal),
55    Pipeline(Pipeline),
56
57    Tuple(Vec<Expr>),
58    Array(Vec<Expr>),
59    Range(Range),
60    Binary(BinaryExpr),
61    Unary(UnaryExpr),
62    FuncCall(FuncCall),
63    Func(Box<Func>),
64    SString(Vec<InterpolateItem>),
65    FString(Vec<InterpolateItem>),
66    Case(Vec<SwitchCase>),
67
68    /// placeholder for values provided after query is compiled
69    Param(String),
70
71    /// When used instead of function body, the function will be translated to a RQ operator.
72    /// Contains ident of the RQ operator.
73    Internal(String),
74}
75
76#[derive(Debug, EnumAsInner, PartialEq, Clone, Serialize, Deserialize)]
77pub enum IndirectionKind {
78    Name(String),
79    Position(i64),
80    Star,
81}
82
83#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
84pub struct BinaryExpr {
85    pub left: Box<Expr>,
86    pub op: BinOp,
87    pub right: Box<Expr>,
88}
89
90#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
91pub struct UnaryExpr {
92    pub op: UnOp,
93    pub expr: Box<Expr>,
94}
95
96/// Function call.
97#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
98pub struct FuncCall {
99    pub name: Box<Expr>,
100    pub args: Vec<Expr>,
101    #[serde(default, skip_serializing_if = "HashMap::is_empty")]
102    pub named_args: HashMap<String, Expr>,
103}
104
105/// Function called with possibly missing positional arguments.
106/// May also contain environment that is needed to evaluate the body.
107#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
108pub struct Func {
109    /// Type requirement for the function body expression.
110    pub return_ty: Option<Ty>,
111
112    /// Expression containing parameter (and environment) references.
113    pub body: Box<Expr>,
114
115    /// Positional function parameters.
116    pub params: Vec<FuncParam>,
117
118    /// Named function parameters.
119    pub named_params: Vec<FuncParam>,
120
121    /// Generic type arguments within this function.
122    pub generic_type_params: Vec<GenericTypeParam>,
123}
124
125#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
126pub struct FuncParam {
127    pub name: String,
128
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub ty: Option<Ty>,
131
132    pub default_value: Option<Box<Expr>>,
133}
134
135#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
136pub struct GenericTypeParam {
137    /// Assigned name of this generic type argument.
138    pub name: String,
139
140    /// Possible values of this type argument.
141    /// For a given instance of this function, the argument must be
142    /// exactly one of types in the domain.
143    pub domain: Vec<Ty>,
144}
145
146/// A value and a series of functions that are to be applied to that value one after another.
147#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
148pub struct Pipeline {
149    pub exprs: Vec<Expr>,
150}
151
152pub type Range = generic::Range<Box<Expr>>;
153pub type InterpolateItem = generic::InterpolateItem<Expr>;
154pub type SwitchCase = generic::SwitchCase<Box<Expr>>;
155
156impl From<token::Literal> for ExprKind {
157    fn from(value: token::Literal) -> Self {
158        ExprKind::Literal(value)
159    }
160}
161
162impl From<Func> for ExprKind {
163    fn from(value: Func) -> Self {
164        ExprKind::Func(Box::new(value))
165    }
166}