Skip to content

Commit

Permalink
Added remaining unary operations
Browse files Browse the repository at this point in the history
  • Loading branch information
Armd04 committed Oct 7, 2024
1 parent 97d53c2 commit 6c19d8c
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 46 deletions.
21 changes: 10 additions & 11 deletions crates/deno_task_shell/src/grammar.pest
Original file line number Diff line number Diff line change
Expand Up @@ -202,34 +202,33 @@ bitwise_or = { "|" }
logical_and = { "&&" }
logical_or = { "||" }

unary_plus = { "+" }
unary_minus = { "-" }
logical_not = { "!" }
bitwise_not = { "~" }
increment = { "++" }
decrement = { "--" }

unary_arithmetic_expr = !{
unary_pre_arithmetic_expr | unary_post_arithmetic_expr
}

unary_pre_arithmetic_expr = !{
(post_arithmetic_op | pre_arithmetic_op) ~ (parentheses_expr | VARIABLE | NUMBER)
pre_arithmetic_op ~ (parentheses_expr | VARIABLE | NUMBER)
}

unary_post_arithmetic_expr = !{
(parentheses_expr | VARIABLE | NUMBER) ~ post_arithmetic_op
}

pre_arithmetic_op= _{
unary_plus | unary_minus | logical_not | bitwise_not
pre_arithmetic_op= !{
increment | decrement | unary_plus | unary_minus | logical_not | bitwise_not
}

unary_plus = { "+" }
unary_minus = { "-" }
logical_not = { "!" }
bitwise_not = { "~" }

post_arithmetic_op = !{
increment | decrement
}

increment = { "++" }
decrement = { "--" }

assignment_operator = _{
assign | multiply_assign | divide_assign | modulo_assign | add_assign | subtract_assign |
left_shift_assign | right_shift_assign | bitwise_and_assign | bitwise_xor_assign | bitwise_or_assign
Expand Down
10 changes: 5 additions & 5 deletions crates/deno_task_shell/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1469,9 +1469,9 @@ fn unary_pre_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {
})
}
Rule::post_arithmetic_op => {
let op = parse_pre_arithmetic_op(first)?;
let op = parse_post_arithmetic_op(first)?;
Ok(ArithmeticPart::UnaryArithmeticExpr {
operator: UnaryArithmeticOp::Pre(op),
operator: UnaryArithmeticOp::Post(op),
operand: Box::new(operand),
})
}
Expand Down Expand Up @@ -1519,12 +1519,12 @@ 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::unary_plus => Ok(PreArithmeticOp::Plus),
Rule::unary_minus => Ok(PreArithmeticOp::Minus),
Rule::logical_not => Ok(PreArithmeticOp::LogicalNot),
Rule::bitwise_not => Ok(PreArithmeticOp::BitwiseNot),
_ => Err(miette!(
"Unexpected rule in post arithmetic operator: {:?}",
"Unexpected rule in pre arithmetic operator: {:?}",
first.as_rule()
)),
}
Expand Down
72 changes: 42 additions & 30 deletions crates/deno_task_shell/src/shell/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,17 +636,19 @@ impl ArithmeticResult {
ArithmeticValue::Integer(val) => match operand {
ArithmeticPart::Variable(name) => {
let mut new_changes = self.changes.clone();
new_changes.push(EnvChange::SetShellVar(
name.to_string(),
match op_type {
PreArithmeticOp::Increment => (*val + 1).to_string(),
PreArithmeticOp::Decrement => (*val - 1).to_string(),
_ => todo!(
"Unary arithmetic operation not implemented {:?}",
op_type
),
},
));
if op_type == PreArithmeticOp::Increment
|| op_type == PreArithmeticOp::Decrement
{
new_changes.push(EnvChange::SetShellVar(
name.to_string(),
match op_type {
PreArithmeticOp::Increment => (*val + 1).to_string(),
PreArithmeticOp::Decrement => (*val - 1).to_string(),
_ => Err(miette!("No change to ENV need for: {}", self))?,
},
));
}

Ok(ArithmeticResult {
value: match op_type {
PreArithmeticOp::Increment => {
Expand All @@ -655,10 +657,14 @@ impl ArithmeticResult {
PreArithmeticOp::Decrement => {
ArithmeticValue::Integer(*val - 1)
}
_ => todo!(
"Unary arithmetic operation not implemented {:?}",
op_type
),
PreArithmeticOp::Plus => ArithmeticValue::Integer((*val).abs()),
PreArithmeticOp::Minus => {
ArithmeticValue::Integer(-(*val).abs())
}
PreArithmeticOp::BitwiseNot => ArithmeticValue::Integer(!*val),
PreArithmeticOp::LogicalNot => {
ArithmeticValue::Integer(if *val == 0 { 1 } else { 0 })
}
},
changes: new_changes,
})
Expand All @@ -671,17 +677,19 @@ impl ArithmeticResult {
ArithmeticValue::Float(val) => match operand {
ArithmeticPart::Variable(name) => {
let mut new_changes = self.changes.clone();
new_changes.push(EnvChange::SetShellVar(
name.to_string(),
match op_type {
PreArithmeticOp::Increment => (*val + 1.0).to_string(),
PreArithmeticOp::Decrement => (*val - 1.0).to_string(),
_ => todo!(
"Unary arithmetic operation not implemented {:?}",
op_type
),
},
));
if op_type == PreArithmeticOp::Increment
|| op_type == PreArithmeticOp::Decrement
{
new_changes.push(EnvChange::SetShellVar(
name.to_string(),
match op_type {
PreArithmeticOp::Increment => (*val + 1.0).to_string(),
PreArithmeticOp::Decrement => (*val - 1.0).to_string(),
_ => Err(miette!("No change to ENV need for: {}", self))?,
},
));
}

Ok(ArithmeticResult {
value: match op_type {
PreArithmeticOp::Increment => {
Expand All @@ -690,10 +698,14 @@ impl ArithmeticResult {
PreArithmeticOp::Decrement => {
ArithmeticValue::Float(*val - 1.0)
}
_ => todo!(
"Unary arithmetic operation not implemented {:?}",
op_type
),
PreArithmeticOp::Plus => ArithmeticValue::Float((*val).abs()),
PreArithmeticOp::Minus => ArithmeticValue::Float(-(*val).abs()),
PreArithmeticOp::BitwiseNot => {
ArithmeticValue::Integer(!(*val as i64))
}
PreArithmeticOp::LogicalNot => {
ArithmeticValue::Float(if *val == 0.0 { 1.0 } else { 0.0 })
}
},
changes: new_changes,
})
Expand Down
24 changes: 24 additions & 0 deletions crates/tests/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,30 @@ async fn arithmetic() {
.assert_stdout("0\n")
.run()
.await;

TestBuilder::new()
.command("echo $((a=1, +a))")
.assert_stdout("1\n")
.run()
.await;

TestBuilder::new()
.command("echo $((a=1, -a))")
.assert_stdout("-1\n")
.run()
.await;

TestBuilder::new()
.command("echo $((a=3, ~a))")
.assert_stdout("-4\n")
.run()
.await;

TestBuilder::new()
.command("echo $((a=0, !a))")
.assert_stdout("1\n")
.run()
.await;
}

#[tokio::test]
Expand Down

0 comments on commit 6c19d8c

Please sign in to comment.