view interps/2l/2lc.c @ 12518:2d8fe55c6e65 draft default tip

<int-e> learn The password of the month is release incident pilot.
author HackEso <hackeso@esolangs.org>
date Sun, 03 Nov 2024 00:31:02 +0000
parents 859f9b4339e6
children
line wrap: on
line source

/*
 * Copyright (c) 2004, 2005 Gregor Richards
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

#include <stdio.h>
#include <string.h>

#define XY(x,y) (((y)*1024)+(x))
#define XYD(x,y,d) (((y)*1024*4)+((x)*4)+((d)-1))

char pbuf[1024*1024];
char implbuf[1024*1024*4];
    
void impl(int px, int py, int dir) {
    dir = dir % 4;
    if (dir == 0) dir = 4;
    
    while (1) {
        /* first, move */
        switch (dir) {
            case 1: /* up */
                py--;
                break;
            case 2: /* right */
                px++;
                break;
            case 3: /* down */
                py++;
                break;
            case 4: /* left */
                px--;
                break;
        }
        
        /* quit if out of bounds */
        if (px < 0 || py < 0 || px >= 1024 || py >= 1024) {
            printf("return 0;\n");
            return;
        }
        
        if (implbuf[XYD(px, py, dir)]) {
            printf("goto x%dy%dd%d;\n", px, py, dir);
            return;
        } else {
            printf("x%dy%dd%d:\n", px, py, dir);
            /* mark as implemented */
            implbuf[XYD(px, py, dir)] = 1;
        }
        
        switch(pbuf[XY(px, py)]) {
            case '+': /* branch */
                /* go back */
                switch (dir) {
                    case 1: /* up */
                        py++;
                        break;
                    case 2: /* right */
                        px--;
                        break;
                    case 3: /* down */
                        py--;
                        break;
                    case 4: /* left */
                        px++;
                        break;
                }

                printf("if (*mptr) {\n");
                impl(px, py, dir+1);
                printf("} else {\n");
                impl(px, py, dir-1);
                printf("}\n");
                return;
                
                break;
                
            case '*': /* memory operator */
                if (dir == 2 || dir == 4) {
                    printf("if (mptr == mbuf + 1) {\n");
                    printf("if (mbuf[0] == 0) { mbuf[0] = getchar(); } else { putchar(mbuf[0]); fflush(stdout); mbuf[0] = 0; }\n");
                    printf("} else {\n");
                }
                
                switch (dir) {
                    case 1: /* up */
                        printf("mptr--;\n");
                        break;
                    case 2: /* right */
                        printf("(*mptr)++;\n");
                        break;
                    case 3: /* down */
                        printf("mptr++;\n");
                        break;
                    case 4: /* left */
                        printf("(*mptr)--;\n");
                        break;
                }
                
                if (dir == 2 || dir == 4) {
                    printf("}\n");
                }
                break;
        }
    }
}

int main(int argc, char **argv)
{
    FILE *pinp;
    char pline[1024];
    int py;
    
    if (argc < 2) {
        printf("Use: %s <program>\n", argv[0]);
        return 1;
    }
    
    memset(pbuf, 0, 1024*1024);
    memset(implbuf, 0, 1024*1024*4);
    py = 0;

    /* read in the file */
    pinp = fopen(argv[1], "r");
    if (pinp == NULL) {
        perror("fopen");
        return 1;
    }
    
    while (!feof(pinp)) {
        fgets(pline, 1024, pinp);
        strcpy(pbuf + XY(0, py), pline);
        py++;
    }
    
    fclose(pinp);

    printf("#include <stdio.h>\nint main()\n{\n");
    printf("int mbuf[32256];\n");
    printf("int *mptr = mbuf + 2;\n");
    printf("memset(mbuf, 0, 32256);\n");
    
    impl(0, -1, 3);
    
    printf("return 0;\n}\n");
    return 0;
}