diff interps/egobf/src/bfc.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/egobf/src/bfc.c	Sun Dec 09 19:30:08 2012 +0000
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 2005  Gregor Richards
+ *
+ * This file is part of egobfi.
+ * 
+ * egobfi is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ * 
+ * egobfi is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with egobfi; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdio.h>
+
+#include "bfc.h"
+#include "egobfi.h"
+
+void bf_compile()
+{
+    char *memtype;
+    struct bfi *bfic;
+
+    switch (bytewidth) {
+        case 1:
+            memtype = "uint8_t";
+            break;
+            
+        case 2:
+            memtype = "uint16_t";
+            break;
+            
+        case 4:
+            memtype = "uint32_t";
+            break;
+            
+        default:
+            memtype = "uint8_t";
+            break;
+    }
+
+    /* header */
+    
+    printf("#include <stdio.h>\n#include <stdint.h>\n");
+#ifdef HAVE_WCHAR_H
+    printf("#include <wchar.h>\n");
+#endif
+    printf("%s *mem;\n", memtype);
+    printf("int mptr;\n"
+           "int mlen;\n"
+           "int main() {\n"
+           "int input;\n"
+           "int iseof;\n"
+           "mem = (%s *) malloc(30000 * sizeof(%s));\n"
+           "mlen = 30000;\n"
+           "mptr = 0;\n",
+           memtype, memtype);
+    
+    printf("#define CHKMSZ(a) \\\n"
+           "if ((a) >= mlen) { \\\n"
+           "mlen += 3000; \\\n"
+           "mem = (%s *) realloc(mem, mlen * sizeof(%s)); \\\n"
+           "if (mem == NULL) { perror(\"realloc\"); exit(1); } \\\n"
+           "memset(mem + mlen - 3000, 0, 3000 * sizeof(%s)); \\\n"
+           "}\n", memtype, memtype, memtype);
+    
+    while (prog[pptr].cmd != FIN) {
+        /*printf("%d\n", pptr);*/
+        bfic = prog + pptr;
+        switch (bfic->cmd) {
+            case ADD:
+                printf("mem[mptr] += %d;\n", bfic->arg1);
+                pptr++;
+                break;
+                
+            case RHT:
+                printf("mptr += %d; CHKMSZ(mptr)\n", bfic->arg1);
+                pptr++;
+                break;
+                
+            case LPO:
+                printf("while (mem[mptr]) {\n");
+                pptr++;
+                break;
+                
+            case LPC:
+                printf("}\n");
+                pptr++;
+                break;
+                
+            case OUT:
+                /* output a character */
+#ifdef HAVE_WCHAR_H
+                if (unicode) {
+                    printf("putwchar(mem[mptr]);\n");
+                } else {
+                    printf("putchar(mem[mptr]);\n");
+                }
+#else
+                printf("putchar(mem[mptr]);\n");
+#endif
+                
+                printf("fflush(stdout);\n");
+                pptr++;
+                break;
+                
+            case INP:
+                /* input a character */
+                printf("iseof = 0;\n");
+#ifdef HAVE_WCHAR_H
+                if (unicode) {
+                    printf("input = (int) getwchar();\n"
+                           "iseof = (input == (int) WEOF);\n");
+                } else {
+                    printf("input = getchar();\n"
+                           "iseof = (input == EOF);");
+                }
+#else
+                printf("input = getchar();\n"
+                       "iseof = (input == EOF);\n");
+#endif
+                
+                printf("if (iseof) {\n");
+                switch (eof) {
+                    case 0:
+                        printf("mem[mptr] = 0; }\n");
+                        break;
+                        
+                    case -1:
+                        printf("mem[mptr] = -1; }\n");
+                        break;
+                }
+                printf("} else {\n");
+                printf("mem[mptr] = input; }\n");
+                pptr++;
+                break;                
+            
+            /*case DBG:
+                pptr++;
+                if (debug) {
+                    cur = mptr - 10;
+                    if (cur < 0) cur = 0;
+                    printf("%d:", cur);
+                    for (; cur < mptr + 40; cur++) {
+                        if (cur == mptr) putchar('*');
+                        CHKMSZ(cur)
+                        printf("%d|", mem[cur]);
+                    }
+                    putchar('\n');
+                }
+                break;*/
+                
+                /* INTERNAL COMMANDS */
+            case ZRO:
+                printf("mem[mptr] = 0;\n");
+                pptr++;
+                break;
+                
+            case ADDTO:
+                printf("CHKMSZ(mptr + %d) ", bfic->arg1);
+                printf("mem[mptr + %d] += %d * mem[mptr]; ", bfic->arg1, bfic->arg2);
+                printf("mem[mptr] = 0;\n");
+                pptr++;
+                break;
+                
+            default:
+                pptr++;
+        }
+    }
+    
+    printf("return 0;\n}\n");
+}