Skip to content

[cli] Enable power operator, built-in functions, constants, and output formatting#171

Merged
forfudan merged 2 commits intoclifrom
update
Feb 26, 2026
Merged

[cli] Enable power operator, built-in functions, constants, and output formatting#171
forfudan merged 2 commits intoclifrom
update

Conversation

@forfudan
Copy link
Copy Markdown
Owner

This PR extends the CLI calculator with Phase 2 features as defined in the cli_calculator plan: the ^ power operator, a full suite of mathematical functions, built-in constants (pi, e), multi-argument function support, and output formatting flags.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades the src/cli/ calculator app to Phase 2 of the CLI plan by extending the expression language (power operator, functions, constants, multi-arg calls) and adding output-formatting flags, with accompanying tokenizer/parser/evaluator test coverage.

Changes:

  • Add new tokens and shunting-yard support for ^ / **, identifiers (functions/constants), and commas for multi-argument calls.
  • Extend RPN evaluation to handle power, built-in functions, and pi/e.
  • Add CLI flags for scientific/engineering notation and padding, plus documentation updates and expanded tests.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/cli/test_tokenizer.mojo Adds tokenizer tests for ^, **, function/constant identifiers, commas, and unary minus interactions.
tests/cli/test_parser.mojo Adds shunting-yard/RPN tests for ^ precedence/associativity and function/constant parsing.
tests/cli/test_evaluator.mojo Adds end-to-end evaluation tests for power, functions, and constants with precision-sensitive assertions.
src/cli/main.mojo Adds CLI output-format flags and implements engineering/pad formatting helpers.
src/cli/calculator/tokenizer.mojo Adds new token kinds (^, func/const, comma), identifier recognition, and ** aliasing.
src/cli/calculator/parser.mojo Extends shunting-yard to support functions/constants and comma-separated arguments.
src/cli/calculator/evaluator.mojo Adds function dispatch, constant handling, and power evaluation in the RPN evaluator.
src/cli/calculator/init.mojo Re-exports newly added token kinds for external/test imports.
docs/readme_unreleased.md Documents the CLI calculator and updates package/version tables and footnotes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/cli/calculator/evaluator.mojo Outdated
Comment on lines +76 to +80
elif name == "log":
stack.append(a.log10(precision))
elif name == "log10":
stack.append(a.log10(precision))
elif name == "exp":
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

log is currently dispatched to log10, which makes log(x, base) impossible and yields incorrect results for users expecting arbitrary-base logarithms (BigDecimal exposes log(self, base, precision)). Consider treating log as a two-argument function (like root) and calling x_val.log(base_val, precision), while keeping log10 for base-10.

Copilot uses AI. Check for mistakes.
Comment thread src/cli/calculator/evaluator.mojo Outdated
if rpn[i].value == "pi":
stack.append(BDec.pi(precision))
elif rpn[i].value == "e":
stack.append(BDec.from_string("1").exp(precision))
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The e constant is computed as exp(1) each time (BDec.from_string("1").exp(...)). Decimo already provides BDec.e(precision); using it avoids repeated parsing/allocation and keeps the intent explicit.

Suggested change
stack.append(BDec.from_string("1").exp(precision))
stack.append(BDec.e(precision))

Copilot uses AI. Check for mistakes.
Comment thread src/cli/main.mojo Outdated
Comment on lines +81 to +83
print(_format_engineering(String(value)))
elif pad:
print(_pad_to_precision(String(value), precision))
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_format_engineering and _pad_to_precision assume their input is a plain fixed-point decimal string, but String(value)/print(value) can produce scientific notation under BigDecimal’s CPython-compatible to_string() rules (e.g., large exponents, very small numbers). Passing a value like "1E+7" into _format_engineering will produce incorrect output. Consider formatting from value.to_string(scientific_notation=True) (then convert to engineering), or implementing these formatters using BigDecimal’s coefficient/scale instead of parsing String(value).

Suggested change
print(_format_engineering(String(value)))
elif pad:
print(_pad_to_precision(String(value), precision))
print(_format_engineering(value.to_string(scientific_notation=False)))
elif pad:
print(_pad_to_precision(value.to_string(scientific_notation=False), precision))

Copilot uses AI. Check for mistakes.
Comment thread docs/readme_unreleased.md Outdated
You can use it to evaluate complex mathematical expressions with high precision directly from your terminal. For example:

```bash
./decimo "2^10 + sqrt(pi) * ln(e^3) - root(125, 3) / abs(-5) + sin(pi/2)" -p 50 --sci
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CLI example uses --sci, but the CLI flag added in src/cli/main.mojo is --scientific (short -s). As written, the documented command won’t work; please update the example to match the actual flag name (or add a --sci alias).

Suggested change
./decimo "2^10 + sqrt(pi) * ln(e^3) - root(125, 3) / abs(-5) + sin(pi/2)" -p 50 --sci
./decimo "2^10 + sqrt(pi) * ln(e^3) - root(125, 3) / abs(-5) + sin(pi/2)" -p 50 --scientific

Copilot uses AI. Check for mistakes.
Comment on lines +47 to +55
"""Pop argument(s) from `stack`, call the named Decimo function,
and push the result back.

Single-argument functions:
sqrt, cbrt, ln, log, log10, exp, sin, cos, tan, cot, csc, abs

Two-argument functions:
root(x, n) — the n-th root of x.
"""
Copy link

Copilot AI Feb 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New function support is added in _call_func (e.g., cbrt/log/log10/cos/tan/cot/csc), but the CLI evaluator tests only cover a subset (sqrt/ln/exp/abs/root/sin). Adding at least one smoke test per supported function (and a 2-arg log(x, base) case if supported) would help prevent dispatch/precision regressions.

Copilot uses AI. Check for mistakes.
@forfudan forfudan merged commit 5b84ab3 into cli Feb 26, 2026
1 check passed
@forfudan forfudan deleted the update branch February 26, 2026 21:54
forfudan added a commit that referenced this pull request Mar 23, 2026
…t formatting (#171)

This PR extends the CLI calculator with Phase 2 features as defined in the cli_calculator plan: the `^` power operator, a full suite of mathematical functions, built-in constants (`pi`, `e`), multi-argument function support, and output formatting flags.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants