diff --git a/crates/deno_task_shell/src/grammar.pest b/crates/deno_task_shell/src/grammar.pest index 1a6d9a7..1481416 100644 --- a/crates/deno_task_shell/src/grammar.pest +++ b/crates/deno_task_shell/src/grammar.pest @@ -208,7 +208,6 @@ unary_arithmetic_expr = !{ unary_pre_arithmetic_expr = !{ (post_arithmetic_op | pre_arithmetic_op) ~ (parentheses_expr | VARIABLE | NUMBER) - } unary_post_arithmetic_expr = !{ diff --git a/crates/deno_task_shell/src/parser.rs b/crates/deno_task_shell/src/parser.rs index 026bb7b..a848bc1 100644 --- a/crates/deno_task_shell/src/parser.rs +++ b/crates/deno_task_shell/src/parser.rs @@ -426,11 +426,6 @@ pub enum ArithmeticPart { operator: BinaryOp, right: Box, }, - #[error("Invalid unary arithmetic expression")] - UnaryArithmeticExpr { - operator: UnaryArithmeticOp, - operand: Box, - }, #[error("Invalid pre arithmetic expression")] PreArithmeticExpr { operator: PreArithmeticOp, @@ -486,21 +481,15 @@ pub enum AssignmentOp { #[cfg_attr(feature = "serialization", derive(serde::Serialize))] #[cfg_attr(feature = "serialization", serde(rename_all = "camelCase"))] #[derive(Debug, Clone, PartialEq, Eq, Copy)] -pub enum UnaryArithmeticOp { +pub enum PreArithmeticOp { + Increment, // ++ + Decrement, // -- Plus, // + Minus, // - LogicalNot, // ! BitwiseNot, // ~ } -#[cfg_attr(feature = "serialization", derive(serde::Serialize))] -#[cfg_attr(feature = "serialization", serde(rename_all = "camelCase"))] -#[derive(Debug, Clone, PartialEq, Eq, Copy)] -pub enum PreArithmeticOp { - Increment, // ++ - Decrement, // -- -} - #[cfg_attr(feature = "serialization", derive(serde::Serialize))] #[cfg_attr(feature = "serialization", serde(rename_all = "camelCase"))] #[derive(Debug, Clone, PartialEq, Eq, Copy)] @@ -1470,16 +1459,16 @@ fn unary_pre_arithmetic_expr(pair: Pair) -> Result { match first.as_rule() { Rule::pre_arithmetic_op => { - let op = parse_unary_arithmetic_op(first)?; - Ok(ArithmeticPart::UnaryArithmeticExpr { - operator: (op), + let op = parse_pre_arithmetic_op(first)?; + Ok(ArithmeticPart::PreArithmeticExpr { + operator: op, operand: (Box::new(operand)), }) } Rule::post_arithmetic_op => { let op = parse_pre_arithmetic_op(first)?; Ok(ArithmeticPart::PreArithmeticExpr { - operator: (op), + operator: op, operand: (Box::new(operand)), }) } @@ -1514,29 +1503,11 @@ fn unary_post_arithmetic_expr(pair: Pair) -> Result { }?; let op = parse_post_arithmetic_op(second)?; Ok(ArithmeticPart::PostArithmeticExpr { - operator: (op), + operator: op, operand: (Box::new(operand)), }) } -fn parse_unary_arithmetic_op(pair: Pair) -> Result { - let first = pair - .into_inner() - .next() - .ok_or_else(|| miette!("Expected unary operator"))?; - - match first.as_rule() { - Rule::add => Ok(UnaryArithmeticOp::Plus), - Rule::subtract => Ok(UnaryArithmeticOp::Minus), - Rule::logical_not => Ok(UnaryArithmeticOp::LogicalNot), - Rule::bitwise_not => Ok(UnaryArithmeticOp::BitwiseNot), - _ => Err(miette!( - "Unexpected rule in unary arithmetic operator: {:?}", - first.as_rule() - )), - } -} - fn parse_pre_arithmetic_op(pair: Pair) -> Result { let first = pair .into_inner() @@ -1545,6 +1516,10 @@ fn parse_pre_arithmetic_op(pair: Pair) -> Result { match first.as_rule() { Rule::increment => Ok(PreArithmeticOp::Increment), Rule::decrement => Ok(PreArithmeticOp::Decrement), + Rule::add => Ok(PreArithmeticOp::Plus), + Rule::subtract => Ok(PreArithmeticOp::Minus), + Rule::logical_not => Ok(PreArithmeticOp::LogicalNot), + Rule::bitwise_not => Ok(PreArithmeticOp::BitwiseNot), _ => Err(miette!( "Unexpected rule in post arithmetic operator: {:?}", first.as_rule() diff --git a/crates/deno_task_shell/src/shell/execute.rs b/crates/deno_task_shell/src/shell/execute.rs index bf00060..1ad4feb 100644 --- a/crates/deno_task_shell/src/shell/execute.rs +++ b/crates/deno_task_shell/src/shell/execute.rs @@ -52,7 +52,6 @@ use crate::parser::RedirectOp; use crate::parser::Sequence; use crate::parser::SequentialList; use crate::parser::SimpleCommand; -use crate::parser::UnaryArithmeticOp; use crate::parser::Word; use crate::parser::WordPart; use crate::shell::types::WordEvalResult; @@ -644,10 +643,6 @@ async fn evaluate_arithmetic_part( let rhs = Box::pin(evaluate_arithmetic_part(right, state)).await?; apply_conditional_binary_op(lhs, operator, rhs) } - ArithmeticPart::UnaryArithmeticExpr { operator, operand } => { - let val = Box::pin(evaluate_arithmetic_part(operand, state)).await?; - apply_unary_op(*operator, val) - } ArithmeticPart::PostArithmeticExpr { operand, operator } => { let val = Box::pin(evaluate_arithmetic_part(operand, state)).await?; apply_post_op(state, *operator, val, operand) @@ -737,22 +732,6 @@ fn apply_conditional_binary_op( } } -fn apply_unary_op( - op: UnaryArithmeticOp, - val: ArithmeticResult, -) -> Result { - match op { - UnaryArithmeticOp::Plus => Ok(val), - UnaryArithmeticOp::Minus => val.checked_neg(), - UnaryArithmeticOp::LogicalNot => Ok(if val.is_zero() { - ArithmeticResult::new(ArithmeticValue::Integer(1)) - } else { - ArithmeticResult::new(ArithmeticValue::Integer(0)) - }), - UnaryArithmeticOp::BitwiseNot => val.checked_not(), - } -} - fn apply_pre_op( state: &mut ShellState, op: PreArithmeticOp, @@ -772,6 +751,9 @@ fn apply_pre_op( state.apply_changes(&result_clone.changes); Ok(result) } + _ => { + todo!("Pre arithmetic operator {:?} is not implemented", op) + } } } diff --git a/crates/deno_task_shell/src/shell/types.rs b/crates/deno_task_shell/src/shell/types.rs index bbfbb1f..92a484c 100644 --- a/crates/deno_task_shell/src/shell/types.rs +++ b/crates/deno_task_shell/src/shell/types.rs @@ -1044,45 +1044,6 @@ impl ArithmeticResult { }) } - pub fn checked_neg(&self) -> Result { - let result = match &self.value { - ArithmeticValue::Integer(val) => val - .checked_neg() - .map(ArithmeticValue::Integer) - .ok_or_else(|| anyhow::anyhow!("Integer overflow: -{}", val))?, - ArithmeticValue::Float(val) => { - let result = -val; - if result.is_finite() { - ArithmeticValue::Float(result) - } else { - return Err(anyhow::anyhow!("Float overflow: -{}", val)); - } - } - }; - - Ok(ArithmeticResult { - value: result, - changes: self.changes.clone(), - }) - } - - pub fn checked_not(&self) -> Result { - let result = match &self.value { - ArithmeticValue::Integer(val) => ArithmeticValue::Integer(!val), - ArithmeticValue::Float(_) => { - return Err(anyhow::anyhow!( - "Invalid arithmetic result type for bitwise NOT: {}", - self - )) - } - }; - - Ok(ArithmeticResult { - value: result, - changes: self.changes.clone(), - }) - } - pub fn checked_shl( &self, other: &ArithmeticResult,