/* * 处理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); }
/** * 处理生成函数的中间代码时 * 在函数的第一行地址前加入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); }