996
|
1 #include <stdio.h>
|
|
2 #include <stdlib.h>
|
|
3
|
|
4 unsigned char prog[1048576];
|
|
5 unsigned char swtch[256];
|
|
6
|
|
7 int main(int argc, char **argv)
|
|
8 {
|
|
9 int pc = 0, max;
|
|
10 FILE *in;
|
|
11 if (argc<2) {
|
|
12 fprintf(stderr, "Usage: %s program\n", argv[0]);
|
|
13 exit(1);
|
|
14 }
|
|
15 in = fopen(argv[1], "r");
|
|
16 if (!in) {
|
|
17 fprintf(stderr, "Could not open '%s'.", argv[1]);
|
|
18 exit(1);
|
|
19 }
|
|
20 max = fread(prog, 1, sizeof(prog), in);
|
|
21 fclose(in);
|
|
22 if (max == sizeof(prog)) {
|
|
23 fprintf(stderr, "Warning: only the first %d bytes of the program "
|
|
24 "were read.", sizeof(prog));
|
|
25 }
|
|
26 while (pc<max) {
|
|
27 if (pc<max-1 && prog[pc] == prog[pc+1]) {
|
|
28 if (pc<max-3 && prog[pc] == prog[pc+2] && prog[pc] == prog[pc+3]) {
|
|
29 int i, v=0;
|
|
30 if (pc>max-20) {
|
|
31 fprintf(stderr, "incomplete instruction at end\n");
|
|
32 exit(1);
|
|
33 }
|
|
34 for (i=0; i<16; i++) {
|
|
35 v <<= 1;
|
|
36 v += swtch[prog[pc+4+i]];
|
|
37 }
|
|
38 if (v) {
|
|
39 /* output */
|
|
40 putchar(v);
|
|
41 } else {
|
|
42 /* input */
|
|
43 v = getchar();
|
|
44 for (i=16; i--; ) {
|
|
45 swtch[prog[pc+4+i]] = v&1;
|
|
46 v >>= 1;
|
|
47 }
|
|
48 }
|
|
49 pc += 20;
|
|
50 } else {
|
|
51 /* NAND */
|
|
52 if (pc>max-5) {
|
|
53 fprintf(stderr, "incomplete instruction at end\n");
|
|
54 exit(1);
|
|
55 }
|
|
56 swtch[prog[pc]] = (swtch[prog[pc+2]] & swtch[prog[pc+3]])^1;
|
|
57 if (!swtch[prog[pc]]) {
|
|
58 /* JUMP */
|
|
59 int nxt = pc+5;
|
|
60 int prv = pc-1;
|
|
61 for ( ; ; nxt++, prv--) {
|
|
62 if (nxt < max && prog[pc+4] == prog[nxt]) {
|
|
63 pc = nxt+1;
|
|
64 break;
|
|
65 }
|
|
66 if (prv >= 0 && prog[pc+4] == prog[prv]) {
|
|
67 pc = prv+1;
|
|
68 break;
|
|
69 }
|
|
70 if (nxt >= max && prv < 0) {
|
|
71 exit(0);
|
|
72 }
|
|
73 }
|
|
74 } else {
|
|
75 pc += 5;
|
|
76 }
|
|
77 }
|
|
78 } else {
|
|
79 /* SWITCH */
|
|
80 swtch[prog[pc]] ^= 1;
|
|
81 pc++;
|
|
82 }
|
|
83 }
|
|
84 return 0;
|
|
85 }
|