International Phonetic Esoteric Language

The International Phonetic Esoteric Language, abbreviated to IPEL, is a stack-based esoteric programming language by User:Bigyihsuan based on the idea of using the Wikipedia:International Phonetic Alphabet (IPA) as the primary instruction set. Its interpreter can be found here
== Overview ==
IPEL uses 2 stacks to store values, named the unvoiced and voiced stacks, as well as a general-use register. There is a pointer to the current stack that gets switched with a set of instructions, further detailed below.
An additional execution stack is used by the interpreter for loops and control flow.
IPEL has three types: numbers, strings, and lists. Numbers represent both integers and floats and act as such. Strings are chains of characters stored as a single value. Lists are a container type that can contain any combination of the three types.
IPEL has a large instruction set that consists solely of single-character strings taken from the IPA.
IPEL also has a labeling system that allows for arbitrary jump points. There is a function system as well that supports recursion.
=== The Three Stacks ===
The three stacks consist of 2 data stacks and 1 execution stack. The data stacks, named "Unvoiced" and "Voiced", are directly worked on by most instructions. The current data stack, as well as which one it is currently, can be changed by some instructions as detailed below.
The execution stack has only the top element exposed by certain instructions. It is used for both storing loop index counters, as well as points for execution to return to when using loops and functions.
=== The Register ===
A general-use register is available. It holds a single value that is set by an instruction, gotten by a different instruction.
It is colloquially called the wegister.
Character	Stack Effect	Mnemonic	Description
w 	(ele -- ) 	SETREG 	Pops a value off the stack and sets the register to it.
ʍ 	( -- ele) 	GETREG 	Pushes a copy of the register onto the stack.
== Types ==
The three types when encountered by the interpreter are pushed onto the currently selected stack.
Code 	Type 	Explanation
0-9 	Number	Single digit.
{...}	Number	Number with more than 1 digit, or a float.
"..."	String	String
[...]	List 	List elements separated by periods .
=== Numbers ===
Numbers represent both integers and floats. Numbers are defined in one of two ways: digit form and multidigit form. The digit form is any digit in 0-9A-Za-z. The multidigit form consists of a whole number, then an optional decimal point with fractional part. They are surrounded by curly braces {}. Floats and negative numbers can only be declared using the multidigit form.
If you use the multi-digit form containing A-Za-z, the number is interpreted as a base-36 integer.
==== Examples ====
 7 ( -- 7)
 78 ( -- 7 8)
 {123} ( -- 123)
 {1.23} ( -- 1.23)
 1{3.3}0 ( -- 1 3.3 0)
 {3.5} ( -- 3.5)
 {abc} ( -- 13368)
=== Strings ===
Strings are a sequence of characters. They are delimited by double quotes "..." Strings can be considered a "pseudo-list" of integers, with each integer representing the ASCII/Unicode value. This lets it be treated like a list with list-manipulating instructions.
Escape sequences are allowed for strings; they can be one of the following subset of the Python escape sequences:
Escape Sequence	Meaning
\newline 	Backslash and newline ignored
\\ 	Backslash (\)
\' 	Single quote (')
\" 	Double quote (")
\a 	ASCII Bell (BEL)
\b 	ASCII Backspace (BS)
\f 	ASCII Formfeed (FF)
\n 	ASCII Linefeed (LF)
\r 	ASCII Carriage Return (CR)
\t 	ASCII Horizontal Tab (TAB)
\v 	ASCII Vertical Tab (VT)
==== Examples ====
 "abc" ( -- "abc")
 "a""b""c" ( -- "a" "b" "c")
 "" ( -- "" )
 "a \
 b" ( -- "a b")
 "\n" ( -- "\n")
 "\"<>" ( -- "\"<>")
 "'hello'" (-- "'hello'")
=== Lists ===
Lists are a type that stores other types, specifically any combination of numbers, strings, or lists. They are delimited by square brackets [].
List elements are separated by periods .. Lists can be nested inside each other by creating a list inside a list.
==== Examples ====
 [] (empty list)
 [1.2.3]
 [{1.2}."string".3]
 [["nested"].["list".["in list"]]."it is"]
=== Type Truthiness ===
IPEL primarily implements the concept of booleans by using numbers: non-zero is truthy, and zero is falsy. In the same vein, strings and lists are also truthy and falsy; empty strings and lists are falsy.
=== Comments ===
Comments are modelled after Forth: text surrounded by parentheses (...) are comments. Just like Forth comments, you can't next comments; (com(com)ment) would terminate the comment at the first ).
==== Examples ====
 (this is a comment)
 (This is a comment (not nested)
 (comment with
 (a newline and tab)
== Labels, Jump, and Skip ==
Labels are characters representing the label name surrounded by pipes |...|. These are used in conjunction with the goto instruction ɔ. When a label is placed after ʟ, execution will jump to the label, then continue execution.
The skip instruction ʌ pops the stack, checks for truthiness, and skips the next instruction if it is truthy. This allows for conditional jumps by placing instructions to check a condition before the skip, and jumping if the condition is falsey.
Code 	Stack Effect	Description
label|	( -- ) 	Defines a label.
label|	( -- ) 	Jump to the specified label.
ʌ 	(con -- ) 	Pop the stack. If con is truthy, skip the next instruction.
== Functions ==
Functions are possible in IPEL by doing the following:
 <name>/code\ (function definition)
 <name> (function call)
Function bodies can contain any code at all: values, instructions, function calls, labels, anything. The ending symbol for a function boundary \ for the interpreter does nothing when execution did not come from a function. Expect undefined behavior or errors if you jump into a function body from a different function, such as <f>/abc|l|def\ <g>/ʟ|l|\.
Recursion is possible by calling the function from within itself: <f>/code <f> code\. It is up to you to set base cases.
== For-Loops ==
For loops are similar to Forth DO-LOOPs. The general structure is as follows:
 (value: end start -- ) (exec: -- end start)
 ɑ
 (code)
 ɒ
When ɑ is encountered, 2 numbers are popped from the current value stack and pushed onto the execution stack. When ɒ is encountered, it checks the execution stack. If index < end, jump to the associated ɑ.
index is manipulated by the 2 instructions e and ø. e pushes a copy of index onto the current value stack. ø pops a value from the current value stack and sets index to that value. This is the same with the limit with æ and œ, respectively.
Note that, unlike Forth, ɒ does nothing with index other than compare it against end.
There is also the ɛ instruction, which clears the execution stack of index and end, and exits the loop.
Character	Stack Effect 	Mnemonic	Description
ɑ 	(end start -- )	FOR 	Pops 2 values for index bounds. Loop jumps back to here if index < end.
ɒ 	( -- ) 	LOOP 	If index < limit, jump to associated For. Else, continue.
e 	( -- index) 	GETIDX 	Pushes the current loop's index. NOP if not in a loop.
ø 	(index -- ) 	SETIDX 	Sets the current loop's index to index.
æ 	( -- limit) 	GETLIM 	Pushes the current loop's limit. NOP if not in a loop.
œ 	(limit -- ) 	SETLIM 	Sets the current loop's limit to limit.
ɛ 	( -- ) 	EXIT 	Discards the current loop's data from the loop stack, and exits the loop. NOP if not in a loop.
=== A note on GETIDX, SETIDX, GETLIM, SETLIM ===
As of interpreter version v1.4.0, GETIDX, SETIDX, GETLIM, and SETLIM access the execution stack directly and run if and only if there is a valid value for it to get or set. The *IDX instructions use the top value, while the *LIM use the 2nd to top.
Because both loops and function calls use the same execution, it's possible to change where a running function will return to using *IDX and *LIM.
 <f>/"Yes"o e2sø\
 <f> "No"o "Skipped no"o
 (Will print "Yes" then "Skipped no". Note that "No"o counts as 2 instructions.)
== Instructions ==
=== Bilabials: Voicings ===
Bilabial consonants handle the selection of the current stack.
Character	Stack Effect 	Mnemonic	Comment
ɸ 	- 	UNVOICED	Sets the voicing to Unvoiced.
β 	- 	VOICED 	Sets the voicing to Voiced.
ɓ 	( -- voicing)	VOICING 	Pushes the current voicing. 0 for unvoiced, 1 for voiced.
=== Plosives: Stack Operations ===
Plosives modify the stack.
Character	Stack Effect 	Mnemnomic	Comment
p 	(a -- ) 	POP 	Pop and discard the top element of the stack.
b 	(a -- a a) 	DUP 	Duplicate the top element of the stack.
t 	( -- size) 	SIZE 	Push the size of the stack.
d 	(a b -- b a) 	SWAP 	Swap the first and second elements of the stack.
ʈ 	(c b a -- a c b) 	RCW 	Rotate the top 3 elements clockwise (upwards).
ɖ 	(c b a -- b a c) 	RCC 	Rotate the top 3 elements counterclockwise (downwards).
c 	(d b a c -- d c b a)	SORT 	Sort the stack. Numbers before Strings before Lists. Order of lists in the stack is preserved. Lower values on top.
ɟ 	(a b c d -- d c b a)	REV 	Reverses the stack.
k 	A(a -- ) B( -- a) 	GIVE 	Pop the top of the current stack and push it onto the other one.
g 	A( -- a) B(a -- ) 	TAKE 	Pop the top of the other stack and push it onto the current one.
q 	(a b -- a b a) 	OVER 	Push the 2nd element from the top of the stack.
=== Central Vowels: Comparisons and Logical Operators ===
Approximates and laterals represent comparisons. For all instructions, 1 is pushed if true, and 0 if false.
ASCII/Unicode order is used for strings. Empty strings are first, followed by shorter stings.
Comparing lists does not work except for the ə "Equal to" operator, where it will check for equality. The interpreter will NOP the instruction if it isn't the case
Character	Stack Effect 	Mnemnomic	Comment
ɨ 	(a b -- a>b) 	GT 	Greater than
ʉ 	(a b -- a>=b)	GE 	Greater than or equal to
ə 	(a b -- a==b) 	EQ 	Equal to
ɘ 	(a b -- a<b) 	LT 	Less than
ɵ 	(a b -- a<=b)	LE 	Less than or equal to
ɜ 	(a b -- a and b)	LAND 	Logical AND
ɞ 	(a b -- a or b) 	LOR 	Logical OR
ɐ 	(a -- not a) 	LNOT 	Logical NOT
=== Frontal Fricatives, Taps/Flaps, Trills: Mathematics ===
Fricatives, taps, flaps, and trills represent mathematical instructions.
These only apply to numbers. Otherwise, the interpreter will NOP the instruction.
Character	Stack Effect 	Mnemnomic	Comment
s 	(a b -- a+b) 	ADD 	Addition
z 	(a b -- a-b) 	SUB 	Subtraction
f 	(a b -- a*b) 	MULT 	Multiplication
v 	(a b -- a/b) 	DIV 	Division; will return 0 if b == 0. Always returns a float.
ⱱ 	(a b -- a%b) 	MOD 	Modulo (Labiodental Tap ⱱ)
ʃ 	(a b -- a**b) 	EXP 	Exponent; Base a, exponent b
ʒ 	(a b -- log(a, b)) 	LOG 	Logarithm; Base a, exponent b
θ 	(a b -- a>>b)	RSH 	Bit shift a to the right b bits
ð 	(a b -- a<<b)	LSH 	Bit shift a to the left b bits
ʂ 	(a b -- a&b) 	BAND 	Bitwise AND
ʐ 	b) 	BOR 	Bitwise OR
r 	(a -- !a) 	BNOT 	Bitwise NOT
ɾ 	(a -- -a) 	INV 	Inverts the sign of a.
ɽ 	(a -- ceil(a)) 	CEIL 	Rounds a to the largest integer
ʙ 	(a -- floor(a)) 	FLOOR 	Rounds a to the smallest integer
ɬ 	(a b -- max) 	MIN 	Minimum
ɮ 	(a b -- min) 	MAX 	Maximum
=== Back Fricatives, Taps/Flaps, Trills: List and String operations ===
Back fricatives, taps, flaps, and trills represent operations on lists. String operations are also in this section.
Character	Stack Effect 	Mnemnomic	Comment
x 	(abc def -- abcdef) 	CAT 	Concatenation. Implicitly casts its arguments into strings, then lists if they are not lists.
ɣ 	(a ... z n -- list) 	NCAT 	Concatenates the next n elements popped off the stack into a list of length n. Will NOP if n is not a number and does ceil(n) if it is.
ħ 	(a -- a n) 	LEN 	List length. Pushes the length of the element peeked. Casts a to a list to get its length. a's type is retained.
ʀ 	(list -- a b ...) 	LSPLIT 	Splits a list into its individual elements. Implicitly casts list to a list.
h 	(list n -- list e) 	GET 	Returns the element e at n, 0-indexed. Will NOP if n is not a number and does ceil(n) if it is
χ 	(num -- str) 	CHR 	Converts a number to a single-character string, based on its ASCII/Unicode value. Will NOP if num is not a number, and ceil(num) if it is.
ʁ 	(str -- n1 n2 n3) 	SSPLIT 	Converts a string to a list of integers representing their ord() values. Will NOP if str is not a list of single-character strings or a string.
ʕ 	(list -- str) 	LTOSTR 	Converts a list to a string.
ʔ 	(list ele -- list in?)	IN? 	Peeking at a list and consuming an element, returns if the list contains that element.
=== IO ===
Input and output is handled by the frontal closed vowels and the back central vowels.
Character	Stack Effect 	Mnemnomic	Comment
i 	( -- str) 	LINE 	Pushes a line from STDIN as a single string.
y 	( -- str str str)	WORD 	Pushes a line from STDIN as multiple strings, separated by whitespace.
ɪ 	( -- ele) 	DATA 	Pushes an IPEL value onto the stack. Can push numbers, strings, and lists. Defaults to pushing strings if no valid numbers or lists are found.
o 	(ele -- ) 	PRINT 	Pops and outputs to STDOUT with trailing newline.
ɤ 	(ele -- ) 	LPRINT 	Pops and outputs to STDOUT. Will cast lists to strings.
u 	(ele -- ) 	CPRINT 	Pops and outputs to STDOUT, with no trailing characters.
ɯ 	(ele trail -- ) 	TPRINT 	Pops and outputs ele to STDOUT with a trailing string trail.
== Examples ==
===Hello, World!===
 "Hello, World!"o
===Cat===
 io
===Factorial===
The function expects a number n on the stack and leaves n!.
 <factorial>/b1əɐʌɔ|end||loop|b1zb1əʌɔ|loop||mult|ft1əʌʟ|mult||end|\
===Fibonacci===
The function expects a number n on the stack and leaves the n-th Fibonacci number. Recursive implementation.
 <fib>/b1ɨʌɔ|end|1zb1z<fib>d<fib>s|end|\
==See also==
* CV(N)(C)
== External Resources ==
* Interpreter Repository
* IPA chart of used IPA characters currently used
Category:Stack-based
Category:2020
Category:Languages
Category:Implemented