Description
The parser treats done as a reserved word even in case pattern position, preventing it from being used as a literal pattern in case statements. In real bash, reserved words are valid as case patterns.
Reproduction
case "$status" in
done) echo "completed" ;;
pending) echo "waiting" ;;
esac
# Expected: matches "done" literally
# Actual: parse error — parser sees "done" as loop terminator keyword
Root Cause
In crates/bashkit/src/parser/mod.rs, case pattern parsing at line 983-1003 only accepts Word, LiteralWord, and QuotedWord tokens:
while matches!(
&self.current_token,
Some(tokens::Token::Word(_))
| Some(tokens::Token::LiteralWord(_))
| Some(tokens::Token::QuotedWord(_))
) {
But the is_keyword check at line 1492-1493 matches Word("done"):
fn is_keyword(&self, keyword: &str) -> bool {
matches!(&self.current_token, Some(tokens::Token::Word(w)) if w == keyword)
}
And NON_COMMAND_WORDS at line 1483-1484 includes "done":
const NON_COMMAND_WORDS: &'static [&'static str] =
&["then", "else", "elif", "fi", "do", "done", "esac", "in"];
The issue is that while the case pattern loop does accept Word tokens, the surrounding while !self.is_keyword("esac") check at line 970 doesn't interfere — but done as a Word token may be consumed elsewhere or the tokenizer may prevent it from reaching the pattern parser.
Suggested Fix
In case pattern position, all words (including reserved words like done, do, if, etc.) should be treated as literal patterns. The pattern parser should accept any word token regardless of reserved word status.
Impact
Low-Medium — Affects scripts using status strings like "done", "in", "do" as case patterns. Found in GPT eval run.
Found In
Eval run 2026-02-25 (GPT model).
Description
The parser treats
doneas a reserved word even in case pattern position, preventing it from being used as a literal pattern incasestatements. In real bash, reserved words are valid as case patterns.Reproduction
Root Cause
In
crates/bashkit/src/parser/mod.rs, case pattern parsing at line 983-1003 only acceptsWord,LiteralWord, andQuotedWordtokens:But the
is_keywordcheck at line 1492-1493 matchesWord("done"):And
NON_COMMAND_WORDSat line 1483-1484 includes"done":The issue is that while the case pattern loop does accept
Wordtokens, the surroundingwhile !self.is_keyword("esac")check at line 970 doesn't interfere — butdoneas a Word token may be consumed elsewhere or the tokenizer may prevent it from reaching the pattern parser.Suggested Fix
In case pattern position, all words (including reserved words like
done,do,if, etc.) should be treated as literal patterns. The pattern parser should accept any word token regardless of reserved word status.Impact
Low-Medium — Affects scripts using status strings like "done", "in", "do" as case patterns. Found in GPT eval run.
Found In
Eval run 2026-02-25 (GPT model).