From Esolang
Jump to navigation Jump to search


SpinGate is a 1 bit computer with a corresponding single bit 1-instruction language intended to be implemented in hardware with the minimum number of logic gates. It has only a single 1-bit instruction - 0 or 1


Interactive Demo


SpinGate Machine and Instruction

A SpinGate machines consists of

  • data register (a shift register)
  • accumulator bit
  • phase bit (load, store)
  • NAND gate

The instruction is as follows

Instruction Description
0 rotate shift register
1 when load - accum <= bit0, phase <= store
when store - bit0 <= bit0 NAND accum, phase <= load


SpinGate does not support I/O, however, the begining of a program can be used to set the state of the data register, and the data register can be considered as output at the completion of a program

JavaScript Implementation

A SpinGate machine can be implemented in JavaScript as follows:

let cpuData = 0
let cpuBits = 4
let cpuIndex = 0
let cpuStore = false
let cpuAccum = 0

function spin() {
    cpuData = cpuData << 1 | (cpuData >> (cpuBits - 1))

function gate() {
    if (cpuStore) {
        cpuData = (cpuData & -2) | !(cpuAccum & (cpuData & 1))
    } else {
        cpuAccum = cpuData & 1
    cpuStore = !cpuStore

Assembly Language

libspingate is a JavaScript library for constructing SpinGate programs.


declare a SpinGate machine, and set its register size and inital state



register a SpinGate program

prog(name, code)

prog("spin", "0")
prog("gate", "1")
prog("spin back", "000")
prog("toggle", "11")
prog("nop", "1111")


define a bit position in the data register, with a label

bit(index, label)

logic0 = bit(0, "0")
regA = bit(1, "A")
regB = bit(2, "B")
out = bit(3, "R")


Perform a NAND operation on two bits:

nand(src, dst)

prog("Clear A", nand(logic0, regA))

Internally, nand() keeps track of the shift register position and uses the register size defined by init() to rotate bit indexes into place. It is therefore defined as a builtin function, to simplify maintaining programs if the register size is changed.

Composing Programs

Further operations can be composed by defining new functions using the nand() gate function as a building block

Bit Operations

toggle = (reg) => nand(reg, reg)
clear = (reg) => nand(logic0, reg)
set = (reg) => nand(logic0, reg) + toggle(reg)
copy = (src, dst) => nand(logic0, dst) + nand(src, dst)
swap = (src, dst) => copy(dst, tmp0) + copy(src, dst) + copy(tmp0, dst)

Logic Gates

and = (dst, src) => nand(dst, src) + toggle(dst)
or = (dst, src) => toggle(dst) + toggle(src) + nand(src, dst) + toggle(src)
nor = (dst, src) => or(dst, src) + toggle(dst)