Repository: reubeno/brush
Pull request #387 (2025-02-20 04:52:40)

docs: add how to use via nixpkgs
I have added the package definition in https://github.com/NixOS/nixpkgs/pull/382795.
I hope this will make it easy to use by visitors without the build step. A binary cache of Nix might be an alternative solution for https://github.com/reubeno/brush/issues/69.


Patch:
diff --git a/README.md b/README.md
index 82c0613..b1b5fe6 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,8 @@
 [![CI workflow badge](https://github.com/reubeno/brush/actions/workflows/ci.yaml/badge.svg)](https://github.com/reubeno/brush/actions/workflows/ci.yaml)
 [![Devcontainer workflow badge](https://github.com/reubeno/brush/actions/workflows/devcontainer.yaml/badge.svg)](https://github.com/reubeno/brush/actions/workflows/devcontainer.yaml)
 
+[![Packaging status](https://repology.org/badge/vertical-allrepos/brush.svg)](https://repology.org/project/brush/versions)
+
 ## About
 
 `brush` (**B**o(u)rn(e) **RU**sty **SH**ell) is a [POSIX-](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html) and [bash-](https://www.gnu.org/software/bash/)compatible shell,
@@ -46,6 +48,12 @@ If you don't have `rust` installed, we recommend installing it via [`rustup`](ht
 (If you *are* interested in having a binary release, then please let us know in the 'Discussions' area of this
 project or by filing a feature request in 'Issues'.)
 
+If you are a Nix user, you can also use the registered version.
+
+```bash
+nix run 'github:NixOS/nixpkgs/nixpkgs-unstable#brush' -- --version
+```
+
 When you run `brush`, it should look exactly as `bash` would on your system since it processes `.bashrc` and
 other usual configuration. If you'd like to customize the look of `brush` to distinguish it from the other shells
 installed on your system, then you can also author a `~/.brushrc` file.
diff --git a/brush-parser/src/arithmetic.rs b/brush-parser/src/arithmetic.rs
index 7ea61da..d38cf51 100644
--- a/brush-parser/src/arithmetic.rs
+++ b/brush-parser/src/arithmetic.rs
@@ -101,9 +101,29 @@ peg::parser! {
         rule _() -> () = quiet!{[' ' | '\t' | '\n' | '\r']*} {}
 
         rule literal_number() -> i64 =
-            // TODO: handle explicit radix (e.g., <base>#<literal>) for bases 2 through 64
-            "0" ['x' | 'X'] s:$(['0'..='9' | 'a'..='f' | 'A'..='F']*) {? i64::from_str_radix(s, 16).or(Err("i64")) } /
-            s:$("0" ['0'..='8']*) {? i64::from_str_radix(s, 8).or(Err("i64")) } /
-            s:$(['1'..='9'] ['0'..='9']*) {? s.parse().or(Err("i64")) }
+            // Literal with explicit radix (format: <base>#<literal>)
+            radix:decimal_literal() "#" s:$(['0'..='9' | 'a'..='z' | 'A'..='Z']+) {?
+                // TODO: Support bases larger than 36. from_str_radix can't handle that.
+                if radix < 2 || radix > 36 {
+                    return Err("invalid base");
+                }
+
+                i64::from_str_radix(s, radix as u32).or(Err("i64"))
+            } /
+            // Hex literal
+            "0" ['x' | 'X'] s:$(['0'..='9' | 'a'..='f' | 'A'..='F']*) {?
+                i64::from_str_radix(s, 16).or(Err("i64"))
+            } /
+            // Octal literal
+            s:$("0" ['0'..='8']*) {?
+                i64::from_str_radix(s, 8).or(Err("i64"))
+            } /
+            // Decimal literal
+            decimal_literal()
+
+        rule decimal_literal() -> i64 =
+            s:$(['1'..='9'] ['0'..='9']*) {?
+                s.parse().or(Err("i64"))
+            }
     }
 }


Test patch:
diff --git a/brush-shell/tests/cases/arithmetic.yaml b/brush-shell/tests/cases/arithmetic.yaml
index 263a4b3..5e0ff56 100644
--- a/brush-shell/tests/cases/arithmetic.yaml
+++ b/brush-shell/tests/cases/arithmetic.yaml
@@ -18,6 +18,18 @@ cases:
       echo "$((0x10))"
       echo "$((0x010))"
 
+  - name: "Arithmetic literals with explicit bases"
+    stdin: |
+      echo "$((2#1010))"
+      echo "$((8#16))"
+      echo "$((16#faf))"
+      echo "$((36#vvv))"
+
+  - name: "Arithmetic literals with base 64 encoding"
+    known_failure: true # Not currently handled.
+    stdin: |
+      echo "$((64#zzz))"
+
   - name: "Parentheses"
     stdin: |
       echo "$(((10)))"