view interps/egobf/src/bfc.c @ 12256:821155c00e34 draft

<fizzie> ` sed -e \'s|wisdom|bin|\' < ../bin/culprits > ../bin/cblprits; chmod a+x ../bin/cblprits
author HackEso <hackeso@esolangs.org>
date Sat, 07 Dec 2019 23:36:22 +0000
parents 859f9b4339e6
children
line wrap: on
line source

/*
 * 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");
}