-Spiral-

If the movie Pi contains any real insight into the world, then everything on earth has a spiral nature. This includes everything made by man, including computers and computer programs. If computer programs have an inherent spiral nature, why does the code we use to create them always look like straight lines?

After poking around the internet at various esoteric programming languages, including programs that are hard to read, like Brainf*ck, and its clones (Ook, Cow, f*ckf*ck), languages that are written, it seems, entirely as jokes, like hq9++, haifu, SMETANA, Whitespace, and, although its authors seem to be fairly serious in their goals, INTERCAL, I was most impressed with the languages that allow execution of two-dimensional code, and allow the program pointer to move in any direction. Such languages as Piet, BDAMD, Weird, and of course, Befunge-93, are not only fairly capable, but their program sources are fun to look at. Therefore, I set out to make a similar, and yet far more capable language. After a few minutes of thought, I came up with the basic idea for Spiral, a Turing-complete language capable of far more than your typical BF or Befunge program, and yet just as fun to code in. It contains aspects of Befunge, Reverse, and Q-Bal.

Like Befunge, Spiral's program pointer can start anywhere and move up, down, left, or right. Unlike Befunge, it cannot move across whitespace. The program pointer only moves to a given location if there is a command there. As soon as the pointer moves to a location, it will look to the right for a command (unless it's looking to the left first, see spiral (@) operator below), and if it finds one, it will execute it. If the command it has just executed gives it permission to, it will then move onto that command's location. If the pointer finds no command (i.e., it finds a space or nothing at all), it will attempt to go straight. If it finds a command directly in front of it, it will execute it, and, again, if it receives permission, will move to that commmand's location. Otherwise, it tries to turn left (unless it is now trying to turn right, see spiral (@) operator below), and if once again it is blocked, it tries to go back the way it came. If it can't go that way, you have created an infinite loop (Oops!). Note that the top and left edges of the program cannot be crossed (sorry, Befunge programmers, no wrapping allowed) and behave exactly like whitespace.

All data in Spiral is contained in a single FIFO (push-down) stack. However, thanks once again to our friend the spiral (@) operator, the stack can function as both a FIFO and FILO stack at the same time, and, despite any operator to do so, any of its elements can be accessed. Each element is a byte, and may contain a signed integer. There is also a utility variable, which you may call villanova. This temporarily stores values that are popped from, or are about to be pushed to the stack.

There are 16 operators in Spiral. Several of them do several things at once. This serves three important purposes by increasing functionality, decreasing program readability, and making the language a bit trickier to use. The operators in Spiral are:

Character Name Operation
@ spiral The spiral operator both alternates the default direction of program flow and reverses the stack (so that you're looking at it from the other end, and the bottom value is now the top, etc.)
! heyyou The heyyou operator immediately terminates the program.
* star When villanova eats a star, it increments his value.
# crosshatch When villanova trips on a crosshatch, it decrements his value.
v push The push operator pushes villanova to the stack.
= bridge The bridge operator does absolutely nothing.
X railroad The railroad operator is the primary decision making operator. It does three things. First, it pops the stack. If the value it gets is zero, it hands it to villanova, and allows the program pointer to come to its location. If it gets a non-zero value, it takes offense, and tells the program pointer to "bugger off" and throws the value it got at it. Fortunately, villanova is very patient, and always picks it up.
~ compare The compare operator 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 pops the top two off the stack, and pushes back their sum. This is provided purely for convenience, because it can be entirely replaced with other Spiral code. (see below)
. cough The cough operator pops the stack and coughs the value as a unicode char to STDOUT
, spit The spit operator pops the stack and spits its numeral value to STDOUT
: chew The chew operator chews up a unicode char from the input buffer and swallows it to the top of the stack. If the input buffer is empty, it gets more input from STDIN. A zero is pushed if the user enters nothing.
; swallow The swallow operator swallows a signed integer from STDIN to the top of the stack.
^ copy The copy operator tells villanova what value the top of the stack contains, and villanova promptly sets himself to this value.
& random Replaces the top byte on the stack with a random integer less than or equal to that number. Will cause an internal error if byte is negative.
$ swap The swap operator swaps the top two values on the stack.
" quote This operator is reserved for implementation in Spiral 2. JSpI-2 will not be backwards-compatible with Spiral programs containing this operator as a label.
any other displayable character label Labels do four things. First they set villanova to zero, the pointer facing right, and the default turning direction to the right, then they jump the pointer to the matching label elsewhere in the program. Thus, they serve as function calls, gotos, and make things like static object code possible. Three or more of the same label in a program will cause some very strange behavior, but will not create an error. One by itself will cause a bad label error. There is one special system label '0' that determines where the program starts, and more than one '0' will also cause strange behavior.

Of course, that last trick, the label, means that comments are impossible in a working Spiral program. Don't worry, you can stick your comments in a separate file. Besides, Spiral code looks so nice you don't want to spoil it with comments cluttering up your source.

Examples

 

Here's an example program in Spiral:

MULT:

0;;m,!
=@=@=
====== X =
= X $+v@
@m===@v@v$vX== ^
== X X #v$@
=X v =====@
= $ = X
======

MULT takes two numbers from the user (either or both of which may be negative) and pushes back their product, without affecting the rest of the stack.

The program above actually works. The program I had here before didn't work, but I went into an in-depth analysis of it anyway. Now that I have spent a few hours coming up with a working solution, I leave it to the reader to figure out how it works.

The Aesthetics of Spiral

Spiral programs are much more beautifuller than other languages. How many languages are there where you can make your program look like what it does? Take for example this HELLO WORLD Program:

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^** *** *** ******* ****

Who cares that half the code serves no purpose? Or that the same program can be written in just a few lines? How many HELLO WORLD Programs are there whose source code spells out HELLO WORLD in big block letters?? Who could mistake this program for any other?

Object Code

 

Spiral is a unique language in that it is the most simple language in which static objects with functions can be created. To create an object use something like the following:



@o=*v^~*v^~*v^~
==X X X X
= X X X
= f g h
= @ @ @
===============


o is your object. f, g, and h are all functions of o that return a single non-zero value on top of the stack. To call h via o, simply push 3 to the stack, and jump to o. Isn't it cool? Of course, you may not make other calls to f, g, or h, but isn't that the way objects work anyway?

Errors

There are no language errors in Spiral (see label above). My interpreter, however, will complain if you program is too long, tall, or wide. There are three fatal runtime errors, and that's trying to perform operations on an empty stack, or pushing values onto a full stack, or misusing labels. The former will terminate and send "Empty Stack" or "Full Stack" and the pointer's location to STDOUT. (The top left corner of the program is called [1,1].) A bad label error is any labeling error (such as a singular label) that causes the program pointer to leave the program area, and will give a "Bad Label" error message, and the name of the faulty label. Any other errors in Spiral are logic errors. This makes debugging a whole lot more fun of course.

More Examples:

 

The ADD program does the same thing as the + operator. This is the simplest and most elegant program I have ever seen in Spiral. The fact that this program works so well is convincing evidence that I should scrap the + operator in Spiral-2.

0;;a,!

==X
a=v
= =
=XX=$v*
#v$=X

The FACT program computes a factorial. It requires the body of the MULT program to be in the same file.


0;f,!            v^
========= =$
=@ ==== X =m
==f==vv$a========X
=v = X v**v~ =v
=*X== =v*= =#
== == a^ =#
====@ v# X

The SHUFFLE program takes the top of the stack as an argument and shuffles the rest of the stack up that number of times. (I.e., if the stack were a deck of cards, it would be cutting that number of cards to the bottom.)

==XX  ===v^==
s=vv=X=$v= v
=X X = #
===@v@X

The CLEAR program clears the input buffer up to the next newline. It's a good idea to run this if you've gotten all the input you need for now, but may want more input later. Remove the red X to pass the entire input buffer (except the terminating newline) onto the stack as a "string." Remove the green X to pass the newline to the stack as well.

  XX
=X====
= XX
cvvX=~v*****=
:$^$*****

The following code will allow two lines of code meeting at a perpendicular intersection to cross paths without interference. To see some more interesting results, try adding or removing bridges in the four spots diagonally adjacent to the center of the intersection.

     =
     =
    =@
===@@@====
    =@
     =
     =
Challenges

These are the challenges I would like to be met with this language:

  • A compiler that will compile Spiral source code directly to JAVA byte code (something I have no idea how to write).
  • A quine
  • A good-looking ASCII art picture of a dragon that prints the dragon's name when executed.
  • A program that does the same thing when compiled in Whitespace as it does in Spiral. (Keep in mind that [TAB] and [SPACE] are considered to have the same width in Spiral, so this program's source may not line up so neatly.)
  • Any combination of the above (a dragon ascii art program that prints its source code in Spiral and Whitespace being the ultimate goal).
Interpreters

JAVA Interpreter Source(18.5 KB)-Compile this yourself. New in v1.1: The ` character will toggle debug mode on and off. According to my specification ` should be a label, but my interpreter doesn't have to follow my specification does it?

Spiral 2

Coming some time next year will be JSpI-2 with my new Spiral 2 spec. It will not only do away with all the unnecessary fluff of Spiral, and be far easier to code in, but it will provide operations for self-modifying code, and code with multiple pointers (akin to multi-threading). Function calls and object code will be easier to create, and comments will be possible. Most importantly, a Spiral 2 library will be created that will simplify all the most basic of Spiral tasks, and since it will be written in Spiral 2 itself, it will remain true to the Esoteric Programming Dream. JSpI-2, when complete, will still be able to run original Spiral programs.

Contact

If you like to amaze me with your Spiral source code, or have any questions about the language, or this website, please send to Quintopia.

This site is a member of WebRing.
To browse visit Here.

Website designed and built by Quintopia in 2003.
Like it? Want your own site designed. David knows how.

Experience in PHP, MySQL, JavaScript, Java, and HTML.
Work done cheap! Email Quintopia.