Somnypna is an esoteric programming language created on 2013-8-14 by Peter Berg. He wrote it while he was extremely sleep-deprived and did not remember the act of writing it when he woke up later that day. Somnypna is his first esolang. The name is a combination of the Greek and Latin roots which both mean "sleep."
A Somnypna program is started with the command "z.z.z." If this command is absent, the program is not valid. The original specification details that the filetype extension for a Somnypna program is .zzz, but to what extent this would be utilized is unknown. Commands are read in order from top to bottom, one at a time. The VOKE command, however, can cause the playhead to jump to another function.
A line in Somnypna ends with an apostrophe. This was done in order to enable an entire program to be written as a single line if necessary. Line breaks are recommended but not necessary. Comments are started with a comma and ended with a period. Comments can contain commas and periods as long as a comma starts it and a period ends it.
Somnypna uses two types of variables. A value has to be stored into a variable in order to create it. If a variable does not exist when it is called by a command, the command is ignored.
The first type of variable is in base-36 (0-9 A-Z) and can be an arbitrary alphanumeric string of up to 217 characters, and can have a decimal point. Base-36 variables are denoted by surrounding a name with two colons on either side, e.g. ::varA::. The alphabetic characters in a base-36 variable must be capitalized. All variables are public by default.
The second type of variable, called a manifold, is in hexadecimal (0-9 A-F) and can be of unlimited length, but cannot have a decimal point. Manifolds are denoted by surrounding a name with two semicolons on either side, e.g. ;;manifoldA;;. Manifolds can be used to store hexadecimal image data as a single unbroken string consisting of each pixel's hexadecimal value read from left-to-right and top-to-bottom.
|z.z.z.||z.z.z.||Starts the program.|
|STRUCTURE||STRUCTURE,primary()'||Opens a function. "primary" is the required name of the first function. Commands in a function go in between the parentheses.|
|RESORT||RESORT,A,B'||Upon execution of the program, replaces every instance of the first parameter in the source code with the second parameter, excluding instances within comments. Effectively functions as a runtime find-and-replace command.|
|Stores a value or a variable in a variable.|
|P||ELF"::varD::P||When placed after the fourth colon of a variable, makes that variable private. If a private variable is created in one function, and a public variable of the same name is created in another function, the second variable becomes private.|
|REC||REC,::var0::'||Opens the program for one line of user input, to be stored in a variable. Standard restrictions on variables apply.|
|+||::varB::+::varC::"::varE::'||Adds one variable to another. The result must be stored into a third variable.|
|-||::varE::-::varC::"::varN::'||Subtracts the second variable from the first. The result must be stored into a third variable.|
|X||::varB::X::varC::"::varF::'||Multiplies one variable by another. The result must be stored into a third variable.|
|Y||::varB::Y::varB::"::varR::'||Divides the first variable by the second. The result must be stored into a third variable. In the event of a division by zero, the null variable's value is changed to the letter O, meaning a base-36 value of 24. The calculation then proceeds as normal. Decimal values are legal. In the event of an irrational decimal value, the value is truncated to 217 digits including the decimal point.|
|PLAY||PLAY,::varC::'||Outputs a variable to the user.|
|ARREST||ARREST,::varE::'||Deletes a variable.|
|VOKE||VOKE,secondary'||Causes the playhead to jump to another function, the name of which is the parameter of this command. Anything in between is skipped. Any commands placed after VOKE within a function are ignored. VOKE can also call WAKEUP, which jumps to the end of the program.|
|SCRAMBLE||SCRAMBLE,X,::varK::'||Generates a random base-36 numeral, X digits in length, and stores it in a variable. The maximum number of digits is 217.|
|REW||REW,::varK::'||Reverses the value of a variable from back to front.|
|NEXUS||NEXUS,::varK::"::varG::'||Takes the middle digit of the value of a variable and stores it in a second variable. If the first variable has an even number of digits, the middle two digits are stored in the second variable.|
|WEDGE||WEDGE,::varG::"::varF::'||Takes a variable and inserts it in the middle of a second variable. If the second variable has an odd number of digits, the first variable is inserted after the middle digit. If the second variable one digit long, the first variable is appended to the end.|
|GLUE||GLUE,::varK::,::varH::,::varI::,::varJ::"::varL::'||Appends a sequence of variables to one another, in the order given, and stores it in a variable. Takes as many parameters as needed.|
|CHOP||CHOP,::varL::'||In the value of a variable, replaces all G-Z characters with 0. Also removes any decimal points. This enables conversion to a manifold. If you do not CHOP a variable before using it as manifold data, any commands referring to said manifold are ignored. Note that the manifold's dimensions still have to be defined with the MANIFOLD command before a CHOPPED variable could be used as its data.|
|MANIFOLD||MANIFOLD,8,5,;;manifoldA;;'||Creates a two-dimensional pixel array of dimensions 8 (horizontal) by 5 (vertical) and stores it in a manifold. When a manifold is created, each pixel has the initial hexadecimal value of 000000. Once a manifold is created, its dimensions cannot be changed. Manifold dimensions are base ten and can be of arbitrary length, but it is not recommended to attempt large sizes if you're manually entering data.|
|NOISE||NOISE,;;manifoldA;;'||Randomizes the hexadecimal value of each pixel in a manifold.|
|Takes a variable or a raw string of hexadecimal data and writes it into a manifold. Hexadecimal data is written from the upper left to the lower right. As seen in the second example here, the upper left pixel would be AAAAAA, the upper right pixel would be F0F0F0, the lower left pixel would be FF0000, and the lower right pixel would be 007CEE. Variables have to be CHOPPED first to be used as data for a manifold.|
|HANG||HANG,;;manifoldA;;'||Exports a manifold as a bitmap file and displays it to the user.|
|SHOOT||SHOOT,;;manifoldB;;'||Gives the user the option to enter the filepath of a bitmap image. The image is then imported and converted into a single string of hexadecimal data, which is stored in a manifold. The SHOOT command automatically defines the dimensions of the manifold. If the user declines the option, all commands referring to the manifold are ignored.|
|SIGH||SIGH,8,5,;;manifoldC;;'||Gives the user the option of manually entering hexadecimal data into a manifold of dimensions 8 (horizontal) by 5 (vertical). If the data entered is not rectangular in shape, the remaining area is filled in with 000000. If a pixel has a malformed value, its value becomes 000000. If the user declines the option, all commands referring to the manifold are ignored.|
|WAKEUP||WAKEUP()'||Ends the program. Any commands thereafter are ignored. No commands can be placed within the parentheses.|
z.z.z. STRUCTURE,primary( ,This program doesn't actually do anything meaningful. It's just to demonstrate how all of the commands work. RESORT,AAAAAA,FFFFFF' 10"::varA::' ::varA::"::varB::' AXLE"::varC::' HI5"::varD::P' REC,::var0::' ::varB::+::varC::"::varE::' ::varE::-::varC::"::varN::' ::varB::X::varB::"::varF::' ::varB::Y::varB::"::varR::' PLAY,::varC::' ARREST,::varE::' VOKE,secondary' )' STRUCTURE,tertiary( MANIFOLD,2,2,;;manifoldA;;' NOISE,;;manifoldA;;' DRAW,(::varL::),;;manifoldA;;' DRAW,(AAAAAAF0F0F0FF0000007CEE),;;manifoldA;;' ,Note here that the string AAAAAA would be replaced by FFFFFF because of the earlier RESORT command. This would make the upper left pixel white instead of grey. HANG,;;manifoldA;;' SHOOT,;;manifoldB;;' SIGH,8,5,;;manifoldC;;' VOKE,WAKEUP' )' STRUCTURE,secondary( SCRAMBLE,6,::varK::' REW,::varK::' NEXUS,::varK::"::varG::' WEDGE,::varG::"::varF::' GLUE,::varK::,::varK::,::varK::,::varK::"::varL::' CHOP,::varL::' VOKE,tertiary' )' WAKEUP()'
z.z.z. STRUCTURE,primary( HelloWorld"::hello::' PLAY,::hello::' )' WAKEUP()'
Or, as one line: