int testtyp(typset, int); void interpret(){ order ir; int pc; int ps; int run = 1, fin = 2, caschk = 3, divchk = 4, inxchk = 5, stkchk = 6, linchk = 7, lngchk = 8, redchk = 9; int t; // top of stack index int b; // base index int lncnt, ocnt, blkcnt, chrcnt; // counters int h1, h2, h3, h4; int fld[5]; // field width int display[101]; // lmax +1 types s[100001];// stacksize +1 int it =0; long fpos; char newch; /* blockmarks: s[b+0] = fct result s[b+1] = return adr s[b+2] = static link s[b+3] = dynamic link s[b+4] = table index */ s[1].i = 0; s[2].i = 0; s[3].i = -1; s[4].i = btab[1].last; b = 0; display[1] = 0; t = btab[2].vsize - 1; pc = tab[s[4].i].adr; ps = run; lncnt = 0; ocnt = 0; chrcnt = 0; fld[1] = intfld; fld[2] = relfld; fld[3] = bolfld; fld[4] = chrfld; do{ ir = code[pc]; //printf(" pc = %d ir.f = %d ir.y = %d ir.x = %d instrution name = %s\n",pc, ir.f, ir.y, ir.x, mnemonics[ir.f]); pc = pc + 1; ocnt = ocnt + 1; switch(ir.f){ case 0:// load address t = t+1; if(t > stacksize) ps = stkchk; else s[t].i = display[ir.x] + ir.y; break; case 1:// load value t = t+1; if (t > stacksize) ps = stkchk; else s[t] = s[display[ir.x]+ir.y]; break; case 2:// load indirect t = t+1; if (t > stacksize) ps = stkchk; else s[t] = s[s[display[ir.x]+ir.y].i]; break; case 3:// update display h1 = ir.y; h2 = ir.x; h3 = b; do{ display[h1] = h3; h1 = h1 - 1; h3 = s[h3+2].i; }while(h1 != h2); break; case 8: switch(ir.y){ case 0: s[t].i = abs(s[t].i); break; case 1: s[t].r = abs(s[t].r); break; case 2: s[t].i = s[t].i * s[t].i; break; case 3: s[t].r = s[t].r * s[t].r; break; case 4: s[t].b = s[t].i%2; break; case 5: s[t].c = s[t].i; if(s[t].i < 0 || s[t].i > inxmax) ps = inxchk; break; case 6: s[t].i = s[t].c; break; case 7: s[t].c = s[t].c + 1; break; case 8: s[t].c = s[t].c - 1; break; case 9: s[t].i = round(s[t].r); break; case 10: s[t].i = trunc(s[t].r); break; case 11: s[t].r = sin(s[t].r); break; case 12: s[t].r = cos(s[t].r); break; case 13: s[t].r = exp(s[t].r); break; case 14: s[t].r = log(s[t].r); break; case 15: s[t].r = sqrt(s[t].r); break; case 16: s[t].r = atan(s[t].r); break; case 17: t = t+1; if(t > stacksize) ps = stkchk; else{ if(line[cc+1] == EOF)s[t].b = 1; else s[t].b = 0; } break; case 18: t = t + 1; if(t > stacksize) ps = stkchk; else{ if(cc==ll-1)s[t].b = 1; else s[t].b = 0; } break; } break; case 9: s[t].i = s[t].i + ir.y; break; // offset case 10: pc = ir.y; break; // jump case 11: //conditional jump if(!s[t].b) pc = ir.y; t = t-1; break; case 12: //switch h1 = s[t].i; t = t - 1; h2 = ir.y; h3 = 0; do{ if(code[h2].f != 13){ h3 = 1; ps = caschk; } else if(code[h2].y == h1) { h3 = 1; pc = code[h2+1].y; } else h2 = h2 + 2; }while(h3 == 0); break; case 14: //for1up h1 = s[t-1].i; if (h1 <= s[t].i) s[s[t-2].i].i = h1; else { t = t-3; pc = ir.y; } break; case 15: //for2up h2 = s[t-2].i; h1 = s[h2].i +1; if(h1 <= s[t].i) { s[h2].i = h1; pc = ir.y; } else t = t -3; break; case 16: // for1down h1 = s[t-1].i; if (h1 >= s[t].i) s[s[t-2].i].i = h1; else { pc = ir.y; t = t-1; } break; case 17: // for2down h2 = s[t-2].i; h1 = s[h2].i -1; if(h1 >= s[t].i){ s[h2].i = h1; pc = ir.y; } else t = t-3; break; case 18: // mark stack h1 = btab[tab[ir.y].ref].vsize; if(t+h1 > stacksize) ps = stkchk; else { t = t+5; s[t-1].i = h1-1; s[t].i = ir.y; } break; case 19: //call h1 = t - ir.y;// h1 points to the top base h2 = s[h1+4].i; h3 = tab[h2].lev; display[h3+1] = h1; h4 = s[h1+3].i + h1; s[h1+1].i = pc; s[h1+2].i = display[h3]; s[h1+3].i = b; for (h3 = t+1; h3 <= h4; h3++) s[h3].i = 0; b = h1; t = h4; pc = tab[h2].adr; break; case 20: //index h1 = ir.y; // h1 points to atab h2 = atab[h1].low; h3 = s[t].i; if (h3 < h2) ps = inxchk; else if(h3 > atab[h1].high) ps = inxchk; else { t = t -1; s[t].i = s[t].i + (h3-h2); } break; case 21: //index h1 = ir.y; h2 = atab[h1].low; h3 = s[t].i; if(h3 < h2) ps = inxchk; else { t = t-1; s[t].i = s[t].i + (h3-h2)*atab[h1].elsize; } break; case 22: // load block h1 = s[t].i; t = t-1; h2 = ir.y + t; if(h2 > stacksize) ps = stkchk; else while(t < h2){ t = t+1; s[t] = s[h1]; h1 = h1+1; } break; case 23: h1 = s[t-1].i; h2 = s[t].i; h3 = h1 + ir.y; while ( h1 < h3 ){ s[h1] = s[h2]; h1 = h1+1; h2 = h2+1; }//end while t = t-2; break; case 24: t = t+1; if ( t > stacksize ) ps = stkchk; else s[t].i = ir.y; break; case 25: t = t+1; if ( t > stacksize ) ps = stkchk; else s[t].r = rconst[ir.y]; break; case 26: h1 = t - ir.y; s[h1].r = s[h1].i; break; case 27: //read if(ch == EOF) ps = redchk; else { switch (ir.y){ case 1: // ints insymbol(); if(sy != intcon){ printf("Input error integer expected %s recieved\n", symbolname[sy]); exit(1); } s[s[t].i].i = inum; break; case 2: // reals insymbol(); if(sy != realcon){ printf("Input error real expected %s recieved\n", symbolname[sy]); exit(1); } s[s[t].i].r = rnum; break; case 4: // chars nextch(); s[s[t].i].c = ch; break; } } t = t-1; break; case 28: h1 = s[t].i; h2 = ir.y; t = t-1; chrcnt = chrcnt + h1; if ( chrcnt > lineleng ) ps = lngchk; do{ printf("%c", stab[h2]); h1 = h1 - 1; h2 = h2 + 1; }while(h1 > 0); break; case 29: chrcnt = chrcnt + fld[ir.y]; if ( chrcnt > lineleng ) ps = lngchk; else{ switch (ir.y){ case 1: printf("%*d", fld[1], s[t].i); break; case 2: printf("%*f", fld[2], s[t].r); break; case 3: printf("%*d", fld[3], s[t].b); break; case 4: printf("%c", s[t].c); break; }//end switch }//end else t = t-1; break; case 30: chrcnt = chrcnt + s[t].i; if ( chrcnt > lineleng ) ps = lngchk; else{ switch (ir.y){ case 1: printf("%*d", s[t].i, s[t-1].i); break; case 2: printf("%*f", s[t].i, s[t-1].r); break; case 3: printf("%*d", s[t].i, s[t-1].b); break; case 4: printf("%*c", s[t].i, s[t-1].c); break; }//end switch }//end else t = t-2; break; case 31: ps = fin; break; case 32: t = b-1; pc = s[b+1].i; b = s[b+3].i; break; case 33: t = b; pc = s[b+1].i; b = s[b+3].i; break; case 34: s[t] = s[s[t].i]; break; case 35: s[t].b = !s[t].b; break; case 36: switch (ir.y){ case 1: s[t].i = -s[t].i; break; case 2: s[t].r = -s[t].r; break; } break; case 37: chrcnt = chrcnt + s[t-1].i; if ( chrcnt > lineleng ) ps = lngchk; else printf("%*.*f", s[t-1].i, s[t].i, s[t-2].r); t = t-3; break; case 38: s[s[t-1].i] = s[t]; t = t-2; break; case 39: t = t-1; s[t].b = (s[t].r == s[t+1].r); break; case 40: t = t-1; s[t].b = (s[t].r != s[t+1].r); break; case 41: t = t-1; s[t].b = (s[t].r < s[t+1].r); break; case 42: t = t-1; s[t].b = (s[t].r <= s[t+1].r); break; case 43: t = t-1; s[t].b = (s[t].r > s[t+1].r); break; case 44: t = t-1; s[t].b = (s[t].r >= s[t+1].r); break; case 45: t = t-1; s[t].b = (s[t].i == s[t+1].i); break; case 46: t = t-1; s[t].b = (s[t].i != s[t+1].i); break; case 47: t = t-1; s[t].b = (s[t].i < s[t+1].i); break; case 48: t = t-1; s[t].b = (s[t].i <= s[t+1].i); break; case 49: t = t-1; s[t].b = (s[t].i > s[t+1].i); break; case 50: t = t-1; s[t].b = (s[t].i >= s[t+1].i); break; case 51: t = t-1; s[t].b = (s[t].b || s[t+1].b); break; case 52: t = t-1; s[t].i = s[t].i + s[t+1].i; break; case 53: t = t-1; s[t].i = s[t].i - s[t+1].i; break; case 54: t = t-1; s[t].r = s[t].r + s[t+1].r; break; case 55: t = t-1; s[t].r = s[t].r - s[t+1].r; break; case 56: t = t-1; s[t].b = (s[t].b && s[t+1].b); break; case 57: t = t-1; s[t].i = s[t].i * s[t+1].i; break; case 58: t = t-1; if ( s[t+1].i == 0 ) ps = divchk; s[t].i = s[t].i / s[t+1].i; break; case 59: t = t-1; if ( s[t+1].i == 0 ) ps = divchk; s[t].i = s[t].i % s[t+1].i; break; case 60: t = t-1; s[t].r = s[t].r*s[t+1].r; break; case 61: t = t-1; s[t].r = s[t].r/s[t+1].r; break; case 62: if(line[cc+1] == EOF)ps = redchk; else nextch(); break; case 63: printf("\n"); lncnt = lncnt + 1; chrcnt = 0; if ( lncnt > linelimit ) ps = linchk; break; }//end switch }while(ps == run);//end do while loop if ( ps != fin ) { printf("\n"); printf("halt at %5d because of", pc); printf("\n"); switch (ps) { case 3: printf("undefined case\n"); break; case 4: printf("division by 0\n"); break; case 5: printf("invalid index\n"); break; case 6: printf("storage overflow\n"); break; case 7: printf("too much output\n"); break; case 8: printf("line too long\n"); break; case 9: printf("reading past the end of file\n"); break; } h1 = b; blkcnt = 10; do{ printf("\n"); blkcnt = blkcnt - 1; if ( blkcnt == 0 ) h1 = 0; h2 = s[h1+4].i; if ( h1 != 0 ) printf(" %s called at %5d", tab[h2].name, s[h1+4].i); h2 = btab[tab[h2].ref].last; while ( h2 != 0 ){ if ( tab[h2].obj == variable ) if ( testtyp(stantyps, tab[h2].typ) ){ printf(" %s = ", tab[h2].name); if ( tab[h2].normal ) h3 = h1+tab[h2].adr; else h3 = s[h1+tab[h2].adr].i; switch (tab[h2].typ){ case 1: printf("%d\n", s[h3].i); break; case 2: printf("%f\n", s[h3].r); break; case 3: printf("%d\n", s[h3].b); break; case 4: printf("%c\n", s[h3].c); break; }//switch }//if testtyp h2 = tab[h2].link; }//end while h1 = s[h1+3].i; }while(h1 >= 0); }//end if(ps!=fin) printf("\n"); printf("%d steps\n", ocnt); }/*end interpret*/