Extensions to SNUSP
This page contains some extensions to SNUSP.
Forking SNUSP
Based on the idea of Brainfork, forking SNUSP is a multi-threaded form of SNUSP that adds a new command, Y, for forking.
When a Y is encountered, the current thread forks into two threads, each having an independent copy of the memory of the original thread. The parent thread has a zero in the current cell. The child has a 1 in the current cell.
The command does not cause the instruction pointer to move; it moves forward at the normal rate.
Piping
When a SNUSP program forks, its output channel is connected to the input channel of its child. The original output channel becomes the child's output channel.
This causes the parent and the child to be connected by a pipe.
When more than one fork occurs, the effect is that the threads are connected into a input-output chain, or pipe, similar to a pipe in Unix.
When a thread terminates, it is removed from the pipe and the input/output channels that are connected to it become connected to each other.
Forking SNUSP was created by User:Deschutron in 2009.
An example Forking SNUSP program
$Y?\parent-.# \-?\child.# \error#
This program forks and then splits into two branches based on the value in the current memory cell: one for the parent and one for the child. If the fork operation reports an error by setting the cell to 255, the program goes down the error path.
When run, this program writes two zeros to standard output, unless there is an error, in which case it writes one zero to standard output.
An example pipe in Unix
$ cat | tac | tail
This command runs three Unix commands in a pipe.
Using Executive SNUSP,
the following SNUSP program achieves the same effect,
as long as there are available SNUSP programs called cat.snusp
, tac.snusp
, and tail.snusp
.
$Y?\~{cat.snusp}# \Y?\~{tac.snusp}# \~{tail.snusp}#
Literal SNUSP
SNUSP with literals included. It is a Wimpmode for SNUSP. Two varieties are stated here.
- Decimal SNUSP
- Literal SNUSP
Decimal SNUSP
Decimal SNUSP is just like normal SNUSP except commands accept multipliers that are specified as decimal numeric digits.
When a decimal numeral '0' - '9' is encountered, the program sets up a multiplier variable and sets it to that digit's numeric value. Then, if it encounters another digit, it multiplies the multiplier variable by 10 and adds the current digit's numreic value to it. It continues this until it encounters a command. When it ecnounters a command, it executes it the number of times specified by the multiplier variable.
eg The program $65+.#
adds 65 to the current memory cell, prints it and then exits. The output is A
.
Full Literal SNUSP
Full literal SNUSP is just like Decimal SNUSP except that it accepts the full set of literals that the C language accepts (with regular expressions):
- decimal numbers (
[1-9][0-9]*
) - octal numbers (
0[0-7]*
) - hexadecimal numbers (
0x[0-9a-f]+
) - character values (
{'.'|'\\E'}
, where E is any C escape code character) - strings (
"{'.'|'\\E'}*"
)
For all the literal types except strings, the value stated is used as a multiplier.
e.g. $'A'+.#
outputs A
.
Strings in Full Literal SNUSP
For strings, the behaviour is bit more complicated.
When a string literal has been read and a command is encountered, the SNUSP program reads the next command as well.
Then, the SNUSP program executes the following loop
for each character c in the string, { execute command1 c times execute command2 }.
If the edge of the code space is next after the first command, so there is only one command available, the program exits after iterating through the loop once.
If command 2 is '#', the program executes at the end of each loop. If the call stack is empty, the program exits when the '#' is executed, as usual.
e.g.
$"Hello"+>!/<.?\# \===/
outputs olleH
Executive SNUSP
Executive SNUSP is an extended form of SNUSP that executes programs. It comes in different levels. Executive SNUSP uses the characters '~', '{' and '}'. It breaks the rule of always ignoring non-command characters. When '~' is encountered, the program activates an exec mode. The first '~' activates level-1 exec mode. When another '~' is encountered, the exec mode is changed to the next level, if the next level exists.
If the program encounters a '{' while it is in an exec mode, the program changes to bracketation mode. When in bracketation mode, no commands are executed. Every character encountered is saved into a buffer, except '}'.
When the program encounters a '}' while in bracketation mode, the program leaves bracketation mode, and executes the exec function corresponding to its exec mode. The contents of the buffer are used as an argument to the exec function.
Two levels of Executive SNUSP are defined here. Higher levels may be defined. A program that only supports up to level n exec functions may be called nth-level Executive SNUSP, e.g. "Second-level Executive SNUSP".
The idea of executive SNUSP and the first two levels of it were created by User:Deschutron in 2009.
1st level: SNUSP EXEC
The first level exec function is SNUSP EXEC
.
SNUSP EXEC
resets the state of the program, except IO channels, loads the filename in the buffer, and executes it as a SNUSP program. This command exits the SNUSP program.
SNUSP EXEC can be used as a way to access SNUSP programs stored on disk. This allows SNUSP modules to be written in different files and the combined at compile time or run-time. This feature was developed with an interpreter in mind, but it is possible to implement with a compiler.
The exec statements cause the SNUSP program to be connected to other SNUSP programs. When compiling, it becomes important whether to link to them statically or dynamically. The choice of linking time not specified by Executive SNUSP.
The effect of static linking
If the compiler compiles a SNUSP program containing SNUSP EXEC commands using static linking, it will load all the SNUSP files linked to, and compile them into the same program file. Dynamic linking to other SNUSP programs will still be possible via using SHELL EXEC commands to call precompiled SNUSP programs. In this way, the choice between static linking and dynamic linking can be made by the choice between SNUSP EXECing and SHELL EXECing other SNUSP programs. This can be used to set the size and scope of modularly developed SNUSP program files.
2nd level: SHELL EXEC
The second level exec function is SHELL EXEC
.
SHELL EXEC
runs a program from the underlying operating system's shell. The shell-executed program's Standard In and Standard Out are mapped to the IO channels of the SNUSP program and the SNUSP program exits.
The idea behind SHELL EXEC is to allow SNUSP programs access to the underlying operating system, and ultimately the hardware of a computer. However, SHELL EXEC allows program logic to be compiled from other languages and then called from SNUSP. This creates an escape route from writing challenging SNUSP code. For this reason, SHELL EXEC can be considered to be a severe Wimpmode for SNUSP.
Toroidal SNUSP
By default, the code space in SNUSP is not toroidal. But with the LEAVE ('#') command defined in Modular SNUSP, it is possible for a SNUSP program to terminate without reaching the edge of its code space. This allows the code space to be toroidal. This variant may be called Toroidal SNUSP.
Rectangular SNUSP
Created by User:asiekierka on December, 2009, it features one new command: ^
, which squares the current cell. While being pretty much useless, it allows huge numbers to be generated quickly.
For example,
$++^++++^#
sets cell 0 to 64
by setting it to 2, squaring it to 4, then adding 4 to create 8 and finally squaring that.
Redirectable SNUSP
Created by User:Deschutron during February 2010, Redirectable SNUSP adds another EXEC-style command.
The code
~~~{,filename}
causes the SNUSP program to change its input to the file "filename". Likewise
~~~{.filename}
redirects the program's output to a file called "filename".
Reverting the input to stdin can be done with the following sequence:
~~~{,-}
Reverting the output to stdout can be done with the following sequence:
~~~{.-}
Notation
The names of these extensions can be combined with each other, and the orignal SNUSP version names, to refer to versions of SNUSP with specific feature sets. e.g. "Forking, Executive, Modular SNUSP"
All these forms of SNUSP assume support of Core SNUSP, so "Forking Core SNUSP" is a tautology at best, or just incorrect, since the point of the term "Core SNUSP" is to point out that it doesn't contain any other features. If a variant of SNUSP is created that implements these extensions but not the commands in Core SNUSP it may called a form of Coreless SNUSP, e.g. "Forking, First-level Executive, Literal, Coreless Bloated SNUSP".
See also
- SNUSP, the predecessor
- Brainfork, the inspiration for Forking SNUSP
- LNUSP, a sister language to SNUSP that also calls subroutines