use chrono::FixedOffset;
use serde::{Deserialize, Serialize};
use super::{
Call, CellPath, Expression, ExternalArgument, FullCellPath, Keyword, MatchPattern, Operator,
Range, Table, ValueWithUnit,
};
use crate::{
ast::ImportPattern, engine::StateWorkingSet, BlockId, ModuleId, OutDest, Signature, Span, VarId,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum Expr {
Bool(bool),
Int(i64),
Float(f64),
Binary(Vec<u8>),
Range(Box<Range>),
Var(VarId),
VarDecl(VarId),
Call(Box<Call>),
ExternalCall(Box<Expression>, Box<[ExternalArgument]>), Operator(Operator),
RowCondition(BlockId),
UnaryNot(Box<Expression>),
BinaryOp(Box<Expression>, Box<Expression>, Box<Expression>), Collect(VarId, Box<Expression>),
Subexpression(BlockId),
Block(BlockId),
Closure(BlockId),
MatchBlock(Vec<(MatchPattern, Expression)>),
List(Vec<ListItem>),
Table(Table),
Record(Vec<RecordItem>),
Keyword(Box<Keyword>),
ValueWithUnit(Box<ValueWithUnit>),
DateTime(chrono::DateTime<FixedOffset>),
Filepath(String, bool),
Directory(String, bool),
GlobPattern(String, bool),
String(String),
RawString(String),
CellPath(CellPath),
FullCellPath(Box<FullCellPath>),
ImportPattern(Box<ImportPattern>),
Overlay(Option<ModuleId>),
Signature(Box<Signature>),
StringInterpolation(Vec<Expression>),
GlobInterpolation(Vec<Expression>, bool),
Nothing,
Garbage,
}
const _: () = assert!(std::mem::size_of::<Expr>() <= 40);
impl Expr {
pub fn pipe_redirection(
&self,
working_set: &StateWorkingSet,
) -> (Option<OutDest>, Option<OutDest>) {
match self {
Expr::Call(call) => working_set.get_decl(call.decl_id).pipe_redirection(),
Expr::Collect(_, _) => {
(None, None)
},
Expr::Subexpression(block_id) | Expr::Block(block_id) => working_set
.get_block(*block_id)
.pipe_redirection(working_set),
Expr::FullCellPath(cell_path) => cell_path.head.expr.pipe_redirection(working_set),
Expr::Bool(_)
| Expr::Int(_)
| Expr::Float(_)
| Expr::Binary(_)
| Expr::Range(_)
| Expr::Var(_)
| Expr::UnaryNot(_)
| Expr::BinaryOp(_, _, _)
| Expr::Closure(_) | Expr::List(_)
| Expr::Table(_)
| Expr::Record(_)
| Expr::ValueWithUnit(_)
| Expr::DateTime(_)
| Expr::String(_)
| Expr::RawString(_)
| Expr::CellPath(_)
| Expr::StringInterpolation(_)
| Expr::GlobInterpolation(_, _)
| Expr::Nothing => {
(Some(OutDest::Null), None)
}
Expr::VarDecl(_)
| Expr::Operator(_)
| Expr::Filepath(_, _)
| Expr::Directory(_, _)
| Expr::GlobPattern(_, _)
| Expr::ImportPattern(_)
| Expr::Overlay(_)
| Expr::Signature(_)
| Expr::Garbage => {
(Some(OutDest::Null), None)
}
Expr::RowCondition(_) | Expr::MatchBlock(_) => {
(None, None)
}
Expr::ExternalCall(_, _) => {
(None, None)
}
Expr::Keyword(_) => {
(None, None)
}
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum RecordItem {
Pair(Expression, Expression),
Spread(Span, Expression),
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum ListItem {
Item(Expression),
Spread(Span, Expression),
}
impl ListItem {
pub fn expr(&self) -> &Expression {
let (ListItem::Item(expr) | ListItem::Spread(_, expr)) = self;
expr
}
pub fn expr_mut(&mut self) -> &mut Expression {
let (ListItem::Item(expr) | ListItem::Spread(_, expr)) = self;
expr
}
}