Skip to content

Add word bitwise NOT with ~ and ~= sugar - #536

Open
axic wants to merge 1 commit into
argotorg:mainfrom
axic:bitwise-not-sugar
Open

Add word bitwise NOT with ~ and ~= sugar#536
axic wants to merge 1 commit into
argotorg:mainfrom
axic:bitwise-not-sugar

Conversation

@axic

@axic axic commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

This follows #485 where this was missed. It uses ~ which is the same as Solidity.

Mirror the binary bitwise operators (&/|/^ from #485) for the unary bitwise NOT, reusing the existing bnotWord primitive (already constant-folded via the not opcode in MastEval):

  • std: add a BitNot type class with word (backed by bnotWord) and uint256 (via Typedef.rep/abs) instances, and export the class. Method name bnot is kept distinct from the boolean not used by !.
  • Parser: ~ prefix operator (same precedence level as !, guarded against ~=) and the unary ~= compound assignment.
  • AST: ExpBNot and StmtBNotEq (a single operand — it is unary), with name resolution desugaring ~ -> BitNot.bnot and e ~= to the in-place e := ~e.
  • Pretty printer and module type-ref renamer handle the new nodes.
  • Test: extend cases/bitwise.solc to exercise ~, ~=, and the bnotWord constant folding (~(~x) == x, a & ~0 == a).

~ (not !) matches Solidity, which uses ~ for bitwise NOT and ! for logical NOT; ! is already taken here for logical NOT (ExpLNot).

@axic axic mentioned this pull request Aug 1, 2026
23 tasks
Mirror the binary bitwise operators (`&`/`|`/`^` from argotorg#485) for the unary
bitwise NOT, reusing the existing `bnotWord` primitive (already
constant-folded via the `not` opcode in MastEval):

- std: add a `BitNot` type class with `word` (backed by `bnotWord`) and
  `uint256` (via `Typedef.rep`/`abs`) instances, and export the class.
  Method name `bnot` is kept distinct from the boolean `not` used by `!`.
- Parser: `~` prefix operator (same precedence level as `!`, guarded
  against `~=`) and the unary `~=` compound assignment.
- AST: `ExpBNot` and `StmtBNotEq` (a single operand — it is unary), with
  name resolution desugaring `~` -> `BitNot.bnot` and `e ~=` to the
  in-place `e := ~e`.
- Pretty printer and module type-ref renamer handle the new nodes.
- Test: extend cases/bitwise.solc to exercise `~`, `~=`, and the
  bnotWord constant folding (`~(~x) == x`, `a & ~0 == a`).

`~` (not `!`) matches Solidity, which uses `~` for bitwise NOT and `!`
for logical NOT; `!` is already taken here for logical NOT (`ExpLNot`).

Co-Authored-By: Alex Beregszaszi <alex@rtfs.hu>
@axic
axic force-pushed the bitwise-not-sugar branch from 9b34609 to 9fe0e5e Compare August 1, 2026 12:07
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