📄 pl0int.c
字号:
/*******************************************************************
Program : Recursive Descent Compiler for PL/0
Module : PL0INT - Interpreter of itermediate code
File : pl0int.c
Compiler: Borland C 3.1 - 4.5, GNU C 2.7.1
Author : H. Weber
Revision: Aug. 1998
********************************************************************/
#include <string.h>
#include <stdio.h>
#include "pl0code.h"
#define codemax 5000
#define stackmax 10000
int pc; /* program counter */
int base; /* base pointer */
int sptr; /* stack pointer */
int jumpswitch; /* indicates jumps */
int stack[stackmax]; /* runtime stack */
FILE *intcode;
struct instr {
int o; /* opcode */
int l; /* level of declaration */
int a; /* rel. address in DSA */
};
struct instr code[codemax];
void readcode(int *count)
/* read intermediate code */
{
int no, o, k;
char oc[4];
*count = 0;
while (!feof(intcode) && *count < codemax) {
k = fscanf(intcode, "%3d %3s %2d %5d",
&no, oc, &code[*count].l,
&code[*count].a);
if (k < 4) break;
if (strcmp(oc, "NUL") == 0) o = NUL;
else if (strcmp(oc, "ADD") == 0) o = ADD;
else if (strcmp(oc, "SUB") == 0) o = SUB;
else if (strcmp(oc, "MPY") == 0) o = MPY;
else if (strcmp(oc, "DVD") == 0) o = DVD;
else if (strcmp(oc, "NEG") == 0) o = NEG;
else if (strcmp(oc, "ODD") == 0) o = ODD;
else if (strcmp(oc, "EQL") == 0) o = EQL;
else if (strcmp(oc, "NEQ") == 0) o = NEQ;
else if (strcmp(oc, "LSS") == 0) o = LSS;
else if (strcmp(oc, "GTR") == 0) o = GTR;
else if (strcmp(oc, "LEQ") == 0) o = LEQ;
else if (strcmp(oc, "GEQ") == 0) o = GEQ;
else if (strcmp(oc, "LIT") == 0) o = LIT;
else if (strcmp(oc, "RET") == 0) o = RET;
else if (strcmp(oc, "CAL") == 0) o = CAL;
else if (strcmp(oc, "LOD") == 0) o = LOD;
else if (strcmp(oc, "STO") == 0) o = STO;
else if (strcmp(oc, "INT") == 0) o = INT;
else if (strcmp(oc, "JPU") == 0) o = JPU;
else if (strcmp(oc, "JPC") == 0) o = JPC;
else if (strcmp(oc, "INP") == 0) o = INP;
else if (strcmp(oc, "PRN") == 0) o = PRN;
else if (strcmp(oc, "ASC") == 0) o = ASC;
else if (strcmp(oc, "PRS") == 0) o = PRS;
else if (strcmp(oc, "PRL") == 0) o = PRL;
else {
fprintf(stderr, "Unknown opcode symbol %s\n",
oc);
exit(1);
}
code[(*count)++].o = o;
}
if (*count == codemax) {
fprintf(stderr, "Program too long.");
exit(1);
}
(*count)--;
}
int sbase(int l)
/* sbase determines the address of a DSA which is l levels
down the runtime stack */
{
int b;
b = base;
while (l != 0) {
b = stack[b];
l--;
}
return b;
}
void main(int argc, char *argv[])
/*------------------------------------------------------------------
The main function of the interpreter reads the intermediate
code file and interpretes itc content.
------------------------------------------------------------------*/
{
int h1, count; //h2,
char cname[20];
char *p;
/* check arguments */
// if (argc == 1) {
// fprintf(stderr, "Usage: %s pcode\n", argv[0]);
// exit(1);
// }
/* set up filenames */
// strcpy(cname, argv[1]);
strcpy(cname, "prim.pl0");
p = strchr(cname, '.');
if (p) *p = 0;
strcat(cname, ".cod");
/* open file */
if ((intcode = fopen(cname, "r")) == NULL) {
fprintf(stderr, "Cannot open intermed. code file %s\n",
cname);
exit(1);
}
/* read code into array */
readcode(&count);
/* initialization of stack */
stack[0] = 0;
stack[1] = 0;
stack[2] = 0;
/* initialization of registers */
base = 0;
sptr = 2; /* neu */
pc = 0;
jumpswitch = 1;
/* main loop */
do {
if (!jumpswitch) pc++;
jumpswitch = 0;
switch (code[pc].o) {
case ADD :
sptr--;
stack[sptr] = stack[sptr] + stack[sptr+1];
break;
case SUB :
sptr--;
stack[sptr] = stack[sptr] - stack[sptr+1];
break;
case MPY :
sptr--;
stack[sptr] = stack[sptr] * stack[sptr+1];
break;
case DVD :
sptr--;
stack[sptr] = stack[sptr] / stack[sptr+1];
break;
case NEG :
stack[sptr] = -stack[sptr];
break;
case ODD :
stack[sptr] = stack[sptr] % 2;
break;
case EQL :
sptr--;
stack[sptr] = stack[sptr] == stack[sptr+1] ? 1 : 0;
break;
case NEQ :
sptr--;
stack[sptr] = stack[sptr] != stack[sptr+1] ? 1 : 0;
break;
case LSS :
sptr--;
stack[sptr] = stack[sptr] < stack[sptr+1] ? 1 : 0;
break;
case GTR :
sptr--;
stack[sptr] = stack[sptr] > stack[sptr+1] ? 1 : 0;
break;
case LEQ :
sptr--;
stack[sptr] = stack[sptr] <= stack[sptr+1] ? 1 : 0;
break;
case GEQ :
sptr--;
stack[sptr] = stack[sptr] >= stack[sptr+1] ? 1 : 0;
break;
case LIT :
stack[++sptr] = code[pc].a;
break;
case RET :
sptr = base - 1;
pc = stack[sptr+3];
base = stack[sptr+2];
break;
case CAL :
stack[sptr+1] = sbase(code[pc].l);
stack[sptr+2] = base;
stack[sptr+3] = pc;
base = sptr + 1;
sptr += 3; /* neu */
pc = code[pc].a;
jumpswitch = 1;
break;
case LOD :
stack[++sptr] = stack[sbase(code[pc].l)+code[pc].a];
break;
case STO :
stack[sbase(code[pc].l)+code[pc].a] = stack[sptr--];
break;
case INT :
sptr += code[pc].a;
break;
case JPU :
jumpswitch = 1;
pc = code[pc].a;
break;
case JPC :
if (stack[sptr] == 0) {
jumpswitch = 1;
pc = code[pc].a;
}
sptr--;
break;
case INP :
scanf("%d", &stack[++sptr]);
break;
case PRN :
printf(" %6d", stack[sptr--]);
break;
case PRS :
for (h1=1; h1<=code[pc].a; h1++)
printf("%c", code[pc+h1].a);
pc += code[pc].a;
break;
case PRL :
printf("\n");
break;
default :
fprintf(stderr, "Unknown opcode %d\n", code[pc].o);
exit(1);
}
} while (pc != 0);
/* close files */
fclose(intcode);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -