Skip to content

Commit d341d0f

Browse files
author
anlang
committed
feat: Add comprehensive AI_README for project guidelines and calculator functionality
1 parent 9c357b0 commit d341d0f

1 file changed

Lines changed: 122 additions & 0 deletions

File tree

AI_README.md

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
# AI_README
2+
3+
A concise, high-signal guide for AI agents working on this repository. Focuses on structure, conventions, and safe extension points. Prefer small, verifiable changes with tests.
4+
5+
## Project overview
6+
- Language/GUI: Rust + egui (eframe)
7+
- Purpose: A desktop utility with multiple pages (number conversion, text conversion, bit viewer, calculator). The calculator currently contains a "Radix" sub‑tool for evaluating expressions typed in a selected base (2/8/10/16), calculating in decimal via mathcore, then rendering results in multiple bases.
8+
- Key external crate: `mathcore` for expression evaluation (functions like `sin`, `cos`, `pow`, etc.).
9+
10+
## Build and test
11+
- Build/check: `cargo check`
12+
- Run app: `cargo run`
13+
- Run tests: `cargo test -q`
14+
- Test policy: Keep test scope minimal and fast. Prefer targeted tests over entire suite when iterating.
15+
16+
## Repository layout (relevant parts)
17+
- src/app/application.rs
18+
- App wiring: fonts, navigation bar, central panel routing.
19+
- src/ui/components/navigation.rs
20+
- Top bar navigation, `AppPage` enum.
21+
- src/ui/pages/mod.rs
22+
- Pages registry (number_conversion, text_conversion, bit_viewer, calculator).
23+
- src/ui/pages/calculator/mod.rs
24+
- Calculator page (Radix sub‑project) implementation. Contains UI, expression conversion, formatting, highlighting, and history.
25+
26+
## Calculator: Radix sub‑project
27+
The Radix calculator lets users type expressions using digits of the selected base. It converts numbers to decimal, evaluates via `mathcore`, then renders results in bases 2/8/10/16. Calculation is automatic on input/base change.
28+
29+
### State (struct RadixCalculator)
30+
- `radix: u32` chosen base (2/8/10/16)
31+
- `input: String` user expression (in chosen base)
32+
- `output: String` last formatted output in the current base (kept for history)
33+
- `last_error: Option<String>` most recent error message (not stored in history)
34+
- `last_value: Option<f64>` last successful decimal value (enables multi‑base display)
35+
- `history: VecDeque<HistoryEntry>` ring buffer; see History
36+
37+
### Compute flow
38+
1) User input changes or base changes → `compute()` called.
39+
2) Convert input from `radix` to a decimal expression string.
40+
- Parses numbers (supports `_` separators) and operators `+ - * / % ^ ,` and parentheses.
41+
- Identifiers (letters/underscore followed by alphanumerics/underscore) are passed through unchanged.
42+
- Supports unary minus for numbers in appropriate positions.
43+
- Supports implicit multiplication (see below).
44+
3) Evaluate decimal expression with `mathcore::MathCore::calculate`.
45+
4) If result is finite:
46+
- Save `last_value`.
47+
- Format an output string in the currently selected base using `format_auto`.
48+
- Push a history entry with: selected radix, original input, decimal expression, and current‑base output.
49+
5) On error/non‑finite: set `last_error` and do not write history, clear `last_value`.
50+
51+
### Implicit multiplication rules
52+
- Insert `*` automatically between adjacent tokens when mathematically implied:
53+
- Number/`)`/Identifier followed by Number/Identifier → insert `*`.
54+
- Number/`)` followed by `(` → insert `*`.
55+
- Identifier followed by `(`:
56+
- If identifier is a known function (e.g., `sin`, `cos`, `sqrt`, `pow`, `log`, `ln`, `min`, `max`, etc.), treat as a function call (no `*`).
57+
- Otherwise insert `*` (e.g., `pi(2)` becomes `pi*2`).
58+
- Note: In non‑decimal bases (e.g., base 16), `A..F` are digits, not identifiers. So `A(B+1)` means `10*(11+1)` in base‑16 semantics.
59+
60+
### Formatting of results
61+
- `format_auto(f64, radix, frac_digits)`:
62+
- If the result is within a small tolerance of an integer (≈1e‑12 relative/absolute), format as an integer in the target base.
63+
- Otherwise format as a floating value.
64+
- For decimal (radix=10): prints a decimal float (12 digits), trimmed trailing zeros and trailing dot.
65+
- For non‑decimal: prints integer part in that base plus a fractional part approximated with repeated multiply‑and‑floor for up to `frac_digits` digits (default 16). Negative sign applied consistently.
66+
- The UI shows the computed value simultaneously in bases 2, 8, 10, 16. The history stores only the output string in the currently selected base, plus the decimal expression.
67+
68+
### History
69+
- Type: `VecDeque<HistoryEntry>`; capacity bound via `MAX_HISTORY` (200). When over capacity, pop from front.
70+
- Contains: `radix`, `input` (original), `decimal_expr` (converted), `output` (formatted string), `error` (unused now; errors aren’t recorded).
71+
- UI offers a “清空历史” (clear) button and a “重用” button to restore a past input and radix.
72+
73+
### Error highlighting (TextEdit)
74+
- A lightweight layouter marks invalid characters in red according to the chosen base.
75+
- Valid: whitespace, digits legal in the base (including `_`), operators `+ - * / % ^ ,`, parentheses, and ASCII alphabetic identifiers/underscore.
76+
- This is a visual aid; actual parsing and conversion enforce validity again.
77+
78+
## Conventions and guardrails for agents
79+
- Prefer minimal, reversible edits. Keep changes scoped and run `cargo check` and relevant tests after changes.
80+
- Do not install or upgrade dependencies without explicit instruction.
81+
- When adding features to the calculator, be careful about base semantics:
82+
- Digits vs identifiers in bases 2/8/16 (A–F are digits in base‑16).
83+
- Implicit multiplication insertion can have side effects; update the rule set and tests together.
84+
- If changing formatting (precision, tolerance), keep constants centralized and document the user‑visible impact.
85+
- History must not record failures. Ensure `last_value` is `Some` only on success.
86+
87+
## Typical extension tasks
88+
- Add more function names as “function‑like”:
89+
- Extend the `is_function_like` helper with additional names if mathcore supports them.
90+
- Keep it case‑insensitive.
91+
- Make fractional precision configurable:
92+
- Add a small UI control to set `FRACTION_DIGITS` at runtime.
93+
- Add angle unit toggle (degree/radian):
94+
- If implemented, apply a transform to trig function inputs in conversion or pre‑evaluation.
95+
- Improve highlighting to token‑aware styles (operators, numbers, identifiers in different colors).
96+
- Persist history:
97+
- Serialize to a file on exit and reload on startup (opt‑in setting).
98+
99+
## Safe refactoring plan (if needed)
100+
- Split `src/ui/pages/calculator/mod.rs` into submodules:
101+
- format.rs: number/float formatting and helpers
102+
- convert.rs: base‑aware tokenization and decimal conversion (incl. implicit multiplication)
103+
- highlight.rs: layouter and input validation
104+
- history.rs: HistoryEntry and bounded deque utils
105+
- Introduce `fn eval_expr(expr:&str, radix:u32)->Result<(f64,String),String>` encapsulating conversion and evaluation; `compute()` only orchestrates state and history.
106+
- After splitting, add focused unit tests for each module.
107+
108+
## Troubleshooting
109+
- `sin(10)` looked like `0`? Ensure no integer‑only formatting; current code supports floats. If regressions occur, re‑check `format_auto` and `format_float_in_radix`.
110+
- `sin(pi/2)` not equal to `1`? Confirm the “near‑integer” rounding is applied before non‑decimal formatting. Check tolerance constants.
111+
- Unexpected identifier behavior in base‑16: remember `A..F` are digits; adjust test expectations accordingly.
112+
- NaN/Inf results: these are treated as errors; they do not enter history.
113+
114+
## Code style and testing guidance
115+
- Keep functions short and single‑purpose; prefer extracting helpers over long, nested blocks.
116+
- Document non‑obvious rules (e.g., implicit multiplication) with examples in comments and tests.
117+
- When adding behavior, add or update tests under the smallest scope that covers the change.
118+
119+
## Glossary
120+
- Decimal expression: The ASCII expression string after converting base‑specific number tokens to decimal integers, with identifiers/operators/parentheses otherwise preserved.
121+
- Function‑like identifier: An identifier followed by `(` that should be considered a function call rather than implicit multiplication; managed by `is_function_like`.
122+

0 commit comments

Comments
 (0)