A grammar-based expression calculator with DateTime and Currency support, built with Rust WebAssembly and React.
https://link-assistant.github.io/calculator/
๐ See USE-CASES.md for more detailed examples with screenshots, including symbolic integration, math functions, dark theme, and more.
- Arithmetic operations:
+,-,*,/,รท,ร,ยท,โwith proper operator precedence - Scientific and readable numbers:
1.5e-6,1_000_000 - Powers and roots:
2^10,2**10,2ยนโฐ,โ81,square root of 625 - Conventional implicit products and functions:
2ฯ,2x,2(3 + 4),sqrt 16 - Natural operators:
plus,minus,times,divided by,mod,power - Spelled numbers and operator words in English, Russian, Hindi, Chinese and
Spanish:
twenty-one times two,ัะตััั ัะผะฝะพะถะธัั ะฝะฐ ัะตะผั,เคฆเคธ เคฌเคเคพ เคฆเฅ,ไบๅไธๅ ไบ,10 dividido por 2(vocabulary indata/words/arithmetic-words.lino) - Exact big integers and factorials:
123123980921093128 * 2348023048230429324,30! - Comparisons:
=,==,!=,โ,<,<=,โค,>,>=,โฅ - Parentheses for explicit grouping:
(2 + 3) * 4 - Negative numbers:
-5 + 3 - Percentages retain their type:
200 + 10% = 220,100 + 10% + 10% = 121, and10% + 20% = 30% - Percentage questions and conversions:
180 is what % off 200,50 to 75 is what %,20/200 as %, and50% as fraction - Percentage phrases:
ten percent of fifty,700 ัะฒะตะปะธัะธัั ะฝะฐ 30 ะฟัะพัะตะฝัะพะฒ,700็็พๅไนไธๅ, and700ใฎ30ใใผใปใณใ - Decimal precision using
rust_decimal
Number conventions are resolved in the lexer before parsing or evaluation:
1,234means 1234: a comma followed by exactly three digits groups thousands when the leading group has one to three digits. Other single commas are decimal separators:12,3means 12.3,1,2means 1.2. The exact spelling1,1is a documented fend compatibility exception and means 11; use1.1for the decimal value.- When both
.and,occur in a number, the rightmost mark is decimal:1,234.5and1.234,5both mean 1234.5. - Valid groups separated by spaces (including Unicode grouping spaces) or
Swiss apostrophes work with either decimal convention:
1 234,5,1'234.5, and1โ234.5all mean 1234.5. - Indian grouping is supported:
12,34,567means 1234567. - Inside function calls every comma separates arguments, regardless of spacing:
max(1,2)means 2,max(1,234)means 234, andround(1,234)supplies two arguments and reports an argument-count error. Use decimal dots and space/apostrophe grouping in arguments, e.g.round(1'234.5). - Planning still exposes the decimal-comma alternative for ambiguous grouped
numbers; the primary interpretation of
1,234 / 100is 12.34.
These rules apply independently to each numeric literal and do not depend on
browser language. The 1,1 exception also exposes 1.1 as an alternative
interpretation in planning. Binary, octal, and hexadecimal literals (including
fractions such as 0b100.001) retain their numeric meaning.
Measured values such as 12,3 ยฑ 4,5 produce 12.3 ยฑ 4.5 with a non-negative
absolute uncertainty. Central value and uncertainty must have matching units;
arithmetic on uncertain values reports an error until propagation is supported.
German Mio. and Mrd. scale by one million and one billion, respectively;
1,08 Mrd. km/h produces 1080000000 km/h, a physical speed (see below).
Values carry a dimension vector (length, mass, time, current, temperature,
amount, luminosity, information, angle, currency) and an exact scale. Units
come from data/units/units.lino: SI base and derived
units with all prefixes (ยตm, ฮผm, um, kฮฉ), binary prefixes (KiB),
Imperial/US, electrical, information, angle and temperature units, with
aliases such as feet, metres, ะผ, ะบะผ and ั.
*,/, powers and roots combine dimensions:10m ร 10m= 100 m^2,(5 volts) / (2 ohms)= 2.5 A,1 mph * 1 hour= 1 mi;sqrt(2m)is an error. Addition and comparison require equal dimensions:2m == 200cmis true.- Unit expressions:
299792458 mโ sโ1,mยทsโปยน,m s^-1,km/h,km per hour,kgยทmยฒ/sยฒ; conversions within/to/as:1 ft to cm= 30.48 cm,9.81 m/sยฒ * 70 kg in N= 686.7 N. - Compound quantities:
5 feet 10 inches in cm= 177.8 cm,6'2",1 meter 20 cm. - Temperatures follow Numbat:
20 celsius= 293.15 K,25 ยฐC in ยฐF= 77 ยฐF, and arithmetic onยฐC/ยฐFsuch as25 ยฐC * 2is rejected (convert toKfirst). mafter a number is the metre andminthe minute;5mmeans minutes only in an explicit time context (5m in s,1h + 5m,now + 5m).
See the issue #235 case study for the design and its documented decisions.
Supports multiple date and time formats:
- ISO format:
2026-01-22,2025.10.15 - US format:
01/22/2026,01-22-2026,10.15.2025 - European format:
22/01/2026,15.10.2025,15-10-2025 - Month names:
Jan 22, 2026,22 Jan 2026 - Time formats:
8:59am,14:30, with timezone support (8:59am UTC) - DateTime arithmetic:
(Jan 27, 8:59am UTC) - (Jan 25, 12:51pm UTC) - Numeric dates work directly in expressions:
15.10.2025 + 180 days,15/10/2025 + 180 days
- Currency amounts:
84 USD,34 EUR - Currency arithmetic with automatic conversion:
100 USD + 50 EUR - Temporal awareness:
84 USD - 34 EUR at 22 Jan 2026 - Support for 50+ currencies including major world currencies, precious metals, and cryptocurrencies
All expressions are represented in links-notation format:
- Step-by-step calculation explanations
- Issue prefill links for unrecognized input
> 2 + 3
Result: 5
Links notation: ((2) + (3))
> (Jan 27, 8:59am UTC) - (Jan 25, 12:51pm UTC)
Result: 1 day, 20 hours, 8 minutes
Links notation: (((Jan 27, 8:59am UTC) - (Jan 25, 12:51pm UTC)))
> 84 USD - 34 EUR
Result: 47.042 USD
Links notation: (((84 USD)) - ((34 EUR)))
grammar/- Lexer and recursive descent parsertypes/- Value, Decimal, DateTime, Currency, Unit typeslino/- Links notation representationerror/- Error types with thiserrorwasm.rs- WebAssembly bindings
- Vite + TypeScript + React 18
- Web Worker for non-blocking WASM calculations
- Responsive design with real-time results
- Example expressions for quick testing
ci.yml- Tests, linting, formatting, WASM builddeploy.yml- GitHub Pages deployment
- Rust 1.70+ with
wasm32-unknown-unknowntarget - Node.js 18+
- wasm-pack
# Clone the repository
git clone https://github.com/link-assistant/calculator.git
cd calculator
# Build the WASM package
wasm-pack build --target web --out-dir web/public/pkg
# Install web dependencies
cd web
npm install
# Start development server
npm run dev# Run all Rust tests
cargo test
# Run tests with verbose output
cargo test --verbose
# Run Clippy lints
cargo clippy --all-targets --all-features
# Format code
cargo fmt
# Check formatting (CI style)
cargo fmt --check# Build optimized WASM
wasm-pack build --target web --release --out-dir web/public/pkg
# Build web frontend
cd web
npm run build.
โโโ .github/workflows/ # CI/CD pipeline configuration
โโโ data/ # Currency exchange rate databases
โ โโโ exchange_rates/ # Historical exchange rates (.lino files)
โโโ docs/ # Documentation and screenshots
โโโ src/ # Rust source code
โ โโโ grammar/ # Lexer, parser, and grammar modules
โ โโโ types/ # Core types (Value, DateTime, Currency, etc.)
โ โโโ lino/ # Links notation module
โ โโโ error.rs # Error types
โ โโโ lib.rs # Library entry point
โ โโโ main.rs # CLI entry point
โ โโโ wasm.rs # WASM bindings
โโโ tests/ # Integration tests
โโโ web/ # React frontend
โ โโโ src/ # TypeScript source
โ โโโ public/ # Static assets
โโโ Cargo.toml # Rust project configuration
โโโ README.md # This file
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Make your changes and add tests
- Run quality checks:
cargo fmt && cargo clippy && cargo test - Add a changelog fragment
- Commit your changes (pre-commit hooks will run automatically)
- Push and create a Pull Request
Unlicense - Public Domain
This is free and unencumbered software released into the public domain. See LICENSE for details.
- Built with Rust and WebAssembly
- Inspired by links-notation
- React frontend powered by Vite



