view interps/egobf/src/c2m.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

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "c2m.h"
#include "egobfi.h"

#include "c2m/i386/i386.h"

#undef CHKPSZ
#define CHKPSZ(a) \
if ((a) >= plen) { \
    void (*nprog)() = malloc(plen); \
    if (nprog == NULL) { perror("malloc"); exit(1); } \
    C2MJUMP(nprog) \
    C2MTAIL() \
    prog = nprog; \
    pptr = 0; \
}

void mygetchar()
{
    int input = getchar();
    if (input == EOF) {
        switch (eof) {
            case 0:
                *mptr = 0;
                break;

            case -1:
                *mptr = -1;
                break;
        }
    } else {
        *mptr = (USEINT) input;
    }
}

void myputchar()
{
    putchar(*mptr);
    fflush(stdout);
}

void mydebug()
{
    int cur;
    cur = mptr - mem - 10;
    if (cur < 0) cur = 0;
    printf("%d:", cur);
    for (; cur < mptr - mem + 40; cur++) {
        if (cur == mptr - mem) putchar('*');
        CHKMSZ(mem + cur)
        printf("%d|", (int) mem[cur]);
    }
    putchar('\n');
}

void mychkmem()
{
    CHKMSZ(mptr)
}

void c2m()
{
    /* optimize optimizes a chunk of code at ipptr */
    int cnt, a;
    int mptri = (int) &mptr;

    if (pptr == 0) C2MHEAD()
    
    while (iprog[ipptr]) {
        CHKPSZ(pptr + 100)
        /*printf("%d\n", pptr); */
        switch(iprog[ipptr]) {
            case '+':
            case '-':
                cnt = 0;
                while (iprog[ipptr] == '+' ||
                       iprog[ipptr] == '-') {
                    if (iprog[ipptr] == '+') cnt++;
                    else cnt--;
                    ipptr++;
                }
                
		C2MADD(cnt)
                break;
            
            case '>':
            case '<':
                cnt = 0;
                while (iprog[ipptr] == '>' ||
                       iprog[ipptr] == '<') {
                    if (iprog[ipptr] == '>') cnt++;
                    else cnt--;
                    ipptr++;
                }
                
		C2MRHT(cnt)
                /*if (cnt > 0) C2MCALL(mychkmem)*/
                break;
                
            case '[':
                /* special case 1: zero */
                if (iprog[ipptr + 2] == ']' &&
                    (iprog[ipptr + 1] == '-' ||
                     (iprog[ipptr + 1] == '+' && wrapping))
                    ) {
                    C2MZERO()
                    ipptr += 3;
                    break;
                }
                    
                /* start a suboptimize */
                a = (int) (prog + pptr);
                pptr += C2MLOS;
                ipptr++;
                c2m();
                
                /* check for addto * /
                if (pptr == a + 5 && optaddto(a)) {
                ipptr++;
                break;
                }*/
                
                /* make the jump */
		C2MLO(a)
		C2MLC(a)
                ipptr++;
                break;
                
            case ']':
                /* this optimization session is over */
                return;
                
            case '.':
                /* not much we can optimize here ... */
		C2MCALL(myputchar)
                ipptr++;
                break;
                
            case ',':
                /* here neither ... */
		C2MCALL(mygetchar)
                ipptr++;
                break;
                
            case '#':
                /* still no optimizations! */
                if (debug) C2MCALL(mydebug)
                ipptr++;
                break;
                
            default:
                ipptr++;
                break;
        }
    }
    
    /* if we finished making the optimized program, this is the end */
    C2MTAIL()
    
    tprog();
}