Spiral
Paradigm(s) | imperative |
---|---|
Designed by | User:Quintopia |
Appeared in | 2003 |
Computational class | Turing complete |
Reference implementation | Wayback (from the Wayback Machine; retrieved on 7 October 2010) |
Influenced by | Wierd,Brainfuck |
File extension(s) | .spi |
Spiral, devised by User:Quintopia, is an esoteric programming language in two dimensions. Unlike other two-dimensional languages (exception: Wierd), the instruction pointer decides where to move based on where there is code to execute. In addition, the only data structure is a deque.
Flow Control
Instructions in spiral consist of single non-whitespace characters and the instruction pointer can be thought of as a robot that rolls along the code like railroad tracks always trying to turn. It can move in any of the four cardinal directions. If the pointer is in right-turning mode, then as soon as it steps onto an instruction it turns 90 degrees to the right. For instance, if it just made a step in an eastward direction, it will turn and face south. Likewise, if it is in left-turning mode, it will immediately turn 90 degrees left.
Next, it looks for a command (any non-whitespace character) in front of it. If there is one, it executes it and then tries to take a step forward. Otherwise, it turns 90 degrees left (or right, if in left-turning mode) and repeats this process. For instance, in right-turning mode it might first try executing a statement on the south, then the east, then the north, then the west, then the south again, etc. Note well that an instruction is always executed before the pointer moves onto it.
The program begins wherever the '0' character first occurs and it should occur only once. Behavior of the '0' label is unspecified if it occurs more than once.
Data Structures
There is a deque bounded only by memory limitations and a general purpose register, which will henceforth be referred to as villanova. All operations that modify the deque do so to the front of it, but which end is the front may be toggled. The only data type for all non-I/O operations is an 8-bit integer.
Commands
Character | Name | Operation |
---|---|---|
@ | spiral | The spiral operator is a toggle switch. When executed, the instruction pointer switches from right-turning to left-turning mode. In addition, it flips the deque over, so that the former front is now the back and vice versa. |
! | heyyou | Halts the program |
* | star | Increments the value in villanova |
# | crosshatch | Decrements the value in villanova |
v | push | Pushes the value in villanova onto the deque. |
= | bridge | A null op |
X | railroad | Pops a value from deque and stores it in villanova. If the value popped is non-zero, the instruction pointer is not allowed to move onto the railroad, with the railroad behaving just like whitespace in this respect. |
~ | compare | Compares the top two values on the stack, and pushes -1 if the first is less, 0 if they are equal, and 1 if the first is greater. |
+ | add | The add operator is entirely syntactic sugar. It pops two values from the deque and pushes their sum. |
. | cough | Pops a byte from the deque, converts it to a character, and prints it. |
, | spit | Pops a byte from the deque and prints its decimal representation. |
: | chew | Consumes a character from the input buffer and pushes it as a byte to the deque. If the input buffer is empty, the programs stalls waiting for input. |
; | swallow | Consumes all characters in the input buffer up to the first newline, interprets the string as a signed decimal integer, and pushes its value to the deque. If the input cannot be interpreted as an integer, it keeps asking for input like Johnny 5 until the input does look like an integer or the stack overflows in frustration. |
^ | copy | Sets villanova to the value at the front of the deque. |
$ | swap | Moves the front byte of the deque behind the second byte, making the second byte the new front byte. |
" | quote | Reserved character |
`
(JSpI-specific command) |
debug | Runs the interpreter in debug mode if the command is found anywhere in the program. |
any other displayable non-whitespace character | label | When the program is initialized, the positions of all occurrences of the character are noted. If the character occurs twice, the instruction pointer is moved to the other occurrence of the character. For any other number of occurrences, behavior of the instruction pointer is unspecified. In addition, the instruction pointer is set to right-turning mode facing the right, and villanova is reset to zero. |
Errors
There are only two possibles errors in theory: Making the instruction pointer leave the program playing field, and trying to pop an empty stack.
In practice, there are also limits on the size of the program and the length of the deque.
Self-intersecting Code
Given multiple lines of code intersecting , it is possible to create an intersection such that if the instruction pointer begins at either end of any line in either right-turning or left-turning mode, it can be mapped to either end of any line so that it arrives in either right-turning or left-turning mode according to any bijection using only the bridge and spiral operators.
The simplest and most useful intersection is one in which two lines of code cross right over each other without changing states. The simplest intersection that accomplishes this is thus:
= = @=@ === === @=@ = =
Although the following will also work:
= = =@ =@@@=== =@ = =
If you wanted an intersection where the instruction pointer always turns right and arrives without changing states, the following is the current smallest and fastest method:
= = === === = =@@ @@= @=@ =@= = ==== === = ==@==== @=@ === = == = = ==@=====@ @ = =
Making it smaller and faster is left as an exercise to the reader.
Notice the little bit on the right that looks like this:
==@==== ==
This object toggles the turning mode of the instruction pointer only if it is coming from the left.
Using that object, here is an object through which the instruction pointer can pass only if it is in right-turning mode; otherwise it goes back the way it came:
= = === == @= =@ == === = =
The mirror image of this object allows the instruction pointer to pass only in left-turning mode.
Examples
Hello World
e0v *** *eXlv** *lX *2X **oXi v * * * * * * 2 * o ** v* * * * * * ***** * v * v * *iX * * * * * * * * ^ v * * * w * * *** * * ***** * v * * * * v * * * * ^ * ^ * * * * * * * *** * * ****v * v * * v * * * * * * * * * * * * * ^ * * * * * * * * ***** * ***** * ***** * *** * * * * * * * * * * * ** ** *** *** ******* *****v^ ******* ***** *wX *** **3Xp *rX4.. d5* qd** * 3 * * ** v^ * .. * * * *** * v * ^ * #pX v * .. . * * * ** * *** v * # r # * .. . * * * !q* * * * * * * # v # * 54 .. * * * * * * * * * * * # * # * @X * * * * * * * * * * * # * # * v * * * * * * * * * * * # * # * * ** * * * * * * * * * * # * # * ** ** * * * *** * * * * * #v* ^ * *** * * ***** * ** ** * ** ** *v * * * * * * * *** ***** *v^** *** *** ******* ****
Rot13
0@v*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v *^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^ v ^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v= ***^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^ * **********v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^## *^v*^v*^v*^v*^v*^v*^v*^v*^v####################### v ^*v^*v^*v^**************v^*v^*v^*v^*v^*v^********** #########^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v*^v**** # ###############v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^*v^* v*^v*^v*^v**************^v ==== X @ i:vX==:==== u@vX=@v i! ==XX ===v^== X vs.vuv @=== s=vv=X=$v= v =X X = # ===@v@X
99 bottles
With JSpI 1.2 comments
b****v^v+^v+^v+.******v^v+^v+^*v+^v+.******v^*v+^* = v = *^+v*^v******..v^+v^+v^+v*^+v^v*******.+v*^+v*^+ = v+^v+^v+.******v^v+^*v+^v+^*v+.*******v^v+^v+^*v = + = +v*^+v*^+v*^+v*^v******.+v^+v^+v^v****Xv# *@+v*^ = . = . v . * $X @=~ = * v XX = * @=====X = * = **v^v+^*v+^*v+^v+.****v^v+^v+^v+.******v^v+^v+^* + v v^+v*^+v^+v^v*******..v^+v*^+v^+v*^+v^v******.+v^+ w****v^v+^v+^v+.******v^*v+^*v+^*v+^*v+.******v^*v . + . +v^+v^+v*^+v^v*******.+v^+v^+v^v****.+v^+v*^+v*^ v .******v^*v+^v+^v+^v+.******v^v+^*v+^v+^*v+.**** ^ v + ^+v^+v^v******.+v*^+v*^+v*^+v^v*******.+v^+v^+v^ v v+^*v+.**** ^ * +v^+v*^+v*^v* n****v^*v+^*v+^*v+^v+.******v^*v+^*v+^*v+^*v+.**** . v + +v*^+v*^v******.+v*^+v^+v*^+v*^v******.+v^+v^+v^ v ^*v+^*v+.*******v^v+^v+ * ^ ^+v^+v*^+v^v******.+v^+v* s****v^v+^*v+^*v+^*v+.******v^*v+^*v+^*v+^*v+.**** . v + ^+v*^+v*^v******.+v^+v^+v*^+v^v*******.+v^+v^+v^ v *v+^*v+.****v^v+^v+^v+.*******v^v+^*v+^v+^v+.*** ^ * v ^+v^v****.+v*^+v^+v*^+v^v******.+v^+v^+v^+v*^v** * v+^v+.*******v^v+^v+^*v+^*v+.*******v^v+^*v+^v+^ * v * .+v^+v*^+v^+v^v*******.+v*^+v*^+v*^+v*^v******.+ * ******v^v+^*v+^v+^*v+.****v^v+^v+^v+.******v^v+^ * v . v^+v*^+v^v******.+v^+v*^+v*^+v*^v******.+v*^+v^+ + +^v+.****v^v+^v+^v+.******v^v+^v+^*v+^v+.******* v v ^ v^+v^v****.+v*^+v^+v^+v*^v*******.+v*^+v^+v*^+v^ + +^v+.*******v^v+^v+^*v+^*v+.******v^*v+^*v+^*v+^ v * * .+v*^+v^+v*^+v^v******.+v*^+v^+v*^+v*^v******.+v ^ ****v^v+^v+^v+.******v^*v+^*v+^v+^*v+.******v^*v + + v v*^+v^v******.+v^+v*^+v^+v^v*******.+v*^+v*^+v*^ * +^v+^* ^ v v*****.+ t*****v^v+^*v+^v+^v+.******v^v+^v+^v+^*v+.******v^ . * + ^+v^+v^v****.+v*^+v^+v*^+v^v******.+v*^+v*^+v^+v v v+.******v^*v+^*v+^*v+^*v+.******v^*v+^*v+^*v+^v ^ + v +v^v******.+v^+v^+v^v****.+v*^+v^+v*^+v^v******. * ^*v+^v+^v+.******v^*v+^*v+^*v+^*v+.*******v^v+^* * v * ^+v*^+v*^v*****.+v^+v*^+v*^+v*^v******.+v*^+v*^+ * v+.****v^v+^v+^v+.****v^v+^v+^v+.*****v^v+^v+^v+ * ^ . v^+v*^+v*^+v^+v^v*******.+v*^+v^+v^+v^v******.+v + ..****v^v+^v+^v+.******v^*v+^v+^v+^*v+.*******v^ v v ^ .+v*^+v^+v^+v^v******.+v^+v^+v^v****.+v^+v^+v*^+ + *******v^v+^v+^*v+^v+.******v^*v+^*v+^*v+^*v+.** v * * *****.+v^+v*^+v*^+v*^v******.+v*^+v^+v*^+v^v**** ^ *v^v+^*v+^v p*****v^*v+^*v r**** + + . = = * v*^v*****.+v^ +v^v*****.+v^+ .+v^v f 09*vq $=@==*==vvv* v$ v v +v*^+v X qvX***v** 9**+^* ! *v ========= *^ == ==Xv *+ = ====@= v w *v p = = ===bX= v^ ===== n v^v = *== vX= ,@*v=Xv@,v^ v @ + ==fX***v~=#v~==X ===== *v r v XX X = = ^ ==X = =vv*== X @ + ======== v@=t=##v@=#v v X X * @=@= ^ s=== # **v^v+^v+ X=v v * ## *** \\\\\ 649\Prints " on the wall". 998\Prints "No more" 1230\Prints "Go to the store and buy some more.\n" 2329\Prints "Take one down. Pass it around.\n" 3261\Prints ".\n". 3276\Prints \n. 3373\This program prints the lyrics to (one version of) the song "99 bottles of beer on the wall." 3420\The main loop. Sets up state for each verse, then calls the printing function until 0 is reached. 3430\Puts 99 on the stack. 3614\Prints one verse.
External resources
- Spiral documentation and interpreter (from the Wayback Machine; retrieved on 7 October 2010)