tally/.kiro/specs/calculator/requirements.md

12 KiB

Requirements: Tally - Cross-Platform Calculator

Overview

A calculator application with three frontends (CLI, TUI, Android) sharing a common Zig engine. Supports standard arithmetic, a programmer mode with struct layout visualization, and financial calculations.


Functional Requirements

FR-1: Standard Calculation Mode

  • FR-1.1: Parse and evaluate infix mathematical expressions with correct operator precedence (PEMDAS).
  • FR-1.2: Support operators: +, -, *, /, % (modulo), ^ (power), unary -.
  • FR-1.3: Support parentheses for grouping.
  • FR-1.4: Support built-in functions: sin, cos, tan, asin, acos, atan, log (base-10), ln (natural), sqrt, cbrt, abs, ceil, floor, round, factorial.
  • FR-1.5: Support constants: pi, e, tau.
  • FR-1.6: Support variable storage (Ans for last result, named variables A-F, X, Y, Z).
  • FR-1.7: Maintain calculation history with replay capability.
  • FR-1.8: Support implicit multiplication (e.g., 2pi, 3(4+5)).

FR-2: Programmer Mode

  • FR-2.1: Accept input in decimal, hexadecimal (0x), octal (0o), and binary (0b) formats.
  • FR-2.2: Simultaneously display results in all four bases (dec, hex, oct, bin).
  • FR-2.3: Support configurable bit widths: 8, 16, 32, 64-bit.
  • FR-2.4: Support bitwise operators: AND (&), OR (|), XOR (^), NOT (~), left shift (<<), right shift (logical >>>), arithmetic right shift (>>), rotate left (rol), rotate right (ror).
  • FR-2.5: Display both signed (two's complement) and unsigned interpretations of the current value.
  • FR-2.6: Visualize the bit pattern as a grid (integer.exposed style) - bits individually addressable/toggleable in TUI and Android.
  • FR-2.7: Quick toggle between base display formats via dedicated keyboard shortcuts (TUI).

FR-3: Struct Layout Visualizer (Programmer Mode Extension)

  • FR-3.1: Accept struct definitions in a mini-DSL:
    struct {
        u32 x;
        u8 flags;
        u16 id;
        u64 timestamp;
    }
    
  • FR-3.2: Compute and display total struct size in bytes.
  • FR-3.3: Display per-field information: offset, size, alignment requirement.
  • FR-3.4: Identify and highlight padding bytes between fields and at the end (tail padding).
  • FR-3.5: Render a byte-level memory map showing which bytes belong to which field and which are padding.
  • FR-3.6: Default to x86-64 System V ABI alignment rules.
  • FR-3.7: Support switching ABI/alignment profiles (extensible design - future: Windows x64, ARM AAPCS, packed).
  • FR-3.8: Support switching endianness display (little-endian default, big-endian available).
  • FR-3.9: Supported field types (initial set): u8, u16, u32, u64, i8, i16, i32, i64, f32, f64, bool, ptr (pointer-sized, arch-dependent).
  • FR-3.10: Show a "packed" comparison - display what the struct would look like with no padding vs. natural alignment.

FR-4: Unit Conversions

  • FR-4.1: Support inline unit conversion syntax: <value> <from_unit> to <to_unit> (e.g., 100 km to miles, 72 F to C).
  • FR-4.2: Support unit conversions within expressions: 5 kg + 3 lb evaluates in the left-hand unit.
  • FR-4.3: Length: mm, cm, m, km, in, ft, yd, mi, nm (nautical mile).
  • FR-4.4: Mass/Weight: mg, g, kg, oz, lb, ton, tonne.
  • FR-4.5: Temperature: C (Celsius), F (Fahrenheit), K (Kelvin).
  • FR-4.6: Time: ms, s, min, hr, day, week, year.
  • FR-4.7: Digital storage: bit, byte, KB, MB, GB, TB, PB (both SI and binary: KiB, MiB, GiB, TiB).
  • FR-4.8: Speed: m/s, km/h, mph, knots.
  • FR-4.9: Area: mm2, cm2, m2, km2, in2, ft2, acre, hectare.
  • FR-4.10: Volume: ml, L, gal, qt, pt, fl_oz, cm3, m3.
  • FR-4.11: Energy: J, kJ, cal, kcal, Wh, kWh, BTU.
  • FR-4.12: Pressure: Pa, kPa, bar, atm, psi, mmHg.
  • FR-4.13: Data rate: bps, Kbps, Mbps, Gbps, B/s, KB/s, MB/s, GB/s.
  • FR-4.14: Angle: deg, rad, grad, turn.
  • FR-4.15: In CLI, support tally "100 km to miles" and tally convert 100 km miles.
  • FR-4.16: In TUI, dedicated conversion panel accessible from any mode.
  • FR-4.17: Unit system extensible - adding a new category requires only a conversion table, no parser changes.

FR-5: Financial Mode

  • FR-5.1: Compute CAGR given start value, end value, and number of periods.
  • FR-5.2: Compute compound interest (future value given principal, rate, periods, compounding frequency).
  • FR-5.3: Compute present value (discount future cash flow).
  • FR-5.4: Support TVM (Time Value of Money) solver - given any 4 of: N, I/Y, PV, PMT, FV, solve for the 5th.
  • FR-5.5: Display intermediate calculation steps/formula used (transparency).

FR-6: CLI Frontend

  • FR-6.1: Invoke as tally "<expression>" for standard mode evaluation.
  • FR-6.2: Flag --programmer or -p for programmer mode: tally -p "0xFF & 0x0F".
  • FR-6.3: Flag --bits <8|16|32|64> to set bit width in programmer mode (default: 64).
  • FR-6.4: Flag --base <dec|hex|oct|bin> to control primary output format (default: show all).
  • FR-6.5: Subcommand tally struct <definition_or_file> for struct layout - accepts inline DSL string or path to a file containing the definition.
  • FR-6.6: Subcommand tally cagr <start> <end> <periods> for quick CAGR.
  • FR-6.7: Subcommand tally tvm with named flags (--pv, --fv, --n, --rate, --pmt) - omit one to solve for it.
  • FR-6.8: Subcommand tally convert <value> <from_unit> <to_unit> for unit conversion.
  • FR-6.9: Output format flags: --json for machine-readable output, plain text default.
  • FR-6.10: Exit code 0 on success, non-zero on parse/evaluation errors with stderr message.

FR-7: TUI Frontend

  • FR-7.1: Full-screen terminal UI with mode tabs (Standard, Programmer, Financial, Convert).
  • FR-7.2: Standard mode: expression input line, result display, scrollable history.
  • FR-7.3: Programmer mode: bit grid (navigable with arrow keys, toggle with Space/Enter), simultaneous base displays, expression input.
  • FR-7.4: Programmer mode struct sub-view: field list editor, live-updating memory map visualization.
  • FR-7.5: Financial mode: form-style input for parameters, result display with formula breakdown.
  • FR-7.6: Convert mode: select category, input value, select from/to units, live result.
  • FR-7.7: Keyboard-driven navigation; no mouse required (mouse optional enhancement).
  • FR-7.8: Quick-switch keys for base display in programmer mode (e.g., d=dec, h=hex, o=oct, b=bin to highlight primary).
  • FR-7.9: Support terminal resize gracefully.
  • FR-7.10: Vi-style and Emacs-style keybinding options for expression input.

FR-8: Android Frontend

  • FR-8.1: Native Android app using Kotlin and Jetpack Compose.
  • FR-8.2: Call into the Zig engine via JNI (C ABI shared library).
  • FR-8.3: Bottom navigation bar for mode switching (Standard, Programmer, Financial, Convert).
  • FR-8.4: Standard mode: traditional calculator layout with button grid, expression display at top, result below.
  • FR-8.5: Programmer mode: tappable bit grid, segmented control for bit width, base display cards, operator button row for bitwise ops.
  • FR-8.6: Programmer mode struct sub-screen: text field for struct input, scrollable field table, color-coded memory map rendered as a custom Canvas composable.
  • FR-8.7: Financial mode: card-based UI with input fields, dropdown for function selection (CAGR, TVM, etc.), compute button, result card with formula.
  • FR-8.8: Convert mode: category picker (horizontal chips), from/to unit selectors, live conversion as user types.
  • FR-8.9: Responsive layout for phone and tablet (multi-pane on tablet).
  • FR-8.10: Follow Material Design 3 guidelines with dynamic color (Android 12+).
  • FR-8.11: Haptic feedback on bit toggle and button presses.
  • FR-8.12: Support landscape orientation with adapted layouts (wider bit grid, side-by-side panels).

Non-Functional Requirements

NFR-1: Performance

  • Expression parsing and evaluation must complete in < 1ms for typical expressions.
  • TUI must render at >= 30fps during interaction (bit toggling, navigation).
  • Struct layout computation must handle structs with up to 256 fields without perceptible delay.

NFR-2: Portability

  • Engine, CLI, and TUI must compile and run on: Linux (x86-64, aarch64), macOS (aarch64, x86-64), Windows (x86-64).
  • Android engine .so must target: arm64-v8a, armeabi-v7a, x86_64.
  • Single zig build invocation to produce all desktop targets (cross-compilation).

NFR-3: Correctness

  • Floating-point arithmetic uses IEEE 754 double precision (64-bit).
  • Programmer mode integer operations must be exact (no floating-point).
  • Struct layout computation must match the actual layout produced by a C compiler under the specified ABI.

NFR-4: Extensibility

  • Adding a new ABI profile for struct layout requires implementing a single interface (alignment rules + pointer size).
  • Adding new financial functions requires no changes to the parser - use a function-call syntax.
  • Adding new unit categories/units requires only table entries, no parser changes.
  • Engine exposes a stable C ABI for future frontends (e.g., WASM, iOS).

NFR-5: Testability

  • Engine must be testable in isolation (no I/O dependencies).
  • Struct layout results must be verifiable against pahole or compiler output for reference structs.
  • Engine test coverage target: >= 80% line coverage. The engine is pure computation with no I/O, so this is achievable and expected.
  • Frontend coverage: best-effort via integration and smoke tests (TUI key-sequence tests, Android instrumented tests). No hard coverage target on frontend code.
  • All public engine API functions must have corresponding unit tests covering happy path, error cases, and edge cases.

NFR-6: Build & Distribution

  • Zig build system for everything. A single zig build invocation at the workspace root handles all targets: engine, CLI, TUI, and Android .so cross-compilation. No Gradle required for the native library build - Gradle only wraps the prebuilt .so into the APK.
  • Mise for toolchain management. All required toolchains (Zig version, Android NDK if needed for validation) are declared in .mise.toml at the project root. A developer needs only mise installed - running mise install provisions everything else.
  • No other system-level dependencies. Outside of mise, a developer should not need to manually install Zig, Android SDK/NDK, or any other toolchain. The .mise.toml is the single source of truth for tool versions.
  • libvaxis for TUI. The TUI frontend uses libvaxis (pulled as a Zig build dependency). No other TUI framework.
  • Produce statically-linked binaries for CLI and TUI (no shared library dependencies on end-user system).
  • Android: produce .so files for arm64-v8a, x86_64 via zig build -Dtarget=aarch64-linux-android (or similar). The Gradle project in android/ consumes these prebuilt artifacts.
  • Minimal runtime dependencies: Zig stdlib + libvaxis (TUI only). No other native deps.

NFR-7: Number Display & Formatting

  • Decimal numbers must use comma grouping for display (e.g., 4,294,967,295).
  • Scientific notation only when value exceeds 15 significant digits or absolute value > 10^15 / < 10^-15. Never jump to scientific notation for values that fit in a readable decimal.
  • Programmer mode hex values display with underscore grouping per 16-bit word (e.g., 0xFFFF_FFFF).
  • Programmer mode binary values display grouped by nibble with spaces (e.g., 1111 1111).
  • All frontends must distinguish between "display format" (with separators) and "clipboard format" (raw, no separators).
  • Android: long-press any result to copy the raw (no-separator) value to clipboard.
  • TUI: yank command copies raw value to system clipboard.
  • CLI: stdout output uses display format by default; --raw flag or --json gives unformatted values.

NFR-8: Security

  • C API must not use null-terminated strings. All string inputs take (pointer, length) pairs to prevent buffer overread.
  • Engine must validate all input lengths before processing.
  • No unbounded allocations from untrusted input (enforce maximum expression length, maximum struct field count).