/* dontmove: a MOV machine for archival. * * First version of this C was written from 00:00 to 00:33, * at which point I was able to write and run a couple of "hello world"s. * This is slightly longer than the 22 minutes it took me to write a Brainfuck * interpreter. The code is almost exactly the same size, except that this * one uses stdio and has some minimal file error handling. * It took me another 20 minutes to get an incrementing loop written and * debugged. I still haven't tested procedure calls, conditionals, * and comparisons, but I'm pretty sure they'll work. */ #include #include typedef uint32_t cell; enum { PROGSIZE = 65536, MEMSIZE = 1048576 }; char program[PROGSIZE]; size_t proglen; cell accumulator, subtractor, memory[MEMSIZE], pc; typedef int bool; bool read_program(char *filename) { FILE *in = fopen(filename, "r"); if (!in) { perror(filename); return 0; } proglen = fread(program, 1, PROGSIZE, in); fclose(in); if (!proglen) { perror(filename); return 0; } return 1; } #define IF break; case #define ELSE break; default void read_memory(cell address) { switch(address) { IF 0: accumulator = getchar(); /* A */ IF 1: accumulator = subtractor; /* B */ /* XXX bounds check? */ IF 2: read_memory(memory[3]); /* C */ IF 4: accumulator = pc; /* E */ ELSE: accumulator = memory[address]; } } void write_memory(cell address) { cell tmp; switch(address) { IF 0: putchar(accumulator); /* a */ IF 1: subtractor -= accumulator; /* b */ /* XXX bounds check? */ IF 2: write_memory(memory[3]); /* c */ IF 4: /* e */ tmp = accumulator; accumulator = pc; pc = tmp; ELSE: memory[address] = accumulator; } } int main(int argc, char **argv) { if (!read_program(argv[1])) return 1; while (pc < proglen) { /* printf("[%d]", pc); fflush(stdout); */ char insn = program[pc++]; if ('A' <= insn && insn <= 'Z') { read_memory(insn - 'A'); } else if ('a' <= insn && insn <= 'z') { write_memory(insn - 'a'); } else if ('0' <= insn && insn <= '9') { accumulator = accumulator * 10 + insn - '0'; } else if ('<' == insn) { accumulator = (accumulator & 0x80000000 ? 0xFfffFfff : 0); } /* else, no op. */ } return 0; }