www.pudn.com > interpreter.zip > interpreter.iprg.c


/*
#define TESTING
#define TEST7
*/
#include "./interpreter.h"
INSTR_PAIR iprg[IPRG_LEN];      /* 中間言語プログラムの格納場所 */
IPRG_STACK iprg_stack[IPRG_STACK_LEN];
                                /* 中間言語実行時のスタック */
int prg_ctr;                    /* 中間言語プログラムカウンタ */
int stack_ptr;                  /* 中間言語実行時スタックポインタ */
double x[VAR_LEN];


/*  中間言語のインタープレータ */
run_iprg(){
    int i;
    double value;

    iprg_init();                /* iprg[], iprg_stack[] およびそれらのポインタの
                                   initialization
                                 */
    
    for (;;){
        switch (iprg[prg_ctr].instr){
            case UNARY:
                if(stack_ptr < 0)
                    iprg_error("parameters for unary operation not on stack.");
                iprg_stack[stack_ptr].value
                    = (*iprg[prg_ctr].ptr.op)(iprg_stack[stack_ptr].value);
                break;
            case BINARY:
                if( stack_ptr < 1 )
                    iprg_error("parameters for binary operation not set on stack");
                stack_ptr--;
                iprg_stack[stack_ptr].value 
                    = (*iprg[prg_ctr].ptr.op)( iprg_stack[stack_ptr].value,
                                              iprg_stack[stack_ptr + 1].value);
                break;

            case PUTCONST:
                if (++stack_ptr >= IPRG_STACK_LEN)
                    iprg_error ("stack full");
                iprg_stack[stack_ptr].value = iprg[prg_ctr].ptr.value;
                break;
                
            case PUTADDR:
                if (++stack_ptr >= IPRG_STACK_LEN)
                    iprg_error ("stack full");
                iprg_stack[stack_ptr].addr = prg_ctr + 1;
                
                break;
                
            case SET:
                if (++stack_ptr >= IPRG_STACK_LEN)
                    iprg_error ("stack full");
                iprg_stack[stack_ptr].value = *iprg[prg_ctr].var;
                break;
            case LET:
                *iprg[prg_ctr].var = iprg_stack[stack_ptr--].value;
                if (stack_ptr < -1)
                    iprg_error ("stack pointer out of range");
                break;
            case GOTO:
                iprg_error ("GOTO not yet implemented");
            case XWHILE:
#ifdef BAKA
                if ( stack_ptr != 0) iprg_error ("something is wrong");
#endif
/* ループのネスティングを許している */
                if ( (iprg_stack[stack_ptr--].value) <= 0.0) {
                    stack_ptr--;
                    i = 0;				/* i: degree of nesting of XWHILE -- LABEL */
                    while ( i >= 0 ){
                        switch(iprg[++prg_ctr].instr){
                            case XWHILE:
                                i++; break;
                            case LABEL:
                                i--; break;
                            case CENTINEL:
                                iprg_error("XWHILE -- LABEL nesting not in order");
                        }
                    }
                }
                break;
            case LABEL:
                prg_ctr = iprg_stack[stack_ptr].addr - 1;
                break;
            case XPRINTSTR:
                printf(iprg[prg_ctr].ptr.str);
                break;
            case XPRINTVAR:
                printf ("%lf", *iprg[prg_ctr].var);
                break;
            case CENTINEL:
                iprg_error ("program counter over run");
            case ENDOFP:
#ifdef TESTING
                iprg_error ("program terminated with ENDOFP");
#else
                if ( stack_ptr >= 0)
                    iprg_error ("warning: something remained on stack");
                exit (0);
#endif
            default:
                iprg_error ("unknown instruction code");
                
        }
        ++prg_ctr;
    }
}

iprg_init ()
{
    int i;
    for ( i = 0; i < IPRG_STACK_LEN; i++){
        iprg_stack[ i ].addr = 8888;
        iprg_stack[ i ].value = 888.888888;
    }

    iprg[IPRG_LEN-1].instr = CENTINEL;
    prg_ctr = 0;
    stack_ptr = -1;
}

iprg_error ( char* message)
{
    printf ("iprg: %s\n", message);
    printf ("prg_ctr:  %d\n     looking at: %d\n", 
            prg_ctr, iprg[prg_ctr].instr);
    printf ("stack_ptr: %d\n    looking at:\n      value: %lf\n      addr:  %d\n", 
            stack_ptr, iprg_stack[stack_ptr].value, iprg_stack[stack_ptr].addr);
    printf ("first 4 pairs of values on stack:\n");
    printf ("iprg_stack[]%14d%14d%14d%14d\n", 0,1,2,3);
    printf ("---------------------------------------------------------------------\n");
    printf ("addr:       %14d%14d%14d%14d\n",
            iprg_stack[0].addr,
            iprg_stack[1].addr,
            iprg_stack[2].addr,
            iprg_stack[3].addr );
    printf ("value:      %14lf%14lf%14lf%14lf\n",
            iprg_stack[0].value,
            iprg_stack[1].value,
            iprg_stack[2].value,
            iprg_stack[3].value );
    printf ("---------------------------------------------------------------------\n");
    printf ("first 15 instructions:\n");
    printf ("%d %d %d %d %d ",
            iprg[0].instr,iprg[1].instr,iprg[2].instr,iprg[3].instr,iprg[4].instr);
    printf ("%d %d %d %d %d ",
            iprg[0].instr,iprg[1].instr,iprg[2].instr,iprg[3].instr,iprg[4].instr);
    printf ("%d %d %d %d %d\n",
            iprg[5].instr,iprg[6].instr,iprg[7].instr,iprg[8].instr,iprg[9].instr);
    
    exit(0);
}

ec_const (double value)
{
    iprg[prg_ctr].instr = PUTCONST;
    iprg[prg_ctr].ptr.value = value;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");
}

ec_asgn (double *var)
{
    iprg[prg_ctr].instr = LET;
    iprg[prg_ctr].var = var;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");
}

ec_set ( double *var)
{
    iprg[prg_ctr].instr = SET;
    iprg[prg_ctr].var = var;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");
}


ec_addr ()
{
    iprg[prg_ctr].instr = PUTADDR;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");

}

ec_label ()
{
    iprg[prg_ctr].instr = LABEL;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");
}

ec_while ()
{
    iprg[prg_ctr].instr = XWHILE;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");
}

ec_pvar (double *var)
{
    iprg[prg_ctr].instr = XPRINTVAR;
    iprg[prg_ctr].var = var;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");
}

ec_pstr (char *str)
{
    iprg[prg_ctr].instr = XPRINTSTR;
    iprg[prg_ctr].ptr.str = str;
    if ( ++prg_ctr >= IPRG_LEN ) iprg_error("input program too large");
}



#ifdef TEST
main (){
    iprg[0].instr = BINARY;
    run_iprg();
}
#endif
#ifdef TEST1
main ()
{
    iprg[0].instr = PUTCONST;
    iprg[0].ptr.value = 35.0;
    run_iprg();
}
#endif
#ifdef TEST2                    /* 無限ループ */
main()
{
    iprg[0].instr = PUTADDR;
    iprg[1].instr = PUTCONST;
    iprg[1].ptr.value = 35.0;
    iprg[2].instr = XWHILE;
    iprg[3].instr = PUTCONST;
    iprg[3].ptr.value = 35.0;
    iprg[4].instr = LABEL;
    
    run_iprg();
}
#endif
#ifdef TEST3                    /* 無限ループ 2*/
main()
{
    int i = 0;
    iprg[i].instr = PUTCONST;
    iprg[i].ptr.value = 22.0;
    iprg[++i].instr = PUTADDR;
    iprg[++i].instr = PUTCONST;
    iprg[i].ptr.value = 35.0;
    iprg[++i].instr = XWHILE;
    iprg[++i].instr = PUTCONST;
    iprg[i].ptr.value = 35.0;
    iprg[++i].instr = LABEL;
    
    run_iprg();
}
#endif
#ifdef TEST4                    /* XWHILE without LABEL*/
main()
{
    int i = 0;
    iprg[i].instr = PUTCONST;
    iprg[i].ptr.value = 22.0;
    iprg[++i].instr = PUTADDR;
    iprg[++i].instr = PUTCONST;
    iprg[i].ptr.value = 35.0;
    iprg[++i].instr = XWHILE;
    iprg[++i].instr = PUTCONST;
    iprg[i].ptr.value = 35.0;
    iprg[++i].instr = ENDOFP;
    
    run_iprg();
} 
#endif 
#ifdef TEST5
main()
{
    prg_ctr = 0;
    ec_const(22.0);
    ec_addr();
    ec_const(1.0);
    ec_while();
    ec_const(35.0);
    ec_label();
    
    run_iprg();
}
#endif
#ifdef TEST6
main()
{
    prg_ctr = 0;

    ec_const(10.0);
    ec_asgn (&x[0]);
    ec_addr();
    ec_set (&x[0]); 
    ec_while();

    ec_set (&x[0]);
    ec_const(1.0);
    iprg[prg_ctr].instr = BINARY;
    iprg[prg_ctr].ptr.op = subop;
    prg_ctr++;
    
    ec_asgn (&x[0]);
    ec_label();

    iprg[prg_ctr].instr = ENDOFP;
    
    run_iprg();
}
#endif
#ifdef TEST7
main()
{
    prg_ctr = 0;

    ec_const(10.0);
    ec_const(12);
    
    iprg[prg_ctr].instr = BINARY;
    iprg[prg_ctr].ptr.op = subop;

    run_iprg();

}
#endif