human review: bitwise.zig

This commit is contained in:
Emil Lerch 2026-08-20 07:15:39 -07:00
parent 7f51e5f9c3
commit f2b61f4da0
Signed by: lobo
GPG key ID: A7B62D657EF764F8
2 changed files with 20 additions and 8 deletions

View file

@ -226,12 +226,19 @@ of an input, not in prefix position, so it cannot appear where an operand can. I
a precedence level in the table above for documentation only: nothing returns it.
**One implementation of the fixed-width operators.** `bitwise.zig` implements the
eight fixed-width binary operators plus `~` and two's complement negation, over a
`Domain` of width plus signedness. Standard mode passes `Domain.standard`, which is
64-bit signed and not configurable; programmer mode passes its configured width and
signedness. Values are `u128` bit patterns masked to the width, the representation
`Integer` already used. Both callers dispatch through an `inline else` prong
that resolves the operator at comptime, so an operator added to `BinaryOp` that
eight fixed-width binary operators plus `~` and two's complement negation, over
`Integer` values that carry their own width and signedness. There is no separate
domain parameter: an operand is a pattern and the type to read it as, together, so an
operation cannot be handed a pattern from one width and a type from another. Standard
mode uses the `Integer` default, 64-bit signed and not configurable (FR-2.3);
programmer mode uses its configured width and signedness. `apply` asserts both
operands are the same type and returns a value of the left operand's type.
The operators this tier owns are named by `bitwise.Op`, a narrower enum than
`ast.BinaryOp`, with `fromBinaryOp` mapping between them and returning null for the
arithmetic operators, which are rational in standard mode and wrapping in programmer
mode and so have nothing to share. Both callers dispatch through an `inline else`
prong that resolves the operator at comptime, so an operator added to `BinaryOp` that
belongs in this tier fails to compile rather than falling through to the rational
tier. FR-2.13 covers the distance rules: shifts run to completion, rotations are
cyclic, negative distances are domain errors.

View file

@ -1082,7 +1082,10 @@ that owns it and the file is gone:
shapes of the same pair: `Integer{raw, bit_width, signedness}`,
`ProgrammerConfig{bit_width, signedness, display_endian}` and the `Domain` added to
`bitwise.zig` during the operator unification. `Integer` is now a pattern plus its
`IntType`, and `bitwise.zig` takes an `IntType` directly. The engine's own
`IntType`, and `bitwise.zig` takes an `IntType` directly. (Task 5.16 went one step
further and dissolved `IntType` too: `width` and `signedness` are fields of
`Integer` directly, and `bitwise.zig` takes whole `Integer` values, so the pair
never travels without the bits it describes.) The engine's own
`Endianness` enum is gone in favour of `std.builtin.Endian`, which has the same two
members.
- `Base` into `tokenizer.zig`: a lexical property with two users, the lexer and the
@ -1250,7 +1253,9 @@ STILL OPEN, in the order I would take them:
amounts wrap in one and clamp in the other, and `evaluator.zig` ignores the
configured bit width entirely.~~ FIXED. `engine/src/bitwise.zig` is the one
implementation of the eight fixed-width binary operators plus `~` and unary
minus, parameterised by a `Domain` (width plus signedness). `evaluator.zig` and
minus, over values that carry their own width and signedness (a `Domain`
parameter at the time, then `IntType`, and now the `Integer` values themselves;
see Tasks 5.12 and 5.16). `evaluator.zig` and
`programmer.zig` both call it from an `inline else` prong, so an operator added
to `BinaryOp` that belongs there is a compile error rather than a silent fall
through. Decisions taken, and the behaviour changes they caused: