Skip to content

Add bitwise and modulo syntactic sugar#485

Merged
mbenke merged 9 commits into
argotorg:mainfrom
axic:bitwise-sugar
Jun 30, 2026
Merged

Add bitwise and modulo syntactic sugar#485
mbenke merged 9 commits into
argotorg:mainfrom
axic:bitwise-sugar

Conversation

@axic

@axic axic commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

And implement it for word.

The first commit also enables MastEval for bandWord, borWord, bxorWord.

@axic axic changed the title Add bitwise and module syntactic sugar Add bitwise and modulo syntactic sugar Jun 23, 2026

@mbenke mbenke left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Alas, this PR breaks the parser - | as an infiox operator conflicts with | as match case separator:

ben@trawa:~/work/review$ grep -v // tmp/parse485.solc

data Opt = None | Some(());

function f(o: Opt) -> () {
  match o {
    | .Some(x) => x
    | .None => ()
  }
}
ben@trawa:~/work/review$ cabal run -- sol-core -f tmp/parse485.solc
<input>:18:19:
   |
18 |     | .Some(x) => x
   |                   ^
unexpected 'x'
expecting '|' or '}'

Comment thread std/std.solc Outdated
@axic

axic commented Jun 24, 2026

Copy link
Copy Markdown
Contributor Author

@mbenke sorry forgot to mark draft, this wasn't fully ready.

@axic axic marked this pull request as draft June 24, 2026 09:21
@axic axic force-pushed the bitwise-sugar branch 3 times, most recently from 621da3f to 60ec697 Compare June 29, 2026 12:33
@axic axic marked this pull request as ready for review June 29, 2026 13:29
The bitwise word primitives `bxorWord` / `bandWord` / `borWord` (defined
via the `xor_` / `and_` / `or_` opcodes) are pure, so the partial
evaluator can fold them when both arguments are statically known words —
the same treatment `subWord` / `gtWord` / `eqWord` already get. Add the
three `evalPrimitive` cases and list the names in `builtinPureFuns`.

This is the foundation the `^` / `&` / `|` operator sugar builds on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Alex Beregszaszi <alex@rtfs.hu>
Comment thread std/std.solc Outdated

@mbenke mbenke left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Add an e2e (dispatch) test and perhaps uint256 instances

claude and others added 5 commits June 30, 2026 13:32
Implement bitwise XOR for words end to end, mirroring the existing
arithmetic/comparison operators and reusing the `bxorWord` primitive
(whose constant folding is already in place):

- std: add a `Xor` type class with a `word:Xor` instance backed by
  `bxorWord`, and export `Xor`.
- Parser: `^` infix operator (guarded against `^=`) and the `^=`
  compound assignment statement.
- AST: `ExpXor` / `StmtXorEq`, with name resolution desugaring `^` to
  `Xor.xor` and `^=` to `lhs := lhs ^ rhs` (matching `+`/`+=`).
- Pretty printer and module type-ref renamer handle the new nodes.
- Test: cases/xor.solc exercising `^`, `^=`, and folding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Alex Beregszaszi <alex@rtfs.hu>
Mirror the XOR operator support for bitwise AND and OR, reusing the
existing `bandWord` / `borWord` primitives (already constant-folded):

- std: add `BitAnd` / `BitOr` type classes with `word` instances backed
  by `bandWord` / `borWord`, and export the classes. Method names
  `band`/`bor` are kept distinct from the boolean `and`/`or` used by
  `&&`/`||`.
- Parser: `&` and `|` infix operators (guarded against `&&`/`&=` and
  `||`/`|=`) and the `&=` / `|=` compound assignments.
- AST: `ExpBAnd`/`ExpBOr` and `StmtBAndEq`/`StmtBOrEq`, with name
  resolution desugaring `&`->`BitAnd.band`, `|`->`BitOr.bor`, and the
  compound forms to `lhs := lhs <op> rhs`.
- Pretty printer and module type-ref renamer handle the new nodes.
- Test: cases/bitwise.solc exercising `&`, `|`, `&=`, `|=`, and folding.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Alex Beregszaszi <alex@rtfs.hu>
The `%` operator and `Mod` class already exist; add the matching `%=`
compound assignment, desugaring `lhs %= rhs` to `lhs := lhs % rhs`
(like `+=`/`^=`). Guard the `%` infix operator against `=` so `%=`
is not mis-parsed as `%` followed by a failing operand.

- AST: `StmtModEq`, with name resolution, pretty printer and module
  type-ref renamer handling it.
- Test: cases/modulo.solc exercising `%` and `%=`.

Co-Authored-By: Alex Beregszaszi <alex@rtfs.hu>
`|` now serves two roles: the bitwise-or operator (`a | b`) and the
match-arm separator (`| pat => ...`). When a match arm ended in a bare
expression statement (no trailing `;`), the operator-precedence parser
greedily read `<arm-body> | <next-pattern> => ...` as a single
`ExpBOr`, swallowing the next arm's `|` and breaking the `match`.

Since `=>` never follows a bitwise-or operand, the two uses are
unambiguous: a `|` is a case separator iff `<patterns> =>` comes next.
Guard the `ExpBOr` operator with `notFollowedBy (try (patListP *>
symbol "=>"))` so it declines that `|`, leaving it for the
match-equation parser.

`patListP` lives in Parser.Patterns, which imports Parser.Expr for
`comptime` patterns, so break the cycle with an Expr.hs-boot and import
Patterns into Expr via `{-# SOURCE #-}`.

Add cases/match-bitwise.solc: a `match` whose arms are bare expressions
ending right before the next `|`, with genuine bitwise-or inside.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Alex Beregszaszi <alex@rtfs.hu>
claude and others added 2 commits June 30, 2026 13:39
Rename the bitwise-xor type class from Xor (method xor) to BitXor
(method bxor) for consistency with BitAnd/BitOr, and reorder the class,
word instance, and uint256 instance to sit after BitOr. Update the ^
operator desugaring in NameResolution to target BitXor.bxor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Alex Beregszaszi <alex@rtfs.hu>
Add bxor2/bor2/band2/mod2 entry points to the basic dispatch contract,
each implemented purely through the operator sugar (^, |, &, %) so the
test exercises the BitXor/BitOr/BitAnd/Mod class desugaring end to end on
uint256. Extend basic.json with matching call cases (252 op 10).

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

axic commented Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

@mbenke done

Bring the bitwise-xor AST constructors in line with their BAnd/BOr
siblings: the compound-assignment node StmtXorEq becomes StmtBXorEq and
the binary-operator node ExpXor becomes ExpBXor, across the syntax tree,
parser, name resolution, pretty printer, and module loader.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mbenke mbenke merged commit cd810da into argotorg:main Jun 30, 2026
4 checks passed
@axic axic deleted the bitwise-sugar branch June 30, 2026 13:36
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.

3 participants