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