Hack-A-Day is a project I'm doing in November, where I try to make 30 new projects, in 30 days.
This is a whimsical virtual machine. Edit and run programs to do what you like. Share programs with friends.
Demo available at here.
Source available on github.
Note! There is a bug where you need to save before running a program.
Good luck! I don't accept bug reports, but I do accept pull requests.
The machine operates in "signed trinary". A WORD is made up of six trits, or signed trinary bits. A trit can be +1, 0, or -1. WORDs can range from -364 to +364.
For example:
- 0 is written as 0, 0. (0 + 0 = 0)
- 1 is written as 0, 1. (0 + 1 = 1)
- 2 is written as 1, -1. (3 + -1 = 1)
- 3 is written as 1, 0. (3 + 0 = 3)
- 4 is written as 1, 1. (3 + 1 = 4)
- 5 is written as 1, -1, -1 (9 + -3 + -1 = 5)
- -5 is written as -1, 1, 1 (-9 + 3 + 1 = -5)
Addition, subtraction, multiplication, comparison, and trit-shifting are easy in this representation. It has many advantages over binary, in fact.
The machine has six registers. Registers are case-sensitive.
- A, B, and C are WORD-sized registers
- d, e, and f are trit-sized registers
- I is the instruction pointer, which can hold any size up to the size of the program. The instruction pointer is automatically incremented. The program halts if it auto-increments past the end.
The machine has 729 trits of memory, addressed from -364 to +364.
On the right, there is a text box to edit your program. On the left, memory is displayed as a square grid. Under the memory is shown the values of the six registers, the current instruction being executed, and the state of the machine (reset, running, paused, or stopped).
Finally, there is a box for input and output. Input can only be read once, and output is only written once.
In addition, memory can be used as a screen. Write appropriate values to it to display pictures. Memory also acts as a "touchscreen" input device. Click any cell to zero it.
The following program
start: d = load B
f d = add d 1
store d B
f B = ADD B 1
I = jump start
In the instruction
``start: d = load B```
start: indicates the line has a label called start.
Later, you can jump to labeled lines, as with
I = jump start
The machine has 21 operators (plus 3 aliases). Each operator takes the following form:
f B = ADD B 1
This instruction ADDs together the contents of WORD-register B and the constant value 1. It puts the main result in WORD-register B*, and sets trit-register f to hold any overflow. All operators have a fixed number of inputs and outputs, of fixed size.
Below they are shown as
- W (for WORD-size)
- t (for trit-size)
- L (for a hardcoded label)
- I (for jumps, which always place their result in the instruction pointer)
It is always okay to put in a trit in something expecting a WORD. It's never okay to put a WORD in something expecting a trit--a compile-time error will result.
Here is a complete list of operators (not all tested yet!)
t = RIGHT W: Copies the rightmost (least significant) trit of the WORDW = RSHIFT W: Shift the entire WORD one trit right, placing 0 on the left side.W = LSHIFT W: Shifts the entire WORD one trit left, placing 0 on the right side.t = CMP W W: Compares two words. Outputs -1 if the one on left is lesser, 0 if they are equal, or 1 if the one on the left is greater.t t = add t t: Adds two trits, with overflow.t W = ADD t W: Adds two WORDs, with overflow.W = MUL W t: Multiplies a WORD by a trit.t = mul t t: Multiplies two trits.W = MOV W: Copies a WORD.t = mov t: Copies a trit.store t W: Store the trit at the given addresst = load W: Loads the trit from the given addressI = jump L: Unconditional jumpI = jz t L: Jump if zero.I = jp t L: Jump if positive.I = jn t L: Jump if negative.I = je t L: Jump if equal (use after CMP).I = jg t L: Jump if greater than (use after CMP).I = jl t L: Jump if less than (use after CMP).t = random: Generate a random trithalt: Stop the machineflush: (not implemented) in fast mode, do a visual screen updateW t = IN: Read one byte of input as an ascii character code. Also returns a trit indicated end-of-input (1 if yes, 0 if no).OUT W: Write one byte of input (an ascii character code). To terminate output, callhalt.
