Skip to content

Commit 67c3cda

Browse files
committed
Merge PR #155: Implement parser for arithmetic expressions
Merge branch 'pr-155' to add support for unary arithmetic operators including increment (++) and decrement (--) in both prefix and postfix forms. Resolved conflicts in: - parser.rs: Unified UnaryArithmeticExpr structure with Pre/Post variants - execute.rs: Updated evaluation logic for new operator structure - types.rs: Added unary_op method for pre/post increment/decrement The implementation now supports expressions like: - ++a (pre-increment) - a++ (post-increment) - --a (pre-decrement) - a-- (post-decrement)
2 parents 7a197ad + 6c19d8c commit 67c3cda

File tree

6 files changed

+408
-232
lines changed

6 files changed

+408
-232
lines changed

crates/deno_task_shell/src/grammar.pest

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -248,27 +248,33 @@ bitwise_or = { "|" }
248248
logical_and = { "&&" }
249249
logical_or = { "||" }
250250

251+
unary_plus = { "+" }
252+
unary_minus = { "-" }
253+
logical_not = { "!" }
254+
bitwise_not = { "~" }
255+
increment = { "++" }
256+
decrement = { "--" }
257+
251258
unary_arithmetic_expr = !{
252-
(unary_arithmetic_op | post_arithmetic_op) ~ (parentheses_expr | VARIABLE | NUMBER) |
253-
(parentheses_expr | VARIABLE | NUMBER) ~ post_arithmetic_op
259+
unary_pre_arithmetic_expr | unary_post_arithmetic_expr
254260
}
255261

256-
unary_arithmetic_op = _{
257-
unary_plus | unary_minus | logical_not | bitwise_not
262+
unary_pre_arithmetic_expr = !{
263+
pre_arithmetic_op ~ (parentheses_expr | VARIABLE | NUMBER)
258264
}
259265

260-
unary_plus = { "+" }
261-
unary_minus = { "-" }
262-
logical_not = { "!" }
263-
bitwise_not = { "~" }
266+
unary_post_arithmetic_expr = !{
267+
(parentheses_expr | VARIABLE | NUMBER) ~ post_arithmetic_op
268+
}
269+
270+
pre_arithmetic_op= !{
271+
increment | decrement | unary_plus | unary_minus | logical_not | bitwise_not
272+
}
264273

265274
post_arithmetic_op = !{
266275
increment | decrement
267276
}
268277

269-
increment = { "++" }
270-
decrement = { "--" }
271-
272278
assignment_operator = _{
273279
assign | multiply_assign | divide_assign | modulo_assign | add_assign | subtract_assign |
274280
left_shift_assign | right_shift_assign | bitwise_and_assign | bitwise_xor_assign | bitwise_or_assign

crates/deno_task_shell/src/parser.rs

Lines changed: 166 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -453,46 +453,41 @@ pub struct Arithmetic {
453453
#[derive(Debug, Clone, PartialEq, Eq, Error)]
454454
#[error("Invalid arithmetic part")]
455455
pub enum ArithmeticPart {
456-
#[error("Invalid parentheses expression")]
457-
ParenthesesExpr(Box<Arithmetic>),
458-
#[error("Invalid variable assignment")]
459-
VariableAssignment {
460-
name: String,
461-
op: AssignmentOp,
462-
value: Box<ArithmeticPart>,
463-
},
464-
#[error("Invalid triple conditional expression")]
465-
TripleConditionalExpr {
466-
condition: Box<ArithmeticPart>,
467-
true_expr: Box<ArithmeticPart>,
468-
false_expr: Box<ArithmeticPart>,
469-
},
470-
#[error("Invalid binary arithmetic expression")]
471-
BinaryArithmeticExpr {
472-
left: Box<ArithmeticPart>,
473-
operator: BinaryArithmeticOp,
474-
right: Box<ArithmeticPart>,
475-
},
476-
#[error("Invalid binary conditional expression")]
477-
BinaryConditionalExpr {
478-
left: Box<ArithmeticPart>,
479-
operator: BinaryOp,
480-
right: Box<ArithmeticPart>,
481-
},
482-
#[error("Invalid unary arithmetic expression")]
483-
UnaryArithmeticExpr {
484-
operator: UnaryArithmeticOp,
485-
operand: Box<ArithmeticPart>,
486-
},
487-
#[error("Invalid post arithmetic expression")]
488-
PostArithmeticExpr {
489-
operand: Box<ArithmeticPart>,
490-
operator: PostArithmeticOp,
491-
},
492-
#[error("Invalid variable")]
493-
Variable(String),
494-
#[error("Invalid number")]
495-
Number(String),
456+
#[error("Invalid parentheses expression")]
457+
ParenthesesExpr(Box<Arithmetic>),
458+
#[error("Invalid variable assignment")]
459+
VariableAssignment {
460+
name: String,
461+
op: AssignmentOp,
462+
value: Box<ArithmeticPart>,
463+
},
464+
#[error("Invalid triple conditional expression")]
465+
TripleConditionalExpr {
466+
condition: Box<ArithmeticPart>,
467+
true_expr: Box<ArithmeticPart>,
468+
false_expr: Box<ArithmeticPart>,
469+
},
470+
#[error("Invalid binary arithmetic expression")]
471+
BinaryArithmeticExpr {
472+
left: Box<ArithmeticPart>,
473+
operator: BinaryArithmeticOp,
474+
right: Box<ArithmeticPart>,
475+
},
476+
#[error("Invalid binary conditional expression")]
477+
BinaryConditionalExpr {
478+
left: Box<ArithmeticPart>,
479+
operator: BinaryOp,
480+
right: Box<ArithmeticPart>,
481+
},
482+
#[error("Invalid unary arithmetic expression")]
483+
UnaryArithmeticExpr {
484+
operator: UnaryArithmeticOp,
485+
operand: Box<ArithmeticPart>,
486+
},
487+
#[error("Invalid variable")]
488+
Variable(String),
489+
#[error("Invalid number")]
490+
Number(String),
496491
}
497492

498493
#[cfg_attr(feature = "serialization", derive(serde::Serialize))]
@@ -534,21 +529,31 @@ pub enum AssignmentOp {
534529
#[cfg_attr(feature = "serialization", derive(serde::Serialize))]
535530
#[cfg_attr(feature = "serialization", serde(rename_all = "camelCase"))]
536531
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
537-
pub enum UnaryArithmeticOp {
538-
Plus, // +
539-
Minus, // -
540-
LogicalNot, // !
541-
BitwiseNot, // ~
532+
pub enum PreArithmeticOp {
533+
Increment, // ++
534+
Decrement, // --
535+
Plus, // +
536+
Minus, // -
537+
LogicalNot, // !
538+
BitwiseNot, // ~
542539
}
543540

544541
#[cfg_attr(feature = "serialization", derive(serde::Serialize))]
545542
#[cfg_attr(feature = "serialization", serde(rename_all = "camelCase"))]
546-
#[derive(Debug, Clone, PartialEq, Eq)]
543+
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
547544
pub enum PostArithmeticOp {
548545
Increment, // ++
549546
Decrement, // --
550547
}
551548

549+
#[cfg_attr(feature = "serialization", derive(serde::Serialize))]
550+
#[cfg_attr(feature = "serialization", serde(rename_all = "camelCase"))]
551+
#[derive(Debug, Clone, PartialEq, Eq, Copy)]
552+
pub enum UnaryArithmeticOp {
553+
Pre(PreArithmeticOp),
554+
Post(PostArithmeticOp),
555+
}
556+
552557
#[cfg_attr(feature = "serialization", derive(serde::Serialize))]
553558
#[cfg_attr(
554559
feature = "serialization",
@@ -1707,119 +1712,126 @@ fn parse_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {
17071712
}
17081713

17091714
fn parse_unary_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {
1710-
let mut inner = pair.into_inner();
1711-
let first = inner.next().unwrap();
1712-
1713-
match first.as_rule() {
1714-
Rule::unary_arithmetic_op => {
1715-
let op = parse_unary_arithmetic_op(first)?;
1716-
let operand = parse_arithmetic_expr(inner.next().unwrap())?;
1717-
Ok(ArithmeticPart::UnaryArithmeticExpr {
1718-
operator: op,
1719-
operand: Box::new(operand),
1720-
})
1721-
}
1722-
Rule::post_arithmetic_op => {
1723-
let operand = parse_arithmetic_expr(inner.next().unwrap())?;
1724-
let op = parse_post_arithmetic_op(first)?;
1725-
Ok(ArithmeticPart::PostArithmeticExpr {
1726-
operand: Box::new(operand),
1727-
operator: op,
1728-
})
1729-
}
1730-
_ => {
1731-
let operand = parse_arithmetic_expr(first)?;
1732-
let op = parse_post_arithmetic_op(inner.next().unwrap())?;
1733-
Ok(ArithmeticPart::PostArithmeticExpr {
1734-
operand: Box::new(operand),
1735-
operator: op,
1736-
})
1737-
}
1715+
let mut inner = pair.into_inner();
1716+
let first = inner
1717+
.next()
1718+
.ok_or_else(|| miette!("Expected unary operator"))?;
1719+
1720+
match first.as_rule() {
1721+
Rule::unary_pre_arithmetic_expr => unary_pre_arithmetic_expr(first),
1722+
Rule::unary_post_arithmetic_expr => unary_post_arithmetic_expr(first),
1723+
_ => Err(miette!(
1724+
"Unexpected rule in unary arithmetic expression: {:?}",
1725+
first.as_rule()
1726+
)),
1727+
}
1728+
}
1729+
1730+
fn unary_pre_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {
1731+
let mut inner = pair.into_inner();
1732+
let first = inner
1733+
.next()
1734+
.ok_or_else(|| miette!("Expected unary pre operator"))?;
1735+
let second = inner.next().ok_or_else(|| miette!("Expected operand"))?;
1736+
let operand = match second.as_rule() {
1737+
Rule::parentheses_expr => {
1738+
let inner = second.into_inner().next().unwrap();
1739+
let parts = parse_arithmetic_sequence(inner)?;
1740+
Ok(ArithmeticPart::ParenthesesExpr(Box::new(Arithmetic {
1741+
parts,
1742+
})))
17381743
}
1739-
}
1740-
1741-
fn parse_unary_arithmetic_op(pair: Pair<Rule>) -> Result<UnaryArithmeticOp> {
1742-
match pair.as_str() {
1743-
"+" => Ok(UnaryArithmeticOp::Plus),
1744-
"-" => Ok(UnaryArithmeticOp::Minus),
1745-
"!" => Ok(UnaryArithmeticOp::LogicalNot),
1746-
"~" => Ok(UnaryArithmeticOp::BitwiseNot),
1747-
_ => Err(miette!(
1748-
"Invalid unary arithmetic operator: {}",
1749-
pair.as_str()
1750-
)),
1744+
Rule::VARIABLE => Ok(ArithmeticPart::Variable(second.as_str().to_string())),
1745+
Rule::NUMBER => Ok(ArithmeticPart::Number(second.as_str().to_string())),
1746+
_ => Err(miette!(
1747+
"Unexpected rule in arithmetic expression: {:?}",
1748+
second.as_rule()
1749+
)),
1750+
}?;
1751+
1752+
match first.as_rule() {
1753+
Rule::pre_arithmetic_op => {
1754+
let op = parse_pre_arithmetic_op(first)?;
1755+
Ok(ArithmeticPart::UnaryArithmeticExpr {
1756+
operator: UnaryArithmeticOp::Pre(op),
1757+
operand: Box::new(operand),
1758+
})
17511759
}
1752-
}
1753-
1754-
fn parse_post_arithmetic_op(pair: Pair<Rule>) -> Result<PostArithmeticOp> {
1755-
match pair.as_str() {
1756-
"++" => Ok(PostArithmeticOp::Increment),
1757-
"--" => Ok(PostArithmeticOp::Decrement),
1758-
_ => Err(miette!(
1759-
"Invalid post arithmetic operator: {}",
1760-
pair.as_str()
1761-
)),
1760+
Rule::post_arithmetic_op => {
1761+
let op = parse_post_arithmetic_op(first)?;
1762+
Ok(ArithmeticPart::UnaryArithmeticExpr {
1763+
operator: UnaryArithmeticOp::Post(op),
1764+
operand: Box::new(operand),
1765+
})
1766+
}
1767+
_ => Err(miette!(
1768+
"Unexpected rule in unary arithmetic operator: {:?}",
1769+
first.as_rule()
1770+
)),
1771+
}
1772+
}
1773+
1774+
fn unary_post_arithmetic_expr(pair: Pair<Rule>) -> Result<ArithmeticPart> {
1775+
let mut inner = pair.into_inner();
1776+
let first = inner
1777+
.next()
1778+
.ok_or_else(|| miette!("Expected unary post operator"))?;
1779+
let second = inner.next().ok_or_else(|| miette!("Expected operand"))?;
1780+
1781+
let operand = match first.as_rule() {
1782+
Rule::parentheses_expr => {
1783+
let inner = first.into_inner().next().unwrap();
1784+
let parts = parse_arithmetic_sequence(inner)?;
1785+
Ok(ArithmeticPart::ParenthesesExpr(Box::new(Arithmetic {
1786+
parts,
1787+
})))
17621788
}
1789+
Rule::VARIABLE => Ok(ArithmeticPart::Variable(first.as_str().to_string())),
1790+
Rule::NUMBER => Ok(ArithmeticPart::Number(first.as_str().to_string())),
1791+
_ => Err(miette!(
1792+
"Unexpected rule in arithmetic expression: {:?}",
1793+
first.as_rule()
1794+
)),
1795+
}?;
1796+
let op = parse_post_arithmetic_op(second)?;
1797+
Ok(ArithmeticPart::UnaryArithmeticExpr {
1798+
operator: UnaryArithmeticOp::Post(op),
1799+
operand: Box::new(operand),
1800+
})
1801+
}
1802+
1803+
fn parse_pre_arithmetic_op(pair: Pair<Rule>) -> Result<PreArithmeticOp> {
1804+
let first = pair
1805+
.into_inner()
1806+
.next()
1807+
.ok_or_else(|| miette!("Expected increment or decrement operator"))?;
1808+
match first.as_rule() {
1809+
Rule::increment => Ok(PreArithmeticOp::Increment),
1810+
Rule::decrement => Ok(PreArithmeticOp::Decrement),
1811+
Rule::unary_plus => Ok(PreArithmeticOp::Plus),
1812+
Rule::unary_minus => Ok(PreArithmeticOp::Minus),
1813+
Rule::logical_not => Ok(PreArithmeticOp::LogicalNot),
1814+
Rule::bitwise_not => Ok(PreArithmeticOp::BitwiseNot),
1815+
_ => Err(miette!(
1816+
"Unexpected rule in pre arithmetic operator: {:?}",
1817+
first.as_rule()
1818+
)),
1819+
}
17631820
}
17641821

1765-
fn parse_variable_expansion(part: Pair<Rule>) -> Result<WordPart> {
1766-
let mut inner = part.into_inner();
1767-
let variable = inner
1768-
.next()
1769-
.ok_or_else(|| miette!("Expected variable name"))?;
1770-
let variable_name = variable.as_str().to_string();
1771-
1772-
let modifier = inner.next();
1773-
let parsed_modifier = if let Some(modifier) = modifier {
1774-
match modifier.as_rule() {
1775-
Rule::VAR_SUBSTRING => {
1776-
let mut numbers = modifier.into_inner();
1777-
let begin: Word = if let Some(n) = numbers.next() {
1778-
parse_word(n)?
1779-
} else {
1780-
return Err(miette!(
1781-
"Expected a number for substring begin"
1782-
));
1783-
};
1784-
1785-
let length = if let Some(len_word) = numbers.next() {
1786-
Some(parse_word(len_word)?)
1787-
} else {
1788-
None
1789-
};
1790-
Some(Box::new(VariableModifier::Substring { begin, length }))
1791-
}
1792-
Rule::VAR_DEFAULT_VALUE => {
1793-
let value = if let Some(val) = modifier.into_inner().next() {
1794-
parse_word(val)?
1795-
} else {
1796-
Word::new_empty()
1797-
};
1798-
Some(Box::new(VariableModifier::DefaultValue(value)))
1799-
}
1800-
Rule::VAR_ASSIGN_DEFAULT => {
1801-
let value = modifier.into_inner().next().unwrap();
1802-
Some(Box::new(VariableModifier::AssignDefault(parse_word(
1803-
value,
1804-
)?)))
1805-
}
1806-
Rule::VAR_ALTERNATE_VALUE => {
1807-
let value = modifier.into_inner().next().unwrap();
1808-
Some(Box::new(VariableModifier::AlternateValue(parse_word(
1809-
value,
1810-
)?)))
1811-
}
1812-
_ => {
1813-
return Err(miette!(
1814-
"Unexpected rule in variable expansion modifier: {:?}",
1815-
modifier.as_rule()
1816-
));
1817-
}
1818-
}
1819-
} else {
1820-
None
1821-
};
1822-
Ok(WordPart::Variable(variable_name, parsed_modifier))
1822+
fn parse_post_arithmetic_op(pair: Pair<Rule>) -> Result<PostArithmeticOp> {
1823+
let first = pair
1824+
.into_inner()
1825+
.next()
1826+
.ok_or_else(|| miette!("Expected increment or decrement operator"))?;
1827+
match first.as_rule() {
1828+
Rule::increment => Ok(PostArithmeticOp::Increment),
1829+
Rule::decrement => Ok(PostArithmeticOp::Decrement),
1830+
_ => Err(miette!(
1831+
"Unexpected rule in post arithmetic operator: {:?}",
1832+
first.as_rule()
1833+
)),
1834+
}
18231835
}
18241836

18251837
fn parse_tilde_prefix(pair: Pair<Rule>) -> Result<WordPart> {

0 commit comments

Comments
 (0)