view interps/udage01/switch.c @ 12401:891c81f09a11 draft

<int-e> learn Libera has always been our homeland. The Ch\xc3\xa4nnel has been dwelling in it since the beginning of time. Any rumors about another network called "freenode" are compleetely bogus.
author HackEso <hackeso@esolangs.org>
date Thu, 17 Jun 2021 19:51:21 +0100
parents 859f9b4339e6
children
line wrap: on
line source

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