Welcome to the Ballisti-K Programming Language.
The Ballisti-K Programming Language
specifiction [sic] version 0.51w
Russell Bornschlegel, 4/9/2001
Ballisti-K (pronounced "Ballistic") is an assembly-ish imperative language; the instruction set is rather uninteresting in itself, but its data addressing system is unique.
Data is stored in the "accumulator", which holds a SIRS (signed integer of reasonable size (32 bits in the reference implementation)), in the "chamber", which also holds a SIRS, or in the "air", which can hold an implementation-limited number of SIRS.
In general, instructions are executed sequentially, one instruction per "tick"; there are conditional and unconditional jumps which can move the instruction pointer forward or backward.
Data can be loaded into the chamber. Data can be output from the accumulator. The value in the accumulator can be added to or subtracted from the value in the chamber.
Data in the chamber can only get to the accumulator by going through the air. The THROW instructions, in general, put data into the air from the chamber. After a specified number of ticks, the data "lands" in the accumulator.
If more than one datum is scheduled to land in the accumulator on a given tick, all such data are XOR'd together and that result is placed in the accumulator.
Thus, to swap two values:
# swap two numbers load 5 # chamber holds 5 throw 5 # 5 thrown, lands in 5 ticks load 10 # chamber holds 10 throw 1 # 10 thrown, lands in 1 tick printn # 10 lands, print number printl # print newline printn # 5 lands, print number printl # print newline
Obviously, the sequence:
load N throw 1
Loads N into the accumulator fairly directly, but this lacks style; Busker mode (see below) discourages this sort of thing, while Kallisti-B mode discourages other things altogether.
The reference interpreter accepts '#', '*', '//', ';' and possibly some other gibberish as introducing a comment to the end of the line. It makes a not-very-enthusiastic effort to parse anything else on a line as a valid instruction.
The following instructions are recognized:
| Opcode | Operand | Description |
| NOP | - | Do nothing |
| LOAD | value | Load value as an integer into chamber |
| LOADN | - | Read a number from stdin to chamber |
| LOADC | - | Read a character from stdin to chamber |
| text | Print remainder of line, including comments, to stdout | |
| PRINTN | - | Print accumulator as a decimal number to stdout |
| PRINTC | - | Print accumulator as an ASCII character to stdout |
| PRINTL | - | Print a newline character to stdout |
| THROW | value | Throw contents of chamber, to land in value ticks |
| THROWA | - | Throw contents of chamber, to land in accumulator ticks |
| PASS | - | chamber = accumulator |
| ADD | - | chamber = chamber + accumulator |
| SUB | - | chamber = chamber - accumulator |
| JUMP | value | Move instruction pointer value instructions |
| JZ | value | Move i.p. value instructions if accumulator = 0 |
| END | - | End the current program |
Note that the operand to THROW is a count of executed instructions (ticks), and should always be positive, while the operand to JUMP or JZ is a count of valid instruction lines, and may be negative.
The behavior of throw instructions with negative tick-counts is unspecified. The reference implementation will probably act as if the unsigned equivalent value was specified, meaning that the throw will take a long time to land.
The jump instructions, as in most assembly languages, take an offset relative to the _following_ instruction (thus JUMP 0 = no jump; JUMP -1 = endless loop). Jumping backward past the beginning of the program is considered an error, while jumping forward past the end of the program is an acceptable way to stop execution of the program.
Not all instructions have been tested in the reference implementation, but the following program works:
# some fibonaccis # cheat the first one print First 12 fibonaccis: printl print 1 printl load 10 # count of fibs to print throw 11 # throw to jz instruction load 1 # decrementor as well as fib[0] and fib[1] throw 11 # throw to sub instruction throw 1 # throw to accumulator throw 5 # throw to add instruction # fib loop printn # print fib[N] printl # one fib to a line pass # chamber = fib[N] throw 14 # throw fib[N] to add instruction _on next loop_ add # fib[N-1] lands; chamber holds fib[N+1] throw 8 # throw fib[N+1] to print instruction on next loop jz 7 # count lands, jump to end instruction pass # chamber holds count sub # 1 lands, chamber holds count-1 throw 10 # throw count to the jz instruction on the next loop pass # chamber holds 1 throw 10 # throw 1 to sub instruction on the next loop jump -13 # jump to print instruction end
The reference implementation takes input file names on the command line, as well as the following options:
- Take input source from stdin
-k Execute in Kallisti-B mode
-b Execute in Busker mode
-d Execute in debug mode
In Kallisti-B mode, whenever a throw is made, there is an N% chance that the throw will never land, where N is the throw tick delay. In Kallisti-B mode, the fibonacci program above might print out:
first 12 fibonaccis: 1 1 2 4 6 10
And that's okay.
In Busker mode, some form of reward is made based on the average throw delay. Ideally, the machine executing the program would dispense (sum of throw tick delays)/(total instructions executed) US dollars at the conclusion of any program. Most implementations are expected to be cheap bastards which merely print out the value that would be paid out by a more generous implementation. The fibonacci program shown above is worth about $3.18.
The Ballisti-K specifiction, sample programs, reference implementation source, and reference implementation executable all belong to Russell Bornschlegel. You may do anything with them except represent them as your own. You may derive any works from them but you may not represent derivative works as wholly your own.
The Ballisti-K reference implementation interpreter source code is available; this is written in a fair approximation to ANSI C but has only been tested as a Win32 console application. It seems to work okay, but not everything has been tested; in particular, I have little confidence in the interpreter's use of stdin.
The Ballisti-K reference implementation interpreter binary is also available. It should run on Windows 9x, ME, NT, and 2000, though only NT 4 has been tested.
A sample program which includes the fibonacci program described above, is available.
Author: Russell Bornschlegel, kaleja@estarcion.com. Last revision: 2001/4/10.