Skip to content

Conditions read =~ and $(( )) as the walk does; bash's integers at start (refactor 3.2, S2) - #242

Open
sf624 wants to merge 6 commits into
refactor/3.2-treesfrom
refactor/3.2-conditions
Open

sf624 wants to merge 6 commits into
refactor/3.2-treesfrom
refactor/3.2-conditions

Conversation

@sf624

@sf624 sf624 commented Oct 23, 2026 •

Copy link
Copy Markdown
Owner

Step 3.2 of docs/design/refactor.md, layer 3 of 3 (stack: #240 → #241 → #242). Also updates the traceability rows S2, S5, S7.

Addresses: S2 (the leftovers of 2.6 given to 3.2)

  • Integers at start: OPTIND, RANDOM, SRANDOM and HISTCMD have the integer attribute in the start state (INTEGERS_AT_START, vars.ts; also the baseline of test/state-probes.test.ts), and text given to an integer runs through the walk's arithmetic with what it assigns (WalkArith.integer): OPTIND='x=5' and declare -i n; n='x=5' set x in the state, as bash does (before, x kept its value). test/state.test.ts "runs the text given to an integer as arithmetic…" (bash rows, including unset OPTIND, local OPTIND, 64-bit wrap and an error). OPTIND=1 keeps status 0.
  • =~: its right side is read with expansions (wordIn(…, 'regex'), quoted characters escaped as bash does) and decided when it matches plain text (plainRegex): p=b; [[ abc =~ $p ]], "$p", ^a$p, a\.c. test/conditions.test.ts rows against bash.
  • $(( )) in conditions: run with the walk's arithmetic (ValueSource.arith), not the constant evaluator: false; [[ $(( $? + 1 )) == 2 ]] is decided. (A name arithmetic reads stays untrusted by the scan, so n=2; [[ $(( n + 1 )) == 3 ]] is not.)
  • Cost per read: a plain word is its own value at once, commandName is kept per node, the walk reads a tree's definitions in one pass. esbuild bundle, main → this stack (medians): a 1,801-line script of conditions 145 → 112 ms, bash_completion 95 → 84 ms, the fixtures 15 → 11 ms.

Not reproduced: the chain of functions where f_i calls f_{i-1} in $( ) and f_{i-2} outside (with and without set -e, several body shapes) stays at 2–20 ms for 40 functions, before and after; no timing test added.

Probe tests and test/decisions.test.ts unchanged (only the probe baseline now comes from vars.ts); fixture dumps unchanged. Node 24 coverage 100%, snippets check clean. CHANGELOG: New (=~, $(( ))) and Fixed (integers).

🤖 Generated with Claude Code

@sf624
sf624 added this pull request to stack #243 October 23, 2026 09:17
@sf624
sf624 force-pushed the refactor/3.2-conditions branch from bb785f6 to db0c72a Compare October 23, 2026 09:18
@sf624 sf624 changed the title Conditions read =~ and $(( )) as the walk does; bash's integers at start (refactor 3.2, S2 leftovers) Conditions read =~ and $(( )) as the walk does; bash's integers at start (refactor 3.2, S2) Oct 23, 2026
@github-actions

github-actions Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

sf624 and others added 5 commits October 23, 2026 21:49
…art (refactor 3.2, S2 leftovers)

- The right of `=~` is read with expansions (wordIn 'regex': quoted
  characters escaped as bash does), and decided when it matches plain
  text (plainRegex); `$(( ))` in a condition's word runs with the
  walk's arithmetic (ValueSource.arith), not the constant evaluator.
- The start state gives OPTIND, RANDOM, SRANDOM and HISTCMD the integer
  attribute (vars.ts INTEGERS_AT_START), and text given to an integer runs
  through the walk's arithmetic with what it assigns: `OPTIND='x=5'` and
  `declare -i n; n='x=5'` set x in the state, as in bash.
- A condition costs less per read: a plain word is its own value at once,
  commandName is kept per node, and the walk reads the definitions of a
  tree in one pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…or eval is made without the integer and case attributes

`declare -i n; n='x=5' f` set x in the model; bash gives the temporary n the text as it is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ashes the model; += to an integer runs before any command (review of 3.2)

`n[0]=5 f` and `n[0]=5 eval :` threw a TypeError (also on main): bash refuses such an assignment and runs the command.
`declare -i n; n+='x=7' true` sets x in bash, as before a function; the model kept x=1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ly the first += of a name runs arithmetic (review of 3.2)

`n+='x=7' n+='x=9' true` sets x to 7 in bash; the model ran x=9. The CHANGELOG says what bash does with an element
assigned before a special builtin in POSIX mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tin in POSIX mode: a limitation in the README, not a CHANGELOG line

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch was successfully deployed

1 active (outdated) deployment
github-pages — 6db75343 Deployed Oct 23, 2026 by sf624 via Deploy to GitHub Pages #514
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant