-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Hi, thank you so much for this project! While using it, I've run into a small limitation.
unbash parses command substitutions as structured CommandExpansion nodes in normal shell-word contexts, but inside arithmetic they are currently flattened into opaque ArithmeticWord nodes.
Problem
In arithmetic contexts such as:
$(( $(cmd) + 1 ))(( $(cmd) + 1 ))
the embedded $(cmd) is preserved only as raw text inside ArithmeticWord.value, rather than being represented structurally in the arithmetic AST.
Repro
Arithmetic expansion
import { parse } from "unbash";
const ast = parse("echo $(( $(rm -rf /) + 1 ))");
console.log(JSON.stringify(ast, null, 2));The arithmetic part is currently shaped like this:
{
"type": "ArithmeticExpansion",
"text": "$(( $(rm -rf /) + 1 ))",
"expression": {
"type": "ArithmeticBinary",
"operator": "+",
"left": {
"type": "ArithmeticWord",
"value": "$(rm -rf /)"
},
"right": {
"type": "ArithmeticWord",
"value": "1"
}
}
}Arithmetic command
import { parse } from "unbash";
const ast = parse("(( $(rm -rf /) + 1 ))");
const cmd = ast.commands[0].command;
console.log(cmd.body);
console.log(cmd.expression);Current behavior:
- top-level node is
ArithmeticCommand bodyis" $(rm -rf /) + 1 "expressionis anArithmeticBinaryexpression.leftis anArithmeticWordwithvalue: "$(rm -rf /)"
Why this matters
This makes arithmetic inconsistent with normal shell-word parsing, where command substitutions are exposed structurally and can be recursively analyzed.
For downstream consumers that walk the AST to inspect nested commands, arithmetic currently creates a blind spot and forces substring/reparse workarounds.
Expected behavior
Command substitutions inside arithmetic should ideally be represented structurally in the AST, rather than flattened into ArithmeticWord.
From reading the source, this appears to come from src/arithmetic.ts, where readDollarAtom() currently treats $(...) as an ArithmeticWord.
I’d be happy to help with a PR if this sounds like a change you’d be open to.