Skip to content

Instantly share code, notes, and snippets.

@skeeto

skeeto/synacorvm.c

Last active Nov 24, 2018
Embed
What would you like to do?
SynacorVM
#include <stdio.h>
#include <stdlib.h>
#define eval(v) (v < 32768u ? v : memory[v])
static int pc, sp;
static unsigned short stack[1024];
static unsigned short memory[(1ul << 15) + 8];
static int
step(void)
{
int in;
unsigned a, b, c, op = memory[pc++];
switch (op) {
case 0: return 0;
case 1: a = memory[pc++];
b = memory[pc++];
memory[a] = eval(b);
return 1;
case 2: a = memory[pc++];
stack[sp++] = eval(a);
return 1;
case 3: if (!sp) abort();
a = memory[pc++];
memory[a] = stack[--sp];
return 1;
case 4: a = memory[pc++];
b = memory[pc++];
c = memory[pc++];
memory[a] = eval(b) == eval(c);
return 1;
case 5: a = memory[pc++];
b = memory[pc++];
c = memory[pc++];
memory[a] = eval(b) > eval(c);
return 1;
case 6: a = memory[pc];
pc = eval(a);
return 1;
case 7: a = memory[pc++];
b = memory[pc++];
if (eval(a)) pc = eval(b);
return 1;
case 8: a = memory[pc++];
b = memory[pc++];
if (!eval(a)) pc = eval(b);
return 1;
case 9: a = memory[pc++];
b = memory[pc++];
c = memory[pc++];
memory[a] = (eval(b) + eval(c)) % 32768u;
return 1;
case 10: a = memory[pc++];
b = memory[pc++];
c = memory[pc++];
memory[a] = (eval(b) * eval(c)) % 32768u;
return 1;
case 11: a = memory[pc++];
b = memory[pc++];
c = memory[pc++];
memory[a] = eval(b) % eval(c);
return 1;
case 12: a = memory[pc++];
b = memory[pc++];
c = memory[pc++];
memory[a] = eval(b) & eval(c);
return 1;
case 13: a = memory[pc++];
b = memory[pc++];
c = memory[pc++];
memory[a] = eval(b) | eval(c);
return 1;
case 14: a = memory[pc++];
b = memory[pc++];
memory[a] = ~eval(b) & 0x7fff;
return 1;
case 15: a = memory[pc++];
b = memory[pc++];
memory[a] = memory[eval(b)];
return 1;
case 16: a = memory[pc++];
b = memory[pc++];
memory[eval(a)] = eval(b);
return 1;
case 17: a = memory[pc++];
stack[sp++] = pc;
pc = eval(a);
return 1;
case 18: if (!sp) return 0;
pc = stack[--sp];
return 1;
case 19: a = memory[pc++];
putchar(eval(a));
return 1;
case 20: in = getchar();
if (in == EOF) abort();
memory[memory[pc++]] = in;
return 1;
case 21: return 1;
}
abort();
}
int
main(int argc, char *argv[])
{
FILE *f = fopen(argv[argc - 1], "rb");
int i = 0;
for (;;) {
unsigned v;
int lo = fgetc(f);
int hi = fgetc(f);
if (lo == EOF) break;
if (hi == EOF) abort();
v = (unsigned)hi << 8 | lo;
if (v > 32775) abort();
memory[i++] = v;
}
fclose(f);
while (step())
;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment