diff --git a/.kiro/specs/calculator/design.md b/.kiro/specs/calculator/design.md index 6109bff..6e60713 100644 --- a/.kiro/specs/calculator/design.md +++ b/.kiro/specs/calculator/design.md @@ -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. diff --git a/.kiro/specs/calculator/tasks.md b/.kiro/specs/calculator/tasks.md index d88b569..dc7c3ec 100644 --- a/.kiro/specs/calculator/tasks.md +++ b/.kiro/specs/calculator/tasks.md @@ -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: