Repository navigation
Releases: dblock/excalc-rs
Release list
v0.3.0
[0.3.0] - 2026-09-26
Added
- Interactive REPL: running
calc/excalcwith no expression while stdin is a terminal now starts a read-eval-print loop (variables persist across lines within the session, Tab-completes function names, and shows/advances through argument-name hints inside a call's parentheses), withhelpfor usage,aboutfor version/author/license info,varsto list assigned variables, andexit/quit/Ctrl-D to leave, instead of just printing usage. - User-defined functions:
name(params) := exprdefines a function (e.g.f(x) := x^2 + 1), visible to later statements the same way a variable assignment is, listed alongside variables by the REPL'svarscommand (showing the actual definition, e.g.f(x) = x ^ 2 + 1, not a placeholder). Functions can call themselves or each other; arguments are evaluated in the caller's scope (proper lexical scoping, no accidental self-shadowing). There's no fixed call-count limit; each nested call checks actual remaining stack space and fails gracefully withfunction call recursion limit exceededonce it's running low, rather than crashing with a native stack overflow. Function names can't collide with built-ins orpi/e, and definitions are session-only, matching variable persistence. - Conditionals:
cond ? then : else(ternary operator) and its exact equivalentif(cond, then, else)— both short-circuit, evaluating only the taken branch, which lets self-recursive user-defined functions actually terminate at a computed base case instead of always recursing, e.g.fact(n) := n < 2 ? 1 : n * fact(n - 1). - Digit-group separators: number literals may use
,or_as a thousands separator (e.g.1,234or1_234_567); a group must be exactly 3 digits, so short argument lists likesum(1,2)still parse as 2 arguments, not a single grouped number. Whichever separator is used first in an expression is echoed back in the printed result, e.g.1,000 + 1prints1,001. - Currency symbols: number literals may be prefixed with
$,£,€, or¥(e.g.$100), which is purely cosmetic and ignored for math. Whichever currency symbol is used first in an expression is echoed back in the printed result, e.g.$1 + 10prints$11; math across different currency symbols isn't tracked or rejected. - REPL command history now persists across sessions, saved to
~/.excalc_historyby default (%USERPROFILE%\.excalc_historyon Windows if$HOMEisn't set); override the location with--history-file <path>or theEXCALC_HISTORY_FILEenvironment variable, or disable persistence entirely with--no-history. - New general/numeric-analysis functions:
nthroot(x, n)(general n-th root) andisqrt(n)(integer square root). - Combinatorics extras:
stirling1(n, k)/stirling2(n, k)(Stirling numbers of the first/second kind),derangement(n), andbell(n)(Bell numbers). - New statistics functions:
skewness(population skewness) andkurtosis(population excess kurtosis). - Unit conversion functions:
c2f/f2c(temperature),km2mi/mi2km(distance),kg2lb/lb2kg(mass),m2ft/ft2m(distance). - Probability distribution functions:
binomialpdf/binomialcdf(binomial),poissonpdf/poissoncdf(Poisson),normalpdf/normalcdf(normal, reusing the existingerf), andzscore(standard score). - Geometry functions:
distance/manhattan/dot(n-dimensional, splitting a single argument list in half between two points/vectors) andnorm(n-dimensional vector magnitude), plus dimension-free shape formulastriarea(Heron's formula),circlearea,circumference,spherevol,spherearea. - New number theory functions:
carmichael(n)(Carmichael function),aliquot(n)(sum of proper divisors),amicable?(n),coprime?(a, b),order(a, n)(multiplicative order),jacobi(a, n)(Jacobi symbol). - Root-finding functions
bisect(expr, var, a, b, tolerance)(bisection method) andsecant(expr, var, x0, x1, tolerance)(secant method), sharing the same expression-and-bare-variable calling convention as the numeric-integration functions. - New sequence/figurate-number functions:
lucas(n)(Lucas numbers, sibling tofib),triangular(n),pentagonal(n),hexagonal(n). - Bit manipulation functions:
popcount(n),bitlen(n),bitreverse(n, width). - New general/rounding functions:
roundto(x, n)(round tondecimal places),floordiv(a, b)andmod2(a, b)(floored division/modulo, complementing//mod's truncated-towards-zero convention). - Combinatorics functions:
factorial(n)(named equivalent of postfix!),perm(n, r),catalan(n),multinomial(n, k1, k2, ...). atan2(y, x): two-argument arctangent, using the sign of both arguments to determine the correct quadrant.excalc/calcread the expression from stdin when no argument is given and stdin is not a TTY, e.g.echo "2 + 2" | calc.--helpand usage output now credit the author.- Windows MSI installer: renamed the default install directory from
excalctoExCalc; added an optional (on by default) "MCP Server Registration" feature that shells out tocopilot mcp addandclaude mcp addto registerexcalc-mcpwith GitHub Copilot CLI and Claude Code CLI, if either is found on the machine (src/bin/excalc-mcp-setup.rs, run as a deferred, impersonated, best-effort custom action). - New standard math/general functions:
log2,cbrt,hypot,sign,clamp,lerp. - New statistics functions:
median,mode,variance,stddev,percentile,covariance,correlation. - New number theory functions:
primorial,digitsum,digitalroot,palindrome?,nextprime. - Base conversion:
hex,oct,binfunctions to format a non-negative integer as text, and0x/0o/0b-prefixed literals to parse hex/octal/binary numbers back into ordinary numeric values. First feature to introduce a non-numeric result type (evaluate_value, returning aValueenum ofNumber/Text);evaluateremainsf64-only for backward compatibility and errors if the result is text.
v0.2.0
[0.2.0] - 2026-09-24
Added
-
Homebrew formula (
Formula/excalc.rb), installable viabrew tap dblock/excalc-rs https://github.com/dblock/excalc-rs && brew install excalc. Builds from source viacargo install. CI audits/installs/tests the formula on every push/PR via.github/workflows/homebrew.yml;RELEASING.mddocuments updating itsurl/sha256on every release. -
Windows MSI installer, built with cargo-wix from
wix/main.wxs(bundlesexcalc,calc, andexcalc-mcp, with an optional PATH entry)..github/workflows/msi.ymlbuilds it on every push/PR;.github/workflows/release.ymlrebuilds it and attaches it to each published GitHub release. -
calcbinary alias forexcalc(same CLI, shorter name). -
docs/reference documentation, per function category, marked ported (implemented) vs. planned (extracted from the original Pascal source as a porting reference). -
README
### Examplessection covering every ported operator and function, verified against the evaluator bytests/readme_examples.rsso it can't silently drift out of sync. -
CONTRIBUTING.mdwith build/test/PR instructions, replacing the README's## Developmentsection. -
CI: test coverage reported to Coveralls via
cargo llvm-cov, plus a CI status and coverage badge in README. -
Test suite brought to ~99% line coverage: unit tests for every reciprocal/hyperbolic trig function and error path, statistics error paths, evaluator error paths (unknown variable, factorial overflow, log/root domain errors), lexer edge cases (decimals, scientific notation), parser error paths, and a new
tests/cli.rsexercising the compiled binary end-to-end. The 3 remaining uncovered lines aretan/sec/sechdivision-by-zero guards that are mathematically unreachable for any real input. -
excalc-mcpbinary: an MCP server exposing a singleevaluatetool over stdio (via rmcp), so AI agents that speak MCP can call the evaluator directly instead of shelling out to the CLI. Built and installed by default via themcpCargo feature (opt out withcargo install excalc --no-default-featuresfor a CLI-only install). Covered bytests/mcp.rs, including a test that keeps the README's example expression in sync with the real evaluator. README documents one-liners to register it with GitHub Copilot CLI (copilot mcp add) and Claude Code (claude mcp add), plus a worked example combining several functions in one expression. -
General / rounding functions:
abs,frac,intg(alias oftrunc),round(round-half-up),trunc,ceil,floor,random(x)(uniform random number in[0, x], via therandcrate). -
Number theory functions:
gcd,lcm,fib,prime?,moebius,mersenne,perfect,fermat,safeprime,primec,primen,mersennegen,mersgen,genmers,sigma,tau,phi/eind, backed by a deterministic Miller-Rabin primality test (valid for the fullu64range). -
Comparison and logical/bitwise operators:
=,>,<(comparison, returning1/0),xor,xnor,and(&synonym),nand,or,nor(bitwise, operating on operands truncated toi64), plusnot(x),shl(x, y),shr(x, y). Precedence: comparison loosest, then logical-or-family, then logical-and-family, then the existing arithmetic chain. Deviates from the original:=now tests equality instead of assigning a variable, and?(the original's equality test) was dropped since it's no longer needed. -
Advanced / special functions:
gamma,beta,pochhammer,bth,bman,ellipticE,ellipticF(aliasellipticK),ellipticCE,ellipticCK,dilog,dawson,erf,erfc,si,ssi,ci,chi,fresnelC,fresnelS,fresnelF,fresnelG. Most of these are thin wrappers around a generic numeric-integration primitive in the original engine; this port routes them through the same shared adaptive-quadrature engine used by the general-purpose numeric integration functions below (gammakeeps its own fixed-step Riemann sum instead, to match its pre-existing worked example) — seedocs/functions/advanced.md. -
Financial functions:
pv,fv,pmt,npv,rate,cterm,term,sln,syd,ddb,db, and the extended payment-timing-aware variantsirate,nper,paymt,fval,pval,ipaymt,ppaymt. Unlike the advanced/special functions, these are all closed-form (or, forirate, a literal secant-method root find) and don't depend on numeric integration. -
General-purpose numeric integration: named composite quadrature rules
trapezoid(aliasestrapez/trapezoide),simpson,newton,boole,ordersix(aliasordresix),weddle(each over a whole-number sub-interval countn), plus adaptive quadratureint(aliasgauss, refining to a requested tolerance). These are the only functions in the port that take an unevaluated expression and a bare variable as arguments instead of plain numbers, evaluating the expression repeatedly at sample points; seedocs/functions/numeric-integration.md. This closes out every function category originally planned for the port. -
Variables:
name := exprassigns to a variable, visible to later statements in the same input, which can now be a;- or newline-separated sequence of statements (assignments and/or plain expressions); the value of the last statement is the result. Assignment is a statement, not an expression, so it can't be nested or chained (x := y := 5), keeping it unambiguous with='s equality meaning.pi/eremain reserved and can't be reassigned. Variables don't persist across separatecalcinvocations or MCP tool calls. -
Degree/radian support:
deg(x)/rad(x)convert between radians and degrees, andsind/cosd/tand/asind/acosd/atandare degree-native variants of the six basic circular trig functions. Deliberately stateless/explicit rather than reviving the original's globalCalcModetoggle — seedocs/functions/standard-math.mdandDESIGN.md#angle-units.
Fixed
- Removed dead/unreachable
Token::Minusarm inparser.rs'sparse_primary(unary minus is always handled earlier byparse_unary, so this branch could never execute). - The original's
Ci/Chiformulas reference an undefined variableG(presumably meant to be the Euler-Mascheroni constant), which the generic variable-lookup mechanism silently defaults to0, making the original results meaningless. This port hardcodes the actual Euler-Mascheroni constant instead. docs/functions/advanced.md's placeholder exampleellipticCK(1) → 5.99158934050168was wrong; corrected to1.57079632679490(pi/2), matchingellipticCE(1)since both reduce to the same integral at that boundary.docs/functions/financial.md's draft named the fixed-declining-balance depreciation functionfdb; corrected todb, matching the name actually dispatched in the original engine.
v0.1.0
Added
- Initial scaffold: lexer, parser, AST, evaluator.
- Core arithmetic:
+ - * / mod ^ \ (root) ! (factorial) %, parentheses, unary minus. - Standard math functions (radians):
sin cos tan asin acos atan sinh cosh tanh asinh acosh atanh sec csc cot asec acsc acot sech csch coth asech acsch acoth sqrt ln log logn. - Statistics functions:
sum average product min max harmonic binom. - CLI binary (
excalc "2 + 2 * 3"). - CI: build/test on Linux, macOS, Windows;
cargo fmtandcargo clippychecks.