/* * 处理leftValue,需要将变量对应在局部变量区的位置压入栈中 * add的结果是保存在栈上 */ public override object VisitLeftValue([NotNull] CMMParser.LeftValueContext context) { if (context.ChildCount == 1) { //只定义成了identifier,将identifier对应的索引地址压栈 if (!curLocalVariablesTable.ContainsKey(context.GetChild(0).GetText())) { throw new VariableNotFountException(context.GetChild(0).GetText(), context); } curLocalVariablesTable.TryGetValue(context.GetChild(0).GetText(), out int addr); IntermediateCode code = new IntermediateCode(addr, InstructionType.push, context.Start.Line); codes.Add(code); } else { // 定义成数组的那种形式a[i] if (!curLocalVariablesTable.ContainsKey(context.GetChild(0).GetText())) { throw new VariableNotFountException(context.GetChild(0).GetText(), context); } curLocalVariablesTable.TryGetValue(context.GetChild(0).GetText(), out int addr); // 把基地址也push到操作栈上 IntermediateCode code0 = new IntermediateCode(addr, InstructionType.push, context.Start.Line); Visit(context.expression()); // 使用add指令,获得addr+expression,add指令使得这个值已经压入栈中 IntermediateCode code1 = new IntermediateCode(InstructionType.add, context.expression().Start.Line); codes.Add(code0); codes.Add(code1); } return(null); }
/// <summary> /// 替换中间代码为int /// </summary> /// <param name="address">中间代码地址</param> /// <returns>被替换掉的中间代码</returns> public IntermediateCode ReplaceWithInt(int address) { IntermediateCode saved = codesArray[address]; codesArray[address] = new IntermediateCode(InstructionType.i, saved.lineNum); return(saved); }
/* * jumpStatement * return 语句在第一遍扫描结束之后回填 * break continue 可以在for while语句的时候,直接转换成为jump语句 */ public override object VisitJumpStatement([NotNull] CMMParser.JumpStatementContext context) { IntermediateCode code = null; switch (context.GetChild(0).GetText()) { case "break": code = new IntermediateCode(InstructionType.b, context.Start.Line); break; case "continue": code = new IntermediateCode(InstructionType.cnt, context.Start.Line); break; case "return": if (context.ChildCount == 2) { // 向操作栈压入0表示没有返回值 codes.Add(new IntermediateCode(0, InstructionType.push, context.Start.Line)); } else { Visit(context.expression()); // 向操作栈压入1表示有返回值 codes.Add(new IntermediateCode(1, InstructionType.push, context.Start.Line)); } code = new IntermediateCode(InstructionType.ret, context.Start.Line); break; } codes.Add(code); return(null); }
// 替换codes[addr0, addr2]中所有的break和continue语句,其中break -> jump addr2, continue -> jump addr1 private void replaceBreakAndConti(List <IntermediateCode> codes, int addr0, int addr2, int addr1) { IntermediateCode[] codeArray = codes.ToArray(); for (int i = addr0; i <= addr2; i++) { IntermediateCode code; switch (codeArray[i].getType()) { case InstructionType.b: code = new IntermediateCode(addr2 + 1, InstructionType.j, codeArray[i].lineNum); codes.RemoveAt(i); codes.Insert(i, code); break; case InstructionType.cnt: code = new IntermediateCode(addr1, InstructionType.j, codeArray[i].lineNum); codes.RemoveAt(i); codes.Insert(i, code); break; default: break; } } }
/* * * 用于initializer的编译,分成两种情况。 * 一种情况是直接对已经定义的普通变量进行赋值,另外一种情况是对数组的操作,没看出来。a[1]=[1],[1] * 前提:Expression Visit的结果已经被push到操作栈中 */ public override object VisitInitializer([NotNull] CMMParser.InitializerContext context) { if (context.ChildCount == 3) { // 直接对已经定义的普通变量进行赋值 if (curLocalVariablesTable.ContainsKey(context.GetChild(0).GetText())) { throw new VariableRedefinedException(context.GetChild(0).GetText(), context); } curLocalVariablesTable.Add(context.GetChild(0).GetText(), curLocalVariablesTableLength); curLocalVariablesTableLength++; Visit(context.GetChild(2)); curLocalVariablesTable.TryGetValue(context.GetChild(0).GetText(), out int index); IntermediateCode code = new IntermediateCode(index, InstructionType.pop, context.Start.Line); codes.Add(code); } else { // 定义数组 // 首先visit a[exp] exp的值被压到当前stack上 // expStack.Clear(); // Visit(context.GetChild(2)); // Double expValue = (Double)expStack.Pop(); // if (Math.Ceiling(expValue) != expValue) { // throw new CompileException("数组元素个数必须为整数!"); // } // 支支持常量定义 int size = Convert.ToInt32(context.GetChild(2).GetText()); curLocalVariablesTable.Add(context.GetChild(0).GetText(), curLocalVariablesTableLength); int initialExpCount = context.expression().Length - 1; for (int i = 1; i < context.expression().Length; i++) { // 求出所有子表达式的值 放在栈上 Visit(context.expression()[i]); } for (int i = 0; i < size - initialExpCount; i++) { // 剩下的元素全部赋值为0 codes.Add(new IntermediateCode(0, InstructionType.push, context.Start.Line)); } for (int i = size - 1; i >= 0; i--) { // 从后往前给数组赋值 codes.Add(new IntermediateCode(curLocalVariablesTableLength + i, InstructionType.pop, context.Start.Line)); } // 更新局部变量表大小 curLocalVariablesTableLength += size; } return(null); }
/* * 处理if语句 */ public override object VisitIfStatement([NotNull] CMMParser.IfStatementContext context) { // 查看expression的结果 Visit(context.expression()); IntermediateCode code0 = new IntermediateCode(0, InstructionType.push, context.expression().Start.Line); codes.Add(code0); // 比较expression的结果和0的关系,等于0的话就跳转走,code1的目的地址待回填 IntermediateCode code1 = new IntermediateCode(InstructionType.je, context.expression().Stop.Line); codes.Add(code1); if (context.codeBlock() != null) { Visit(context.codeBlock()); } IntermediateCode code3 = new IntermediateCode(InstructionType.j, context.codeBlock().Stop.Line); codes.Add(code3); // 条件不符合的情况应该执行的代码行号为addr0,回填一下 int addr0 = codes.Count; code1.setOperant(addr0); List <IntermediateCode> needToAddFinishAddrCodes = new List <IntermediateCode>(); needToAddFinishAddrCodes.Add(code3); // 每个else语句都执行一下 if (context.elseClause() != null) { foreach (CMMParser.ElseClauseContext ctx in context.elseClause()) { if (ctx.ifStatement() == null) { Visit(ctx.codeBlock()); IntermediateCode code = new IntermediateCode(InstructionType.j, ctx.codeBlock().Stop.Line); needToAddFinishAddrCodes.Add(code); codes.Add(code); } else { Visit(ctx.ifStatement()); } } } foreach (IntermediateCode c in needToAddFinishAddrCodes) { c.operant = codes.Count; } return(null); }
/* * 访问do while表达式 */ public override object VisitDoWhileStatement([NotNull] CMMParser.DoWhileStatementContext context) { // addr0是codeBlock开始地址 int addr0 = codes.Count; Visit(context.codeBlock()); IntermediateCode code0 = new IntermediateCode(0, InstructionType.push, context.expression().Start.Line); // 查看expression的结果 Visit(context.expression()); // 比较expression的结果和0的关系,如果不相等的话,就要跳转回去执行codeBlock IntermediateCode code1 = new IntermediateCode(addr0, InstructionType.jne, context.expression().Start.Line); codes.Add(code0); codes.Add(code1); return(null); }
/* * 写指令 */ public override object VisitWriteStatement([NotNull] CMMParser.WriteStatementContext context) { IntermediateCode code; if (context.ChildCount == 4) { // write不带参数 code = new IntermediateCode(0, InstructionType.write, context.Start.Line); } else { // write带参数 先访问参数 将其压栈 VisitChildren(context); // 打印栈顶元素 code = new IntermediateCode(1, InstructionType.write, context.Start.Line); } codes.Add(code); return(null); }
/** * 处理生成函数的中间代码时 * 在函数的第一行地址前加入j指令跳转到函数的最后一行地址之后 * */ public override object VisitFunctionDeclaration([NotNull] CMMParser.FunctionDeclarationContext context) { string funcName = context.GetChild(1).GetText(); // jump到函数ret的下一行代码 最后再回填 IntermediateCode jumpCode = new IntermediateCode(InstructionType.j, context.Start.Line); codes.Add(jumpCode); // 保存局部变量表和大小 Dictionary <string, int> storedVariableTable = curLocalVariablesTable; int storedVariableTableSize = curLocalVariablesTableLength; curLocalVariablesTable = new Dictionary <string, int>(); curLocalVariablesTableLength = 0; // 用于记录该函数的各种信息 FunctionInformation funcInfo = new FunctionInformation(funcName); // 记录函数的起始地址 int funcAddress = codes.Count; functionAddressTable.Add(funcName, funcAddress); funcInfo.enrtyAddress = funcAddress; // 访问参数列表 Visit(context.parameterClause()); // visit code block生成当前函数的中间代码 Visit(context.codeBlock()); // 填入函数的出口地址 funcInfo.outAddress = codes.Count - 1; // 回填jump指令 jumpCode.setOperant(codes.Count); funcInfo.localVariableTable = curLocalVariablesTable; // 将函数信息保存到函数信息表中 functionInformations.Add(funcName, funcInfo); // 恢复局部变量表和大小 curLocalVariablesTable = storedVariableTable; curLocalVariablesTableLength = storedVariableTableSize; return(null); }
/* * * 访问while表达式 */ public override object VisitWhileStatement([NotNull] CMMParser.WhileStatementContext context) { /* * 如果expression的操作结果是false,就在栈中压入0,否则压入1. * */ int curSize = curLocalVariablesTableLength; int idx = codes.Count; IntermediateCode code0 = new IntermediateCode(0, InstructionType.push, context.Start.Line); codes.Add(code0); // 查看expression的结果 Visit(context.expression()); // 比较expression的结果和1的关系 // code1的目的地址等待后续回填。因为如果与0相等,说明是false,则需要跳转到codeBlock后面的位置。 IntermediateCode code1 = new IntermediateCode(InstructionType.je, context.expression().Start.Line); codes.Add(code1); // addr0是codeBlock的开始地址。 int addr0 = codes.Count; Visit(context.codeBlock()); IntermediateCode code2 = new IntermediateCode(0, InstructionType.j, context.codeBlock().Stop.Line); codes.Add(code2); int addr1 = codes.Count; // 这个时候回填地址,如果刚才的条件判断不满足,那么目的地址是codeBlock结束的地址addr1 code1.setOperant(addr1); code2.setOperant(idx); codes.Add(new IntermediateCode(curSize, InstructionType.delv, context.codeBlock().Stop.Line)); curLocalVariablesTableLength = curSize; removeVariableBiggerThanK(curSize); return(null); }
/** * */ public override object VisitAdditiveExpression([NotNull] CMMParser.AdditiveExpressionContext context) { Double op1, op2; IntermediateCode code = new IntermediateCode(context.Start.Line); // 先遍历左右子树 VisitChildren(context); if (context.ChildCount.Equals(3)) { // 左右 switch (context.GetChild(1).GetText()) { case "+": code.type = InstructionType.add; // 计算当前表达式的值 以便万一要给数组分配大小 // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 + op1); break; case "-": code.type = InstructionType.sub; // 计算当前表达式的值 以便万一要给数组分配大小 // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 - op1); break; } codes.Add(code); } else { // 子树是term的情况 不用处理 } return(null); }
/** * 读取identifier的text,然后从函数地址表中读取该函数的中间代码起始地址 * 调用call指令 * 将expression List压入被调用函数的局部变量表中 */ public override object VisitCallStatement([NotNull] CMMParser.CallStatementContext context) { // 看一下有多少参数 VisitExpressionList(context.expressionList()); int count = 0; if (context.expressionList() != null) { count = getLen(context.expressionList()); } // IntermediateCode code1 = new IntermediateCode(count, InstructionType.push, context.Start.Line); codes.Add(code1); IntermediateCode code0 = new IntermediateCode(context.Identifier().GetText(), InstructionType.call, context.Start.Line); codes.Add(code0); return(null); }
/* * 处理赋值操作, * 前提:leftValue将待赋值的变量在局部变更量表中的索引已经压入栈中,expression处理的结果已经压入操作栈中 */ public override object VisitAssignment([NotNull] CMMParser.AssignmentContext context) { Visit(context.leftValue()); // tmp是一个虚拟的变量,用于 存储leftVal的索引 在局部变量表的位置 int tmp = curLocalVariablesTableLength; // 把leftVal的值放到局部变更量表Count位置上 IntermediateCode code0 = new IntermediateCode(tmp, InstructionType.pop, context.leftValue().Start.Line); codes.Add(code0); // 把Expression的值压入栈中 Visit(context.expression()); //将Experession的值放入Count中 IntermediateCode code1 = new IntermediateCode("(" + tmp + ")", InstructionType.pop, context.expression().Start.Line); // 这个过程中,局部变量表并没有增加新的元素,所以curLocalVariable并没有Add操作 codes.Add(code1); // 局部变量表里面,1号位置的值是0 return(null); }
/// <summary> /// 开始调试 /// </summary> public void Run() { // 初始化栈 stack = new Stack <StackFrame>(); entryStacks = new Stack <int>(); stacks.Add(stack); // 当前栈帧 currentStackFrame = new StackFrame(0); globalStackFrame = currentStackFrame; stack.Push(currentStackFrame); // 代码区长度 int length = codesArray.Count; // 初始化程序计数器 pc = 0; isStop = false; // 设置当前符号表 currentSymbolTable = globalSymbolTable; // 执行中间代码 while (pc < length && !isStop) { IntermediateCode code = codesArray[pc]; InterpretSingleInstruction(code); pc++; } // 停止运行 // 运行结束销毁 stacks.Remove(stack); RunFinish?.Invoke(); }
/// <summary> /// 获取源代码-中间代码信息 /// </summary> /// <returns>源代码-中间代码信息</returns> public Dictionary <int, IntermediateCodeInformation> GetIntermediateCodeInformation() { int length = codesArray.Count; Dictionary <int, IntermediateCodeInformation> informations = new Dictionary <int, IntermediateCodeInformation>(); // 遍历中间代码 for (int i = 0; i < length; i++) { IntermediateCode current = codesArray[i]; int currentLine = current.lineNum; IntermediateCodeInformation currentInformation; // 判断该中间指令对应源代码的行是否已经加入信息表中 if (informations.TryGetValue(currentLine, out currentInformation)) { // 该行含函数调用则更新函数入口地址列表 if (current.type == InstructionType.call) { currentInformation.IsFunctionCall = true; currentInformation.FuncionEntryList.AddLast((int)current.operant); informations[currentLine] = currentInformation; } } else { // 该行源代码首条中间指令 currentInformation = new IntermediateCodeInformation(); currentInformation.Address = i; currentInformation.Line = currentLine; currentInformation.IsFunctionCall = false; currentInformation.FuncionEntryList = new LinkedList <int>(); informations.Add(currentLine, currentInformation); } } return(informations); }
/** * 判断子表达式的值并压入栈中 * * */ public override object VisitBoolExpression([NotNull] CMMParser.BoolExpressionContext context) { Object res = VisitChildren(context); Double op1, op2; if (context.ChildCount.Equals(3)) { string relationalOperator = context.GetChild(1).GetText(); IntermediateCode code = new IntermediateCode(context.Start.Line); switch (relationalOperator) { case "<=": code.type = InstructionType.le; // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 <= op1 ? 1 : 0); break; case ">=": code.type = InstructionType.ge; // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 >= op1 ? 1 : 0); break; case "==": code.type = InstructionType.eq; // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 == op1 ? 1 : 0); break; case "<": code.type = InstructionType.l; // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 < op1 ? 1 : 0); break; case ">": code.type = InstructionType.g; // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 > op1 ? 1 : 0); break; case "<>": code.type = InstructionType.ne; // op1 = (Double)expStack.Pop(); // op2 = (Double)expStack.Pop(); // expStack.Push(op2 != op1 ? 1 : 0); break; default: break; } codes.Add(code); } else { // additiveExpression的情况不用处理 直接把值压栈 } return(res); }
/// <summary> /// 恢复中间代码 /// </summary> /// <param name="address">中间代码地址</param> /// <param name="code">中间代码</param> public void Resume(int address, IntermediateCode code) { codesArray[address] = code; }
/* * 处理for语句 */ public override object VisitForStatement([NotNull] CMMParser.ForStatementContext context) { // 当前局部变量表的大小,访问完ForStatement之后要恢复局部变量表 int curSize = curLocalVariablesTableLength; // 这里面可能会定义新的变量,不过没关系,直接插入局部变量表中就可以了,最后我们恢复的。 if (context.forInitializer() != null) { Visit(context.forInitializer()); } // 访问expression,将执行的结果压入栈中 // addr_expression是expression(比较)的地址 int addr_expression = codes.Count; IntermediateCode code0, code1 = null; if (context.expression() != null) { Visit(context.expression()); // 如果expression的结果是真,才会访问 // 这里的0是数字,不是索引,要加上范围!! code0 = new IntermediateCode(0, InstructionType.push, context.Start.Line); // 如果是0的话,就直接跳转到codeBlock之后,并且释放局部变量。目的地址待回填 code1 = new IntermediateCode(InstructionType.je, context.Start.Line); // addr0是codeBlock的起始地址 codes.Add(code0); codes.Add(code1); } int addr0 = codes.Count; // 访问codeBlock if (context.codeBlock() != null) { Visit(context.codeBlock()); } // 访问更新操作,更新操作的起始地址是addr1 int addr1 = codes.Count; if (context.assignment() != null) { Visit(context.assignment()); } // 跳转回去expression去判断 codes.Add(new IntermediateCode(addr_expression, InstructionType.j, context.Start.Line)); // addr2是执行完codeBlock,而且判断确定不跳转的代码 int addr2 = codes.Count; if (code1 != null) { code1.setOperant(addr2); } // 替换所有出现的continue break,代码的范围是addr0-add2, 更新操作的代码在addr1 replaceBreakAndConti(codes, addr0, addr2 - 1, addr1); //局部变量表大于curSize的部分全部删掉! codes.Add(new IntermediateCode(curSize, InstructionType.delv, context.Stop.Line)); curLocalVariablesTableLength = curSize; removeVariableBiggerThanK(curSize); return(null); }
/// <summary> /// 执行单条指令 /// </summary> /// <param name="code">单条指令</param> public void InterpretSingleInstruction(IntermediateCode code) { switch (code.type) { case InstructionType.add: add(currentStackFrame, pc); break; case InstructionType.sub: sub(currentStackFrame, pc); break; case InstructionType.mul: mul(currentStackFrame); break; case InstructionType.div: div(currentStackFrame); break; case InstructionType.neg: neg(currentStackFrame); break; case InstructionType.and: and(currentStackFrame); break; case InstructionType.or: or(currentStackFrame); break; case InstructionType.not: not(currentStackFrame); break; case InstructionType.push: push(currentStackFrame, code.operant); break; case InstructionType.pop: pop(currentStackFrame, code.operant); break; case InstructionType.g: g(currentStackFrame); break; case InstructionType.l: l(currentStackFrame); break; case InstructionType.ge: ge(currentStackFrame); break; case InstructionType.le: le(currentStackFrame); break; case InstructionType.eq: eq(currentStackFrame); break; case InstructionType.ne: ne(currentStackFrame); break; case InstructionType.j: j(code.operant); break; case InstructionType.je: je(currentStackFrame, code.operant); break; case InstructionType.jg: jg(currentStackFrame, code.operant); break; case InstructionType.jl: jl(currentStackFrame, code.operant); break; case InstructionType.jne: jne(currentStackFrame, code.operant); break; case InstructionType.call: // 创建新的函数栈帧 传入pc StackFrame newStackFrame = new StackFrame(pc); // 首先获取参数个数 int paraNum = (int)currentStackFrame.popFromOperantStack(); // 向新的栈帧中压入参数 Stack <Object> tmp = new Stack <Object>(); for (int i = 0; i < paraNum; i++) { tmp.Push(currentStackFrame.popFromOperantStack()); } for (int i = 0; i < paraNum; i++) { newStackFrame.pushToVariableStack(tmp.Pop()); } // 压入新栈 stack.Push(newStackFrame); entryStacks.Push((int)code.operant); currentStackFrame = newStackFrame; currentSymbolTable = functionSymbolTable[(int)code.operant]; pc = (int)code.operant - 1; break; case InstructionType.read: read(currentStackFrame); break; case InstructionType.write: write(currentStackFrame, code.operant); break; case InstructionType.delv: delv(currentStackFrame); break; case InstructionType.b: b(currentStackFrame); break; case InstructionType.cnt: cnt(currentStackFrame); break; case InstructionType.pushv: pushv(currentStackFrame, code.operant); break; case InstructionType.i: i(); break; case InstructionType.ret: pc = currentStackFrame.getReturnAddress(); int flag = (int)currentStackFrame.popFromOperantStack(); Object returnValue = currentStackFrame.peek(); // 函数返回 移除当前栈帧 stack.Pop(); entryStacks.Pop(); if (flag == 1) { // 将函数返回值压入到调用者的栈帧中 stack.Peek().pushToOperantStack(returnValue); } currentStackFrame = stack.Peek(); currentSymbolTable = globalSymbolTable; break; default: break; } }
/// <summary> /// 解释执行代码 /// </summary> /// <param name="codes">中间代码</param> /// <returns>是否成功运行</returns> public Boolean interpret(List <IntermediateCode> codes) { // 初始化栈 Stack <StackFrame> stack = new Stack <StackFrame>(); stacks.Add(stack); // 当前栈帧 StackFrame currentStackFrame = new StackFrame(0); stack.Push(currentStackFrame); codesArray = codes; printCodes(); for (; pc < codes.Count; pc++) { IntermediateCode code = codesArray[pc]; switch (code.type) { case InstructionType.add: add(currentStackFrame, pc); break; case InstructionType.sub: sub(currentStackFrame, pc); break; case InstructionType.mul: mul(currentStackFrame); break; case InstructionType.div: div(currentStackFrame); break; case InstructionType.neg: neg(currentStackFrame); break; case InstructionType.and: and(currentStackFrame); break; case InstructionType.or: or(currentStackFrame); break; case InstructionType.not: not(currentStackFrame); break; case InstructionType.push: push(currentStackFrame, code.operant); break; case InstructionType.pop: pop(currentStackFrame, code.operant); break; case InstructionType.g: g(currentStackFrame); break; case InstructionType.l: l(currentStackFrame); break; case InstructionType.ge: ge(currentStackFrame); break; case InstructionType.le: le(currentStackFrame); break; case InstructionType.eq: eq(currentStackFrame); break; case InstructionType.ne: ne(currentStackFrame); break; case InstructionType.j: j(code.operant); break; case InstructionType.je: je(currentStackFrame, code.operant); break; case InstructionType.jg: jg(currentStackFrame, code.operant); break; case InstructionType.jl: jl(currentStackFrame, code.operant); break; case InstructionType.jne: jne(currentStackFrame, code.operant); break; case InstructionType.call: // 创建新的函数栈帧 传入pc StackFrame newStackFrame = new StackFrame(pc); // 首先获取参数个数 int paraNum = (int)currentStackFrame.popFromOperantStack(); // 向新的栈帧中压入参数 Stack <Object> tmp = new Stack <Object>(); for (int i = 0; i < paraNum; i++) { tmp.Push(currentStackFrame.popFromOperantStack()); } for (int i = 0; i < paraNum; i++) { newStackFrame.pushToVariableStack(tmp.Pop()); } // 压入新栈 stack.Push(newStackFrame); currentStackFrame = newStackFrame; pc = (int)code.operant - 1; break; case InstructionType.read: read(currentStackFrame); break; case InstructionType.write: write(currentStackFrame, code.operant); break; case InstructionType.delv: delv(currentStackFrame); break; case InstructionType.b: b(currentStackFrame); break; case InstructionType.cnt: cnt(currentStackFrame); break; case InstructionType.pushv: pushv(currentStackFrame, code.operant); break; case InstructionType.i: break; case InstructionType.ret: pc = currentStackFrame.getReturnAddress(); int flag = (int)currentStackFrame.popFromOperantStack(); Object returnValue = currentStackFrame.peek(); // 函数返回 移除当前栈帧 stack.Pop(); if (flag == 1) { // 将函数返回值压入到调用者的栈帧中 stack.Peek().pushToOperantStack(returnValue); } currentStackFrame = stack.Peek(); break; default: break; } } // 运行结束销毁 stacks.Remove(stack); return(true); }