WalrusOS/Walc
Walculator is a program designed for use in command shells that comes bundled with the WalrusOS. It is designed as an esoteric sort of desktop calculator that works in reverse-polish notation. It includes modules for Geometry, Arithmetic, Complex and similar numbers, Set Theory, Logic, and String Manipulation. It supports variables, registers, and a deque for data manipulation.
It is accessed via the walc
command, which serves as an acceptable alternative name, hence the page name.
Commands
Walculator usage is something like using GHCi. When a non-specially-marked command is typed, standard expressions are used; when a command starts with a special character (specifically, the colon), it behaves as a command for modifying, examining, or interacting with the runtime of the program.
Expression commands are written in standard RPN, that is, they work as stack manipulation: Data is PUSHed onto the stack and operations POP their arguments before PUSHing the result. Operators are, generally, typable ASCII, but unicode may be used.
Usage
As has been mentioned, interacting with Walculator is simple: you type a command (with spaces separating individual subcommands) and hit enter, then it gets executed as an example to other members of the resistance.
Values
Individual subcommands are simple:
- A subcommand matching the regex
^-?[0-9]+(\.[0-9]+)?$
is treated as a double-precision floating-point number (or bigfloat, if the implementation allows) or long integer (or bigint, if the implementation allows), based on the presence of a decimal point. It is pushed on the deque when encountered. - A subcommand matching the regex
^-?0b[01_]+$
is treated as a binary integer, with underscores having no meaning (being removed from the string prior to interpretation). The number is converted to an integer then pushed onto the deque when encountered. - A subcommand matching the regex
^-?0t[0-2_]+$
is treated as a ternary integer, with underscores having no meaning (being removed from the string prior to interpretation). The number is converted to an integer then pushed onto the deque when encountered. - A subcommand matching the regex
^-?0q[0-3_]+$
is treated as a quaternary integer, with underscores having no meaning (being removed from the string prior to interpretation). The number is converted to an integer then pushed onto the deque when encountered. - A subcommand matching the regex
^-?0o[0-7_]+$
is treated as an octal integer, with underscores having no meaning (being removed from the string prior to interpretation). The number is converted to an integer then pushed onto the deque when encountered. - A subcommand matching the regex
^-?0x[0-9a-fA-F]+$
is treated as a hexadecimal integer. The number is converted to an integer then pushed onto the deque when encountered. - A subcommand starting and ending with a double quote is treated as a string, with the quotes stripped before usage and % codes (as used in URLs) evaluated. The evaluated string is pushed onto the deque when encountered.
- A subcommand matching the regex
^[a-zA-Z_][a-zA-Z0-9_]$
is interpreted as a name. It is called when encountered. - A subcommand matching the regex
^\\[a-zA-Z_][a-zA-Z0-9_]$
is interpreted as an anonymous name. It is pushed onto the deque when encountered. - A subcommand equal to "[" starts list mode, which starts compiling its arguments into a list.
- A subcommand equal to "]" exits list mode and pushes the list onto the stack
- A subcommand equal to "{" starts block mode and starts compiling commands as a block instead of executing them. If already in block mode, add 1 to block mode counter.
- A subcommand equal to "}" subtracts one from the block mode counter and, if it is equal to zero, exits block mode and pushes the block onto the stack.
- A subcommand not matching any of the above regexes is treated as an operator, which pops its arguments from the deque then pushes the result onto it or otherwise manipulates the values in the deque.
Operators and Builtin Functions
Arithmetic | ||||
---|---|---|---|---|
Operator | Name | Meaning | Type | Example |
S
|
INC | Pop a value, push its successor | (a -- b)
|
(5 -- 6)
|
P
|
DEC | Pop a value, push its predecessor | (a -- b)
|
(5 -- 4)
|
+
|
ADD | Pop two values and push their sum | (a b -- c
|
(5 6 -- 11)
|
-
|
SUB | Pop two values off the stack, push the difference between the second and the first. | (a b -- c)
|
(5 2 -- 3)
|
-'
|
NEGATE | Pop a value and push its additive inverse | (a -- b)
|
(5 -- -5)
|
*
|
MULT | Pop two numbers and push their product | (a b -- c)
|
(5 12 -- 60)
|
/
|
DIV | Pop two numbers, divide the second by the first | (a b -- c)
|
(6 2 -- 3)
|
//
|
FLOORDIV | Pop two values, divide the second by the first and floor the result | (a b -- c)
|
(6 4 -- 1)
|
/'
|
RECIP | Pop a value and push its multiplicative inverse (its reciprocal) | (a -- b)
|
(5 -- 0.2)
|
%
|
MOD | Pop two values and push the remainder when the second is integer divided by the first | (a b -- c)
|
(12 5 -- 2)
|
**
|
EXP | Pop two values and raise the second to the power of the first | (a b -- c)
|
(5 3 -- 125)
|
**%
|
EXPMOD | Calculate a**b%c efficiently | (a b c -- d)
|
(12 2 100 -- 44)
|
||
|
ABS | Pop a number, push its absolute value | (a -- b)
|
(5 -- 5)
|
Special Types | ||||
Operator | Name | Meaning | Type | Example |
*i
|
IMAGINE | Pop a number and push it multiplied by i | (n -- i)
|
(5 -- 5i)
|
CONJ
|
CONJUGATE | Pop a number and push its (complex or other) conjugate | (z -- z*)
|
(2+5i -- 2-5i)
|
String and List Manipulation | ||||
Operator | Name | Meaning | Type | Example |
++
|
JOIN | Concatenate one list onto another | (a<t> b<t> -- c<t>)
|
("walrus " "man" -- "walrus man")
|
!!
|
INDEX | Get a value by index | (i l<t> -- t)
|
(1 [1, 2, 3] -- 2)
|
|
|
| ||
Trigonometry | ||||
Operator | Name | Meaning | Type | Example |
SIN
|
SINE | Pop a number, push its sine | (a -- b)
|
(45 -- 1)
|
COS
|
COSINE | Pop a number, push its cosine | (a -- b)
|
(30 -- 0.154251449887584)
|
TAN
|
TANGENT | Pop a number, push its tangent | (a -- b)
|
(12 -- -0.635859928661581)
|
ASIN
|
ASIN | Pop a number, push its inverse sine | (a -- b)
|
|
ACOS
|
ACOS | Pop a number, push its inverse cosine | (a -- b)
|
|
ATAN
|
ATAN | Pop a number, push its inverse tangent | (a -- b)
|
|
Stack Manipulation | ||||
Operator | Name | Meaning | Type | Example |
:
|
DUP | Duplicate the value on the top of the stack | (a -- a a)
|
(5 -- 5 5)
|
\
|
SWAP | Pop two values from the stack and push them in the order they were popped | (a b -- b a)
|
(1 2 -- 2 1)
|
$
|
DROP | Pop a value off the top of the stack and discard it. | (a -- )
|
(5 -- )
|
:'
|
DUP PRIME or or DUP GROUP or DROUP | Pop an int "n" off the stack then duplicate the top n values on the stack. If n=0, duplicate the entire stack on top of itself. | (n a[n] -- a[n] a[n])
|
(3 1 2 3 -- 1 2 3 1 2 3
|
\'
|
SWAP PRIME or INVERT GROUP | Pop an int "n" off the stack then invert the top n values on the stack. If n=0, invert the whole stack. | (n a[n] -- invert(a[n]))
|
(4 1 2 3 4 -- 4 3 2 1)
|
$'
|
DROP PRIME or DROP GROUP | Pop an int n off the stack then pop n more items off the stack and discard them | (n a[n] -- )
|
(5 1 2 3 4 5 -- )
|
:''
|
DUP DOUBLE PRIME or LOTS | Pop an int n off the stack, pop a value v off the stack, push n copies of v onto the stack. | (n v -- v*n)
|
(3 1 -- 1 1 1)
|
:'''
|
DUP TRIPLE PRIME or GROUP LOTS | Pop an int n off the stack, pop an int o off the stack, duplicate the top o items on the stack n times. | (n o a[n] -- a[n]*o
|
(2 2 1 2 -- 1 2 1 2 1 2
|
ROT
|
ROT | Rotate the top three values on the stack | (a b c -- b c a)
|
(1 2 3 -- 2 3 1)
|
REVROT
|
REVROT | Reverse rotate the top three values on the stack | (a b c -- c a b)
|
(1 2 3 -- 3 1 2)
|
ROT'
|
ROT PRIME | Pop n, rotate the top n items on the stack | (n a[n] -- rotate(a[n]))
|
(5 1 2 3 4 5 -- 2 3 4 5 1)
|
REVROT'
|
REVROT PRIME | Pop n, reverse rotate the top n items on the stack | (n a[n] -- reverse_rotate(a[n]))
|
(5 1 2 3 4 5 -- 5 1 2 3 4)
|
ROT''
|
ROT DOUBLE PRIME | Pop n, rotate the top 3 elements on the stack by n | (n a[3] -- rotate(a[3], n)
|
(2 1 2 3 -- 3 1 2)
|
REVROT''
|
REVROT DOUBLE PRIME | Pop n, reverse rotate the top 3 elements on the stack by n | (n a[3] -- reverse_rotate(a[3], n)
|
(2 1 2 3 -- 2 3 1)
|
ROT'''
|
ROT TRIPLE PRIME | Pop n, pop o, rotate the top o elements on the stack by n | (n o a[o] -- rotate(a[o], n)
|
(4 2 1 2 3 4 -- 3 4 1 2)
|
REVROT'''
|
REVROT TRIPLE PRIME | Pop n, pop o, reverse rotate the top o elements on the stack by n | (n o a[o] -- reverse_rotate(a[o], n)
|
(4 2 1 2 3 4 -- 4 3 1 2)
|
ROLL
|
ROLL | Rotate the deque such that the front element is moved to the back | (b -- ...b
|
(1 -- ...1)
|
REVROLL
|
REVROLL | Rotate the deque in reverse (back becomes the front) | (...a -- a)
|
(...1 -- 1)
|
ROLL'
|
ROLL PRIME | Pop n, roll the deque by n slots | (n a[n] -- ...reverse(a[n]))
|
(2 1 2 -- ... 2 1)
|
REVROLL'
|
REVROLL PRIME | Pop n, reverse rotate the deque by n slots | (n ... a[n] -- reverse(a[n]))
|
(3 ... 1 2 3 -- 3 2 1
|
CHUNKROLL
|
CHUNKROLL | Pop n, move the front n elements in the deque to the back | (n a[n] -- ...a[n])
|
(2 1 2 -- ...1 2)
|
CHUNKREVROLL
|
CHUNKREVROLL | Pop n, move the back n elements in the deque to the front | (n ... a[n] -- a[n])
|
(3 ... 1 2 3 -- 1 2 3
|