# Reverse Polish Notation Calculator
## Versions
* 1.0.0
* Initial version.
## Introduction
RPN is a command line reverse Polish notation calculator. As such, it pushes integer and fractional numbers onto a stack, and pops them off for operations:
```
$ rpn
dec> 6 7
dec> show
6
7
dec> mul
42
```
RPN accepts input from files if supplied on the command line, and automatically detects if it's part of a POSIX shell command pipeline:
```
$ cat input.txt
6 7
mul
$ rpn input.txt
42
$ rpn <input.txt
42
$ rpn >output.txt
6 7
mul
$ cat output.txt
42
```
RPN optionally accepts input directly from the command line:
```
$ rpn --command 6 7 mul
42
```
Some operations are binary like `add` and `mul`, some are unary like `neg` and `inv`, some are nullary like `now`, some operate on the entire stack like `sum` and `prod`. Inline help provides a hint on expected inputs and outputs:
```
dec> help
Arithmetic operations:
N N add,+ N Add two values
N N sub,- N Subtract two values
N N mul,* N Multiply two values
N N div,/ N Divide two values
N N mod,% N Modulo two values
N neg N Find the negative
N inv N Find the inverse
N N pow N Raise to the power
N sqrt N Find the square root
* sum N Sum all values
* prod N Multiply all values
Bitwise operations:
N N and N Bitwise AND two values
N N or N Bitwise OR two values
N N xor N Bitwise XOR two values
N N shl N Shift left (multiply by power of 2)
N N shr N Shift right (divide by power of 2)
Time operations:
now N Get the current time
N plain N Convert to a plain value
N delta N Convert to a delta value
N time N Convert to a time value
Formatting commands:
dec Expect and format values as decimal
hex Expect and format values as hexadecimal
sep Include a separator
nosep Include no separator
N dp Use fixed decimal places
nodp Use free decimal places
Stack commands:
* c(lear) Remove all values from the stack
N p(op) Remove a value from the stack
N d(up) N N Duplicate a value on the stack
N N s(wap) N N Swap two values on the stack
N cut Cut a value to the internal clipboard
N copy N Copy a value to the internal clipboard
paste N Paste a value from the internal clipboard
History commands:
u(ndo) Undo the last operation
r(edo) Redo the next operation
h(ist) Show all undo/redo history
General commands:
show Show all values on the stack
help Show this help text
```
Feature requests are welcome, but it's a hobby project in a language I don't get to use in my day job, so I prefer to do all the development myself.
## Features
### Arithmetic Operations
The `add` operation adds two values:
```
dec> 5.5 2.5 show
5.5
2.5
dec> add
8
```
The `sub` operation subtracts two values:
```
dec> 5.5 2.5 show
5.5
2.5
dec> sub
3
```
The `mul` operation multiplies two values:
```
dec> 5.5 2.5 show
5.5
2.5
dec> mul
13.75
```
The `div` operation divides two values:
```
dec> 5.5 2.5 show
5.5
2.5
dec> div
2.2
```
The `mod` operation divides two values and finds the remainder:
```
dec> 5.5 2.5 show
5.5
2.5
dec> mod
0.5
```
The `neg` operation finds the negative:
```
dec> 8 show
8
dec> neg
-8
```
The `inv` operation finds the inverse:
```
dec> 8 show
8
dec> inv
0.125
```
The `pow` operation raises to the power:
```
dec> 3 4 show
3
4
dec> pow
81
```
The `sqrt` operation finds the square root:
```
dec> 100 show
100
dec> sqrt
10
```
The `sum` operation sums all values on the stack:
```
dec> 1 2 3 4 show
1
2
3
4
dec> sum
10
```
The `prod` operation multiplies all values on the stack:
```
dec> 1 2 3 4 show
1
2
3
4
dec> prod
24
```
### Bitwise Operations
The `and` operation performs a bitwise AND on all bits:
```
dec> hex
hex> ffff ff00ff show
0000ffff
00ff00ff
hex> and
000000ff
```
The `or` operation performs a bitwise OR on all bits:
```
dec> hex
hex> ffff ff00ff show
0000ffff
00ff00ff
hex> or
00ffffff
```
The `xor` operation performs a bitwise XOR on all bits:
```
dec> hex
hex> ffff ff00ff show
0000ffff
00ff00ff
hex> xor
00ffff00
```
The `shl` operation shifts left, i.e. multiplies by a power of 2:
```
dec> 16 4 show
16
4
dec> shl
256
```
The `shr` operation shifts right, i.e. divides by a power of 2:
```
dec> 16 4 show
16
4
dec> shr
1
```
### Time Operations
The `now` command gets the current time, showing times in UTC:
```
dec> now
2024-03-02T11:37:15.724
```
The `plain` command converts to an integer or fractional value:
```
dec> now
2024-03-02T11:37:15.724
dec> plain
1709379435.724
```
The `delta` command converts to a delta value, optionally showing days, hours, minutes, seconds and milliseconds:
```
dec> 86399 show
86399
dec> delta
23:59:59.000
```
The `time` command converts to a time value, showing times in UTC:
```
dec> 1709294400 show
1709294400
dec> time
2024-03-01T12:00:00.000
```
Delta values can be added to or subtracted from times:
```
dec> 1709294400 time 86400 delta
2024-03-01T12:00:00.000
1:00:00:00.000
dec> sub
2024-02-29T12:00:00.000
```
One time value can be subtracted from another:
```
dec> 1709294400 time 1709208000 time
2024-03-01T12:00:00.000
2024-02-29T12:00:00.000
dec> sub
1:00:00:00.000
```
### Formatting Commands
The `dec` and `hex` commands expect and format values as decimal and hexadecimal:
```
dec> 2 32 pow hex
0000000100000000
hex> dec
4294967296
```
The `sep` and `nosep` commands show and hide a separator for decimal and hexadecimal:
```
dec> 2 32 pow hex sep
00000001 00000000
hex> dec
4,294,967,296
```
The `dp` and `nodp` commands set and cancel fixed precision for decimal:
```
dec> 2 sqrt
1.4142135623730951454746218587388284504413604736328125
dec> 0 dp
1
dec> 3 dp
1.414
dec> 6 dp
1.414214
dec> nodp
1.4142135623730951454746218587388284504413604736328125
```
### Stack Commands
The `clear` command removes all values from the stack:
```
dec> 1 23 456 show
1
23
456
dec> clear
```
The `pop` command removes a value from the stack:
```
dec> 1 23 456 show
1
23
456
dec> pop
1
23
```
The `dup` command duplicates a value on the stack:
```
dec> 1 23 456 show
1
23
456
dec> dup
1
23
456
456
```
The `swap` command swaps two values on the stack:
```
dec> 1 23 456 show
1
23
456
dec> swap
1
456
23
```
The `cut` and `copy` commands store a value from the stack in the internal clipboard. The `paste` command copies that value back to the stack:
```
dec> 1 23 show
1
23
dec> copy
dec> 456 show
1
23
456
dec> paste
1
23
456
23
```
### History Commands
The `undo` and `redo` commands undo the last operation, and redo the next operation in the history:
```
dec> 1 23 456 show
1
23
456
dec> prod
10488
dec> undo
1
23
456
dec> undo
dec> redo
1
23
456
dec> redo
10488
```
The `hist` command shows all undo/redo history:
```
dec> 1 23 456 show
1
23
456
dec> prod
10488
dec> undo
1
23
456
dec> hist
1 23 456
<==
prod
```