Mercurial > repo
diff interps/2l/2lc.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/2l/2lc.c Sun Dec 09 19:30:08 2012 +0000 @@ -0,0 +1,164 @@ +/* + * 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; +}