1 unstable release

0.1.0 May 30, 2022

#3 in #nucleus

GPL-2.0-or-later

34KB
597 lines

This is an intro to the Nucleus game and the kaon language. The goal is to write a program (quark) that will outlive every other program, in a shared memory core.

Installation instructions

You can install lepton (the implimentation of nucleus) using flakes or cargo (TODO!). Using nix flakes: nix run git+https://time.ta.rdis.dev/el/lepton Using cargo: cargo install leptonvm(!) (TODO!)

Tutorial

The "core" is a linear sequence of random-access memory, 4096 instructions wide. Access are 0-indexed and wrap around (Address 4096 is the same as address 0)

Example core (4 instructions wide)

Index Instruction

0

JUMP

1

ADD

2

JUMP

3

DIE

Quarks are written in a language called kaon. Every quark must start with an author + title line. The format for a so-called "title line" is @ Author name : Program Name, such as @ John Doe : Brutus. Quarks are encouraged to have unique program names to reduce confusion about winners

After the title line, one or more instructions follow. Each instruction takes the form of keyword, followed by one or more arguments. Arguments are comma-separated, with one or more spaces between the arguments and keyword.

All arguments are also addresses. There are four kinds of addresses: literal, absolute, relative, and relative-offset. Literal addresses are a number, used as a value in a computation. They are stored in the core as a DIE instruction. Absolute addresses are prefixed with a #, such as #3. They reference addresses from the start of the core. A relative address is a number of instructions ahead or behind the current instruction, like .1 (the next instruction). Each relative instruction is prefixed with a .. The last type of address, a relative-offset address takes the form of .x#y. This behaves like a relative address except that the value of address y is added to the computed relative address. This could be written as "The address x units from where I am plus the value of address y".

Jumps six instructions ahead

die 5
jump .1#-1

If the instruction at y is not a DIE, the quark will stop execution. For example, .1#-1 will move the value of .-1 spaces past the next instruction (.1).

Each quark has its own thread. Each cycle, the computer switches between threads. For two threads, A & B, this looks like: ABABABABABABAB; for three: ABCABCABCABCABC. When a program dies, it is no longer executed. If program C dies: ABC ABC AB AB AB. Dead quarks do not have their memory zeroed or otherwise removed. This means you could jump into a dead thread and revive it (though unlikely). A winner is declared when there is only one thread left.

Usage of lepton

Lepton is the reference implementation of nucleus. It is available at https://time.ta.rdis.dev/el/lepton. Pass each program as an argument to the command line. Use RUST_LOG to enable logging. debug will list the loading and unloading of quarks. trace will print each instruction being executed. Passing -p / --playback will produce a dump of the core at each cycle for debugging / inspection. Each line contains the state from the current cycle (first line is before execution, second line is after cycle 1). To set the number of iterations, use -i / --iterations (The default is 4096*8)

Example quarks

A simple loop

@ Ellie : Loop
jump .0

Jumps to the current address

A quark that moves forward

@ Ellie : Jogger
mov .0 .1

Copy the current instruction to the next instruction (which is then executed)

A quark that bombs the core with DIE

@ Ellie : Bomber
jump .2
die 0
mov .-1 .3#-1
add 1, .-2
jump .-2

This uses relative-offset addresses to make the target of the bomb move forward (ADD).

Instruction reference

Instruction syntax

Arguments

Results

Notes

move x, y

x: The source address; y: the destination address

Copies value x to y

y should not be constant.

cmp x, y

x: any value; y: any value

Compares x to y and sets the equality flag if they are

Only compares equality

ptlcmp x, y

x: any value; y: any value

Compares the instruction type of a to b. Sets the flag if they are

jump 0 == jump 1

if a

a: any address

Jumps to a if the equality flag is set (i.e. the last cmp was true)

A constant is treated as an absolute address.

jump a

a: any address

Moves execution of the current thread to address a.

A constant is treated as an absolute address.

add a, b

a: any value; b: any address

Adds a to b and stores the result in b

b should not be constant. If b is constant, the program dies.

sub a, b

a: any value; b: any address

Subtracts a from b and stores the result in b

b should not be constant. If b is constant, the programs dies.

mul a, b

a: any value; b: any address

Multiplies a and b and stores the result in b

b should not be constant. If b is constant, the programs dies.

div a, b

a: any value; b: any address

divides a by b and stores the value in b

b should not be constant. The value of b should not b 0. If either of these is true, the program dies.

die x

x: any literal

If this instruction is executed, the program stops. However, it stores data for use by other instructions.

Magic death trap

Dependencies

~5–16MB
~178K SLoC