Skip to content

expand: Support integer bases in arithmetic#1328

Merged
mvdan merged 1 commit into
mvdan:masterfrom
stephen-fox:add-base-support-to-arith
May 10, 2026
Merged

expand: Support integer bases in arithmetic#1328
mvdan merged 1 commit into
mvdan:masterfrom
stephen-fox:add-base-support-to-arith

Conversation

@stephen-fox
Copy link
Copy Markdown
Contributor

@stephen-fox stephen-fox commented Apr 24, 2026

The existing arithmetic logic is hard coded to always treat strings as base 10 integers. This commit updates that logic to support what bash supports based on its manual page. [1]

References

  1. https://www.man7.org/linux/man-pages/man1/bash.1.html

@mvdan
Copy link
Copy Markdown
Owner

mvdan commented Apr 24, 2026

What shell syntax does this follow? I don't see any mention of 0b in man bash for example.

@stephen-fox
Copy link
Copy Markdown
Contributor Author

Hello @mdvan. The 0b is something I picked up from Go. If we want to adhere strictly to bash, this is what the manual page says:

Integer constants follow the C language definition, without
suffixes or character constants. Constants with a leading 0 are
interpreted as octal numbers. A leading 0x or 0X denotes
hexadecimal. Otherwise, numbers take the form [base#]n, where the
optional base is a decimal number between 2 and 64 representing
the arithmetic base, and n is a number in that base. If base# is
omitted, then base 10 is used. When specifying n, if a non-digit
is required, the digits greater than 9 are represented by the
lowercase letters, the uppercase letters, @, and _, in that order.
If base is less than or equal to 36, lowercase and uppercase
letters may be used interchangeably to represent numbers between
10 and 35.

... which I guess looks like this:

bash-3.2$ echo $((0xff+1))
256
bash-3.2$ echo $((0Xff+1))
256
bash-3.2$ echo $((0377+1))
256
bash-3.2$ echo $((10#1+1))
2
bash-3.2$ echo $((16#ff+1))
256
bash-3.2$ echo $((2#11111111+1))
256

Happy to update the commit to match that syntax.

@mvdan
Copy link
Copy Markdown
Owner

mvdan commented Apr 24, 2026

Yep, mimicking bash is good. Just add some tests near existing arithmetic ones.

@stephen-fox stephen-fox force-pushed the add-base-support-to-arith branch from e167cd2 to d96931f Compare May 1, 2026 22:40
@stephen-fox
Copy link
Copy Markdown
Contributor Author

@mvdan, I updated the commit to use bash's syntax for integer base handling. I am not a huge fan of the code I wrote, but I think it's a good starting point. I'm not sure if the test format is what you are looking for. But, the tests pass and the bash examples I posted earlier work now.

Copy link
Copy Markdown
Owner

@mvdan mvdan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! SGTM, just two thoughts.

Comment thread expand/arith.go Outdated
// letters may be used interchangeably to represent numbers between
// 10 and 35.
//
// - https://www.man7.org/linux/man-pages/man1/bash.1.html
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to quote the whole section of the bash man page; simply mention that this mimics the documented bash behavior.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed it.

Comment thread expand/expand_test.go Outdated
}
}

func TestArith(t *testing.T) {
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need to add an entirely new test; you can add test cases in interp/interp_test.go after the existing arithmetic ones with echo $((...)). An advantage of that route is that those get run against bash as well, so we catch any discrepancy.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I moved the tests around as requested.

@mvdan
Copy link
Copy Markdown
Owner

mvdan commented May 3, 2026

Also, please add "Fixes #339" to the commit message.

@stephen-fox stephen-fox force-pushed the add-base-support-to-arith branch 2 times, most recently from e7af52d to 7e66d77 Compare May 10, 2026 13:52
@stephen-fox
Copy link
Copy Markdown
Contributor Author

Hey @mvdan, I have updated the commit with the requested changes and ran the interp package's tests on a Debian machine and they passed.

Copy link
Copy Markdown
Owner

@mvdan mvdan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much!

@mvdan
Copy link
Copy Markdown
Owner

mvdan commented May 10, 2026

Hm, the tests failed on 32-bit.

@stephen-fox
Copy link
Copy Markdown
Contributor Author

Awesome. I can probably make the test pass by just using a smaller number... It does make me wonder about sh's handling of integer bit width and what the "correct" behavior would look like though.

@mvdan
Copy link
Copy Markdown
Owner

mvdan commented May 10, 2026

All the arithmetic code should be on 64-bit integers; there might be a spot that isn't the case. This might be a latent bug and not introduced by your fix, but perhaps just surfaced by your test.

@mvdan
Copy link
Copy Markdown
Owner

mvdan commented May 10, 2026

Ah, I see that expand.Arithm returns int rather than int64, and I have a TODO for that. Perhaps just comment out the test case you have here and add a smaller one for now. I'll deal with the int vs int64 issue at a later time.

@stephen-fox stephen-fox force-pushed the add-base-support-to-arith branch from 7e66d77 to 6e66536 Compare May 10, 2026 18:39
The existing arithmetic logic is hard coded to always treat
strings as base 10 integers. This commit updates that logic
to support what bash supports based on its manual page. [1]

References

1. https://www.man7.org/linux/man-pages/man1/bash.1.html

Fixes mvdan#339.
@stephen-fox stephen-fox force-pushed the add-base-support-to-arith branch from 6e66536 to e124d5f Compare May 10, 2026 18:41
@stephen-fox
Copy link
Copy Markdown
Contributor Author

I commented out that test and added another with a smaller number.

@mvdan mvdan merged commit f5c6e27 into mvdan:master May 10, 2026
8 checks passed
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.

2 participants