A hand-built Python command-line calculator with its own lexer, parser, AST, and evaluator.
It does not use eval().
python -m venv .venv
.venv\Scripts\activate
pip install -r requirements.txt
python -m calc "2 + 2 * 3"Run interactive mode:
python -m calcRun tests:
pytestpython -m calc "2 + 2"
python -m calc --precision 50 "1 / 7"
python -m calc --angle deg "sin(90)"
python -m calc --format scientific "123456789"
python -m calc -f script.calc
"sqrt(81) + max(2, 7)" | python -m calcSupported flags:
-f, --file: evaluate expressions from a script file (one expression per line)--precision N: Decimal precision (1 to 200)--angle {rad,deg}: trigonometry angle mode--format {auto,fixed,scientific}: output formatting mode--version: print version--help: show CLI help
- Addition
+, subtraction-, multiplication*, division/ - Integer division
//, modulo%, exponentiation^and** - Unary plus/minus (
+x,-x,-(2+3)) - Parentheses with precedence handling (PEMDAS)
- Decimal-based numeric evaluation using
decimal.Decimal
- Integer literals:
42 - Decimal literals:
3.1415 - Scientific notation:
2.5e-3 - Hex literals:
0xFF - Binary literals:
0b1010 - Octal literals:
0o77
- Variable assignment:
x = 5 - Variable usage:
x * 3 - Auto-updated answer variable:
ans - Built-in constants:
pietauinf
- Define functions:
f(x) = x^2 + 1 - Call functions:
f(10) - Multi-parameter functions:
g(a, b) = a + b - Scoped argument binding per call
- Validation for duplicate parameters and incorrect argument counts
- Core helpers:
abs,round,floor,ceil - Power/root:
pow,sqrt - Aggregates:
min,max - Integer math:
factorial,gcd - Logarithms:
log,log10,log2 - Trigonometry:
sin,cos,tan
Notes:
- Log functions enforce valid domains (
x > 0, base constraints). - Trigonometric functions support radians and degrees.
- Precision-sensitive paths use Decimal-based computation.
Start REPL with:
python -m calcCommands:
help: show command help and exampleshistory: show command/result historyclear historyorhistory clear: clear historyvars: list current variables (includingans)clear: clear user-defined variables and functionsset precision N: update precision at runtimeset angle deg|rad: change angle modeset format auto|fixed|scientific: change output modequitorexit: leave REPL
Input handling:
- Empty lines are ignored
- Ctrl+C cancels current input without exiting
- Ctrl+D exits cleanly
- Script mode:
python -m calc -f script.calc - Pipe mode: standard input is read line-by-line when stdin is not a TTY
- Script/piped lines that are empty or start with
#are skipped - Script errors are reported with line numbers and processing continues
- Output format modes:
autofixedscientific
- Runtime and startup precision control
- Session precision applies to Decimal evaluation and display behavior
- Config file:
~/.calcrc(JSON) - Supported config keys:
precisionangle_modeoutput_formatsave_history
- History file:
~/.calc_history - History can be loaded/saved across sessions (up to recent entries)
Custom error hierarchy with human-readable messages:
CalcErrorLexerErrorParseErrorEvaluationErrorDivisionByZeroErrorUndefinedVariableError
Behavior:
- Position-aware error messages
- Caret-style rendering for source errors
- Graceful REPL recovery after invalid input
calc/lexer.py: tokenizes source inputcalc/parser.py: recursive-descent parser producing ASTcalc/ast_nodes.py: AST node modelcalc/evaluator.py: tree-walking evaluatorcalc/environment.py: variables/constants/functions statecalc/formatter.py: output formatting strategiescalc/engine.py: session orchestrationcalc/repl.py: interactive loop and commandscalc/cli.py: command-line entrypoint and execution modescalc/config.py: config load/validatecalc/history.py: session and persisted historytests/: unit and integration tests
pip install -r requirements.txt
pytest
python -m calc