Mercurial > repo
diff interps/udage01/switch.c @ 996:859f9b4339e6
<Gregor> tar xf egobot.tar.xz
author | HackBot |
---|---|
date | Sun, 09 Dec 2012 19:30:08 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/interps/udage01/switch.c Sun Dec 09 19:30:08 2012 +0000 @@ -0,0 +1,85 @@ +#include <stdio.h> +#include <stdlib.h> + +unsigned char prog[1048576]; +unsigned char swtch[256]; + +int main(int argc, char **argv) +{ + int pc = 0, max; + FILE *in; + if (argc<2) { + fprintf(stderr, "Usage: %s program\n", argv[0]); + exit(1); + } + in = fopen(argv[1], "r"); + if (!in) { + fprintf(stderr, "Could not open '%s'.", argv[1]); + exit(1); + } + max = fread(prog, 1, sizeof(prog), in); + fclose(in); + if (max == sizeof(prog)) { + fprintf(stderr, "Warning: only the first %d bytes of the program " + "were read.", sizeof(prog)); + } + while (pc<max) { + if (pc<max-1 && prog[pc] == prog[pc+1]) { + if (pc<max-3 && prog[pc] == prog[pc+2] && prog[pc] == prog[pc+3]) { + int i, v=0; + if (pc>max-20) { + fprintf(stderr, "incomplete instruction at end\n"); + exit(1); + } + for (i=0; i<16; i++) { + v <<= 1; + v += swtch[prog[pc+4+i]]; + } + if (v) { + /* output */ + putchar(v); + } else { + /* input */ + v = getchar(); + for (i=16; i--; ) { + swtch[prog[pc+4+i]] = v&1; + v >>= 1; + } + } + pc += 20; + } else { + /* NAND */ + if (pc>max-5) { + fprintf(stderr, "incomplete instruction at end\n"); + exit(1); + } + swtch[prog[pc]] = (swtch[prog[pc+2]] & swtch[prog[pc+3]])^1; + if (!swtch[prog[pc]]) { + /* JUMP */ + int nxt = pc+5; + int prv = pc-1; + for ( ; ; nxt++, prv--) { + if (nxt < max && prog[pc+4] == prog[nxt]) { + pc = nxt+1; + break; + } + if (prv >= 0 && prog[pc+4] == prog[prv]) { + pc = prv+1; + break; + } + if (nxt >= max && prv < 0) { + exit(0); + } + } + } else { + pc += 5; + } + } + } else { + /* SWITCH */ + swtch[prog[pc]] ^= 1; + pc++; + } + } + return 0; +}