package midend.visit; import java.util.ArrayList; import frontend.ast.block.Block; import frontend.ast.block.ForStmt; import frontend.ast.block.Stmt; import frontend.ast.exp.Cond; import frontend.ast.exp.Exp; import frontend.ast.exp.LVal; import frontend.ast.token.TokenNode; import frontend.lexer.Token; import midend.symbol.SymbolManager; import midend.llvm.IrBuilder; import midend.llvm.constant.IrConstantStr; import midend.llvm.instr.GetIntInstr; import midend.llvm.instr.JumpInstr; import midend.llvm.instr.PutIntInstr; import midend.llvm.instr.PutStrInstr; import midend.llvm.instr.ReturnInstr; import midend.llvm.instr.StoreInstr; import midend.llvm.type.IrInterType; import midend.llvm.type.IrType; import midend.llvm.value.IrBasicBlock; import midend.llvm.value.IrValue; import midend.llvm.value.IrLoop; public class VisitorStmt { public static void visitStmt(Stmt stmt) { if (stmt.getChild(0) instanceof LVal) { visitAssign(stmt); } else if (stmt.getChild(0) instanceof Exp || (stmt.getChild(0) instanceof TokenNode && ((TokenNode) stmt.getChild(0)).getValue().equals(";"))) { visitExp(stmt); } else if (stmt.getChild(0) instanceof Block) { visitBlock(stmt); } else if (((TokenNode) stmt.getChild(0)).getValue().equals("if")) { visitIf(stmt); } else if (((TokenNode) stmt.getChild(0)).getValue().equals("for")) { visitFor(stmt); } else if (((TokenNode) stmt.getChild(0)).getValue().equals("break")) { visitBreak(stmt); } else if (((TokenNode) stmt.getChild(0)).getValue().equals("continue")) { visitContinue(stmt); } else if (((TokenNode) stmt.getChild(0)).getValue().equals("return")) { visitReturn(stmt); } else { visitPrintf(stmt); } } public static void visitBlock(Stmt stmt) { Block block = (Block) stmt.getChild(0); VisitorBlock.visitBlock(block); } public static void visitExp(Stmt stmt) { if (stmt.getChild(0) instanceof Exp) { VisitorExp.visitExp((Exp) stmt.getChild(0)); } } public static void visitAssign(Stmt stmt) { if (!stmt.isGetint()) { LVal lval = (LVal) stmt.getChild(0); Exp exp = (Exp) stmt.getChild(2); IrValue lvalIr = VisitorExp.visitLVal(lval, true); IrValue expIr = VisitorExp.visitExp(exp); expIr = IrType.convertType(expIr, IrInterType.INT32); StoreInstr storeInstr = new StoreInstr(expIr, lvalIr); IrBuilder.addInstr(storeInstr); } else { LVal lval = (LVal) stmt.getChild(0); IrValue lvalIr = VisitorExp.visitLVal(lval, true); GetIntInstr getIntInstr = new GetIntInstr(IrBuilder.getLocalName()); IrBuilder.addInstr(getIntInstr); StoreInstr storeInstr = new StoreInstr(getIntInstr, lvalIr); IrBuilder.addInstr(storeInstr); } } public static void visitPrintf(Stmt stmt) { // System.out.println(((TokenNode)stmt.getChild(0)).getValue());//TODO:debug String strconst = ((TokenNode) stmt.getChild(2)).getValue(); ArrayList expList = stmt.getExpList(); ArrayList expIrList = new ArrayList<>(); for (Exp exp : expList) { expIrList.add(VisitorExp.visitExp(exp)); } StringBuilder sb = new StringBuilder(); int expnum = 0; ArrayList printValue = new ArrayList<>(); for (int i = 0; i < strconst.length(); i++) { if (strconst.charAt(i) == '%') { if (!sb.isEmpty() && !sb.toString().equals("\"")) { IrConstantStr str = IrBuilder.getCurrentModule().getStr(sb.toString()); // System.out.println(sb.toString());//TODO:debug if (str == null) { str = new IrConstantStr(sb.toString(), IrBuilder.getStrName()); IrBuilder.addNewStr(str); } printValue.add(str); // 修改为到最后统一输出,而不是立即输出 // PutStrInstr putStrInstr = new PutStrInstr(IrBuilder.getLocalName(), str); // IrBuilder.addInstr(putStrInstr); sb.setLength(0); } else if (sb.toString().equals("\"")) { sb.setLength(0); } IrValue expIr = expIrList.get(expnum++); expIr = IrType.convertType(expIr, IrInterType.INT32); printValue.add(expIr); // 修改为到最后统一输出,而不是立即输出 // PutIntInstr putIntInstr = new PutIntInstr(IrBuilder.getLocalName(), expIr); // IrBuilder.addInstr(putIntInstr); i++; } else { sb.append(strconst.charAt(i)); } } if (!sb.isEmpty() && !sb.toString().equals("\"")) { IrConstantStr str = IrBuilder.getCurrentModule().getStr(sb.toString()); // System.out.println(sb.toString());//TODO:debug if (str == null) { str = new IrConstantStr(sb.toString(), IrBuilder.getStrName()); IrBuilder.addNewStr(str); } printValue.add(str); // 修改为到最后统一输出,而不是立即输出 // PutStrInstr putStrInstr = new PutStrInstr(IrBuilder.getLocalName(), str); // IrBuilder.addInstr(putStrInstr); sb.setLength(0); } for (IrValue irValue : printValue) { if (irValue instanceof IrConstantStr) { PutStrInstr putStrInstr = new PutStrInstr( IrBuilder.getLocalName(), (IrConstantStr) irValue); IrBuilder.addInstr(putStrInstr); } else { PutIntInstr putIntInstr = new PutIntInstr(IrBuilder.getLocalName(), irValue); IrBuilder.addInstr(putIntInstr); } } } public static void visitReturn(Stmt stmt) { IrValue retValue = null; if (stmt.getChild(1) instanceof Exp) { retValue = VisitorExp.visitExp((Exp) stmt.getChild(1)); retValue = IrType.convertType(retValue, IrInterType.INT32); } ReturnInstr returnInstr = new ReturnInstr(retValue); IrBuilder.addInstr(returnInstr); } public static void visitIf(Stmt stmt) { Cond cond = (Cond) stmt.getChild(2); Stmt ifStmt = (Stmt) stmt.getChild(4); if (stmt.getChildren().size() == 7) { IrBasicBlock ifBlock = new IrBasicBlock( IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(ifBlock); IrBasicBlock elseBlock = new IrBasicBlock( IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(elseBlock); VisitorExp.visitCond(cond, ifBlock, elseBlock); // ifblock解析 IrBuilder.setCurrentBBlock(ifBlock); VisitorStmt.visitStmt(ifStmt); IrBasicBlock followBlock = new IrBasicBlock( IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(followBlock); JumpInstr jumpInstr = new JumpInstr(followBlock); IrBuilder.addInstr(jumpInstr); //elseblock解析 IrBuilder.setCurrentBBlock(elseBlock); Stmt elseStmt = (Stmt) stmt.getChild(6); VisitorStmt.visitStmt(elseStmt); jumpInstr = new JumpInstr(followBlock); IrBuilder.addInstr(jumpInstr); //跳转至followblock IrBuilder.setCurrentBBlock(followBlock); } else { IrBasicBlock ifBlock = new IrBasicBlock( IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(ifBlock); IrBasicBlock followBlock = new IrBasicBlock( IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(followBlock); VisitorExp.visitCond(cond, ifBlock, followBlock); IrBuilder.setCurrentBBlock(ifBlock); VisitorStmt.visitStmt(ifStmt); JumpInstr jumpInstr = new JumpInstr(followBlock); IrBuilder.addInstr(jumpInstr); //跳转至followblock IrBuilder.setCurrentBBlock(followBlock); } } public static void visitFor(Stmt stmt) { IrBasicBlock condBB = new IrBasicBlock(IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(condBB); IrBasicBlock bodyBB = new IrBasicBlock(IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(bodyBB); IrBasicBlock stepBB = new IrBasicBlock(IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(stepBB); IrBasicBlock followBB = new IrBasicBlock(IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); IrBuilder.addNewBB(followBB); IrLoop loop = new IrLoop(condBB, bodyBB, stepBB, followBB); IrBuilder.pushLoop(loop); ForStmt initStmt = stmt.getinitStmt(); if (initStmt != null) { VisitorStmt.visitForStmt(initStmt); } JumpInstr jumpInstr = new JumpInstr(condBB); IrBuilder.addInstr(jumpInstr); IrBuilder.setCurrentBBlock(condBB); Cond cond = stmt.getCond(); if (cond != null) { VisitorExp.visitCond(cond, bodyBB, followBB); } else { JumpInstr jumpBody = new JumpInstr(bodyBB); IrBuilder.addInstr(jumpBody); } IrBuilder.setCurrentBBlock(bodyBB); Stmt bodyStmt = stmt.getBodyStmt(); VisitorStmt.visitStmt(bodyStmt); jumpInstr = new JumpInstr(stepBB); IrBuilder.addInstr(jumpInstr); IrBuilder.setCurrentBBlock(stepBB); ForStmt stepStmt = stmt.getStepStmt(); if (stepStmt != null) { VisitorStmt.visitForStmt(stepStmt); } JumpInstr jumpCond = new JumpInstr(condBB); IrBuilder.addInstr(jumpCond); IrBuilder.popLoop(); IrBuilder.setCurrentBBlock(followBB); } /*TODO:此处可能还有问题,循环体和条件、步长表达式等可能不在一个符号表,应该修改,应该比较好改,判断一下stmt是否为block再决定是否last 细想应该不用,如果body是一个block,那visit的时候符号表next,visit完之后符号表还会next,相当于再解析step的时候还是原来的符号表*/ public static void visitForStmt(ForStmt stmt) { ArrayList lvalList = stmt.getLValList(); ArrayList expList = stmt.getExpList(); for (int i = 0; i < lvalList.size(); i++) { LVal lval = lvalList.get(i); Exp exp = expList.get(i); IrValue lvalIr = VisitorExp.visitLVal(lval, true); IrValue expIr = VisitorExp.visitExp(exp); expIr = IrType.convertType(expIr, IrInterType.INT32); StoreInstr storeInstr = new StoreInstr(expIr, lvalIr); IrBuilder.addInstr(storeInstr); } } public static void visitBreak(Stmt stmt) { IrLoop loop = IrBuilder.getCurrentLoop(); IrBasicBlock followBB = loop.getFollowBB(); JumpInstr jumpInstr = new JumpInstr(followBB); IrBuilder.addInstr(jumpInstr); } public static void visitContinue(Stmt stmt) { IrLoop loop = IrBuilder.getCurrentLoop(); IrBasicBlock stepBB = loop.getStepBB(); JumpInstr jumpInstr = new JumpInstr(stepBB); IrBuilder.addInstr(jumpInstr); } }