Public
Edited
Nov 23
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
memory
Insert cell
accumulator
Insert cell
Insert cell
function test() {
return run(
[0, 1],
["add", 1],
["storeAtPointer"],
["addFromPointer"],
["inc"],
["storeAtPointer"],
["addFromPointer"],
["inc"],
["storeAtPointer"],
["addFromPointer"],
["inc"],
["storeAtPointer"],
["addFromPointer"],
["inc"],
["storeAtPointer"],
["addFromPointer"],
["inc"],
["storeAtPointer"],
["addFromPointer"],
["inc"],
["storeAtPointer"],
["addFromPointer"],
["inc"],
["storeAtPointer"]
);
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
bits = 32
Insert cell
hz = 10 // cycles per second
Insert cell
maxCycles = 128
Insert cell
instructions = [
loadN,
loadFrom,
loadFromPointer,
storeAt,
storeAtPointer,

add,
addFrom,
addFromPointer,
sub,
subFrom,
subFromPointer,

inc,
dec,

jumpTo
]
Insert cell
Insert cell
Insert cell
mutable running = false
Insert cell
mutable cycle = 0
Insert cell
mutable currentInstructionIndex = 0
Insert cell
mutable currentInstructionSet = []
Insert cell
function loadInstructionSet (...args) {
mutable currentInstructionSet = normalizeInstructionSet(...args)
}
Insert cell
mutable log = []
Insert cell
function writeIntoLog (...args) {
mutable log = [args, ...mutable log]
}
Insert cell
Insert cell
function run(...args) {
// Conveniently load new instruction set
if (args.length) {
loadInstructionSet(...args);
}

reset();
mutable cycle = 0;

return play();
}
Insert cell
function play() {
mutable running = true;

// Execute instruction set
// NOTE: absolute failsafe of 100 k cycles
// Because no computer in the world would be able to run for so long without failing
let i = 0;
while (
mutable running &&
mutable cycle < maxCycles &&
mutable currentInstructionSet[mutable currentInstructionIndex] &&
i < (100 * 1000)
) {
// Execute individual instruction
runCycle();

mutable currentInstructionIndex = mutable currentInstructionIndex + 1;
mutable cycle = mutable cycle + 1;

i++;
}

mutable running = false;

return mutable accumulator;
}
Insert cell
function pause() {
mutable running = false;
}
Insert cell
function reset() {
mutable currentInstructionIndex = 0;
mutable accumulator = 0;
mutable pointer = 0;
mutable memory = Array(bits);
}
Insert cell
function runCycle() {
// Instruction can be string or number, and an optional argument
const instruction = mutable currentInstructionSet[
mutable currentInstructionIndex
];

// We get the actual instruction function here
const f = getInstruction(instruction[0]);

// Catch bad instruction sets
if (!f) {
throw new Error("Invalid instruction", instruction);
}

writeIntoLog(...instruction)

// Pass on one argument to instruction function
f(instruction[1]);
}
Insert cell
Insert cell
Insert cell
mutable accumulator = 0
Insert cell
mutable pointer = 0
Insert cell
mutable memory = Array(bits)
Insert cell
Insert cell
function inc () {
mutable pointer = pos(mutable pointer + 1)
}
Insert cell
function dec () {
mutable pointer = pos(mutable pointer - 1)
}
Insert cell
// Jump to position in instruction set
// FIXME: How to use jump without causing infinite loops?
function jumpTo(i) {
mutable currentInstructionIndex = i % mutable currentInstructionSet.length;
}
Insert cell
Insert cell
function add (n) {
mutable accumulator += n
}
Insert cell
function addFrom (i) {
return add(mutable memory[pos(i)])
}
Insert cell
function addFromPointer () {
return add(mutable memory[mutable pointer])
}
Insert cell
Insert cell
function sub (n) {
mutable accumulator -= n
}
Insert cell
function subFrom (i) {
return sub(mutable memory[pos(i)])
}
Insert cell
function subFromPointer () {
return sub(mutable memory[mutable pointer])
}
Insert cell
Insert cell
function loadN (n) {
mutable accumulator = n
}
Insert cell
function loadFrom (i) {
return loadN(mutable memory[pos(i)])
}
Insert cell
function loadFromPointer () {
return loadFrom(mutable pointer)
}
Insert cell
Insert cell
function storeAt (i) {
mutable memory[i] = mutable accumulator

// https://talk.observablehq.com/t/mutable-push-to-array/4234
mutable memory = mutable memory
}
Insert cell
function storeAtPointer () {
return storeAt(mutable pointer)
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
[0, 1, 127, 128, 129, 513].map(pos)
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more