1use chrono::FixedOffset;
2use serde::{Deserialize, Serialize};
3
4use super::{
5 AttributeBlock, Call, CellPath, Expression, ExternalArgument, FullCellPath, Keyword,
6 MatchPattern, Operator, Range, Table, ValueWithUnit,
7};
8use crate::{
9 BlockId, ModuleId, OutDest, Signature, Span, VarId, ast::ImportPattern, engine::StateWorkingSet,
10};
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub enum Expr {
15 AttributeBlock(AttributeBlock),
16 Bool(bool),
17 Int(i64),
18 Float(f64),
19 Binary(Vec<u8>),
20 Range(Box<Range>),
21 Var(VarId),
22 VarDecl(VarId),
23 Call(Box<Call>),
24 ExternalCall(Box<Expression>, Box<[ExternalArgument]>), Operator(Operator),
26 RowCondition(BlockId),
27 UnaryNot(Box<Expression>),
28 BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), Collect(VarId, Box<Expression>),
30 Subexpression(BlockId),
31 Block(BlockId),
32 Closure(BlockId),
33 MatchBlock(Vec<(MatchPattern, Expression)>),
34 List(Vec<ListItem>),
35 Table(Table),
36 Record(Vec<RecordItem>),
37 Keyword(Box<Keyword>),
38 ValueWithUnit(Box<ValueWithUnit>),
39 DateTime(chrono::DateTime<FixedOffset>),
40 Filepath(String, bool),
42 Directory(String, bool),
44 GlobPattern(String, bool),
46 String(String),
47 RawString(String),
48 CellPath(CellPath),
49 FullCellPath(Box<FullCellPath>),
50 ImportPattern(Box<ImportPattern>),
51 Overlay(Option<ModuleId>),
52 Signature(Box<Signature>),
53 StringInterpolation(Vec<Expression>),
54 GlobInterpolation(Vec<Expression>, bool),
56 Nothing,
57 Garbage,
58}
59
60const _: () = assert!(std::mem::size_of::<Expr>() <= 40);
64
65impl Expr {
66 pub fn pipe_redirection(
67 &self,
68 working_set: &StateWorkingSet,
69 ) -> (Option<OutDest>, Option<OutDest>) {
70 match self {
71 Expr::AttributeBlock(ab) => ab.item.expr.pipe_redirection(working_set),
72 Expr::Call(call) => working_set.get_decl(call.decl_id).pipe_redirection(),
73 Expr::Collect(_, _) => {
74 (None, None)
77 },
78 Expr::Subexpression(block_id) | Expr::Block(block_id) => working_set
79 .get_block(*block_id)
80 .pipe_redirection(working_set),
81 Expr::FullCellPath(cell_path) => cell_path.head.expr.pipe_redirection(working_set),
82 Expr::Bool(_)
83 | Expr::Int(_)
84 | Expr::Float(_)
85 | Expr::Binary(_)
86 | Expr::Range(_)
87 | Expr::Var(_)
88 | Expr::UnaryNot(_)
89 | Expr::BinaryOp(_, _, _)
90 | Expr::Closure(_) | Expr::List(_)
92 | Expr::Table(_)
93 | Expr::Record(_)
94 | Expr::ValueWithUnit(_)
95 | Expr::DateTime(_)
96 | Expr::String(_)
97 | Expr::RawString(_)
98 | Expr::CellPath(_)
99 | Expr::StringInterpolation(_)
100 | Expr::GlobInterpolation(_, _)
101 | Expr::Nothing => {
102 (Some(OutDest::Null), None)
105 }
106 Expr::VarDecl(_)
107 | Expr::Operator(_)
108 | Expr::Filepath(_, _)
109 | Expr::Directory(_, _)
110 | Expr::GlobPattern(_, _)
111 | Expr::ImportPattern(_)
112 | Expr::Overlay(_)
113 | Expr::Signature(_)
114 | Expr::Garbage => {
115 (Some(OutDest::Null), None)
118 }
119 Expr::RowCondition(_) | Expr::MatchBlock(_) => {
120 (None, None)
123 }
124 Expr::ExternalCall(_, _) => {
125 (None, None)
127 }
128 Expr::Keyword(_) => {
129 (None, None)
131 }
132 }
133 }
134}
135
136#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
138pub enum RecordItem {
139 Pair(Expression, Expression),
141 Spread(Span, Expression),
143}
144
145#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
147pub enum ListItem {
148 Item(Expression),
150 Spread(Span, Expression),
152}
153
154impl ListItem {
155 pub fn expr(&self) -> &Expression {
156 let (ListItem::Item(expr) | ListItem::Spread(_, expr)) = self;
157 expr
158 }
159
160 pub fn expr_mut(&mut self) -> &mut Expression {
161 let (ListItem::Item(expr) | ListItem::Spread(_, expr)) = self;
162 expr
163 }
164}