Mercurial > repo
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"); +}