matmoul 62a0f447c5 feat: update calculator function key labels and shortcuts
Add titles for function and trig buttons to expose keyboard hints, and remap reciprocal/power10 shortcuts to match the new key layout.
Update the portrait visual spec to reflect the revised keypad and function ordering.
2026-05-17 00:35:50 +02:00

RPN Virtual Calculator

A browser-friendly RPN calculator built around a small JavaScript API.

Overview

This project provides:

  • a reusable JavaScript RPN engine in src/rpn-calculator.js
  • a classic browser demo in samples/dev/
  • a portrait-first HP48GX-inspired demo in samples/calc-02/
  • a centralized command system with aliases
  • a compact public API focused on stack operations, editing, and command dispatch

The main class is RpnCalculator.

Project structure

  • src/rpn-calculator.js: calculator engine
  • samples/dev/index.html: browser demo entry point
  • samples/dev/index.css: demo styles
  • samples/dev/index.js: demo UI and keyboard logic
  • samples/calc-02/index.html: portrait-first HP48GX-style demo entry point
  • samples/calc-02/index.css: portrait-first demo styles
  • samples/calc-02/index.js: portrait-first HP48GX-style demo UI and keyboard logic
  • samples/calc-XX/: placeholder name for future demo variants

Public API

The calculator API is centered on these methods:

  • push(value)
  • pop()
  • clear()
  • swap(index1, index2)
  • remove(index)
  • edit(index)
  • isValidIndex(index)
  • input(command)
  • command(name, ...args)

Instance helpers also available:

  • getOperationsByCategory()
  • getConstants()
  • listConstants()
  • setConstant(name, value)
  • removeConstant(name)
  • hasConstant(name)

Static helpers also available:

  • RpnCalculator.getOperationCategories()
  • RpnCalculator.getOperationsByCategory()

State exposed on instances:

  • inputValue as a string
  • isEditing as a boolean
  • stack as the current internal stack array used by the demo
  • angleMode
  • base
  • maxSize

Constructor options

const calc = new RpnCalculator({
	maxSize: 2048,
	base: 10,
	angleMode: 'deg',
	enabledCommands: ['add', 'sub', 'mul', 'div']
});

Supported options:

  • maxSize: maximum stack size, default 2048
  • base: numeric base, default 10, accepted range 2..16
  • angleMode: deg, rad, or grad, default deg
  • enabledCommands: optional whitelist of enabled commands and aliases

Constants

Available constants:

  • pi
  • e
  • phi
  • g
  • c
  • plus any user-defined constants added through the engine API

They can be used through command(...):

calc.command('pi');
calc.command('e');

Supported commands

Stack

  • enter
  • dup
  • drop
  • swap
  • clear

Arithmetic

  • add alias: +
  • sub alias: -
  • mul alias: *
  • div alias: /
  • mod alias: %
  • pow aliases: ^, y^x
  • root aliases: y√x, yroot, nroot
  • sqr
  • neg
  • sqrt alias: sqrt(x)
  • recip alias: 1/x
  • log
  • ln

Trigonometry

  • sin
  • cos
  • tan
  • asin
  • acos
  • atan

Behavior notes

  • mod is a percentage operator:
    • a b % => (a * b) / 100
  • pow accepts aliases ^ and y^x
  • sqrt accepts alias sqrt(x)
  • recip accepts alias 1/x
  • div and recip throw Division by zero when needed
  • root computes the y-th root as x^(1/y) and throws Invalid input for root for invalid inputs
  • sqrt throws Invalid input for sqrt for negative values
  • asin and acos throw explicit domain errors outside [-1, 1]
  • log throws Invalid input for log for values <= 0
  • ln throws Invalid input for ln for values <= 0
  • log uses Math.log10
  • ln uses Math.log
  • direct trigonometric functions convert input using toRadians(...)
  • inverse trigonometric functions convert results back using the current angle mode
  • angleMode supports deg, rad, and grad
  • formatted numeric values are rounded to 12 decimal places
  • -0 is normalized to 0
  • inputValue remains a string to preserve future non-decimal input support
  • base 10 input is parsed with Number(...)
  • non-decimal input currently uses parseInt(..., base)

Input handling

input(command) supports two modes:

  • single-character editing input
  • command dispatch

Accepted single-character editing input currently includes:

  • 0-9
  • A-F
  • a-f
  • +
  • -
  • .

Everything else is forwarded to command(...).

Basic usage

CommonJS

const RpnCalculator = require('./src/rpn-calculator');

const calc = new RpnCalculator();
calc.push(2);
calc.push(3);
calc.command('add');

console.log(calc.pop()); // 5

Browser

<script src="./src/rpn-calculator.js"></script>
<script>
	const calc = new RpnCalculator({ angleMode: 'deg' });
	calc.push(9);
	calc.command('sqrt');
	console.log(calc.pop());
</script>

Editing values through input(...)

const calc = new RpnCalculator();

calc.input('1');
calc.input('2');
calc.input('.');
calc.input('5');
calc.command('enter');

console.log(calc.pop()); // 12.5

Aliases

const calc = new RpnCalculator();
calc.push(6);
calc.push(7);
calc.command('+');
console.log(calc.pop()); // 13

Constants and trigonometry

const calc = new RpnCalculator({ angleMode: 'deg' });
calc.command('pi');
console.log(calc.pop());

calc.push(30);
calc.command('sin');
console.log(calc.pop()); // 0.5

Demo

The default demo lives in samples/dev/.

Main UI features:

  • four visible stack lines
  • main display/status area
  • visible angle mode indicator
  • angle mode selector for deg, rad, and grad
  • status pills for inputValue and isEditing
  • grouped panels for Stack, Arithmetic, Trigonometry, and Constants
  • keyboard-friendly hidden input on desktop

Calc 02 demo

samples/calc-02/ is a portrait-first HP48GX-inspired demo. It keeps the display-adjacent button row aligned in four columns, uses compact popup menus for mode and constants, and supports clipboard paste plus the y√x root operation.

The demo loads the engine from:

<script src="../../src/rpn-calculator.js"></script>

Demo keyboard support

The current demo supports:

  • digits and decimal point
  • numpad digits and numpad arithmetic keys
  • Enter
  • Backspace
  • Delete
  • Escape
  • ArrowUp, ArrowDown, ArrowRight
  • +, -, *, /, %, ^
  • s, S, r, R, v, u
  • l, L, n, N, e, E
  • i, o, a, I, O, A

The demo also implements stack selection and stack-item move mode in its UI layer using the public calculator methods. It keeps the calculator screen focused and updates the visible stack window as the selection moves.

Note: calc-02 keyboard shortcuts are the reference for this project.

Exports

RpnCalculator is exposed in both environments:

  • browser: window.RpnCalculator
  • CommonJS: module.exports = RpnCalculator
S
Description
No description provided
Readme 590 KiB
Languages
JavaScript 82.6%
Shell 17.4%