Files
mtm-rpn-js/README.md
T

6.1 KiB

RPN Virtual Calculator

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

Overview

This project provides:

  • a reusable JavaScript RPN engine in src/rpn-calculator.js
  • a browser demo in samples/dev/
  • a command system centralized in a single operation dictionary
  • a small public API focused on stack operations and generic command dispatch

The main class is RpnCalculator.

Project structure

  • src/rpn-calculator.js: calculator engine
  • samples/dev/index.html: active browser demo entry point
  • samples/dev/index.css: demo styles
  • samples/dev/index.js: demo UI and keyboard logic
  • samples/calc-01/index.html: active browser demo entry point
  • samples/calc-01/index.css: demo styles
  • samples/calc-01/index.js: demo UI and keyboard logic
  • samples/calc-02/index.html: new responsive HP48GX-style demo entry point
  • samples/calc-02/index.css: new responsive demo styles
  • samples/calc-02/index.js: new 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()

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

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
  • 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
  • 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 active 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
  • error display area

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
  • +, -, *, /, %, ^
  • q, n, r, i, g, l, s, c, S, C
  • x, y, z, t

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.

Calc 02 demo

samples/calc-02/ is a new responsive HP48GX-inspired demo. It adapts its layout to the browser window and switches between the supplied portrait and landscape arrangements.

Exports

RpnCalculator is exposed in both environments:

  • browser: window.RpnCalculator
  • CommonJS: module.exports = RpnCalculator