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;
+}