From ea54f87ea06f48035878c1ff2659d6bb7dd4f512 Mon Sep 17 00:00:00 2001 From: Mykhailo Chalyi Date: Fri, 27 Mar 2026 23:41:01 +0000 Subject: [PATCH] fix(interpreter): expand special variables ($#, $?, etc.) in arithmetic Special shell variables like $# were not recognized by expand_arithmetic_vars_depth because it only consumed alphanumeric/_ chars after $. Add handling for special variable characters (#, ?, $, !, @, *, -) so they resolve correctly inside (( )) arithmetic context. Closes #876 --- crates/bashkit/src/interpreter/mod.rs | 11 +++++++++ .../tests/spec_cases/bash/arithmetic.test.sh | 23 +++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/crates/bashkit/src/interpreter/mod.rs b/crates/bashkit/src/interpreter/mod.rs index aca72bdb..8b261484 100644 --- a/crates/bashkit/src/interpreter/mod.rs +++ b/crates/bashkit/src/interpreter/mod.rs @@ -7165,6 +7165,17 @@ impl Interpreter { } else { result.push_str(&expanded); } + } else if let Some(&c) = chars.peek() + && matches!(c, '#' | '?' | '$' | '!' | '@' | '*' | '-') + { + // Handle special variables: $#, $?, $$, $!, $@, $*, $- + chars.next(); + let value = self.expand_variable(&c.to_string()); + if value.is_empty() { + result.push('0'); + } else { + result.push_str(&value); + } } else { // Handle $var syntax (common in arithmetic) let mut name = String::new(); diff --git a/crates/bashkit/tests/spec_cases/bash/arithmetic.test.sh b/crates/bashkit/tests/spec_cases/bash/arithmetic.test.sh index 3ca493fe..9ad74ee0 100644 --- a/crates/bashkit/tests/spec_cases/bash/arithmetic.test.sh +++ b/crates/bashkit/tests/spec_cases/bash/arithmetic.test.sh @@ -493,3 +493,26 @@ echo $x ### expect 42 ### end + +### arith_special_var_hash +# $# in arithmetic context +set -- a b c +echo "argc: $#" +(( $# > 0 )) && echo "true" || echo "false" +(( 3 > 0 )) && echo "true2" || echo "false2" +x=$# +(( x > 0 )) && echo "true3" || echo "false3" +### expect +argc: 3 +true +true2 +true3 +### end + +### arith_special_var_question +# $? in arithmetic context +true +(( $? == 0 )) && echo "zero" || echo "nonzero" +### expect +zero +### end