⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 interpreter.java

📁 一个C语言子集的编译器
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * @(#)Intepreter.java	1.0.0  05/13/2007
 *
 * Copyright 2007 Xuxt@buaa, No.34060520 All rights reserved.
 */
package com.king4solomon.homework.compiler.pvm;

import java.util.*;
import javax.swing.*;
import com.king4solomon.homework.compiler.core.*;
import com.king4solomon.homework.compiler.gui.*;

/**
 * 对生成MidCode的解释执行虚机类
 * 
 * @author Xuxt@buaa
 * @version 1.0.0
 */
public class Interpreter implements Runnable {
	public Interpreter() {

	}

	@SuppressWarnings("deprecation")
	public void run() {
		init();
		if (readCode() != 0) {
			int tmp = codeBuf.size();
			while (px < tmp) {
				crtInstr = codeBuf.get(px++);
				ConsolePane.write("    "
						+ CodeGen.instructions[crtInstr.instruction] + "    "
						+ crtInstr.level + "    " + crtInstr.value + '\n');
				interpret(crtInstr);
				if (isDebug)
					thr.suspend();
				CodePane.setSelect(px);
			}
		} else {
			ProblemPane.write("No code available!"+'\n');
			halt();
		}
	}

	/**
	 * 设置当前线程方法
	 * 
	 * @param t
	 *            当前线程
	 */
	public static void setThread(Thread t) {
		thr = t;
	}

	/**
	 * 指令解释执行方法
	 * 
	 * @param i
	 *            当前待执行指令
	 */
	public void interpret(Instruction i) {
		switch (i.instruction) {
		case ConstSet.JMP_INSTR:
			jmpInstr(i);
			break;
		case ConstSet.JPC_INSTR:
			jpcInstr(i);
			break;
		case ConstSet.OPR_INSTR:
			oprInstr(i);
			break;
		case ConstSet.STO_INSTR:
			stoInstr(i);
			break;
		case ConstSet.LOD_INSTR:
			lodInstr(i);
			break;
		case ConstSet.RED_INSTR:
			redInstr(i);
			break;
		case ConstSet.WRT_INSTR:
			wrtInstr(i);
			break;
		case ConstSet.LIT_INSTR:
			litInstr(i);
			break;
		case ConstSet.INT_INSTR:
			intInstr(i);
			break;
		case ConstSet.CAL_INSTR:
			calInstr(i);
			break;
		case ConstSet.RET_INSTR:
			retInstr();
			break;
		case ConstSet.STR_INSTR:
			strInstr(i);
			break;
		case ConstSet.STC_INSTR:
			stcInstr(i);
			break;
		case ConstSet.LDR_INSTR:
			ldrInstr();
			break;
		case ConstSet.LDC_INSTR:
			ldcInstr();
			break;
		case ConstSet.HLT_INSTR:
			hltInstr();
			break;
		case ConstSet.LST_INSTR:
			lstInstr();
			break;
		case ConstSet.CRJ_INSTR:
			crjInstr();
			break;
		case ConstSet.CRC_INSTR:
			crcInstr();
			break;
		case ConstSet.TPC_INSTR:
			tpcInstr(i);
			break;
		default:

		}

	}

	/**
	 * 设置调试标志方法
	 * 
	 * @param flg
	 *            待设置的值
	 */
	public static void setDebug(boolean flg) {
		isDebug = flg;
	}

	/**
	 * 线程初始化方法
	 */
	public void init() {
		StackTable.clear();
		StackVM.clear();
		CorePane.clear();
		pCountStack = new Stack<StackUnit>();
		stack = new StackVM();
		codeBuf = new ArrayList<Instruction>(); // 代码栈
		HandoutFrame.centPane.addC(new JScrollPane(new StackTable()));
		ProblemPane.write(ConstSet.INTESTART);
		ConsolePane.write(ConstSet.INTESTART);
		InfoPane.write(ConstSet.INTESTART);
		px = 0;
		bx = 0;
		stack.push(new StackUnit(ConstSet.INTEGER, ""));
		stack.push(new StackUnit(ConstSet.INTEGER, ""));
		stack.push(new StackUnit(ConstSet.INTEGER, ""));

	}

	/**
	 * 读入所有指令到指令数组方法
	 */
	private static int readCode() {
		codeBuf = CodeGen.getCode();
		return codeBuf.size();
	}

	/**
	 * 无条件跳转指令解释执行方法
	 * 
	 * @param i
	 */
	private void jmpInstr(Instruction i) {
		px = Integer.parseInt(i.value) - 1;
	}

	/**
	 * 有条件条转指令解释执行方法
	 * 
	 * lv == 0:栈顶是0就跳转;lv == 1:栈顶不是0就跳转
	 * 
	 * @param i
	 */
	private void jpcInstr(Instruction i) {
		try {
			StackUnit unit = stack.pop();
			if (i.level == 0) {
				if (unit.type == ConstSet.REAL) {
					if (Float.parseFloat(unit.value) == 0.0)
						px = Integer.parseInt(i.value) - 1;
				} else {
					if (Integer.parseInt(unit.value) == 0)
						px = Integer.parseInt(i.value) - 1;
				}
			} else {
				if (unit.type == ConstSet.REAL) {
					if (Float.parseFloat(unit.value) != 0.0)
						px = Integer.parseInt(i.value) - 1;
				} else {
					if (Integer.parseInt(unit.value) != 0)
						px = Integer.parseInt(i.value) - 1;
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 读方法
	 * 
	 * 弹出对话框每次输入一个参数
	 * 
	 * @param i
	 *            当前指令
	 */
	@SuppressWarnings("deprecation")
	private void redInstr(Instruction i) {
		try {
			HandoutFrame.tb10.setEnabled(false);
			String type;
			if(i.level==ConstSet.INTEGER)
				type = "int";
			else if(i.level==ConstSet.CHARACTER)
				type = "char";
			else type = "float";
			InputFrame in = new InputFrame(type);
			InputFrame.setThread(thr);
			thr.suspend();
			if (!in.buf.equals("")) {
				if (i.level != ConstSet.CHARACTER)
					stack.push(new StackUnit(i.level, in.buf));
				else {
					try {
						int tmpVal = Lexer.charVal(in.buf.charAt(0));
						if (tmpVal != -1)
							stack.push(new StackUnit(i.level, tmpVal + ""));
						else {
							ProblemPane
									.write("Invalid character input!" + '\n');
							halt();
						}
					} catch (Exception e1) {
						stack.push(new StackUnit(i.level, in.buf));
					}
				}
			} else {

			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 写方法,写立即数或栈顶到输出
	 * 
	 * @param i
	 *            当前指令
	 */
	private void wrtInstr(Instruction i) {
		// 立即数输出
		if (i.level == 0) {
			InfoPane.write(i.value + '\n');
		}
		// 栈顶输出
		else {
			InfoPane.write(stack.pop().value + '\n');
		}
	}

	/**
	 * 存数方法
	 * 
	 * @param i
	 *            当前指令
	 */
	private void stoInstr(Instruction i) {
		try {
			int absAdd;
			if (i.level == 0) {
				absAdd = bx + Integer.parseInt(i.value);
			} else {
				absAdd = Integer.parseInt(stack.getValueOf(bx))
						+ Integer.parseInt(i.value);
			}
			stack.set(absAdd, stack.pop());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 取数方法
	 * 
	 * @param i
	 *            当前指令
	 */
	private void lodInstr(Instruction i) {
		try {
			int absAdd;
			if (i.level == 0) {
				absAdd = bx + Integer.parseInt(i.value);
			} else {
				absAdd = Integer.parseInt(stack.getValueOf(bx))
						+ Integer.parseInt(i.value);
			}
			stack.push(stack.getUnit(absAdd));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 压入立即数方法
	 * 
	 * @param i
	 *            当前指令
	 */
	private void litInstr(Instruction i) {
		try {
			stack.push(new StackUnit(i.level, i.value));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 栈顶自增方法
	 * 
	 * @param i
	 *            当前指令
	 */
	private void intInstr(Instruction i) {
		try {
			for (int idx = Integer.parseInt(i.value); idx > 0; idx--) {
				stack.push(new StackUnit(ConstSet.UNINITTYPE, ""));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}

	}

	/**
	 * 函数调用指令解释执行方法
	 * 
	 * @param i
	 *            当前指令
	 */
	private void calInstr(Instruction i) {
		try {
			int tmp = stack.getLength()
					- Integer.parseInt(pCountStack.pop().value) - 3;
			stack.set(tmp++, new StackUnit(ConstSet.INTEGER, "0"));
			stack.set(tmp++, new StackUnit(ConstSet.INTEGER, bx + ""));
			stack.set(tmp++, new StackUnit(ConstSet.INTEGER, px + 1 + ""));
			bx = tmp - 3;
			px = Integer.parseInt(i.value) - 1;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}

	}

	/**
	 * 返回指令解释执行方法
	 */
	private void retInstr() {
		try {
			px = Integer.parseInt(stack.getValueOf(bx + 2)) - 1;
			int tmp = Integer.parseInt(stack.getValueOf(bx + 1));
			stack.free(bx - 1);
			bx = tmp;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 将栈顶填入返回寄存器方法
	 * 
	 * @param i
	 *            当前指令
	 */
	private void strInstr(Instruction i) {
		// 返回类型匹配
		if (i.level == stack.getTypeOf(stack.getLength() - 1))
			retReg = stack.pop();
		else {
			ProblemPane.write("Fetal error! Different return type!");
			halt();
		}
	}

	/**
	 * 将指令中的立即数压入参数个数栈方法
	 * 
	 * @param i
	 *            当前指令
	 */
	private void stcInstr(Instruction i) {
		try {
			pCountStack.push(new StackUnit(ConstSet.INTEGER, i.value));
		} catch (RuntimeException e) {
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 取返回值解释执行方法
	 */
	private void ldrInstr() {
		try {
			stack.push(retReg);
		} catch (Exception e) {
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 取参数个数解释执行方法
	 */
	private void ldcInstr() {
		try {
			stack.push(new StackUnit(ConstSet.INTEGER, "" + pCountStack));
		} catch (RuntimeException e) {
			ProblemPane.write(e.toString() + '\n');
			halt();
		}
	}

	/**
	 * 停机指令解释执行方法
	 */
	@SuppressWarnings("deprecation")
	private void hltInstr() {
		stack.free(bx - 1);
		SourcePane.paint();
		ProblemPane.write(ConstSet.INTECOMPLETE);
		ConsolePane.write(ConstSet.INTECOMPLETE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -