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