view interps/udage01/switch.c @ 12500:e48c08805365 draft default tip

<b_jonas> ` learn \'The password of the month is Cthulhuquagdonic Mothraquagdonic Narwhalicorn.\' # https://logs.esolangs.org/libera-esolangs/2024-04.html#lKE Infinite craft
author HackEso <hackeso@esolangs.org>
date Wed, 01 May 2024 06:39:10 +0000
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;
}