/* #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