Calculator.app

From Esolang
Jump to navigation Jump to search
Calculator.app
Paradigm(s) Concatenative, imperative
Designed by User:RocketRace
Appeared in 2023
Memory system Stack-based
Computational class
Reference implementation Calculator.app
File extension(s) {{{files}}}

Calculator.app is a pseudo-concatenative, stack-oriented programming language by User:RocketRace that tastefully reimplements the macOS default calculator app by the same name. This language exists to demonstrate the (surprisingly) rich feature set of the app, such as RPN support, unit conversions, and bitwise operations.

Examples

The following program prints fibonacci numbers when executed in a loop on persistent state (as the reference implementation does).

Scientific
enter 1 enter 5 2Vx + enter 2 / enter mr y^x enter 1 +/- enter 5 2Vx - enter 2 / enter mr +/- y^x - enter 5 2Vx /
Programmer [10] Large-Type Scientific
drop enter 1 m+ drop

The following program takes as an argument elements X and Y on the stack (pushed in that order), and returns with X%Y on the stack.

Scientific Rad
enter Rv x<->y R^
/
enter pi *
cos 2nd cos^-1 2nd
enter pi /
*

Reference

A Calculator.app program is a UTF-8 string of whitespace-delimited words, each word representing a button available in the calculator app. These buttons each affect the state of the program in some way. Some buttons may cause an error to be raised (such as with invalid values or not enough values on the stack to perform an action), which halts execution. Many buttons have both a pretty-unicode and an ASCII representation.

The below aims to describe the reference implementation, which is the primary source of truth on the language.

Deviations from source material

There are some deviations from the app itself when translating its behavior into an esolang. Calculator.app is not a full recreation of the source app. There are a number of features in the original that are confusing, janky, or otherwise annoying to program in (and especially annoying to implement), and have been removed:

  • The specific behavior of C and AC
  • Implicit bitwidth narrowing
  • Entering values in RPN mode is inconsistent across numeric & programmer modes
  • The way numbers are converted while entering Programmer mode is lossy:
  • When exiting Programmer mode, numbers are not always converted to doubles; until an operation is performed on them, they are displayed and stored as their 64-bit integer value (which may not be representable as a float).
  • The stack is sometimes cleared when enabling and disabling RPN input.
  • The ASCII and Unicode output options are flags that toggle a permanent display to the side of the number.
  • There are some buttons with ambiguous labels, such as C.
  • (Infix functions were also removed. It's a stack language now.)


State

The runtime has two main sources of data: Stack and State. State contains flags and registers that alter the behavior of buttons.

  • Current mode (Basic, Scientific or Programmer)
  • Digit input data (decimal point presence & location, visible digits)
  • Base in programmer mode
  • Angle and Palette in scientific mode
  • The contents of the memory cell in scientific mode

The stack contains either 64-bit unsigned integers or 64-bit floating point numbers, based on the current mode. (Floats in basic / scientific, ints in programmer).

Buttons

Below is a list of buttons by category and their actions.

Stack

Stack buttons are available in every mode.

x↔︎y or x<->y Swap the top 2 elements of the stack
R↓ or Rv Roll the stack “down”, i.e. pop an element normally and push it to the wrong end of the stack. The wording here is bad because the original app visualizes the stack as growing downwards, and hence the "top" of the stack is in fact at the bottom. "Normally" refers to the default action of the stack, and "wrong" refers to doing things at the opposite end (which is not a feature of stacks but oh well)
R↑ or R^ Roll the stack “up”, i.e. pop an element from the wrong end of the stack and push it normally
drop Drop the top of the stack. If there is only 1 element on the stack, push 0 to the stack afterwards. (This means the stack is never empty.)
enter Duplicate the top of the stack

Basic arithmetic

Basic arithmetic is available in every mode. Note that in programmer mode, these operations can overflow.

+ Pop two elements and push their sum
- Pop one element, pop another, push the second element minus the first
× or * Pop two elements and push their product
÷ or / Pop x, pop y. If in programmer mode and x is 0, then push y and push x. Else, push y divided by x. This makes integer division by zero a complete noop instead of erroring.

Numeric modifiers

These buttons are available in basic and scientific modes.

⁺∕₋ or +/- Negate the top of the stack
% Divide the top of the stack by 100

Digit buttons

The behavior of the numeric buttons and the decimal point (including double digit buttons in programmer mode) are influenced by digit input data. When the digit state is clear, pressing a digit will replace the top of the stack with that digit. Pressing additional numbers after that point will concatenate them with the top of the stack. Pressing the decimal point after zero or more digits inserts the decimal point at the specified position. In programmer mode, decimal points cannot be entered, and the digits a~f can only be entered in hexadecimal base.

0, 1, 2, 3, 4, 5, 6, 7, 8, or 9: When in basic or scientific mode Apply the behavior of the given digit
. or ,: When in basic or scientific mode Apply the behavior of the decimal point
0, 1, 2, 3, 4, 5, 6, or 7: When in Programmer mode and any base Apply the behavior of the given digit
8 or 9: When in Programmer mode and decimal or hexadecimal base Apply the behavior of the given digit
a, b, c, d, e, or f: When in Programmer mode and hexadecimal base Apply the behavior of the given digit
00: When in Programmer mode Apply the behavior of the 0 digit twice
ff: When in Programmer mode and hexadecimal base Apply the behavior of the f digit twice

Clear

Clear buttons are available in every mode.

C Set the top of the stack to 0, clear digit data
AC Clear the stack and state
⌘Q or Q Quit the program successfully

Mode

Mode buttons are available in every mode.

Basic Set the mode to basic. If the previous mode was programmer mode, then turn every int in the stack to the float closest to it in value
Scientific Set the mode to scientific. If the previous mode was programmer mode, then turn every int in the stack to the float closest to it in value
Programmer Set the mode to programmer. If the previous mode was not programmer mode, then truncate every float on the stack into an 64-bit integer, taking only the bottom 64 bits of the int
Programmer' Set the mode to programmer. If the previous mode was not programmer mode, then reinterpret the bitwise data of the doubles on the stack as int data

Angle

Angle buttons are available in scientific mode. The default angle mode is degrees. This influences the behavior of trigonometric functions.

Rad: When the angle mode is degrees Set the angle mode to radians
Deg: When the angle mode is radians Set the angle mode to degrees

Palette

The palette button is available in scientific mode. The default palette is "first". This enables and disables certain buttons.

2ⁿᵈ or 2nd Toggle the current palette from first to second, or from second to first

Memory cell

The memory cell buttons are available in scientific mode. The memory cell is initialized with the value 0.

mr Replace the top of the stack with the contents of the memory cell
m+ Add the value at the top of the stack to the memory cell
m- Subtract the value at the top of the stack from the memory cell
mc Set the memory cell's value to 0

Base

The base buttons are available in programmer mode. The default base is hexadecimal.

[8] Set the base to octal
[10] Set the base to decimal
[16] Set the base to hexadecimal

Output

The output buttons print results to standard output.

Large-Type: When in basic or scientific mode Print the number at the top of the stack to standard output (with a newline).
Large-Type: When in programmer mode Print the number at the top of the stack to standard output (with a newline). The output is formatted in the current base.
[ASCII]: When in programmer mode Print the ASCII character corresponding to the lowest 7 bits of the number at the top of the stack, to standard output (without a newline).
[Unicode]: When in programmer mode Print the Unicode scalar value corresponding to the lowest 21 bits of the number at the top of the stack, to standard output (without a newline). Output is encoded in UTF-8. Single surrogates are not valid characters and therefore cause an error.

Shared scientific

These buttons are available in scientific mode.

Rand Set the top of the stack to a uniformly random number between 0 and 1
E Set the top of the stack to euler's constant e
π or pi Set the top of the stack to the circle constant pi
EE Pop x, pop y, push (y * 10^x)
¹∕ₓ or 1/x Pop x, push one divided by x
x! Pop x, push x factorial (extended to real domain using the gamma function)
or x^2 Pop x, push x squared
or x^3 Pop x, push x cubed
or y^x Pop x, pop y, push y to the power of x
²√x or 2Vx Pop x, push the square root of x
³√x or 3Vx Pop x, push the cube root of x
ˣ√y or xVy Pop x, pop y, push the xth root of y. (note that there is no yVx button)

First palette

These buttons are available in scientific mode, when in the first palette.

sin Set the top of the stack to the sine of the top of the stack, using the current angle mode
cos Set the top of the stack to the cosine of the top of the stack, using the current angle mode
tan Set the top of the stack to the tangent of the top of the stack, using the current angle mode
sinh Set the top of the stack to the hyperbolic sine of the top of the stack
cosh Set the top of the stack to the hyperbolic cosine of the top of the stack
tanh Set the top of the stack to the hyperbolic tangent of the top of the stack
ln Pop x, push the natural logarithm (base e) of x
or e^x Pop x, push the exponential function (exp) of x
10ˣ or 10^x Pop x, push 10 to the power of x
log⏨ or log10 Pop x, push the logarithm base 10 of x

Second palette

These buttons are available in scientific mode, when in the second palette.

sin⁻¹ or sin^-1 Set the top of the stack to the inverse sine of the top of the stack, using the current angle mode
cos⁻¹ or cos^-1 Set the top of the stack to the inverse cosine of the top of the stack, using the current angle mode
tan⁻¹ or tan^-1 Set the top of the stack to the inverse tangent of the top of the stack, using the current angle mode
sinh⁻¹ or sinh^-1 Set the top of the stack to the inverse hyperbolic sine of the top of the stack
cosh⁻¹ or cosh^-1 Set the top of the stack to the inverse hyperbolic cosine of the top of the stack
tanh⁻¹ or tanh^-1 Set the top of the stack to the inverse hyperbolic tangent of the top of the stack
logᵧ or logy Pop x, pop y, push the logarithm base y of x. (Note that the unicode variant of this buttons is specified to have gamma instead of y for some reason)
or x^y Pop x, pop y, push x to the power of y
or 2^x Pop x, push 2 to the power of x
or log2 Pop x, push the logarithm base 2 of x

Programmer

These buttons are available in programmer mode.

AND Pop X, pop Y, push the bitwise AND of X and Y
OR Pop X, pop Y, push the bitwise OR of X and Y
NOR Pop X, pop Y, push the bitwise NOR of X and Y
XOR Pop X, pop Y, push the bitwise XOR of X and Y
<< Pop X, push X nudged left by one bit. The lowest bit of the result is always zero
>> Pop X, push X nudged right by one bit. The highest bit of the result is always zero
X<<Y Pop Y, pop X, push X shifted left by Y bits. The lowest bits (shifted in) of the result are always zero
X>>Y Pop Y, pop X, push X shifted right by Y bits. The highest bits (shifted out) of the result are always zero
byte-flip Pop X, swap the pairwise bytes of X (0x0123456789abcdef turns into 0x23016745ab89efcd) and push
word-flip Pop X, swap the pairwise words of X (0x0123456789abcdef turns into 0x45670123cdef89ab) and push
RoL Pop X, push X rotated left by one bit (cycling)
RoR Pop X, push X rotated right by one bit (cycling)
2's Pop X, push the two's complement of X
1's Pop X, push the one's complement of X

Conversions

A conversion button is composed of two elements: The unit to convert from, a > character, and the unit to convert to. An example of a conversion button is Celsius>Fahrenheit. Conversion buttons are available in basic and scientific modes. A conversion will pop x from the stack, then perform the conversion on x and push the result to the stack.

Only compatible units can be converted between. Below is a list of units available in each category:

Area
Acres
Ares
Decares
Hectares
Square-Centimeters Refers to square centimeters
Square-Feet Refers to square feet
Square-Kilometers Refers to square kilometers
Square-Meters Refers to square meters
Square-Miles Refers to square miles
Square-Millimeters Refers to square millimeters
Square-Yards Refers to square yards
Energy or work
BTUs British thermal units
Calories Food calories
Ergs
Foot-Pounds Foot pounds
Joules
Kilogram-Calories The other kind of calories
Kilogram-Meters (???)
Kilowatt-Hours Refers to kilowatt hours
Newton-Meters It's the same as Joules
Length
Centimeters
Feet
Inches
Kilometers
Meters
Miles
Millimeters
Nautical-Miles Refers to nautical miles
Yards
Power
BTUs/Minute BTUs per minute
Foot-Pounds/Minute Foot pounds per minute
Foot-Pounds/Second Foot pounds per second
Horsepower
Kilowatts
Watts


Speed
Feet/Minute Feet per minute
Feet/Second Feet per second
Kilometers/Hour Kilometers per hour
Kilometers/Minute Kilometers per minute
Knots
Meters/Second Meters per second
Miles/Hour Miles per hour
Miles/Minute Miles per minute
Temperature
Celsius
Fahrenheit
Kelvin
Time
Seconds
Minutes
Hours
Days
Weeks
Years
Volume
Cubic-Feet Feet cubed
Cubic-Meters Meters cubed
Fluid-Drams(US) Fluid drams (US unit)
Fluid-Ounces(US) Fluid ounces (US unit)
Gallons(US) Gallons (US unit)
Liters
Pints(US) Pints (US unit)
Quarts(US) Quarts (US unit)
Weights and masses
Drams
Grams
Kilograms
Long-Tons Long tons
Ounces
Pounds(US) Pounds (US unit)
Short-Tons(US) Short tons (US unit)
Slugs
Tonnes