TOPLWARLNTMIHTACAFFTPLAIHTASTNBIHTMAIAIU
TOPLWARLNTMIHTACAFFTPLAIHTASTNBIHTMAIAIU (for short: TOPL) is a deliberately convoluted yet strangely consistent programming language created by User:TeraByte. It started as a joke about Java's syntax being needlessly verbose.
Abbreviation & Pronounciation
TOPL's name stands for "that one programming language with a really long name that makes it hard to actually create a file for the programming language also it's hard to actually say the name because it's hard to memorize and its abbreviation is unpronouncable."
Directly contradicting the last part of the abbreviation, the name is pronounced "TAH-pl-WARL-nt-MIH-tuh-KAFFT-ply-TAST-n-BIT-mah-YAH-yoo."
File Structure
TOPL files must have the .toplwarlntmihtacafftplaihtastnbihtmaiaiu file extension. Just using .topl will not work.
Every program must start and end with:
#BEGINFILE ... #ENDFILE
No exceptions. Programs missing these sentinels are invalid.
Comments
TOPL supports two types of comments:
Single-line comments:
<<>> this is a single-line comment
Block comments:
>>> This is a block comment that can span multiple lines <<<
Syntax Overview
Rightwards Flow
Assignments, function results, and calls all use =>.
General pattern:
<expression> => <destination>
Examples:
init type Val => Var <<>> initialize variable init lib import numbers => Numbers <<>> import library init int Math:Add(One, Two) => Three <<>> function application
Indentation
Blocks use curly braces { ... }.
Indentation inside blocks must use two spaces only. Tabs are not allowed.
Libraries
There is a library for most data types and all I/O systems. You can't write out these values, you have to import these libraries if you want to use their respective types.
Numbers
init lib import numbers => N <<>> import N:Add(arg1, arg2, arg3...) <<>> adds any number of arguments N:Subtract(arg1, arg2) <<>> subtracts two arguments N:Multiply(arg1, arg2, arg3...) <<>> multiplies any number of arguments N:Divide(arg1, arg2) <<>> divides two arguments N:Power(arg1, arg2) <<>> exponentiates two arguments N:ToFloat(arg) <<>> converts to float N:ToInt(arg) <<>> converts to int N:Zero <<>> 0 N:One <<>> 1 N:Pi <<>> ~3.14 N:E <<>> ~2.71 N:RootTwo <<>> ~1.41
Strings
init lib import strings => S <<>> import S:Convert(item) <<>> convert to string S:FromASCII(int) <<>> get ascii character S:Append(arg1, arg2, arg3...) <<>> append any amount of strings S:GetChar(string, idx) <<>> obtain character, zero-indexed S:SetChar(string, idx, char) <<>> replace character, zero-indexed S:Nil <<>> empty string
Booleans
init lib import booleans => B <<>> import B:And(arg1, arg2, arg3...) <<>> returns true if all inputs are true B:Or(arg1, arg2, arg3...) <<>> returns true if any input is true B:Not(arg) <<>> returns true if input is false B:Equal(arg1, arg2, arg3...) <<>> returns true if all inputs are equal B:Less(arg1, arg2) <<>> returns true if arg1 < arg2 B:Greater(arg1, arg2) <<>> returns true if arg1 > arg2 B:True <<>> true B:False <<>> false
Lists
init lib import lists => L <<>> import L:Append(list, item1, item2, item3...) <<>> appends items to the end of a list L:Get(list, idx) <<>> obtain item, zero-indexed L:Replace(list, idx) <<>> replace item, zero-indexed L:Remove(list, idx) <<>> remove and return item, zero-indexed L:Nil <<>> empty list
Console
init lib import console => C <<>> import C:Print(arg1, arg2, arg3) <<>> print items to console C:Input(question) <<>> prompt the user for a string
Functions
Functions are defined with:
init func (in: <params>, out: <return>) {
... body ...
} => <FunctionName>
Parameters and outputs must be declared, even if nothing.
The main function is the entry point:
init func (in: nothing, out: nothing) {
<<>> program body
} => main
Functions that have output can return items like this:
init func (in: (int A), out: (int B)) {
N:Multiply(A, A) => B
} => square
Branching
If statements are done as follows:
<<>> if
if(Condition, (in: nothing, out: nothing) {
<<>> do something
})
<<>> if/else
if(Condition, (in: nothing, out: nothing) {
<<>> do something
}, (in: nothing, out: nothing) {
<<>> do something else
})
There are no standard loops in TOPL. Instead, you must use recursion:
init func (in: (int A), out: (int B)) {
if(B:Equal(A, N:Zero), (in: nothing, out: nothing) {
N:One => B
}, (in: nothing, out: nothing) {
N:Multiply(A, factorial(N:Subtract(A, N:One))) => B
})
} => factorial
Example Programs
Hello World
#BEGINFILE
init lib import console => Con
init lib import numbers => Num
init lib import strings => Str
init func (in: nothing, out: nothing) {
init int Num:Add(Num:One, Num:One) => Two
init int Num:Add(Two, Two) => Four
init int Num:Multiply(Four, Two) => Eight
init int Num:Multiply(Eight, Two) => Sixteen
init int Num:Multiply(Sixteen, Two) => Thirty
init int Num:Multiply(Thirty, Two) => Sixty
init string Str:FromASCII(Num:Add(Sixty, Eight)) => H
init string Str:FromASCII(Num:Add(Sixty, Thirty, Four, N:One)) => E
init string Str:FromASCII(Num:Add(H, Thirty, Four)) => L
init string Str:FromASCII(Num:Add(L, Two, Num:One)) => O
init string Str:FromASCII(Num:Add(Thirty, Eight, Four)) => Comma
init string Str:FromASCII(Thirty) => Space
init string Str:FromASCII(Num:Add(Sixty, Sixteen, Four, Two, Num:One)) => W
init string Str:FromASCII(Num:Add(Sixty, Thirty, Sixteen, Two)) => R
init string Str:FromASCII(Num:Add(Sixty, Thirty, Four)) => D
init string Str:FromASCII(Num:Add(Comma, Num:One)) => Exclaim
init string Str:FromASCII(Num:Add(Eight, Two)) => Newline
init string Str:Append(
H, E, L, L, O, Comma, Space, W, O, R, L, D, Exclaim, Newline
) => HelloString
Con:Print(HelloString)
} => main
#ENDFILE
Truth Machine
#BEGINFILE
init lib import console => Con
init lib import numbers => Num
init lib import strings => Str
init lib import booleans => Bool
init func (in: int A, out: nothing) {
Con:Print(A)
if(Bool:Equal(A, Num:One), (in: nothing, out: nothing) {
print(A)
})
} => print
init func (in: nothing, out: nothing) {
print(Num:ToInt(Con:Input(Str:Nil)))
} => main
#ENDFILE