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 (None, None)
106 }
107 Expr::VarDecl(_)
108 | Expr::Operator(_)
109 | Expr::Filepath(_, _)
110 | Expr::Directory(_, _)
111 | Expr::GlobPattern(_, _)
112 | Expr::ImportPattern(_)
113 | Expr::Overlay(_)
114 | Expr::Signature(_)
115 | Expr::Garbage => {
116 (Some(OutDest::Null), None)
119 }
120 Expr::RowCondition(_) | Expr::MatchBlock(_) => {
121 (None, None)
124 }
125 Expr::ExternalCall(_, _) => {
126 (None, None)
128 }
129 Expr::Keyword(_) => {
130 (None, None)
132 }
133 }
134 }
135}
136
137#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
139pub enum RecordItem {
140 Pair(Expression, Expression),
142 Spread(Span, Expression),
144}
145
146#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
148pub enum ListItem {
149 Item(Expression),
151 Spread(Span, Expression),
153}
154
155impl ListItem {
156 pub fn expr(&self) -> &Expression {
157 let (ListItem::Item(expr) | ListItem::Spread(_, expr)) = self;
158 expr
159 }
160
161 pub fn expr_mut(&mut self) -> &mut Expression {
162 let (ListItem::Item(expr) | ListItem::Spread(_, expr)) = self;
163 expr
164 }
165}