diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/Compiler.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/Compiler.java index 2af000e..ce7aa93 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/Compiler.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/Compiler.java @@ -4,23 +4,43 @@ import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTree; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.teachfx.antlr4.ep21.ast.ASTNode; +import org.teachfx.antlr4.ep21.ir.IRNode; +import org.teachfx.antlr4.ep21.ir.stmt.Label; import org.teachfx.antlr4.ep21.parser.CymbolLexer; import org.teachfx.antlr4.ep21.parser.CymbolParser; import org.teachfx.antlr4.ep21.pass.ast.CymbolASTBuilder; +import org.teachfx.antlr4.ep21.pass.cfg.CFG; import org.teachfx.antlr4.ep21.pass.cfg.ControlFlowAnalysis; import org.teachfx.antlr4.ep21.pass.codegen.CymbolAssembler; import org.teachfx.antlr4.ep21.pass.ir.CymbolIRBuilder; import org.teachfx.antlr4.ep21.pass.symtab.LocalDefine; +import org.teachfx.antlr4.ep21.utils.StreamUtils; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; +import java.io.*; +import java.util.ArrayList; +import java.util.LinkedList; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; public class Compiler { + private final static Logger logger = LogManager.getLogger(Compiler.class); + protected static void printIRTree(List irNodeList) { + var prettyFormatText = irNodeList.stream().map(irNode -> { + if (irNode instanceof Label) { + return irNode.toString(); + } + return " "+irNode.toString(); + }).reduce((a, b) -> a + "\n" + b); + prettyFormatText.ifPresent(logger::debug); + } + public static void main(String[] args) throws IOException { String fileName = args.length > 0 ? args[0] : (new File("src/main/resources/t.cymbol")).getAbsolutePath(); @@ -31,23 +51,98 @@ public static void main(String[] args) throws IOException { CommonTokenStream tokenStream = new CommonTokenStream(lexer); CymbolParser parser = new CymbolParser(tokenStream); ParseTree parseTree = parser.file(); - CymbolASTBuilder astBuilder = new CymbolASTBuilder("t.cymbol"); + + CymbolASTBuilder astBuilder = new CymbolASTBuilder(); + ASTNode astRoot = parseTree.accept(astBuilder); + astRoot.accept(new LocalDefine()); + var irBuilder = new CymbolIRBuilder(); astRoot.accept(irBuilder); - var dataFlowAnalysis = new ControlFlowAnalysis(); + irBuilder.prog.optimizeBasicBlock(); + + Stream.of( + StreamUtils.indexStream(irBuilder.prog.blockList.stream() + .map(irBuilder::getCFG)) + .peek(cfgPair -> { + var cfg = cfgPair.getRight(); + var idx = cfgPair.getLeft(); + saveToEp20Res(cfg.toString(), "%d_origin".formatted(idx)); + cfg.addOptimizer(new ControlFlowAnalysis<>()); + cfg.applyOptimizers(); + saveToEp20Res(cfg.toString(), "%d_optimized".formatted(idx)); + }) + .map(Pair::getRight) + .map(CFG::getIRNodes) + .reduce(new ArrayList(), (a, b) -> { + a.addAll(b); + return a; + }) + ) + .map(irNodeList -> { + var assembler = new CymbolAssembler(); + assembler.visit(irNodeList); + return assembler; + }) + .forEach(assembler -> { + saveToEp18Res(assembler.getAsmInfo()); + logger.debug("\n%s".formatted(assembler.getAsmInfo())); + }); + } + + protected static void saveToEp18Res(String buffer) { + String modulePath = "../ep18/src/main/resources"; // 替换 "my-module" 为你的模块名称 + File moduleDirectory = new File(modulePath); + logger.debug("file path %s".formatted(moduleDirectory.getAbsolutePath())); + if (moduleDirectory.exists()) { + logger.debug("模块路径:" + moduleDirectory.getAbsolutePath()); + var filePath = modulePath+"/t.vm"; + File file = new File(filePath); + try (var outputStream = new FileOutputStream(file)) { + if (!file.exists()) { + var res = file.createNewFile(); + logger.debug("create file %s is %b".formatted(filePath,res)); + } + outputStream.write(buffer.getBytes()); + + } catch (IOException e) { + throw new RuntimeException(e); + } + + } else { + logger.error("模块路径不存在!"); + } + } - var assembler = new CymbolAssembler(); + protected static void saveToEp20Res(String buffer,String suffix) { + String modulePath = "./src/main/resources"; // 替换 "my-module" 为你的模块名称 + File moduleDirectory = new File(modulePath); + logger.debug("file path %s".formatted(moduleDirectory.getAbsolutePath())); + if (moduleDirectory.exists()) { + logger.debug("模块路径:" + moduleDirectory.getAbsolutePath()); + var filePath = modulePath+"/graph_%s.md".formatted(suffix); + File file = new File(filePath); + try (var outputStream = new FileOutputStream(file)) { + if (!file.exists()) { + var res = file.createNewFile(); + logger.debug("create file %s is %b".formatted(filePath,res)); + } + String template = """ + ```mermaid + %s + ``` + """.formatted(buffer); + outputStream.write(template.getBytes()); - List.of(dataFlowAnalysis,assembler).forEach(irBuilder.root::accept); + } catch (IOException e) { + throw new RuntimeException(e); + } - System.out.println(assembler.flushCode()); - var url = Compiler.class.getClassLoader().getResource("t.vm"); - System.out.println(">>>=" + new File(".").getAbsolutePath()); - assembler.saveToFile("src/main/resources/t.vm"); - assembler.saveToFile("../ep18/src/main/resources/t.vm"); + } else { + logger.error("模块路径不存在!"); + } } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTNode.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTNode.java index efde85c..dcf2b96 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTNode.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/ASTNode.java @@ -39,5 +39,10 @@ public void dump(Dumper d) { } abstract protected void _dump(Dumper d); + + @Override + public String toString() { + return ctx.getText(); + } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/CompileUnit.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/CompileUnit.java index a8fbb2c..43760ec 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/CompileUnit.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/CompileUnit.java @@ -9,7 +9,6 @@ import java.util.List; public class CompileUnit extends ASTNode { - private String srcName; public void addFuncDecl(FuncDeclNode funcDecl) { this.funcDeclarations.add(funcDecl); @@ -29,9 +28,7 @@ public CompileUnit(List varDeclarations, List funcDec this.ctx = ctx; } - public CompileUnit(String srcName) { - this.srcName = srcName; - } + public CompileUnit() {} public List getVarDeclarations() { return varDeclarations; @@ -56,14 +53,6 @@ protected void _dump(Dumper d) { d.printNodeList("funcDecl",funcDeclarations); } - public String getSrcName() { - return srcName; - } - - public void setSrcName(String srcName) { - this.srcName = srcName; - } - @Override public void accept(ASTVisitor visitor) { visitor.visit(this); diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/decl/VarDeclNode.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/decl/VarDeclNode.java index ae7b6e5..5ec9380 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/decl/VarDeclNode.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/decl/VarDeclNode.java @@ -3,12 +3,15 @@ import org.antlr.v4.runtime.ParserRuleContext; import org.teachfx.antlr4.ep21.ast.ASTVisitor; import org.teachfx.antlr4.ep21.ast.expr.ExprNode; +import org.teachfx.antlr4.ep21.ast.expr.IDExprNode; import org.teachfx.antlr4.ep21.debugger.ast.Dumper; import org.teachfx.antlr4.ep21.symtab.symbol.VariableSymbol; import java.util.Objects; public class VarDeclNode extends DeclNode { + private IDExprNode idExprNode; + private ExprNode assignExprNode; public ExprNode initializerExpr() { @@ -20,10 +23,11 @@ public boolean hasInitializer() { } - public VarDeclNode(VariableSymbol variableSymbol,ExprNode assignExprNode, ParserRuleContext ctx) { + public VarDeclNode(VariableSymbol variableSymbol,ExprNode assignExprNode,IDExprNode idExprNode, ParserRuleContext ctx) { this.refSymbol = variableSymbol; this.assignExprNode = assignExprNode; this.ctx = ctx; + this.idExprNode = idExprNode; this.declName = variableSymbol.getName(); } @@ -52,4 +56,12 @@ protected void _dump(Dumper d) { d.printMember("type",getRefSymbol().getType()); if (Objects.nonNull(assignExprNode)) d.printMember("assignee",assignExprNode); } + + public IDExprNode getIdExprNode() { + return idExprNode; + } + + public void setIdExprNode(IDExprNode idExprNode) { + this.idExprNode = idExprNode; + } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/expr/IDExprNode.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/expr/IDExprNode.java index f2924b2..9592412 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/expr/IDExprNode.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/expr/IDExprNode.java @@ -13,12 +13,21 @@ public class IDExprNode extends ExprNode { protected Symbol refSymbol; + protected boolean isVal = false; + public IDExprNode(String image,ParserRuleContext ctx) { this.image = image; this.ctx = ctx; } + public boolean isLValue() { + return isVal; + } + + public void setLValue(boolean isVal) { + this.isVal = isVal; + } public Symbol getRefSymbol() { return refSymbol; diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/stmt/IfStmtNode.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/stmt/IfStmtNode.java index 6fd213d..156c252 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/stmt/IfStmtNode.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ast/stmt/IfStmtNode.java @@ -21,7 +21,7 @@ public IfStmtNode(ExprNode exprNode, StmtNode then, StmtNode elseBlock, ParserRu this.ctx = ctx; } - public ExprNode getConditionalNode() { + public ExprNode getCondExpr() { return conditionalNode; } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/driver/Phase.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/driver/Phase.java index 4bad0f5..f7feb51 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/driver/Phase.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/driver/Phase.java @@ -3,7 +3,6 @@ import java.util.Optional; public abstract class Phase implements Task,ErrorIssuer { - public final String name; public Phase(String name) { diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/IRVisitor.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/IRVisitor.java index 1a76244..5ad2164 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/IRVisitor.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/IRVisitor.java @@ -1,23 +1,14 @@ package org.teachfx.antlr4.ep21.ir; -import org.teachfx.antlr4.ep21.ir.def.Func; -import org.teachfx.antlr4.ep21.ir.expr.ArrayAccessExpr; import org.teachfx.antlr4.ep21.ir.expr.CallFunc; -import org.teachfx.antlr4.ep21.ir.expr.ClassAccessExpr; -import org.teachfx.antlr4.ep21.ir.expr.Temp; +import org.teachfx.antlr4.ep21.ir.expr.addr.FrameSlot; +import org.teachfx.antlr4.ep21.ir.expr.addr.OperandSlot; import org.teachfx.antlr4.ep21.ir.expr.arith.BinExpr; import org.teachfx.antlr4.ep21.ir.expr.arith.UnaryExpr; -import org.teachfx.antlr4.ep21.ir.expr.values.BoolVal; -import org.teachfx.antlr4.ep21.ir.expr.values.IntVal; -import org.teachfx.antlr4.ep21.ir.expr.values.StringVal; -import org.teachfx.antlr4.ep21.ir.expr.values.Var; +import org.teachfx.antlr4.ep21.ir.expr.val.ConstVal; import org.teachfx.antlr4.ep21.ir.stmt.*; public interface IRVisitor { - /// Expr - E visit(IntVal node); - E visit(BoolVal node); - E visit(StringVal node); E visit(BinExpr node); @@ -30,22 +21,18 @@ public interface IRVisitor { S visit(CJMP cjmp); S visit(Assign assign); - S visit(Func func); - - E visit(Var var); - - E visit(ClassAccessExpr classAccessExpr); - - E visit(ArrayAccessExpr arrayAccessExpr); - default S visit(Stmt stmt) { return stmt.accept(this);} S visit(ReturnVal returnVal); - S visit(ExprStmt exprStmt); + default S visit(ExprStmt exprStmt) { return exprStmt.accept(this); } + + default S visit(Prog prog) { return null; } + + E visit(OperandSlot operandSlot); - S visit(Prog prog); + E visit(FrameSlot frameSlot); - E visit(Temp temp); + E visit(ConstVal tConstVal); /// Stmt diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/JMPInstr.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/JMPInstr.java new file mode 100644 index 0000000..7fcc6eb --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/JMPInstr.java @@ -0,0 +1,7 @@ +package org.teachfx.antlr4.ep21.ir; + +import org.teachfx.antlr4.ep21.ir.stmt.Label; + +public interface JMPInstr { + public Label getTarget(); +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/Prog.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/Prog.java index f8d0e1d..3e28037 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/Prog.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/Prog.java @@ -1,16 +1,25 @@ package org.teachfx.antlr4.ep21.ir; -import org.teachfx.antlr4.ep21.ir.def.Func; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.jetbrains.annotations.NotNull; +import org.teachfx.antlr4.ep21.ir.stmt.CJMP; +import org.teachfx.antlr4.ep21.ir.stmt.FuncEntryLabel; +import org.teachfx.antlr4.ep21.ir.stmt.JMP; +import org.teachfx.antlr4.ep21.ir.stmt.Label; +import org.teachfx.antlr4.ep21.pass.cfg.LinearIRBlock; + +import java.util.*; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; public class Prog extends IRNode { - public List defuncList; + public List blockList; + protected static Logger logger = LogManager.getLogger(Prog.class); + public List instrs = new ArrayList<>(); - public Prog(List stmts) { - this.defuncList = Objects.isNull(stmts) ? new ArrayList<>() : stmts; + private final List truncateInstrList = new LinkedList<>(); + public Prog() { + this.blockList = new ArrayList<>() ; } public S accept(IRVisitor visitor){ @@ -18,10 +27,111 @@ public S accept(IRVisitor visitor){ return visitor.visit(this); } - public void addFunc(Func func) { - if (Objects.isNull(defuncList)) - defuncList = List.of(func); - else if (!defuncList.contains(func) && func != null) - defuncList.add(func); + public void addBlock(LinearIRBlock linearIRBlock) { + blockList.add(linearIRBlock); + } + protected TreeSet needRemovedBlocks = new TreeSet<>(); + + private void optimizeEmptyBlock(@NotNull LinearIRBlock linearIRBlock) { + // replace empty block within non-empty first successor + if (linearIRBlock.getStmts().isEmpty()){ + // Drop empty block + if (linearIRBlock.getSuccessors().isEmpty()) { + logger.debug("Block %s will be removed".formatted(linearIRBlock)); + needRemovedBlocks.add(linearIRBlock); + return; + } + // Auto-fill next block for jmp/cjmp + var nextBlock = linearIRBlock.getSuccessors().get(0); + for (var ref : linearIRBlock.getJmpRefMap()){ + if (ref instanceof JMP jmp) { + logger.debug(" %s is next for %s".formatted(nextBlock,linearIRBlock)); + jmp.setNext(nextBlock); + + } else if (ref instanceof CJMP cjmp) { + logger.debug(" %s is else-case for %s".formatted(nextBlock,linearIRBlock)); + cjmp.setElseBlock(nextBlock); + } + } + + linearIRBlock.getPredecessors().forEach(prev -> { + prev.removeSuccessor(linearIRBlock); + prev.getSuccessors().add(nextBlock); + }); + + needRemovedBlocks.add(linearIRBlock); + } + + // recursive call + for(var successor : linearIRBlock.getSuccessors()){ + optimizeEmptyBlock(successor); + } + } + + private void insertLabelForBlock(LinearIRBlock startBlock) { + for (var stmt : startBlock.getStmts()) { + if (stmt instanceof Label) { + break; + } + + startBlock.insertStmt(new Label(startBlock.getScope(), startBlock.getOrd()),0); + break; // only insert one label for each block which is not func-entry block. + } + + for (var successor : startBlock.getSuccessors()) { + insertLabelForBlock(successor); + } + } + protected void buildInstrs(LinearIRBlock block) { + instrs.addAll(block.getStmts()); + + for (var successor : block.getSuccessors()) { + buildInstrs(successor); + } + + } + + public void optimizeBasicBlock() { + for(var func : blockList) { + optimizeEmptyBlock(func); + } + + for( var emptyBlock : needRemovedBlocks) { + emptyBlock.getPredecessors().forEach(p -> p.removeSuccessor(emptyBlock)); + } + + for(var func : blockList) { + insertLabelForBlock(func); + } + } + + public List linearInstrs() { + + if (!truncateInstrList.isEmpty()){ + return truncateInstrList; + } + + for(var func : blockList) { + buildInstrs(func); + } + + IRNode prev; + IRNode cur = null; + + for (IRNode instr : instrs) { + prev = cur; + cur = instr; + if (Objects.nonNull(prev) && prev instanceof Label) { + if (cur instanceof FuncEntryLabel) { + truncateInstrList.remove(prev); + } + } + + truncateInstrList.add(cur); + } + + return truncateInstrList; } + + } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/def/Define.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/def/Define.java deleted file mode 100644 index bd9cfad..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/def/Define.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.def; - -import org.teachfx.antlr4.ep21.ir.IRNode; -import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.symtab.symbol.Symbol; - -public abstract class Define extends IRNode { - public Symbol symbol; - - public abstract String getDeclName(); - - //IR Visitor - public abstract S accept(IRVisitor visitor); - - - -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/def/Func.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/def/Func.java deleted file mode 100644 index 927c1c2..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/def/Func.java +++ /dev/null @@ -1,67 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.def; - -import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.stmt.ReturnVal; -import org.teachfx.antlr4.ep21.ir.stmt.Stmt; -import org.teachfx.antlr4.ep21.symtab.symbol.MethodSymbol; - -import java.util.List; - -public class Func extends Define { - /// filed - public String funcName; - private int locals; - public List body; - public ReturnVal retHook; - - public Func(String funcName, MethodSymbol symbol , List body) { - // init - this.funcName = funcName; - this.symbol = symbol; - this.body = body; - } - - public String getFuncName() { - return funcName; - } - - public void setFuncName(String funcName) { - this.funcName = funcName; - } - - public int getArgs() { - return getFuncSymbol().getMembers().size(); - } - protected MethodSymbol getFuncSymbol() { - return (MethodSymbol)symbol; - } - public int getLocals() { - return locals; - } - - public void setLocals(int locals) { - this.locals = locals; - } - - public List getBody() { - return body; - } - - public void setBody(List body) { - this.body = body; - } - - @Override - public String getDeclName() { - return getFuncName(); - } - - @Override - public S accept(IRVisitor visitor) { - return visitor.visit(this); - } - - public String toSource() { - return ".def %s: args=%d ,locals=%d".formatted(getFuncName(), getFuncSymbol().getArgs(),getFuncSymbol().getMembers().size() - getFuncSymbol().getArgs()); - } -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ArrayAccessExpr.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ArrayAccessExpr.java deleted file mode 100644 index 6d4d312..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ArrayAccessExpr.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.expr; - - -import org.teachfx.antlr4.ep21.ir.IRVisitor; - -public class ArrayAccessExpr extends Expr { - - private Expr arrayExpr; - private Expr indexExpr; - - public Expr getArrayExpr() { - return arrayExpr; - - } - - public Expr getIndexExpr() { - return indexExpr; - } - - @Override - public E accept(IRVisitor visitor) { - return visitor.visit(this); - } -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/CallFunc.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/CallFunc.java index 7e71a8f..b81b01e 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/CallFunc.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/CallFunc.java @@ -2,37 +2,41 @@ import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.values.Var; - -import java.util.List; - -public class CallFunc extends Expr{ - protected List args; - protected Var funcExpr; - - public CallFunc(Var funcExpr,List args) { - this.funcExpr = funcExpr; +import org.teachfx.antlr4.ep21.symtab.symbol.MethodSymbol; + +public class CallFunc extends Expr { + protected MethodSymbol funcType; + protected String funcName; + protected int args; + public CallFunc(String funcName,int args,MethodSymbol funcType) { + this.funcName = funcName; this.args = args; + this.funcType = funcType; } - public Var getFuncExpr() { - return funcExpr; + public String getFuncName() { + return funcName; } - public void setFuncExpr(Var funcExpr) { - this.funcExpr = funcExpr; + public void setFuncName(String funcName) { + this.funcName = funcName; } - public List getArgs() { + public int getArgs() { return args; } - public void setArgs(List args) { - this.args = args; + public MethodSymbol getFuncType() { + return funcType; } @Override public E accept(IRVisitor visitor) { return visitor.visit(this); } + + @Override + public String toString() { + return "call " + funcName + "(args:" + args + ")"; + } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ClassAccessExpr.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ClassAccessExpr.java deleted file mode 100644 index d4b8e37..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ClassAccessExpr.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.expr; - -import org.teachfx.antlr4.ep21.ir.IRVisitor; - -public class ClassAccessExpr extends Expr -{ - private Expr expr; - private String name; - - public ClassAccessExpr(Expr expr, String name) { - this.expr = expr; - this.name = name; - } - - @Override - public E accept(IRVisitor visitor) { - return visitor.visit(this); - } - - @Override - public String toString() - { - return "ClassAccessExpr [expr=" + expr + ", name=" + name + "]"; - } -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Expr.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Expr.java index e6dae6b..50c0ae9 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Expr.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Expr.java @@ -4,6 +4,5 @@ import org.teachfx.antlr4.ep21.ir.IRVisitor; public abstract class Expr extends IRNode { - - abstract public E accept(IRVisitor visitor); + public abstract E accept(IRVisitor visitor); } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ImmValue.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ImmValue.java new file mode 100644 index 0000000..21724a7 --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/ImmValue.java @@ -0,0 +1,5 @@ +package org.teachfx.antlr4.ep21.ir.expr; + +public abstract class ImmValue extends Operand { + +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Operand.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Operand.java new file mode 100644 index 0000000..aadc5e8 --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Operand.java @@ -0,0 +1,7 @@ +package org.teachfx.antlr4.ep21.ir.expr; + +import org.teachfx.antlr4.ep21.ir.IRVisitor; + +public abstract class Operand extends Expr { + abstract public E accept(IRVisitor visitor); +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Temp.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Temp.java deleted file mode 100644 index 73e5fc5..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/Temp.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.expr; - -import org.teachfx.antlr4.ep21.ir.IRVisitor; - -public class Temp extends Expr{ - - public Temp() { - super(); - } - - @Override - public E accept(IRVisitor visitor) { - return visitor.visit(this); - } -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/VarSlot.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/VarSlot.java new file mode 100644 index 0000000..7a4104e --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/VarSlot.java @@ -0,0 +1,5 @@ +package org.teachfx.antlr4.ep21.ir.expr; + +public abstract class VarSlot extends Operand { + +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/addr/FrameSlot.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/addr/FrameSlot.java new file mode 100644 index 0000000..df52619 --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/addr/FrameSlot.java @@ -0,0 +1,31 @@ +package org.teachfx.antlr4.ep21.ir.expr.addr; + +import org.teachfx.antlr4.ep21.ir.IRVisitor; +import org.teachfx.antlr4.ep21.ir.expr.VarSlot; +import org.teachfx.antlr4.ep21.symtab.symbol.VariableSymbol; + +public class FrameSlot extends VarSlot { + + protected int slotIdx = 0; + + public static FrameSlot get(VariableSymbol variableSymbol) { + return new FrameSlot(variableSymbol.getSlotIdx()); + } + + public FrameSlot(int idx) { + this.slotIdx = idx; + } + public int getSlotIdx() { + return slotIdx; + } + + @Override + public E accept(IRVisitor visitor) { + return visitor.visit(this); + } + + @Override + public String toString() { + return "@%d".formatted(slotIdx); + } +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/addr/OperandSlot.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/addr/OperandSlot.java new file mode 100644 index 0000000..7f02e80 --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/addr/OperandSlot.java @@ -0,0 +1,38 @@ +package org.teachfx.antlr4.ep21.ir.expr.addr; + +import org.teachfx.antlr4.ep21.ir.IRVisitor; +import org.teachfx.antlr4.ep21.ir.expr.VarSlot; + +public class OperandSlot extends VarSlot { + private static int ordSeq = 0; + + public static OperandSlot genTemp() { + return new OperandSlot(); + } + + private int ord = 0; + private OperandSlot() { + this.ord = OperandSlot.ordSeq++; + } + public int getOrd() { + return ord; + } + + @Override + public String toString() { + return "t"+ ord ; + } + + @Override + public E accept(IRVisitor visitor) { + return visitor.visit(this); + } + + + public static OperandSlot pushStack() { return OperandSlot.genTemp(); } + public static void popStack() { ordSeq--;} + + public static int getOrdSeq() { + return ordSeq; + } +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/BinExpr.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/BinExpr.java index b1cb851..0d57743 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/BinExpr.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/BinExpr.java @@ -2,33 +2,35 @@ import org.teachfx.antlr4.ep21.ir.IRVisitor; import org.teachfx.antlr4.ep21.ir.expr.Expr; +import org.teachfx.antlr4.ep21.ir.expr.Operand; +import org.teachfx.antlr4.ep21.ir.expr.VarSlot; import org.teachfx.antlr4.ep21.symtab.type.OperatorType; public class BinExpr extends Expr { - protected Expr lhs; - protected Expr rhs; + protected VarSlot lhs; + protected VarSlot rhs; protected OperatorType.BinaryOpType opType; - public BinExpr(OperatorType.BinaryOpType op, Expr left, Expr right) { + public BinExpr(OperatorType.BinaryOpType op, VarSlot left, VarSlot right) { this.opType = op; this.lhs = left; this.rhs = right; } - public Expr getLhs() { + public VarSlot getLhs() { return lhs; } - public void setLhs(Expr lhs) { + public void setLhs(VarSlot lhs) { this.lhs = lhs; } - public Expr getRhs() { + public VarSlot getRhs() { return rhs; } - public void setRhs(Expr rhs) { + public void setRhs(VarSlot rhs) { this.rhs = rhs; } @@ -42,11 +44,17 @@ public void setOpType(OperatorType.BinaryOpType opType) { @Override public String toString() { - return "BinaryExpr"; + return "%s %s %s".formatted(lhs,opType,rhs); } @Override public E accept(IRVisitor visitor) { return visitor.visit(this); } + + public static BinExpr with(OperatorType.BinaryOpType opType,VarSlot lhs,VarSlot rhs) { + return new BinExpr(opType,lhs,rhs); + } + + } \ No newline at end of file diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/UnaryExpr.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/UnaryExpr.java index bc037a2..6e28025 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/UnaryExpr.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/arith/UnaryExpr.java @@ -2,13 +2,15 @@ import org.teachfx.antlr4.ep21.ir.IRVisitor; import org.teachfx.antlr4.ep21.ir.expr.Expr; +import org.teachfx.antlr4.ep21.ir.expr.VarSlot; +import org.teachfx.antlr4.ep21.symtab.type.OperatorType; import org.teachfx.antlr4.ep21.symtab.type.OperatorType.UnaryOpType; public class UnaryExpr extends Expr { public UnaryOpType op; - public Expr expr; - public UnaryExpr(UnaryOpType op, Expr expr) { + public VarSlot expr; + public UnaryExpr(UnaryOpType op, VarSlot expr) { this.op = op; this.expr = expr; } @@ -17,4 +19,13 @@ public UnaryExpr(UnaryOpType op, Expr expr) { public E accept(IRVisitor visitor) { return visitor.visit(this); } + + public static UnaryExpr with(OperatorType.UnaryOpType opType, VarSlot operand) { + return new UnaryExpr(opType,operand); + } + + @Override + public String toString() { + return "%s %s".formatted(op,expr); + } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/val/ConstVal.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/val/ConstVal.java new file mode 100644 index 0000000..2cf9b42 --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/val/ConstVal.java @@ -0,0 +1,42 @@ +package org.teachfx.antlr4.ep21.ir.expr.val; + +import org.teachfx.antlr4.ep21.ir.IRVisitor; +import org.teachfx.antlr4.ep21.ir.expr.ImmValue; + +public class ConstVal extends ImmValue { + private T val; + + public ConstVal(T val) { + this.val = val; + } + + public static ConstVal valueOf(T val) { + return new ConstVal<>(val); + } + + @Override + public E accept(IRVisitor visitor) { + return visitor.visit(this); + } + + public T getVal() { + return val; + } + + public void setVal(T val) { + this.val = val; + } + + @Override + public String toString() { + if(val instanceof String) { + return " '%s' ".formatted(val); + } else if (val instanceof Integer) { + return " %d ".formatted(val); + } else if (val instanceof Boolean) { + return " %b ".formatted(val); + } + + return "val(%s)".formatted(val.toString()); + } +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/BoolVal.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/BoolVal.java deleted file mode 100644 index f9105c7..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/BoolVal.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.expr.values; - -import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.Expr; - -public class BoolVal extends Expr { - public boolean value; - - @Override - public E accept(IRVisitor visitor) { - return visitor.visit(this); - } - - public BoolVal(boolean value) { - this.value = value; - } - - @Override - public String toString() { - return "BoolVal(" + value + ")"; - } - -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/IntVal.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/IntVal.java deleted file mode 100644 index 9435b4e..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/IntVal.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.expr.values; - -import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.Expr; - -public class IntVal extends Expr { - - public int value; - - public IntVal(int value) { - this.value = value; - } - - @Override - public String toString() { - return "IntVal [value=" + value + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + value; - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - IntVal other = (IntVal) obj; - if (value != other.value) - return false; - return true; - } - - @Override - public E accept(IRVisitor visitor) { - return visitor.visit(this); - } -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/StringVal.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/StringVal.java deleted file mode 100644 index bd8bdaa..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/StringVal.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.expr.values; - -import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.Expr; - -public class StringVal extends Expr { - public String value; - - - public StringVal(String value) { - this.value = value; - } - - @Override - public String toString() { - return "StringVal [value=" + value + "]"; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((value == null) ? 0 : value.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - StringVal other = (StringVal) obj; - if (value == null) { - if (other.value != null) - return false; - } else if (!value.equals(other.value)) - return false; - return true; - } - - @Override - public E accept(IRVisitor visitor) { - return visitor.visit(this); - } -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/Var.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/Var.java deleted file mode 100644 index c51e059..0000000 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/expr/values/Var.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.teachfx.antlr4.ep21.ir.expr.values; - -import org.teachfx.antlr4.ep21.ast.stmt.ScopeType; -import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.Expr; -import org.teachfx.antlr4.ep21.symtab.symbol.Symbol; - -public class Var extends Expr { - public Symbol symbol; - - private ScopeType scopeType; - - public Var(Symbol varSymbol) { - this.symbol = varSymbol; - this.scopeType = ScopeType.FuncScope; - } - - public String getDeclName() { - return symbol.getName(); - } - - public Symbol getSymbol() { - return symbol; - } - - public void setSymbol(Symbol symbol) { - this.symbol = symbol; - } - - public ScopeType getScopeType() { - return scopeType; - } - - public void setScopeType(ScopeType scopeType) { - this.scopeType = scopeType; - } - @Override - public E accept(IRVisitor visitor) { - return visitor.visit(this); - } - public String toSource(boolean isWriting) { - int varSlotIdx = symbol.getSlotIdx(); - String operator = ""; - switch ( scopeType) { - /// Generate all cases for scopeType - case ClassScope -> { - operator =isWriting ? "xload" : "xstore"; - } - case GlobalScope -> { - operator = isWriting? "gload": "gstore"; - } - default -> { - operator = isWriting? "load" : "store"; - } - } - return String.format("%s %d", operator, varSlotIdx); - } -} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Assign.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Assign.java index f6b2a84..b9e5fe0 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Assign.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Assign.java @@ -1,31 +1,50 @@ package org.teachfx.antlr4.ep21.ir.stmt; import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.Expr; -import org.teachfx.antlr4.ep21.ir.expr.values.Var; +import org.teachfx.antlr4.ep21.ir.expr.Operand; +import org.teachfx.antlr4.ep21.ir.expr.VarSlot; public class Assign extends Stmt { - protected Var lhs; - protected Expr rhs; + protected VarSlot lhs; + protected Operand rhs; - public Assign(Var lhs, Expr rhs) { + /** + * Assign a value to a variable + * @param lhs Variable to assign + * @param rhs Value to assign + * @return Assign object + */ + @SuppressWarnings("unused") // Used in generated code. + public static Assign with(VarSlot lhs,VarSlot rhs) { + return new Assign(lhs,rhs); + } + /** + * Assign a value to a variable + * @param lhs Variable to assign + * @param rhs Value to assign + * @return Assign object + */ + public static Assign with(VarSlot lhs, Operand rhs) { + return new Assign(lhs,rhs); + } + public Assign(VarSlot lhs, Operand rhs) { this.lhs = lhs; this.rhs = rhs; } // Generate getter and setter for lhs and rhs - public Var getLhs() { + public VarSlot getLhs() { return lhs; } - public Expr getRhs() { + public Operand getRhs() { return rhs; } - public void setLhs(Var lhs) { + public void setLhs(VarSlot lhs) { this.lhs = lhs; } - public void setRhs(Expr rhs) { + public void setRhs(VarSlot rhs) { this.rhs = rhs; } @@ -38,4 +57,9 @@ public S accept(IRVisitor visitor) { public StmtType getStmtType() { return StmtType.ASSIGN; } + + @Override + public String toString() { + return "%s = %s".formatted(getLhs(),getRhs()); + } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/CJMP.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/CJMP.java index 1e8d4bf..40d89fe 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/CJMP.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/CJMP.java @@ -1,19 +1,28 @@ package org.teachfx.antlr4.ep21.ir.stmt; +import org.jetbrains.annotations.NotNull; import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.Expr; +import org.teachfx.antlr4.ep21.ir.JMPInstr; +import org.teachfx.antlr4.ep21.ir.expr.VarSlot; +import org.teachfx.antlr4.ep21.pass.cfg.LinearIRBlock; -public class CJMP extends Stmt { - public Expr cond; +public class CJMP extends Stmt implements JMPInstr { + public VarSlot cond; + private LinearIRBlock thenBlock; + private LinearIRBlock elseBlock; - public Label thenLabel; - public Label elseLabel; - - public CJMP(Expr cond,Label thenLabel,Label elseLabel) { + public CJMP(@NotNull VarSlot cond, @NotNull LinearIRBlock thenLabel,@NotNull LinearIRBlock elseLabel) { this.cond = cond; - this.thenLabel = thenLabel; - this.elseLabel = elseLabel; + this.thenBlock = thenLabel; + this.elseBlock = elseLabel; + thenLabel.refJMP(this); + elseBlock.refJMP(this); + } + + @Override + public Label getTarget() { + return elseBlock.getLabel(); } @Override @@ -25,4 +34,27 @@ public S accept(IRVisitor visitor) { public StmtType getStmtType() { return StmtType.CJMP; } + + @Override + public String toString() { + return "jmpIf %s,%s,%s".formatted(cond,thenBlock,elseBlock); + } + + public void setElseBlock(LinearIRBlock elseBlock) { + this.elseBlock = elseBlock; + elseBlock.refJMP(this); + } + + public void setThenBlock(LinearIRBlock thenBlock) { + this.thenBlock = thenBlock; + thenBlock.refJMP(this); + } + + public LinearIRBlock getElseBlock() { + return elseBlock; + } + + public LinearIRBlock getThenBlock() { + return thenBlock; + } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/ExprStmt.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/ExprStmt.java index 5246f0b..39f5dec 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/ExprStmt.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/ExprStmt.java @@ -1,27 +1,27 @@ package org.teachfx.antlr4.ep21.ir.stmt; import org.teachfx.antlr4.ep21.ir.IRVisitor; -import org.teachfx.antlr4.ep21.ir.expr.Expr; +import org.teachfx.antlr4.ep21.ir.expr.VarSlot; public class ExprStmt extends Stmt { - private Expr expr; - public ExprStmt(Expr expr) + private VarSlot varSlot; + public ExprStmt(VarSlot varSlot) { - this.expr = expr; + this.varSlot = varSlot; } @Override public String toString() { - return expr.toString(); + return varSlot.toString(); } - public Expr getExpr() { - return expr; + public VarSlot getExpr() { + return varSlot; } - public void setExpr(Expr expr) { - this.expr = expr; + public void setExpr(VarSlot varSlot) { + this.varSlot = varSlot; } @Override diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/FuncEntryLabel.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/FuncEntryLabel.java new file mode 100644 index 0000000..756e640 --- /dev/null +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/FuncEntryLabel.java @@ -0,0 +1,21 @@ +package org.teachfx.antlr4.ep21.ir.stmt; + +import org.teachfx.antlr4.ep21.symtab.scope.Scope; + +public class FuncEntryLabel extends Label{ + + public FuncEntryLabel(String funcName,int args,int locals, Scope scope) { + super(".def %s: args=%d ,locals=%d".formatted(funcName,args,locals), scope); + } + + + @Override + public String toSource() { + return getRawLabel(); + } + + @Override + public String toString() { + return getRawLabel(); + } +} diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/JMP.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/JMP.java index 409d707..edc02d6 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/JMP.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/JMP.java @@ -1,22 +1,45 @@ package org.teachfx.antlr4.ep21.ir.stmt; +import org.jetbrains.annotations.NotNull; import org.teachfx.antlr4.ep21.ir.IRVisitor; +import org.teachfx.antlr4.ep21.ir.JMPInstr; +import org.teachfx.antlr4.ep21.pass.cfg.LinearIRBlock; -public class JMP extends Stmt +public class JMP extends Stmt implements JMPInstr { @Override public S accept(IRVisitor visitor) { return visitor.visit(this); } - public JMP(Label label) + public JMP(@NotNull LinearIRBlock block) { - this.label = label; + this.next = block; + block.refJMP(this); + } + private LinearIRBlock next; + + @Override + public Label getTarget() { + return next.getLabel(); } - public Label label; @Override public StmtType getStmtType() { return StmtType.JMP; } + + @Override + public String toString() { + return "jmp %s".formatted(next); + } + + public void setNext(LinearIRBlock next) { + this.next = next; + next.refJMP(this); + } + + public LinearIRBlock getNext() { + return this.next; + } } diff --git a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Label.java b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Label.java index 04c32b5..79c185c 100644 --- a/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Label.java +++ b/ep21/src/main/java/org/teachfx/antlr4/ep21/ir/stmt/Label.java @@ -1,14 +1,18 @@ package org.teachfx.antlr4.ep21.ir.stmt; +import org.jetbrains.annotations.NotNull; import org.teachfx.antlr4.ep21.ir.IRVisitor; import org.teachfx.antlr4.ep21.symtab.scope.Scope; import java.util.Objects; -public class Label extends Stmt { +public class Label extends Stmt implements Comparable