PL/0编译器(java version) - Interpreter.java

时间:2023-12-21 19:03:08
   1:  package compiler;
   2:   
   3:  import java.io.BufferedReader;
   4:  import java.io.BufferedWriter;
   5:  import java.io.IOException;
   6:  import java.util.Arrays;
   7:  import java.util.logging.Level;
   8:  import java.util.logging.Logger;
   9:   
  10:  /**
  11:   * 类P-code代码解释器(含代码生成函数)
  12:   *
  13:   * @author jiangnan
  14:   *
  15:   */
  16:  public class Interpreter {
  17:   
  18:      //运行栈上限
  19:      private static final int stackSize = 1000;
  20:      //pcode数组上线
  21:      private static final int arraySize = 500;
  22:      //虚拟机代码指针,取值范围[0,arraySize-1]
  23:      public int arrayPtr = 0;
  24:      //存放虚拟机代码的数组
  25:      public Pcode[] pcodeArray;
  26:      //显示虚拟代码与否
  27:      public static boolean listswitch = true;
  28:   
  29:      public Interpreter() {
  30:          pcodeArray = new Pcode[arraySize];
  31:      }
  32:   
  33:      /**
  34:       * 生成虚拟机代码
  35:       *
  36:       * @param x Pcodeuction.f
  37:       * @param y Pcodeuction.l
  38:       * @param z Pcodeuction.a
  39:       */
  40:      public void gen(int f, int l, int a) {
  41:          if (arrayPtr >= arraySize) {                                                                          //超出堆栈的上限
  42:              throw new Error("***ERROR:Program too long***");
  43:          }
  44:          pcodeArray[arrayPtr++] = new Pcode(f, l, a);
  45:   
  46:      }
  47:   
  48:      /**
  49:       * 输出目标代码清单
  50:       *
  51:       * @param start 开始输出的位置
  52:       */
  53:      public void listcode(int start) {
  54:          if (listswitch) {                                                                         //是否显示P-code代码
  55:              for (int i = start; i < arrayPtr; i++) {
  56:                  try {
  57:                      String msg = i + "  " + Pcode.pcode[pcodeArray[i].f] + "  " + pcodeArray[i].l + " " + pcodeArray[i].a;                //形如: lit l,a
  58:                      System.out.println(msg);
  59:                      PL0.pcodeWriter.write(i + "  " + msg + '\n');
  60:                  } catch (Exception e) {
  61:                      e.printStackTrace();
  62:                      System.out.println("***list pcode meet with error***");
  63:                  }
  64:   
  65:              }
  66:          }
  67:      }
  68:   
  69:      /**
  70:       * 这个过程模拟了一台可以运行类PCODE指令的栈式计算机。 它拥有一个栈式数据段用于存放运行期数据, 拥有一个代码段用于存放类PCODE程序代码。
  71:       * 同时还拥用数据段分配指针、指令指针、指令寄存器、局部段基址指针等寄存器。
  72:       *
  73:       * @param stdin 从键盘输入无符号整数
  74:       * @param stdout 显示pcode运行过程
  75:       */
  76:      public void interpret(BufferedReader stdin, BufferedWriter stdout) {
  77:          int[] runtimeStack = new int[stackSize];                  // 程序运行栈
  78:          Arrays.fill(runtimeStack, 0);                                   //初始化
  79:          System.out.println("***Start Interpret P_CODE***");
  80:   
  81:          int pc = 0, // pc:指令指针,
  82:                  bp = 0, //bp:指令基址,
  83:                  sp = 0;                                                                //sp:栈顶指针
  84:   
  85:          do {
  86:   
  87:              Pcode index = pcodeArray[pc++];// index :存放当前指令, 读当前指令
  88:              System.out.println(pc + "  " + Pcode.pcode[index.f] + " " + index.l + " " + index.a);
  89:              switch (index.f) {
  90:                  case Pcode.LIT:                                                   // 将a的值取到栈顶
  91:                      runtimeStack[sp++] = index.a;
  92:                      break;
  93:                  case Pcode.OPR:                                                   // 数学、逻辑运算
  94:                      switch (index.a) {
  95:                          case 0:                                                          //OPR 0 0;RETURN 返回
  96:                              sp = bp;
  97:                              pc = runtimeStack[sp + 2];
  98:                              bp = runtimeStack[sp + 1];
  99:                              break;
 100:                          case 1:                                                           //OPR 0 1 ;NEG取反
 101:                              runtimeStack[sp - 1] = -runtimeStack[sp - 1];
 102:                              break;
 103:                          case 2:                                                           //OPR 0 2;ADD加法
 104:                              sp--;
 105:                              runtimeStack[sp - 1] += runtimeStack[sp];
 106:                              break;
 107:                          case 3:                                                             //OPR 0 3;SUB减法
 108:                              sp--;
 109:                              runtimeStack[sp - 1] -= runtimeStack[sp];
 110:                              break;
 111:                          case 4:                                                             //OPR 0 4;MUL乘法
 112:                              sp--;
 113:                              runtimeStack[sp - 1] =runtimeStack[sp - 1] * runtimeStack[sp];
 114:                              break;
 115:                          case 5:                                                             //OPR 0 5;DIV除法
 116:                              sp--;
 117:                              runtimeStack[sp - 1] /= runtimeStack[sp];
 118:                              break;
 119:                          case 6:                                                              //OPR 0 6;ODD对2取模mod 2
 120:                              runtimeStack[sp - 1] %= 2;
 121:                              break;
 122:                          case 7:                                                              //OPR 0 7;MOD取模
 123:                              sp--;
 124:                              runtimeStack[sp - 1] %= runtimeStack[sp];
 125:                              break;
 126:                          case 8:                                                             //OPR 0 8;==判断相等
 127:                              sp--;
 128:                              runtimeStack[sp - 1] = (runtimeStack[sp] == runtimeStack[sp - 1] ? 1 : 0);
 129:                              break;
 130:                          case 9:                                                                //OPR 0 9;!=判断不相等
 131:                              sp--;
 132:                              runtimeStack[sp - 1] = (runtimeStack[sp] != runtimeStack[sp - 1] ? 1 : 0);
 133:                              break;
 134:                          case 10:                                                               //OPR 0 10;<判断小于
 135:                              sp--;
 136:                              runtimeStack[sp - 1] = (runtimeStack[sp] < runtimeStack[sp - 1] ? 1 : 0);
 137:                              break;
 138:                          case 11:                                                                //OPR 0 11;>=判断大于等于
 139:                              sp--;
 140:                              runtimeStack[sp - 1] = (runtimeStack[sp] >= runtimeStack[sp - 1] ? 1 : 0);
 141:                              break;
 142:                          case 12:                                                                //OPG 0 12;>判断大于
 143:                              sp--;
 144:                              runtimeStack[sp - 1] = (runtimeStack[sp] > runtimeStack[sp - 1] ? 1 : 0);
 145:                              break;
 146:                          case 13:                                                                 //OPG 0 13;<=判断小于等于
 147:                              sp--;
 148:                              runtimeStack[sp - 1] = (runtimeStack[sp] <= runtimeStack[sp - 1] ? 1 : 0);
 149:                              break;
 150:                          case 14:                                                                 //OPG 0 14;输出栈顶值
 151:                              System.out.println("runtimeStack[sp - 1]" + runtimeStack[sp - 1] + ' ');
 152:                              try {
 153:                                  stdout.write(" " + runtimeStack[sp - 1] + ' ');
 154:                                  stdout.flush();
 155:                              } catch (Exception ex) {
 156:                                  System.out.println("***case 14 meet with error***");
 157:                              }
 158:                              sp--;
 159:                              break;
 160:                          case 15:                                                                 //OPG 0 15;输出换行
 161:                              System.out.print("\n");
 162:                              try {
 163:                                  stdout.write("\n");
 164:                              } catch (Exception ex) {
 165:                                  System.out.println("***case 15 meet with error***");
 166:                              }
 167:                              break;
 168:                          case 16:                                                                 //OPG 0 16;读入一行输入,置入栈顶
 169:                              System.out.print("Please Input a Integer : ");
 170:                              runtimeStack[sp] = 0;
 171:                              try {
 172:                                  runtimeStack[sp] = Integer.parseInt(stdin.readLine().trim());       //读入一个整型数字
 173:                                  System.out.println(runtimeStack[sp]);
 174:                                  sp++;
 175:                              } catch (Exception e) {
 176:                                  e.printStackTrace();
 177:                                  System.out.println("***read data meet with error***");
 178:                              }
 179:                              try {
 180:                                  stdout.write(" " + runtimeStack[sp] + '\n');
 181:                                  stdout.flush();
 182:                              } catch (Exception ex) {
 183:                                  System.out.println("***case 16 meet with error***");
 184:                              }
 185:                              break;
 186:                      }
 187:                      break;
 188:                  case Pcode.LOD:                                          //取相对当前过程的数据基地址为a的内存的值到栈顶
 189:                      runtimeStack[sp] = runtimeStack[base(index.l, runtimeStack, bp) + index.a];
 190:                      sp++;
 191:                      break;
 192:                  case Pcode.STO:                                         //栈顶的值存到相对当前的过程的数据基地址为a的内存
 193:                      sp--;
 194:                      runtimeStack[base(index.l, runtimeStack, bp) + index.a] = runtimeStack[sp];
 195:                      break;
 196:                  case Pcode.CAL:                                                                 //调用子程序
 197:                      runtimeStack[sp] = base(index.l, runtimeStack, bp);            //将静态作用域基地址入栈
 198:                      runtimeStack[sp + 1] = bp;                                                //将动态作用域基地址
 199:                      runtimeStack[sp + 2] = pc;                                               //将当前指针入栈
 200:                      bp = sp;                                                                        //改变基地址指针值为新过程的基地址
 201:                      pc = index.a;                                                                 //跳转至地址a
 202:                      break;
 203:                  case Pcode.INT:                                                               //开辟空间大小为a
 204:                      sp += index.a;
 205:                      break;
 206:                  case Pcode.JMP:                                                               //直接跳转至a
 207:                      pc = index.a;
 208:                      break;
 209:                  case Pcode.JPC:
 210:                      sp--;
 211:                      if (runtimeStack[sp] == 0) //条件跳转至a(当栈顶指针为0时)
 212:                      {
 213:                          pc = index.a;
 214:                      }
 215:                      break;
 216:              }
 217:          } while (pc != 0);
 218:      }
 219:   
 220:      /**
 221:       * 通过给定的层次差来获得该层的堆栈帧基址
 222:       *
 223:       * @param l 目标层次与当前层次的层次差
 224:       * @param runtimeStack 运行栈
 225:       * @param b 当前层堆栈帧基地址
 226:       * @return 目标层次的堆栈帧基地址
 227:       */
 228:      private int base(int l, int[] runtimeStack, int b) {
 229:          while (l > 0) {                                                       //向上找l层
 230:              b = runtimeStack[b];
 231:              l--;
 232:          }
 233:          return b;
 234:      }
 235:   
 236:      public void debugPcodeArray() throws IOException {
 237:          System.out.println("***Auto-Generated Pcode Array***");
 238:          String msg = null;
 239:          for (int i = 0; pcodeArray[i] != null; i++) {
 240:              msg = "" + i + "  " + Pcode.pcode[pcodeArray[i].f] + "  " + pcodeArray[i].l + "  " + pcodeArray[i].a;
 241:              System.out.println(msg);
 242:              PL0.pcodeWriter.write(msg + '\n');
 243:          }
 244:      }
 245:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }