Skip to content

Commit

Permalink
Combined unary and pre expr
Browse files Browse the repository at this point in the history
  • Loading branch information
Armd04 committed Sep 24, 2024
1 parent 781b0b8 commit 237ac4e
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 98 deletions.
1 change: 0 additions & 1 deletion crates/deno_task_shell/src/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -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 = !{
Expand Down
49 changes: 12 additions & 37 deletions crates/deno_task_shell/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,11 +426,6 @@ pub enum ArithmeticPart {
operator: BinaryOp,
right: Box<ArithmeticPart>,
},
#[error("Invalid unary arithmetic expression")]
UnaryArithmeticExpr {
operator: UnaryArithmeticOp,
operand: Box<ArithmeticPart>,
},
#[error("Invalid pre arithmetic expression")]
PreArithmeticExpr {
operator: PreArithmeticOp,
Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -1470,16 +1459,16 @@ fn unary_pre_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {

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)),
})
}
Expand Down Expand Up @@ -1514,29 +1503,11 @@ fn unary_post_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {
}?;
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<Rule>) -> Result<UnaryArithmeticOp> {
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<Rule>) -> Result<PreArithmeticOp> {
let first = pair
.into_inner()
Expand All @@ -1545,6 +1516,10 @@ fn parse_pre_arithmetic_op(pair: Pair<Rule>) -> Result<PreArithmeticOp> {
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()
Expand Down
24 changes: 3 additions & 21 deletions crates/deno_task_shell/src/shell/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -737,22 +732,6 @@ fn apply_conditional_binary_op(
}
}

fn apply_unary_op(
op: UnaryArithmeticOp,
val: ArithmeticResult,
) -> Result<ArithmeticResult, Error> {
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,
Expand All @@ -772,6 +751,9 @@ fn apply_pre_op(
state.apply_changes(&result_clone.changes);
Ok(result)
}
_ => {
todo!("Pre arithmetic operator {:?} is not implemented", op)
}
}
}

Expand Down
39 changes: 0 additions & 39 deletions crates/deno_task_shell/src/shell/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1044,45 +1044,6 @@ impl ArithmeticResult {
})
}

pub fn checked_neg(&self) -> Result<ArithmeticResult, Error> {
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<ArithmeticResult, Error> {
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,
Expand Down

0 comments on commit 237ac4e

Please sign in to comment.