WalrusOS/Walc

From Esolang
Jump to: navigation, search

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