diff --git a/Compiler.java b/Compiler.java old mode 100644 new mode 100755 index 22f7088..6e9e055 --- a/Compiler.java +++ b/Compiler.java @@ -1,42 +1,48 @@ -import java.nio.file.Files; -import java.nio.file.Paths; -import frontend.lexer.Lexer; -import frontend.lexer.TokenStream; -import frontend.parser.Parser; -import midend.Midend; -import midend.errorhandle.ErrorHandler; - -import error.Errors; -import midend.symbol.SymbolManager; - -public class Compiler { - public static void main(String[] args) { - Errors errors = new Errors(); - try { - String content = new String(Files.readAllBytes(Paths.get("testfile.txt"))); - String llvmFile = "llvm_ir.txt"; - String errorFile = "error.txt"; - Lexer lexer = new Lexer(content); - lexer.lex(errors); - TokenStream ts = new TokenStream(lexer.getTokens()); - Parser parser = new Parser(ts); - parser.parse(errors); - ErrorHandler errorHandler = new ErrorHandler(parser.getCompUnit()); - errorHandler.visit(errors); - // for (int i : SymbolManager.getSequence()) { - // System.out.print(i + " "); - // } - // System.out.println(); // TODO:debug - if (errors.size() > 0) { - StringBuilder sb = errors.toStringBuilder(); - Files.write(Paths.get(errorFile), sb.toString().getBytes()); - } else { - Midend midend = new Midend(parser.getCompUnit()); - midend.generateLLvmIr(); - midend.writeToFile(llvmFile); - } - } catch (Exception e) { - e.printStackTrace(); - } - } -} +import java.nio.file.Files; +import java.nio.file.Paths; + +import backend.BackEnd; +import frontend.lexer.Lexer; +import frontend.lexer.TokenStream; +import frontend.parser.Parser; +import midend.Midend; +import midend.errorhandle.ErrorHandler; + +import error.Errors; +import midend.symbol.SymbolManager; + +public class Compiler { + public static void main(String[] args) { + Errors errors = new Errors(); + try { + String content = new String(Files.readAllBytes(Paths.get("testfile.txt"))); + String llvmFile = "llvm_ir.txt"; + String mipsFile = "mips.txt"; + String errorFile = "error.txt"; + Lexer lexer = new Lexer(content); + lexer.lex(errors); + TokenStream ts = new TokenStream(lexer.getTokens()); + Parser parser = new Parser(ts); + parser.parse(errors); + ErrorHandler errorHandler = new ErrorHandler(parser.getCompUnit()); + errorHandler.visit(errors); + // for (int i : SymbolManager.getSequence()) { + // System.out.print(i + " "); + // } + // System.out.println(); // TODO:debug + if (errors.size() > 0) { + StringBuilder sb = errors.toStringBuilder(); + Files.write(Paths.get(errorFile), sb.toString().getBytes()); + } else { + Midend midend = new Midend(parser.getCompUnit()); + midend.generateLLvmIr(); + // midend.writeToFile(llvmFile); + BackEnd backEnd = new BackEnd(midend.getModule()); + backEnd.toMips(); + backEnd.writeToFile(mipsFile); + } + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/backend/BackEnd.java b/backend/BackEnd.java new file mode 100644 index 0000000..12c1a5e --- /dev/null +++ b/backend/BackEnd.java @@ -0,0 +1,32 @@ +package backend; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; + +import backend.mips.MipsBuilder; +import backend.mips.MipsModule; +import midend.llvm.IrModule; + +public class BackEnd { + private MipsModule mipsModule; + private IrModule irModule; + + public BackEnd(IrModule irModule) { + this.irModule = irModule; + this.mipsModule = new MipsModule(); + } + + public void toMips() { + MipsBuilder.setModule(mipsModule); + irModule.toMips(); + } + + public void writeToFile(String fileName) { + try { + Files.write(Paths.get(fileName), mipsModule.toString().getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/backend/mips/MipsBuilder.java b/backend/mips/MipsBuilder.java new file mode 100644 index 0000000..e9df5b1 --- /dev/null +++ b/backend/mips/MipsBuilder.java @@ -0,0 +1,93 @@ +package backend.mips; + +import java.util.HashMap; +import java.util.ArrayList; + +import backend.mips.instr.MipsInstr; +import backend.mips.instr.data.MipsAsciiz; +import backend.mips.instr.data.MipsSpace; +import backend.mips.instr.data.MipsWord; +import midend.llvm.value.IrFuncValue; +import midend.llvm.value.IrValue; + +public class MipsBuilder { + private static MipsModule module = null; + private static int offset = 0; + private static HashMap valueOffsetMap = new HashMap<>(); + private static HashMap valueRegisterMap = new HashMap<>(); + + public static void setModule(MipsModule module) { + MipsBuilder.module = module; + } + + public static int getOffset() { + return offset; + } + + public static void setOffset(int offset) { + MipsBuilder.offset = offset; + } + + public static void setValueOffsetMap(HashMap valueOffsetMap) { + MipsBuilder.valueOffsetMap = valueOffsetMap; + } + + public static HashMap getValueOffsetMap() { + return valueOffsetMap; + } + + public static void setValueRegisterMap(HashMap valueRegisterMap) { + MipsBuilder.valueRegisterMap = valueRegisterMap; + } + + public static HashMap getValueRegisterMap() { + return valueRegisterMap; + } + + public static MipsModule getModule() { + return module; + } + + public static void addMipsInstr(MipsInstr instr) { + if (instr instanceof MipsAsciiz || instr instanceof MipsWord || instr instanceof MipsSpace) { //data段 + module.addData(instr); + } else { + module.addText(instr); + } + } + + public static void enterNewFunc(IrFuncValue func) { + offset = 0; + valueOffsetMap = func.getValueOffsetMap(); + valueOffsetMap.clear(); //TODO:是否需要清空? + valueRegisterMap = func.getValueRegisterMap(); + } + + public static Register getRegister(IrValue value) { + return valueRegisterMap.get(value); + } + + public static Integer getOffset(IrValue value) { + return valueOffsetMap.get(value); + } + + public static void allocaRegister(IrValue value, Register reg) { + valueRegisterMap.put(value, reg); + } + + public static void allocaOffset(IrValue value) { + if (!valueOffsetMap.containsKey(value)) { + offset -= 4; + int valueOffset = offset; + valueOffsetMap.put(value, valueOffset); + } + } + + public static void allocaOffset(int extra) { + offset -= extra; + } + + public static ArrayList getUsedRegisters() { + return new ArrayList<>(valueRegisterMap.values()); + } +} diff --git a/backend/mips/MipsModule.java b/backend/mips/MipsModule.java new file mode 100644 index 0000000..c756566 --- /dev/null +++ b/backend/mips/MipsModule.java @@ -0,0 +1,51 @@ +package backend.mips; + +import java.util.ArrayList; + +import backend.mips.instr.MipsAnnotation; +import backend.mips.instr.MipsLabel; +import backend.mips.instr.MipsInstr; + +public class MipsModule { + private ArrayList dataList; + private ArrayList textList; + + public MipsModule() { + this.dataList = new ArrayList(); + this.textList = new ArrayList(); + } + + public ArrayList getDataList() { + return dataList; + } + + public ArrayList getTextList() { + return textList; + } + + public void addData(MipsInstr instr) { + dataList.add(instr); + } + + public void addText(MipsInstr instr) { + textList.add(instr); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(".data\n"); + for (MipsInstr instr : dataList) { + sb.append("\t" + instr.toString()); + } + sb.append("\n.text\n"); + for (MipsInstr instr : textList) { + if (instr instanceof MipsLabel || instr instanceof MipsAnnotation) { + sb.append(instr.toString()); + continue; + } + sb.append("\t" + instr.toString()); + } + return sb.toString(); + } + +} diff --git a/backend/mips/Register.java b/backend/mips/Register.java new file mode 100755 index 0000000..b948f14 --- /dev/null +++ b/backend/mips/Register.java @@ -0,0 +1,58 @@ +package backend.mips; + +import java.util.ArrayList; + +public enum Register { + ZERO("$zero"), + AT("$at"), + V0("$v0"), + V1("$v1"), + A0("$a0"), + A1("$a1"), + A2("$a2"), + A3("$a3"), + T0("$t0"), + T1("$t1"), + T2("$t2"), + T3("$t3"), + T4("$t4"), + T5("$t5"), + T6("$t6"), + T7("$t7"), + S0("$s0"), + S1("$s1"), + S2("$s2"), + S3("$s3"), + S4("$s4"), + S5("$s5"), + S6("$s6"), + S7("$s7"), + T8("$t8"), + T9("$t9"), + K0("$k0"), + K1("$k1"), + GP("$gp"), + SP("$sp"), + FP("$fp"), + RA("$ra"); + + private String regName; + + Register(String regName) { + this.regName = regName; + } + + public String toString() { + return regName; + } + + public static ArrayList availableRegisters() { + ArrayList regs = new ArrayList<>(); + for (Register reg : Register.values()) { + if (reg.toString().charAt(1) == 't' || reg.toString().charAt(1) == 's') { + regs.add(reg); + } + } + return regs; + } +} \ No newline at end of file diff --git a/backend/mips/instr/MipsAlu.java b/backend/mips/instr/MipsAlu.java new file mode 100755 index 0000000..f45eed2 --- /dev/null +++ b/backend/mips/instr/MipsAlu.java @@ -0,0 +1,39 @@ +package backend.mips.instr; + +import backend.mips.Register; +import backend.mips.instr.type.MipsAluType; +import backend.mips.instr.type.MipsType; + +public class MipsAlu extends MipsInstr { + private MipsAluType aluType; + private Register rd; + private Register rs; + private Register rt; + private int immediate; + private boolean isImInstr; + + public MipsAlu(MipsAluType aluType, Register rd, Register rs, Register rt) { + super(MipsType.ALU); + this.aluType = aluType; + this.rd = rd; + this.rs = rs; + this.rt = rt; + this.immediate = 0; + this.isImInstr = false; + } + + public MipsAlu(MipsAluType aluType, Register rd, Register rs, int immediate) { + super(MipsType.ALU); + this.aluType = aluType; + this.rd = rd; + this.rs = rs; + this.rt = null; + this.immediate = immediate; + this.isImInstr = true; + } + + public String toString() { + return isImInstr ? aluType.toString() + " " + rd + ", " + rs + ", " + immediate + "\n" + : aluType.toString() + " " + rd + ", " + rs + ", " + rt + "\n"; + } +} diff --git a/backend/mips/instr/MipsAnnotation.java b/backend/mips/instr/MipsAnnotation.java new file mode 100755 index 0000000..e755675 --- /dev/null +++ b/backend/mips/instr/MipsAnnotation.java @@ -0,0 +1,16 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsType; + +public class MipsAnnotation extends MipsInstr { + private String annotation; + + public MipsAnnotation(String anno) { + super(MipsType.ANNOTATION); + this.annotation = anno; + } + + public String toString() { + return "# " + this.annotation + "\n"; + } +} diff --git a/backend/mips/instr/MipsBranch.java b/backend/mips/instr/MipsBranch.java new file mode 100644 index 0000000..52f91a0 --- /dev/null +++ b/backend/mips/instr/MipsBranch.java @@ -0,0 +1,36 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsBranchType; +import backend.mips.instr.type.MipsType; +import backend.mips.Register; + +public class MipsBranch extends MipsInstr{ + private MipsBranchType branchType; + private Register rs; + private Register rt; + private String label; + + public MipsBranch(MipsBranchType branchType, Register rs, Register rt, String label) { + super(MipsType.BRANCH); + this.branchType = branchType; + this.rs = rs; + this.rt = rt; + this.label = label; + } + + public MipsBranch(MipsBranchType branchType, Register rs, String label) { + super(MipsType.BRANCH); + this.branchType = branchType; + this.rs = rs; + this.rt = null; + this.label = label; + } + + public String toString() { + if (this.rt == null) { + return this.branchType.toString() + " " + this.rs + ", " + this.label + "\n"; + } else { + return this.branchType.toString() + " " + this.rs + ", " + this.rt + ", " + this.label + "\n"; + } + } +} diff --git a/backend/mips/instr/MipsComp.java b/backend/mips/instr/MipsComp.java new file mode 100644 index 0000000..fee36fc --- /dev/null +++ b/backend/mips/instr/MipsComp.java @@ -0,0 +1,42 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsCompareType; +import backend.mips.instr.type.MipsType; +import backend.mips.Register; + +public class MipsComp extends MipsInstr { + private MipsCompareType compareType; + private Register rd; + private Register rs; + private Register rt; + private int immediate; + private boolean isImmediate; + + public MipsComp(MipsCompareType compareType, Register rd, Register rs, Register rt) { + super(MipsType.COMPARE); + this.compareType = compareType; + this.rd = rd; + this.rs = rs; + this.rt = rt; + this.immediate = 0; + this.isImmediate = false; + } + + public MipsComp(MipsCompareType compareType, Register rd, Register rs, int immediate) { + super(MipsType.COMPARE); + this.compareType = compareType; + this.rd = rd; + this.rs = rs; + this.rt = null; + this.immediate = immediate; + this.isImmediate = true; + } + + public String toString() { + if (this.isImmediate) { + return this.compareType.toString() + " " + this.rd + ", " + this.rs + ", " + this.immediate + "\n"; + } else { + return this.compareType.toString() + " " + this.rd + ", " + this.rs + ", " + this.rt + "\n"; + } + } +} diff --git a/backend/mips/instr/MipsInstr.java b/backend/mips/instr/MipsInstr.java new file mode 100755 index 0000000..b371b70 --- /dev/null +++ b/backend/mips/instr/MipsInstr.java @@ -0,0 +1,21 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsType; +import backend.mips.MipsBuilder; + +public class MipsInstr { + private MipsType mt; + + public MipsInstr(MipsType mt) { + this.mt = mt; + MipsBuilder.addMipsInstr(this); + } + + public String toString() { + return ""; + } + + public MipsType getType() { + return mt; + } +} diff --git a/backend/mips/instr/MipsJump.java b/backend/mips/instr/MipsJump.java new file mode 100644 index 0000000..ed2c3a3 --- /dev/null +++ b/backend/mips/instr/MipsJump.java @@ -0,0 +1,33 @@ +package backend.mips.instr; + +import backend.mips.Register; +import backend.mips.instr.type.MipsJumpType; +import backend.mips.instr.type.MipsType; + +public class MipsJump extends MipsInstr { + private MipsJumpType jumpType; + private String label; + private Register rd; + + public MipsJump(MipsJumpType jumpType, String label) { + super(MipsType.JUMP); + this.jumpType = jumpType; + this.label = label; + this.rd = null; + } + + public MipsJump(MipsJumpType jumpType, Register rd) { + super(MipsType.JUMP); + this.jumpType = jumpType; + this.label = null; + this.rd = rd; + } + + public String toString() { + if (this.rd == null) { + return this.jumpType.toString() + " " + this.label + "\n"; + } else { + return this.jumpType.toString() + " " + this.rd + "\n"; + } + } +} diff --git a/backend/mips/instr/MipsLabel.java b/backend/mips/instr/MipsLabel.java new file mode 100644 index 0000000..a135de6 --- /dev/null +++ b/backend/mips/instr/MipsLabel.java @@ -0,0 +1,16 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsType; + +public class MipsLabel extends MipsInstr { + private String label; + + public MipsLabel(String label) { + super(MipsType.LABEL); + this.label = label; + } + + public String toString() { + return this.label + ":\n"; + } +} diff --git a/backend/mips/instr/MipsLs.java b/backend/mips/instr/MipsLs.java new file mode 100644 index 0000000..f114b28 --- /dev/null +++ b/backend/mips/instr/MipsLs.java @@ -0,0 +1,39 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsLsType; +import backend.mips.instr.type.MipsType; +import backend.mips.Register; + +public class MipsLs extends MipsInstr { + private MipsLsType lsType; + private Register rd; + private Register rt; + private int offset; + private String label; + + public MipsLs(MipsLsType lsType, Register rd, Register rt, int offset) { + super(MipsType.LS); + this.lsType = lsType; + this.rd = rd; + this.rt = rt; + this.offset = offset; + this.label = null; + } + + public MipsLs(MipsLsType lsType, Register rd, int offset, String label) { + super(MipsType.LS); + this.lsType = lsType; + this.rd = rd; + this.rt = null; + this.offset = offset; + this.label = label; + } + + public String toString() { + if (this.label == null) { + return this.lsType.toString() + " " + this.rd + ", " + this.offset + "(" + this.rt + ")\n"; + } else { + return this.lsType.toString() + " " + this.rd + ", " + this.label + " + " + this.offset + "\n"; + } + } +} diff --git a/backend/mips/instr/MipsMd.java b/backend/mips/instr/MipsMd.java new file mode 100644 index 0000000..e981f98 --- /dev/null +++ b/backend/mips/instr/MipsMd.java @@ -0,0 +1,33 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsMdType; +import backend.mips.instr.type.MipsType; +import backend.mips.Register; + +public class MipsMd extends MipsInstr { + private MipsMdType mdType; + private Register rd; + private Register rt; + + public MipsMd(MipsMdType mdType, Register rd, Register rt) { + super(MipsType.MD); + this.mdType = mdType; + this.rd = rd; + this.rt = rt; + } + + public MipsMd(MipsMdType mdType, Register rd) { + super(MipsType.MD); + this.mdType = mdType; + this.rd = rd; + this.rt = null; + } + + public String toString() { + if (this.rt == null) { + return this.mdType.toString() + " " + this.rd + "\n"; + } else { + return this.mdType.toString() + " " + this.rd + ", " + this.rt + "\n"; + } + } +} diff --git a/backend/mips/instr/MipsSyscall.java b/backend/mips/instr/MipsSyscall.java new file mode 100644 index 0000000..8cdb1e3 --- /dev/null +++ b/backend/mips/instr/MipsSyscall.java @@ -0,0 +1,13 @@ +package backend.mips.instr; + +import backend.mips.instr.type.MipsType; + +public class MipsSyscall extends MipsInstr { + public MipsSyscall() { + super(MipsType.SYSCALL); + } + + public String toString() { + return "syscall\n"; + } +} diff --git a/backend/mips/instr/data/MipsAsciiz.java b/backend/mips/instr/data/MipsAsciiz.java new file mode 100644 index 0000000..631cd1a --- /dev/null +++ b/backend/mips/instr/data/MipsAsciiz.java @@ -0,0 +1,19 @@ +package backend.mips.instr.data; + +import backend.mips.instr.MipsInstr; +import backend.mips.instr.type.MipsType; + +public class MipsAsciiz extends MipsInstr { + private String name; + private String str; + + public MipsAsciiz(String name, String str) { + super(MipsType.DATA); + this.name = name; + this.str = str; + } + + public String toString() { + return name + ": .asciiz \"" + str.replaceAll("\n", "\\n") + "\"\n"; + } +} diff --git a/backend/mips/instr/data/MipsSpace.java b/backend/mips/instr/data/MipsSpace.java new file mode 100644 index 0000000..2d95ec6 --- /dev/null +++ b/backend/mips/instr/data/MipsSpace.java @@ -0,0 +1,19 @@ +package backend.mips.instr.data; + +import backend.mips.instr.MipsInstr; +import backend.mips.instr.type.MipsType; + +public class MipsSpace extends MipsInstr { + private int size; + private String name; + + public MipsSpace(int size, String name) { + super(MipsType.DATA); + this.size = size; + this.name = name; + } + + public String toString() { + return name + ": .space " + size + "\n"; + } +} diff --git a/backend/mips/instr/data/MipsWord.java b/backend/mips/instr/data/MipsWord.java new file mode 100644 index 0000000..aa8ae47 --- /dev/null +++ b/backend/mips/instr/data/MipsWord.java @@ -0,0 +1,39 @@ +package backend.mips.instr.data; + +import java.util.ArrayList; + +import backend.mips.instr.MipsInstr; +import backend.mips.instr.type.MipsType; + +public class MipsWord extends MipsInstr { + private String name; + private ArrayList valueList; + + public MipsWord(String name, ArrayList valueList) { + super(MipsType.DATA); + this.name = name; + this.valueList = valueList; + } + + public MipsWord(String name, int value) { + super(MipsType.DATA); + this.name = name; + this.valueList = new ArrayList(); + this.valueList.add(value); + } + + public int getValueNum() { + return valueList.size(); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(name).append(": .word "); + for (int value : valueList) { + sb.append(value).append(", "); + } + sb.delete(sb.length() - 2, sb.length()); + sb.append("\n"); + return sb.toString(); + } +} diff --git a/backend/mips/instr/fake/MipsLa.java b/backend/mips/instr/fake/MipsLa.java new file mode 100644 index 0000000..88b2d96 --- /dev/null +++ b/backend/mips/instr/fake/MipsLa.java @@ -0,0 +1,28 @@ +package backend.mips.instr.fake; + +import backend.mips.instr.MipsInstr; +import backend.mips.instr.type.MipsType; +import backend.mips.Register; + +public class MipsLa extends MipsInstr { + private Register rd; + private String label; + + public MipsLa(Register rd, String label) { + super(MipsType.FAKE); + this.rd = rd; + this.label = label; + } + + public Register getRd() { + return rd; + } + + public String getLabel() { + return label; + } + + public String toString() { + return "la " + rd + ", " + label + "\n"; + } +} diff --git a/backend/mips/instr/fake/MipsLi.java b/backend/mips/instr/fake/MipsLi.java new file mode 100644 index 0000000..f47e832 --- /dev/null +++ b/backend/mips/instr/fake/MipsLi.java @@ -0,0 +1,29 @@ +package backend.mips.instr.fake; + +import backend.mips.instr.MipsInstr; +import backend.mips.instr.type.MipsType; +import backend.mips.Register; + + +public class MipsLi extends MipsInstr { + private Register rd; + private int value; + + public MipsLi(Register rd, int value) { + super(MipsType.FAKE); + this.rd = rd; + this.value = value; + } + + public Register getRd() { + return rd; + } + + public int getValue() { + return value; + } + + public String toString() { + return "li " + rd + ", " + value + "\n"; + } +} diff --git a/backend/mips/instr/fake/MipsMove.java b/backend/mips/instr/fake/MipsMove.java new file mode 100644 index 0000000..a648563 --- /dev/null +++ b/backend/mips/instr/fake/MipsMove.java @@ -0,0 +1,28 @@ +package backend.mips.instr.fake; + +import backend.mips.instr.MipsInstr; +import backend.mips.instr.type.MipsType; +import backend.mips.Register; + +public class MipsMove extends MipsInstr { + private Register rd; + private Register rt; + + public MipsMove(Register rd, Register rt) { + super(MipsType.FAKE); + this.rd = rd; + this.rt = rt; + } + + public Register getDest() { + return rd; + } + + public Register getSrc() { + return rt; + } + + public String toString() { + return "move " + rd + ", " + rt + "\n"; + } +} diff --git a/backend/mips/instr/type/MipsAluType.java b/backend/mips/instr/type/MipsAluType.java new file mode 100755 index 0000000..c87838c --- /dev/null +++ b/backend/mips/instr/type/MipsAluType.java @@ -0,0 +1,16 @@ +package backend.mips.instr.type; + +public enum MipsAluType { + // calc_R + ADD, SUB, ADDU, SUBU, AND, OR, NOR, XOR, SLT, SLTU, + // shiftv + SLLV, SRAV, SRLV, + // calc_I + ADDI, ADDIU, ANDI, ORI, XORI, SLTI, SLTIU, + // shift + SLL, SRA, SRL; + + public String toString() { + return this.name().toLowerCase(); + } +} diff --git a/backend/mips/instr/type/MipsBranchType.java b/backend/mips/instr/type/MipsBranchType.java new file mode 100644 index 0000000..35cbfb2 --- /dev/null +++ b/backend/mips/instr/type/MipsBranchType.java @@ -0,0 +1,9 @@ +package backend.mips.instr.type; + +public enum MipsBranchType { + BEQ, BNE, BLEZ, BGTZ, BLTZ, BGEZ; + + public String toString() { + return this.name().toLowerCase(); + } +} diff --git a/backend/mips/instr/type/MipsCompareType.java b/backend/mips/instr/type/MipsCompareType.java new file mode 100644 index 0000000..f32897f --- /dev/null +++ b/backend/mips/instr/type/MipsCompareType.java @@ -0,0 +1,9 @@ +package backend.mips.instr.type; + +public enum MipsCompareType { + SLT, SLE, SGT, SGE, SEQ, SNE, SLTI; + + public String toString() { + return this.name().toLowerCase(); + } +} diff --git a/backend/mips/instr/type/MipsJumpType.java b/backend/mips/instr/type/MipsJumpType.java new file mode 100644 index 0000000..d7e272b --- /dev/null +++ b/backend/mips/instr/type/MipsJumpType.java @@ -0,0 +1,9 @@ +package backend.mips.instr.type; + +public enum MipsJumpType { + J, JAL, JR; + + public String toString() { + return this.name().toLowerCase(); + } +} diff --git a/backend/mips/instr/type/MipsLsType.java b/backend/mips/instr/type/MipsLsType.java new file mode 100644 index 0000000..d1982a2 --- /dev/null +++ b/backend/mips/instr/type/MipsLsType.java @@ -0,0 +1,9 @@ +package backend.mips.instr.type; + +public enum MipsLsType { + LW, SW, LH, SH, LHU, LB, SB, LBU; + + public String toString() { + return this.name().toLowerCase(); + } +} diff --git a/backend/mips/instr/type/MipsMdType.java b/backend/mips/instr/type/MipsMdType.java new file mode 100644 index 0000000..e0deb36 --- /dev/null +++ b/backend/mips/instr/type/MipsMdType.java @@ -0,0 +1,9 @@ +package backend.mips.instr.type; + +public enum MipsMdType { + MFHI, MFLO, MULT, DIV, MTHI, MTLO; + + public String toString() { + return this.name().toLowerCase(); + } +} diff --git a/backend/mips/instr/type/MipsType.java b/backend/mips/instr/type/MipsType.java new file mode 100755 index 0000000..e9f6cdb --- /dev/null +++ b/backend/mips/instr/type/MipsType.java @@ -0,0 +1,15 @@ +package backend.mips.instr.type; + +public enum MipsType { + ALU, + COMPARE, + BRANCH, + JUMP, + SYSCALL, + DATA, + LABEL, + ANNOTATION, + LS, + MD, + FAKE +} diff --git a/config.json b/config.json new file mode 100755 index 0000000..e1d3bcb --- /dev/null +++ b/config.json @@ -0,0 +1,4 @@ +{ + "programming language": "java", + "object code": "mips" +} \ No newline at end of file diff --git a/error/Error.java b/error/Error.java old mode 100644 new mode 100755 index 88011da..d47c5dc --- a/error/Error.java +++ b/error/Error.java @@ -1,27 +1,27 @@ -package error; - -public class Error { - private int line; - private ErrorType type; - - public Error(int line, ErrorType type) { - this.line = line; - this.type = type; - } - - public void printError() { - System.out.println(this.line + " " + this.type); - } - - public int getLine() { - return this.line; - } - - public ErrorType getType() { - return this.type; - } - - public String toString() { - return this.line + " " + this.type + "\n"; - } -} +package error; + +public class Error { + private int line; + private ErrorType type; + + public Error(int line, ErrorType type) { + this.line = line; + this.type = type; + } + + public void printError() { + System.out.println(this.line + " " + this.type); + } + + public int getLine() { + return this.line; + } + + public ErrorType getType() { + return this.type; + } + + public String toString() { + return this.line + " " + this.type + "\n"; + } +} diff --git a/error/ErrorType.java b/error/ErrorType.java old mode 100644 new mode 100755 index c4b2283..46410f1 --- a/error/ErrorType.java +++ b/error/ErrorType.java @@ -1,17 +1,17 @@ -package error; - -public enum ErrorType { - a, - b, - c, - d, - e, - f, - g, - h, - i, - j, - k, - l, - m -} +package error; + +public enum ErrorType { + a, + b, + c, + d, + e, + f, + g, + h, + i, + j, + k, + l, + m +} diff --git a/error/Errors.java b/error/Errors.java old mode 100644 new mode 100755 diff --git a/frontend/.DS_Store b/frontend/.DS_Store old mode 100644 new mode 100755 diff --git a/frontend/ast/.DS_Store b/frontend/ast/.DS_Store old mode 100644 new mode 100755 diff --git a/frontend/ast/CompUnit.java b/frontend/ast/CompUnit.java old mode 100644 new mode 100755 diff --git a/frontend/ast/Node.java b/frontend/ast/Node.java old mode 100644 new mode 100755 diff --git a/frontend/ast/NodeStack.java b/frontend/ast/NodeStack.java old mode 100644 new mode 100755 index f689a03..dfed099 --- a/frontend/ast/NodeStack.java +++ b/frontend/ast/NodeStack.java @@ -1,23 +1,23 @@ -package frontend.ast; - -import java.util.ArrayList; - -public class NodeStack { - private ArrayList stack; - - public NodeStack() { - stack = new ArrayList(); - } - - public void push(Node node) { - stack.add(node); - } - - public Node pop() { - return stack.remove(stack.size() - 1); - } - - public int size() { - return stack.size(); - } -} +package frontend.ast; + +import java.util.ArrayList; + +public class NodeStack { + private ArrayList stack; + + public NodeStack() { + stack = new ArrayList(); + } + + public void push(Node node) { + stack.add(node); + } + + public Node pop() { + return stack.remove(stack.size() - 1); + } + + public int size() { + return stack.size(); + } +} diff --git a/frontend/ast/SyntaxType.java b/frontend/ast/SyntaxType.java old mode 100644 new mode 100755 diff --git a/frontend/ast/block/Block.java b/frontend/ast/block/Block.java old mode 100644 new mode 100755 diff --git a/frontend/ast/block/BlockItem.java b/frontend/ast/block/BlockItem.java old mode 100644 new mode 100755 index ba18d81..4686796 --- a/frontend/ast/block/BlockItem.java +++ b/frontend/ast/block/BlockItem.java @@ -1,28 +1,28 @@ -package frontend.ast.block; - -import error.Errors; -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.decl.Decl; - -public class BlockItem extends Node { - public BlockItem(TokenStream ts) { - super(SyntaxType.BLOCK_ITEM, ts); - } - - public void parse(Errors errors) { - if (getCurrToken().getType() == TokenType.CONSTTK - || getCurrToken().getType() == TokenType.STATICTK - || getCurrToken().getType() == TokenType.INTTK) { - Decl decl = new Decl(this.ts); - decl.parse(errors); - addChild(decl); - } else { - Stmt stmt = new Stmt(this.ts); - stmt.parse(errors); - addChild(stmt); - } - } -} +package frontend.ast.block; + +import error.Errors; +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.decl.Decl; + +public class BlockItem extends Node { + public BlockItem(TokenStream ts) { + super(SyntaxType.BLOCK_ITEM, ts); + } + + public void parse(Errors errors) { + if (getCurrToken().getType() == TokenType.CONSTTK + || getCurrToken().getType() == TokenType.STATICTK + || getCurrToken().getType() == TokenType.INTTK) { + Decl decl = new Decl(this.ts); + decl.parse(errors); + addChild(decl); + } else { + Stmt stmt = new Stmt(this.ts); + stmt.parse(errors); + addChild(stmt); + } + } +} diff --git a/frontend/ast/block/ForStmt.java b/frontend/ast/block/ForStmt.java old mode 100644 new mode 100755 index 21c5056..b745dd7 --- a/frontend/ast/block/ForStmt.java +++ b/frontend/ast/block/ForStmt.java @@ -1,57 +1,57 @@ -package frontend.ast.block; - -import frontend.ast.SyntaxType; -import frontend.ast.token.TokenNode; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.Node; -import frontend.ast.exp.Exp; -import frontend.ast.exp.LVal; - -import java.util.ArrayList; - -import error.Errors; - -public class ForStmt extends Node { - public ForStmt(TokenStream ts) { - super(SyntaxType.FOR_STMT, ts); - } - - public void parse(Errors errors) { - handleAssign(errors); - while (getCurrToken().getType() == TokenType.COMMA) { - addChild(new TokenNode(ts)); // comma - handleAssign(errors); - } - } - - public void handleAssign(Errors errors) { - LVal lval = new LVal(this.ts); - lval.parse(errors); - addChild(lval); - addChild(new TokenNode(ts)); // assign - Exp exp = new Exp(this.ts); - exp.parse(errors); - addChild(exp); - } - - public ArrayList getLValList() { - ArrayList lvalList = new ArrayList<>(); - for (int i = 0; i < getChildren().size(); i++) { - if (getChild(i) instanceof LVal) { - lvalList.add((LVal) getChild(i)); - } - } - return lvalList; - } - - public ArrayList getExpList() { - ArrayList expList = new ArrayList<>(); - for (int i = 0; i < getChildren().size(); i++) { - if (getChild(i) instanceof Exp) { - expList.add((Exp) getChild(i)); - } - } - return expList; - } -} +package frontend.ast.block; + +import frontend.ast.SyntaxType; +import frontend.ast.token.TokenNode; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.Node; +import frontend.ast.exp.Exp; +import frontend.ast.exp.LVal; + +import java.util.ArrayList; + +import error.Errors; + +public class ForStmt extends Node { + public ForStmt(TokenStream ts) { + super(SyntaxType.FOR_STMT, ts); + } + + public void parse(Errors errors) { + handleAssign(errors); + while (getCurrToken().getType() == TokenType.COMMA) { + addChild(new TokenNode(ts)); // comma + handleAssign(errors); + } + } + + public void handleAssign(Errors errors) { + LVal lval = new LVal(this.ts); + lval.parse(errors); + addChild(lval); + addChild(new TokenNode(ts)); // assign + Exp exp = new Exp(this.ts); + exp.parse(errors); + addChild(exp); + } + + public ArrayList getLValList() { + ArrayList lvalList = new ArrayList<>(); + for (int i = 0; i < getChildren().size(); i++) { + if (getChild(i) instanceof LVal) { + lvalList.add((LVal) getChild(i)); + } + } + return lvalList; + } + + public ArrayList getExpList() { + ArrayList expList = new ArrayList<>(); + for (int i = 0; i < getChildren().size(); i++) { + if (getChild(i) instanceof Exp) { + expList.add((Exp) getChild(i)); + } + } + return expList; + } +} diff --git a/frontend/ast/block/Stmt.java b/frontend/ast/block/Stmt.java old mode 100644 new mode 100755 index cf40506..5fa278d --- a/frontend/ast/block/Stmt.java +++ b/frontend/ast/block/Stmt.java @@ -1,274 +1,274 @@ -package frontend.ast.block; - -import error.Errors; - -import java.util.ArrayList; - -import error.Error; -import error.ErrorType; -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import frontend.ast.exp.Exp; -import frontend.ast.exp.Cond; -import frontend.ast.exp.LVal; - -public class Stmt extends Node { - private boolean getint; - - public Stmt(TokenStream ts) { - super(SyntaxType.STMT, ts); - getint = false; - } - - public void parse(Errors errors) { - if (getCurrToken().getType() == TokenType.LBRACE) { - Block block = new Block(this.ts); - block.parse(errors); - addChild(block); - } else if (getCurrToken().getType() == TokenType.IFTK) { - handleIf(errors); - } else if (getCurrToken().getType() == TokenType.FORTK) { - handleFor(errors); - } else if (getCurrToken().getType() == TokenType.BREAKTK) { - TokenNode breakkk = new TokenNode(this.ts); - addChild(breakkk); - if (getCurrToken().getType() == TokenType.SEMICN) { - TokenNode semicolon = new TokenNode(this.ts); - addChild(semicolon); - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); - } - } else if (getCurrToken().getType() == TokenType.CONTINUETK) { - TokenNode continuekk = new TokenNode(this.ts); - addChild(continuekk); - if (getCurrToken().getType() == TokenType.SEMICN) { - TokenNode semicolon = new TokenNode(this.ts); - addChild(semicolon); - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); - } - } else if (getCurrToken().getType() == TokenType.RETURNTK) { - handleReturn(errors); - } else if (getCurrToken().getType() == TokenType.PRINTFTK) { - handlePrintf(errors); - } else { - handleAssign(errors); - } - } - - public void handleIf(Errors errors) { - TokenNode ifkk = new TokenNode(this.ts); - addChild(ifkk); - TokenNode lparent = new TokenNode(this.ts); - addChild(lparent); - Cond cond = new Cond(this.ts); - cond.parse(errors); - addChild(cond); - if (getCurrToken().getType() == TokenType.RPARENT) { - TokenNode rparent = new TokenNode(this.ts); - addChild(rparent); - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); - } - Stmt stmt = new Stmt(this.ts); - stmt.parse(errors); - addChild(stmt); - if (getCurrToken().getType() == TokenType.ELSETK) { - TokenNode elsekk = new TokenNode(this.ts); - addChild(elsekk); - Stmt elseStmt = new Stmt(this.ts); - elseStmt.parse(errors); - addChild(elseStmt); - } - } - - public void handleFor(Errors errors) { - TokenNode forkk = new TokenNode(this.ts); - addChild(forkk); - TokenNode lparent = new TokenNode(this.ts); - addChild(lparent); - if (getCurrToken().getType() == TokenType.SEMICN) { - TokenNode semicolon = new TokenNode(this.ts); - addChild(semicolon); - } else { - ForStmt fst = new ForStmt(this.ts); - fst.parse(errors); - addChild(fst); - TokenNode semicolon = new TokenNode(this.ts); - addChild(semicolon); - } - if (getCurrToken().getType() == TokenType.SEMICN) { - TokenNode semicolon = new TokenNode(this.ts); - addChild(semicolon); - } else { - Cond cond = new Cond(this.ts); - cond.parse(errors); - addChild(cond); - TokenNode semicolon = new TokenNode(this.ts); - addChild(semicolon); - } - if (getCurrToken().getType() == TokenType.RPARENT) { - TokenNode rparent = new TokenNode(this.ts); - addChild(rparent); - } else { - ForStmt fst = new ForStmt(this.ts); - fst.parse(errors); - addChild(fst); - TokenNode rparent = new TokenNode(this.ts); - addChild(rparent); - } - Stmt stmt = new Stmt(this.ts); - stmt.parse(errors); - addChild(stmt); - } - - public void handleReturn(Errors errors) { - TokenNode returnkk = new TokenNode(this.ts); - addChild(returnkk); - if (currentIsExp()) { - Exp exp = new Exp(this.ts); - exp.parse(errors); - addChild(exp); - } - if (getCurrToken().getType() == TokenType.SEMICN) { - TokenNode semicolon = new TokenNode(this.ts); - addChild(semicolon); - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); - } - } - - public void handlePrintf(Errors errors) { - TokenNode printfkk = new TokenNode(this.ts); - addChild(printfkk); - addChild(new TokenNode(this.ts)); // lparent - addChild(new TokenNode(this.ts)); // strconst - while (getCurrToken().getType() == TokenType.COMMA) { - addChild(new TokenNode(this.ts)); // comma - Exp exp = new Exp(this.ts); - exp.parse(errors); - addChild(exp); - } - if (getCurrToken().getType() != TokenType.RPARENT) { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); - } else { - addChild(new TokenNode(this.ts)); // rparent - } - if (getCurrToken().getType() != TokenType.SEMICN) { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); - } else { - addChild(new TokenNode(this.ts)); // semicolon - } - } - - public void handleAssign(Errors errors) { - if (getCurrToken().getType() == TokenType.IDENFR) { - if (this.ts.peek(1).getType() == TokenType.ASSIGN) { - LVal lval = new LVal(this.ts); - lval.parse(errors); - addChild(lval); - addChild(new TokenNode(this.ts)); // assign - if (getCurrToken().getValue().equals("getint")) { - getint = true; - } - Exp exp = new Exp(this.ts); - exp.parse(errors); - addChild(exp); - if (getCurrToken().getType() == TokenType.SEMICN) { - addChild(new TokenNode(this.ts)); // semicolon - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); - } - } else if (this.ts.peek(1).getType() == TokenType.LBRACK) { - int start = this.ts.getCurrentIndex(); - LVal lval = new LVal(this.ts); - lval.parse(errors); - if (getCurrToken().getType() == TokenType.ASSIGN) { - addChild(lval); - addChild(new TokenNode(this.ts)); // assign - if (getCurrToken().getValue().equals("getint")) { - getint = true; - } - handleExpInAssign(errors); - } else { - this.ts.resetIndex(start); - // parse exp ; - handleExpInAssign(errors); - } - } else { - handleExpInAssign(errors); - } - } else { - if (currentIsExp()) { - handleExpInAssign(errors); - } else { - if (getCurrToken().getType() == TokenType.SEMICN) { - addChild(new TokenNode(this.ts)); // semicolon - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); - } - } - } - } - - public void handleExpInAssign(Errors errors) { - Exp exp = new Exp(this.ts); - exp.parse(errors); - addChild(exp); - if (getCurrToken().getType() == TokenType.SEMICN) { - addChild(new TokenNode(this.ts)); // semicolon - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); - } - } - - public boolean currentIsExp() { - TokenType t = getCurrToken().getType(); - return t == TokenType.PLUS || t == TokenType.MINU || t == TokenType.NOT - || t == TokenType.IDENFR || t == TokenType.LPARENT || t == TokenType.INTCON; - } - - public boolean isGetint() { - return getint; - } - - public ArrayList getExpList() { - ArrayList expList = new ArrayList<>(); - for (int i = 0; i < getChildren().size(); i++) { - if (getChild(i) instanceof Exp) { - expList.add((Exp) getChild(i)); - } - } - return expList; - } - - public Cond getCond() { //just for fortype stmt - for (int i = 0; i < getChildren().size(); i++) { - if (getChild(i) instanceof Cond) { - return (Cond) getChild(i); - } - } - return null; - } - - public ForStmt getinitStmt() { - if (getChild(2) instanceof ForStmt) { - return (ForStmt) getChild(2); - } - return null; - } - - public ForStmt getStepStmt() { - if (getChild(getChildren().size() - 3) instanceof ForStmt) { - return (ForStmt) getChild(getChildren().size() - 3); - } - return null; - } - - public Stmt getBodyStmt() { - return (Stmt) getChild(getChildren().size() - 1); - } -} +package frontend.ast.block; + +import error.Errors; + +import java.util.ArrayList; + +import error.Error; +import error.ErrorType; +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import frontend.ast.exp.Exp; +import frontend.ast.exp.Cond; +import frontend.ast.exp.LVal; + +public class Stmt extends Node { + private boolean getint; + + public Stmt(TokenStream ts) { + super(SyntaxType.STMT, ts); + getint = false; + } + + public void parse(Errors errors) { + if (getCurrToken().getType() == TokenType.LBRACE) { + Block block = new Block(this.ts); + block.parse(errors); + addChild(block); + } else if (getCurrToken().getType() == TokenType.IFTK) { + handleIf(errors); + } else if (getCurrToken().getType() == TokenType.FORTK) { + handleFor(errors); + } else if (getCurrToken().getType() == TokenType.BREAKTK) { + TokenNode breakkk = new TokenNode(this.ts); + addChild(breakkk); + if (getCurrToken().getType() == TokenType.SEMICN) { + TokenNode semicolon = new TokenNode(this.ts); + addChild(semicolon); + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); + } + } else if (getCurrToken().getType() == TokenType.CONTINUETK) { + TokenNode continuekk = new TokenNode(this.ts); + addChild(continuekk); + if (getCurrToken().getType() == TokenType.SEMICN) { + TokenNode semicolon = new TokenNode(this.ts); + addChild(semicolon); + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); + } + } else if (getCurrToken().getType() == TokenType.RETURNTK) { + handleReturn(errors); + } else if (getCurrToken().getType() == TokenType.PRINTFTK) { + handlePrintf(errors); + } else { + handleAssign(errors); + } + } + + public void handleIf(Errors errors) { + TokenNode ifkk = new TokenNode(this.ts); + addChild(ifkk); + TokenNode lparent = new TokenNode(this.ts); + addChild(lparent); + Cond cond = new Cond(this.ts); + cond.parse(errors); + addChild(cond); + if (getCurrToken().getType() == TokenType.RPARENT) { + TokenNode rparent = new TokenNode(this.ts); + addChild(rparent); + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); + } + Stmt stmt = new Stmt(this.ts); + stmt.parse(errors); + addChild(stmt); + if (getCurrToken().getType() == TokenType.ELSETK) { + TokenNode elsekk = new TokenNode(this.ts); + addChild(elsekk); + Stmt elseStmt = new Stmt(this.ts); + elseStmt.parse(errors); + addChild(elseStmt); + } + } + + public void handleFor(Errors errors) { + TokenNode forkk = new TokenNode(this.ts); + addChild(forkk); + TokenNode lparent = new TokenNode(this.ts); + addChild(lparent); + if (getCurrToken().getType() == TokenType.SEMICN) { + TokenNode semicolon = new TokenNode(this.ts); + addChild(semicolon); + } else { + ForStmt fst = new ForStmt(this.ts); + fst.parse(errors); + addChild(fst); + TokenNode semicolon = new TokenNode(this.ts); + addChild(semicolon); + } + if (getCurrToken().getType() == TokenType.SEMICN) { + TokenNode semicolon = new TokenNode(this.ts); + addChild(semicolon); + } else { + Cond cond = new Cond(this.ts); + cond.parse(errors); + addChild(cond); + TokenNode semicolon = new TokenNode(this.ts); + addChild(semicolon); + } + if (getCurrToken().getType() == TokenType.RPARENT) { + TokenNode rparent = new TokenNode(this.ts); + addChild(rparent); + } else { + ForStmt fst = new ForStmt(this.ts); + fst.parse(errors); + addChild(fst); + TokenNode rparent = new TokenNode(this.ts); + addChild(rparent); + } + Stmt stmt = new Stmt(this.ts); + stmt.parse(errors); + addChild(stmt); + } + + public void handleReturn(Errors errors) { + TokenNode returnkk = new TokenNode(this.ts); + addChild(returnkk); + if (currentIsExp()) { + Exp exp = new Exp(this.ts); + exp.parse(errors); + addChild(exp); + } + if (getCurrToken().getType() == TokenType.SEMICN) { + TokenNode semicolon = new TokenNode(this.ts); + addChild(semicolon); + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); + } + } + + public void handlePrintf(Errors errors) { + TokenNode printfkk = new TokenNode(this.ts); + addChild(printfkk); + addChild(new TokenNode(this.ts)); // lparent + addChild(new TokenNode(this.ts)); // strconst + while (getCurrToken().getType() == TokenType.COMMA) { + addChild(new TokenNode(this.ts)); // comma + Exp exp = new Exp(this.ts); + exp.parse(errors); + addChild(exp); + } + if (getCurrToken().getType() != TokenType.RPARENT) { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); + } else { + addChild(new TokenNode(this.ts)); // rparent + } + if (getCurrToken().getType() != TokenType.SEMICN) { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); + } else { + addChild(new TokenNode(this.ts)); // semicolon + } + } + + public void handleAssign(Errors errors) { + if (getCurrToken().getType() == TokenType.IDENFR) { + if (this.ts.peek(1).getType() == TokenType.ASSIGN) { + LVal lval = new LVal(this.ts); + lval.parse(errors); + addChild(lval); + addChild(new TokenNode(this.ts)); // assign + if (getCurrToken().getValue().equals("getint")) { + getint = true; + } + Exp exp = new Exp(this.ts); + exp.parse(errors); + addChild(exp); + if (getCurrToken().getType() == TokenType.SEMICN) { + addChild(new TokenNode(this.ts)); // semicolon + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); + } + } else if (this.ts.peek(1).getType() == TokenType.LBRACK) { + int start = this.ts.getCurrentIndex(); + LVal lval = new LVal(this.ts); + lval.parse(errors); + if (getCurrToken().getType() == TokenType.ASSIGN) { + addChild(lval); + addChild(new TokenNode(this.ts)); // assign + if (getCurrToken().getValue().equals("getint")) { + getint = true; + } + handleExpInAssign(errors); + } else { + this.ts.resetIndex(start); + // parse exp ; + handleExpInAssign(errors); + } + } else { + handleExpInAssign(errors); + } + } else { + if (currentIsExp()) { + handleExpInAssign(errors); + } else { + if (getCurrToken().getType() == TokenType.SEMICN) { + addChild(new TokenNode(this.ts)); // semicolon + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); + } + } + } + } + + public void handleExpInAssign(Errors errors) { + Exp exp = new Exp(this.ts); + exp.parse(errors); + addChild(exp); + if (getCurrToken().getType() == TokenType.SEMICN) { + addChild(new TokenNode(this.ts)); // semicolon + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.i)); + } + } + + public boolean currentIsExp() { + TokenType t = getCurrToken().getType(); + return t == TokenType.PLUS || t == TokenType.MINU || t == TokenType.NOT + || t == TokenType.IDENFR || t == TokenType.LPARENT || t == TokenType.INTCON; + } + + public boolean isGetint() { + return getint; + } + + public ArrayList getExpList() { + ArrayList expList = new ArrayList<>(); + for (int i = 0; i < getChildren().size(); i++) { + if (getChild(i) instanceof Exp) { + expList.add((Exp) getChild(i)); + } + } + return expList; + } + + public Cond getCond() { //just for fortype stmt + for (int i = 0; i < getChildren().size(); i++) { + if (getChild(i) instanceof Cond) { + return (Cond) getChild(i); + } + } + return null; + } + + public ForStmt getinitStmt() { + if (getChild(2) instanceof ForStmt) { + return (ForStmt) getChild(2); + } + return null; + } + + public ForStmt getStepStmt() { + if (getChild(getChildren().size() - 3) instanceof ForStmt) { + return (ForStmt) getChild(getChildren().size() - 3); + } + return null; + } + + public Stmt getBodyStmt() { + return (Stmt) getChild(getChildren().size() - 1); + } +} diff --git a/frontend/ast/decl/ConstDecl.java b/frontend/ast/decl/ConstDecl.java old mode 100644 new mode 100755 diff --git a/frontend/ast/decl/ConstDef.java b/frontend/ast/decl/ConstDef.java old mode 100644 new mode 100755 diff --git a/frontend/ast/decl/Decl.java b/frontend/ast/decl/Decl.java old mode 100644 new mode 100755 diff --git a/frontend/ast/decl/VarDecl.java b/frontend/ast/decl/VarDecl.java old mode 100644 new mode 100755 diff --git a/frontend/ast/decl/VarDef.java b/frontend/ast/decl/VarDef.java old mode 100644 new mode 100755 diff --git a/frontend/ast/exp/AddExp.java b/frontend/ast/exp/AddExp.java old mode 100644 new mode 100755 index 9a322a6..3199286 --- a/frontend/ast/exp/AddExp.java +++ b/frontend/ast/exp/AddExp.java @@ -1,73 +1,73 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.NodeStack; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import midend.symbol.SymbolManager; -import error.Errors; - -public class AddExp extends Node { - public AddExp(TokenStream ts) { - super(SyntaxType.ADD_EXP, ts); - } - - public void parse(Errors errors) { - NodeStack stack = new NodeStack(); - while (true) { - MulExp mep = new MulExp(this.ts); - mep.parse(errors); - stack.push(mep); - if (isAddOp()) { - stack.push(new TokenNode(ts)); // addop - } else { - break; - } - } - if (stack.size() == 1) { - this.addChild((MulExp) stack.pop()); - } else { - AddExp temp = this; - while (stack.size() > 1) { - AddExp ae = new AddExp(this.ts); - MulExp mep = (MulExp) stack.pop(); - TokenNode op = (TokenNode) stack.pop(); - temp.addChild(ae); - temp.addChild(op); - temp.addChild(mep); - temp = ae; - } - temp.addChild((MulExp) stack.pop()); - } - } - - public boolean isAddOp() { - TokenType t = getCurrToken().getType(); - return t == TokenType.PLUS || t == TokenType.MINU; - } - - public int getType() { - if (getChildren().size() == 1) { - return ((MulExp) getChild(0)).getType(); - } else { - return ((AddExp) getChild(0)).getType() - | ((MulExp) getChild(2)).getType(); - } - } - - public int getValue() { - if (getChild(0) instanceof MulExp) { - return ((MulExp) getChild(0)).getValue(); - } else { - int left = ((AddExp) getChild(0)).getValue(); - int right = ((MulExp) getChild(2)).getValue(); - if (((TokenNode) getChild(1)).getType() == TokenType.PLUS) { - return left + right; - } else { - return left - right; - } - } - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.NodeStack; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import midend.symbol.SymbolManager; +import error.Errors; + +public class AddExp extends Node { + public AddExp(TokenStream ts) { + super(SyntaxType.ADD_EXP, ts); + } + + public void parse(Errors errors) { + NodeStack stack = new NodeStack(); + while (true) { + MulExp mep = new MulExp(this.ts); + mep.parse(errors); + stack.push(mep); + if (isAddOp()) { + stack.push(new TokenNode(ts)); // addop + } else { + break; + } + } + if (stack.size() == 1) { + this.addChild((MulExp) stack.pop()); + } else { + AddExp temp = this; + while (stack.size() > 1) { + AddExp ae = new AddExp(this.ts); + MulExp mep = (MulExp) stack.pop(); + TokenNode op = (TokenNode) stack.pop(); + temp.addChild(ae); + temp.addChild(op); + temp.addChild(mep); + temp = ae; + } + temp.addChild((MulExp) stack.pop()); + } + } + + public boolean isAddOp() { + TokenType t = getCurrToken().getType(); + return t == TokenType.PLUS || t == TokenType.MINU; + } + + public int getType() { + if (getChildren().size() == 1) { + return ((MulExp) getChild(0)).getType(); + } else { + return ((AddExp) getChild(0)).getType() + | ((MulExp) getChild(2)).getType(); + } + } + + public int getValue() { + if (getChild(0) instanceof MulExp) { + return ((MulExp) getChild(0)).getValue(); + } else { + int left = ((AddExp) getChild(0)).getValue(); + int right = ((MulExp) getChild(2)).getValue(); + if (((TokenNode) getChild(1)).getType() == TokenType.PLUS) { + return left + right; + } else { + return left - right; + } + } + } +} diff --git a/frontend/ast/exp/Cond.java b/frontend/ast/exp/Cond.java old mode 100644 new mode 100755 index 3ddff91..a5b96ec --- a/frontend/ast/exp/Cond.java +++ b/frontend/ast/exp/Cond.java @@ -1,18 +1,18 @@ -package frontend.ast.exp; - -import frontend.ast.SyntaxType; -import error.Errors; -import frontend.lexer.TokenStream; -import frontend.ast.Node; - -public class Cond extends Node { - public Cond(TokenStream ts) { - super(SyntaxType.COND_EXP, ts); - } - - public void parse(Errors errors) { - LOrExp lep = new LOrExp(this.ts); - lep.parse(errors); - addChild(lep); - } -} +package frontend.ast.exp; + +import frontend.ast.SyntaxType; +import error.Errors; +import frontend.lexer.TokenStream; +import frontend.ast.Node; + +public class Cond extends Node { + public Cond(TokenStream ts) { + super(SyntaxType.COND_EXP, ts); + } + + public void parse(Errors errors) { + LOrExp lep = new LOrExp(this.ts); + lep.parse(errors); + addChild(lep); + } +} diff --git a/frontend/ast/exp/ConstExp.java b/frontend/ast/exp/ConstExp.java old mode 100644 new mode 100755 diff --git a/frontend/ast/exp/EqExp.java b/frontend/ast/exp/EqExp.java old mode 100644 new mode 100755 index 2d36914..5702973 --- a/frontend/ast/exp/EqExp.java +++ b/frontend/ast/exp/EqExp.java @@ -1,49 +1,49 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.NodeStack; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import error.Errors; - -public class EqExp extends Node { - public EqExp(TokenStream ts) { - super(SyntaxType.EQ_EXP, ts); - } - - public void parse(Errors errors) { - NodeStack stack = new NodeStack(); - while (true) { - RelExp relexp = new RelExp(this.ts); - relexp.parse(errors); - stack.push(relexp); - if (isEqOp()) { - stack.push(new TokenNode(ts)); // eqop - } else { - break; - } - } - if(stack.size() == 1) { - this.addChild((RelExp)stack.pop()); - } else { - EqExp temp = this; - while (stack.size() > 1) { - EqExp eep = new EqExp(this.ts); - RelExp relexp = (RelExp)stack.pop(); - TokenNode eqop = (TokenNode)stack.pop(); - temp.addChild(eep); - temp.addChild(eqop); - temp.addChild(relexp); - temp = eep; - } - temp.addChild((RelExp)stack.pop()); - } - } - - public boolean isEqOp() { - TokenType t = getCurrToken().getType(); - return t == TokenType.EQL || t == TokenType.NEQ; - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.NodeStack; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import error.Errors; + +public class EqExp extends Node { + public EqExp(TokenStream ts) { + super(SyntaxType.EQ_EXP, ts); + } + + public void parse(Errors errors) { + NodeStack stack = new NodeStack(); + while (true) { + RelExp relexp = new RelExp(this.ts); + relexp.parse(errors); + stack.push(relexp); + if (isEqOp()) { + stack.push(new TokenNode(ts)); // eqop + } else { + break; + } + } + if(stack.size() == 1) { + this.addChild((RelExp)stack.pop()); + } else { + EqExp temp = this; + while (stack.size() > 1) { + EqExp eep = new EqExp(this.ts); + RelExp relexp = (RelExp)stack.pop(); + TokenNode eqop = (TokenNode)stack.pop(); + temp.addChild(eep); + temp.addChild(eqop); + temp.addChild(relexp); + temp = eep; + } + temp.addChild((RelExp)stack.pop()); + } + } + + public boolean isEqOp() { + TokenType t = getCurrToken().getType(); + return t == TokenType.EQL || t == TokenType.NEQ; + } +} diff --git a/frontend/ast/exp/Exp.java b/frontend/ast/exp/Exp.java old mode 100644 new mode 100755 diff --git a/frontend/ast/exp/LAndExp.java b/frontend/ast/exp/LAndExp.java old mode 100644 new mode 100755 index 9759ef0..6c1089c --- a/frontend/ast/exp/LAndExp.java +++ b/frontend/ast/exp/LAndExp.java @@ -1,44 +1,44 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.NodeStack; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import error.Errors; - -public class LAndExp extends Node { - public LAndExp(TokenStream ts) { - super(SyntaxType.LAND_EXP, ts); - } - - public void parse(Errors errors) { - NodeStack stack = new NodeStack(); - while (true) { - EqExp eep = new EqExp(this.ts); - eep.parse(errors); - stack.push(eep); - if (getCurrToken().getType() == TokenType.AND) { - stack.push(new TokenNode(ts)); // landop - } else { - break; - } - } - if (stack.size() == 1) { - this.addChild((EqExp)stack.pop()); - } else { - LAndExp temp = this; - while(stack.size() > 1) { - LAndExp lae = new LAndExp(this.ts); - EqExp eep = (EqExp)stack.pop(); - TokenNode landop = (TokenNode)stack.pop(); - temp.addChild(lae); - temp.addChild(landop); - temp.addChild(eep); - temp = lae; - } - temp.addChild((EqExp)stack.pop()); - } - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.NodeStack; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import error.Errors; + +public class LAndExp extends Node { + public LAndExp(TokenStream ts) { + super(SyntaxType.LAND_EXP, ts); + } + + public void parse(Errors errors) { + NodeStack stack = new NodeStack(); + while (true) { + EqExp eep = new EqExp(this.ts); + eep.parse(errors); + stack.push(eep); + if (getCurrToken().getType() == TokenType.AND) { + stack.push(new TokenNode(ts)); // landop + } else { + break; + } + } + if (stack.size() == 1) { + this.addChild((EqExp)stack.pop()); + } else { + LAndExp temp = this; + while(stack.size() > 1) { + LAndExp lae = new LAndExp(this.ts); + EqExp eep = (EqExp)stack.pop(); + TokenNode landop = (TokenNode)stack.pop(); + temp.addChild(lae); + temp.addChild(landop); + temp.addChild(eep); + temp = lae; + } + temp.addChild((EqExp)stack.pop()); + } + } +} diff --git a/frontend/ast/exp/LOrExp.java b/frontend/ast/exp/LOrExp.java old mode 100644 new mode 100755 index d4e80af..c5589ba --- a/frontend/ast/exp/LOrExp.java +++ b/frontend/ast/exp/LOrExp.java @@ -1,44 +1,44 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.NodeStack; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import error.Errors; - -public class LOrExp extends Node { - public LOrExp(TokenStream ts) { - super(SyntaxType.LOR_EXP, ts); - } - - public void parse(Errors errors) { - NodeStack stack = new NodeStack(); - while (true) { - LAndExp andexp = new LAndExp(this.ts); - andexp.parse(errors); - stack.push(andexp); - if (getCurrToken().getType() == TokenType.OR) { - stack.push(new TokenNode(ts)); // lorop - } else { - break; - } - } - if (stack.size() == 1) { - this.addChild((LAndExp)stack.pop()); - } else { - LOrExp temp = this; - while(stack.size() > 1) { - LOrExp loe = new LOrExp(this.ts); - LAndExp lae = (LAndExp)stack.pop(); - TokenNode lorop = (TokenNode)stack.pop(); - temp.addChild(loe); - temp.addChild(lorop); - temp.addChild(lae); - temp = loe; - } - temp.addChild((LAndExp)stack.pop()); - } - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.NodeStack; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import error.Errors; + +public class LOrExp extends Node { + public LOrExp(TokenStream ts) { + super(SyntaxType.LOR_EXP, ts); + } + + public void parse(Errors errors) { + NodeStack stack = new NodeStack(); + while (true) { + LAndExp andexp = new LAndExp(this.ts); + andexp.parse(errors); + stack.push(andexp); + if (getCurrToken().getType() == TokenType.OR) { + stack.push(new TokenNode(ts)); // lorop + } else { + break; + } + } + if (stack.size() == 1) { + this.addChild((LAndExp)stack.pop()); + } else { + LOrExp temp = this; + while(stack.size() > 1) { + LOrExp loe = new LOrExp(this.ts); + LAndExp lae = (LAndExp)stack.pop(); + TokenNode lorop = (TokenNode)stack.pop(); + temp.addChild(loe); + temp.addChild(lorop); + temp.addChild(lae); + temp = loe; + } + temp.addChild((LAndExp)stack.pop()); + } + } +} diff --git a/frontend/ast/exp/LVal.java b/frontend/ast/exp/LVal.java old mode 100644 new mode 100755 index 51fd790..8aeb4fd --- a/frontend/ast/exp/LVal.java +++ b/frontend/ast/exp/LVal.java @@ -1,59 +1,59 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.ast.token.TokenNode; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import midend.symbol.SymbolManager; -import midend.symbol.Symbol; -import midend.symbol.ArraySymbol; -import error.Errors; -import error.Error; -import error.ErrorType; - -public class LVal extends Node { - public LVal(TokenStream ts) { - super(SyntaxType.LVAL_EXP, ts); - } - - public void parse(Errors errors) { - addChild(new TokenNode(this.ts)); // idenfr - if (getCurrToken().getType() == TokenType.LBRACK) { - addChild(new TokenNode(this.ts)); // lbrack - Exp exp = new Exp(this.ts); - exp.parse(errors); - addChild(exp); - if (getCurrToken().getType() == TokenType.RBRACK) { - addChild(new TokenNode(this.ts)); // rbrack - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.k)); - } - } - } - - public int getType() { - if (getChildren().size() == 1) { - TokenNode idenfr = (TokenNode) getChild(0); - Symbol symbol = SymbolManager.getSymbol(idenfr.getName()); - if (symbol instanceof ArraySymbol) { - return 1; - } - return 0; - } else { - return 0; - } - } - - public int getValue() { - TokenNode idenfr = (TokenNode) getChild(0); //idenfr一定是个常量,可在符号表找到且有值 - if (getChildren().size() == 1) { - Symbol symbol = SymbolManager.getSymbol(idenfr.getName()); - return symbol.getValue(0); - } else { - int index = ((Exp) getChild(2)).getValue(); - Symbol symbol = SymbolManager.getSymbol(idenfr.getName()); - return symbol.getValue(index); - } - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.ast.token.TokenNode; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import midend.symbol.SymbolManager; +import midend.symbol.Symbol; +import midend.symbol.ArraySymbol; +import error.Errors; +import error.Error; +import error.ErrorType; + +public class LVal extends Node { + public LVal(TokenStream ts) { + super(SyntaxType.LVAL_EXP, ts); + } + + public void parse(Errors errors) { + addChild(new TokenNode(this.ts)); // idenfr + if (getCurrToken().getType() == TokenType.LBRACK) { + addChild(new TokenNode(this.ts)); // lbrack + Exp exp = new Exp(this.ts); + exp.parse(errors); + addChild(exp); + if (getCurrToken().getType() == TokenType.RBRACK) { + addChild(new TokenNode(this.ts)); // rbrack + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.k)); + } + } + } + + public int getType() { + if (getChildren().size() == 1) { + TokenNode idenfr = (TokenNode) getChild(0); + Symbol symbol = SymbolManager.getSymbol(idenfr.getName()); + if (symbol instanceof ArraySymbol) { + return 1; + } + return 0; + } else { + return 0; + } + } + + public int getValue() { + TokenNode idenfr = (TokenNode) getChild(0); //idenfr一定是个常量,可在符号表找到且有值 + if (getChildren().size() == 1) { + Symbol symbol = SymbolManager.getSymbol(idenfr.getName()); + return symbol.getValue(0); + } else { + int index = ((Exp) getChild(2)).getValue(); + Symbol symbol = SymbolManager.getSymbol(idenfr.getName()); + return symbol.getValue(index); + } + } +} diff --git a/frontend/ast/exp/MulExp.java b/frontend/ast/exp/MulExp.java old mode 100644 new mode 100755 index 96f0aeb..a88cbff --- a/frontend/ast/exp/MulExp.java +++ b/frontend/ast/exp/MulExp.java @@ -1,75 +1,75 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import frontend.ast.NodeStack; -import midend.symbol.SymbolManager; -import error.Errors; - -public class MulExp extends Node { - public MulExp(TokenStream ts) { - super(SyntaxType.MUL_EXP, ts); - } - - public void parse(Errors errors) { - NodeStack stack = new NodeStack(); - while (true) { - UnaryExp uep = new UnaryExp(this.ts); - uep.parse(errors); - stack.push(uep); - if (isMulOp()) { - stack.push(new TokenNode(ts)); // mulop - } else { - break; - } - } - if (stack.size() == 1) { - addChild((UnaryExp)stack.pop()); - } else { - MulExp temp = this; - while (stack.size() > 1) { - MulExp mep = new MulExp(this.ts); - UnaryExp uep = (UnaryExp) stack.pop(); - TokenNode mulop = (TokenNode) stack.pop(); - temp.addChild(mep); - temp.addChild(mulop); - temp.addChild(uep); - temp = mep; - } - temp.addChild((UnaryExp)stack.pop()); - } - } - - public boolean isMulOp() { - TokenType t = getCurrToken().getType(); - return t == TokenType.MULT || t == TokenType.DIV || t == TokenType.MOD; - } - - public int getType() { - if (getChildren().size() == 1) { - return ((UnaryExp) getChild(0)).getType(); - } else { - return ((MulExp) getChild(0)).getType() - | ((UnaryExp) getChild(2)).getType(); - } - } - - public int getValue() { - if (getChild(0) instanceof UnaryExp) { - return ((UnaryExp) getChild(0)).getValue(); - } else { - int left = ((MulExp) getChild(0)).getValue(); - int right = ((UnaryExp) getChild(2)).getValue(); - if (((TokenNode) getChild(1)).getType() == TokenType.MULT) { - return left * right; - } else if (((TokenNode) getChild(1)).getType() == TokenType.DIV) { - return left / right; - } else { - return left % right; - } - } - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import frontend.ast.NodeStack; +import midend.symbol.SymbolManager; +import error.Errors; + +public class MulExp extends Node { + public MulExp(TokenStream ts) { + super(SyntaxType.MUL_EXP, ts); + } + + public void parse(Errors errors) { + NodeStack stack = new NodeStack(); + while (true) { + UnaryExp uep = new UnaryExp(this.ts); + uep.parse(errors); + stack.push(uep); + if (isMulOp()) { + stack.push(new TokenNode(ts)); // mulop + } else { + break; + } + } + if (stack.size() == 1) { + addChild((UnaryExp)stack.pop()); + } else { + MulExp temp = this; + while (stack.size() > 1) { + MulExp mep = new MulExp(this.ts); + UnaryExp uep = (UnaryExp) stack.pop(); + TokenNode mulop = (TokenNode) stack.pop(); + temp.addChild(mep); + temp.addChild(mulop); + temp.addChild(uep); + temp = mep; + } + temp.addChild((UnaryExp)stack.pop()); + } + } + + public boolean isMulOp() { + TokenType t = getCurrToken().getType(); + return t == TokenType.MULT || t == TokenType.DIV || t == TokenType.MOD; + } + + public int getType() { + if (getChildren().size() == 1) { + return ((UnaryExp) getChild(0)).getType(); + } else { + return ((MulExp) getChild(0)).getType() + | ((UnaryExp) getChild(2)).getType(); + } + } + + public int getValue() { + if (getChild(0) instanceof UnaryExp) { + return ((UnaryExp) getChild(0)).getValue(); + } else { + int left = ((MulExp) getChild(0)).getValue(); + int right = ((UnaryExp) getChild(2)).getValue(); + if (((TokenNode) getChild(1)).getType() == TokenType.MULT) { + return left * right; + } else if (((TokenNode) getChild(1)).getType() == TokenType.DIV) { + return left / right; + } else { + return left % right; + } + } + } +} diff --git a/frontend/ast/exp/NumberExp.java b/frontend/ast/exp/NumberExp.java old mode 100644 new mode 100755 index 12b93af..2ee3fec --- a/frontend/ast/exp/NumberExp.java +++ b/frontend/ast/exp/NumberExp.java @@ -1,21 +1,21 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import error.Errors; -import frontend.ast.token.TokenNode; - -public class NumberExp extends Node { - public NumberExp(TokenStream ts) { - super(SyntaxType.NUMBER, ts); - } - - public void parse(Errors errors) { - addChild(new TokenNode(ts)); //intconst - } - - public int getValue() { - return Integer.parseInt(((TokenNode) getChild(0)).getValue()); - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import error.Errors; +import frontend.ast.token.TokenNode; + +public class NumberExp extends Node { + public NumberExp(TokenStream ts) { + super(SyntaxType.NUMBER, ts); + } + + public void parse(Errors errors) { + addChild(new TokenNode(ts)); //intconst + } + + public int getValue() { + return Integer.parseInt(((TokenNode) getChild(0)).getValue()); + } +} diff --git a/frontend/ast/exp/PrimaryExp.java b/frontend/ast/exp/PrimaryExp.java old mode 100644 new mode 100755 index 9934797..4ad11c7 --- a/frontend/ast/exp/PrimaryExp.java +++ b/frontend/ast/exp/PrimaryExp.java @@ -1,58 +1,58 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import error.Errors; -import error.Error; -import error.ErrorType; - -public class PrimaryExp extends Node { - public PrimaryExp(TokenStream ts) { - super(SyntaxType.PRIMARY_EXP, ts); - } - - public void parse(Errors errors) { - if (getCurrToken().getType() == TokenType.LPARENT) { - addChild(new TokenNode(ts)); // lparent - Exp exp = new Exp(this.ts); - exp.parse(errors); - addChild(exp); - if (getCurrToken().getType() == TokenType.RPARENT) { - addChild(new TokenNode(ts)); // rparent - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); - } - } else if (getCurrToken().getType() == TokenType.IDENFR) { - LVal lval = new LVal(this.ts); - lval.parse(errors); - addChild(lval); - } else { - NumberExp num = new NumberExp(this.ts); - num.parse(errors); - addChild(num); - } - } - - public int getType() { - if (getChild(0) instanceof TokenNode) { - return ((Exp) getChild(1)).getType(); - } else if (getChild(0) instanceof LVal) { - return ((LVal) getChild(0)).getType(); - } else { - return 0; - } - } - - public int getValue() { - if (getChild(0) instanceof TokenNode) { - return ((Exp) getChild(1)).getValue(); - } else if (getChild(0) instanceof LVal) { - return ((LVal) getChild(0)).getValue(); - } else { - return ((NumberExp) getChild(0)).getValue(); - } - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import error.Errors; +import error.Error; +import error.ErrorType; + +public class PrimaryExp extends Node { + public PrimaryExp(TokenStream ts) { + super(SyntaxType.PRIMARY_EXP, ts); + } + + public void parse(Errors errors) { + if (getCurrToken().getType() == TokenType.LPARENT) { + addChild(new TokenNode(ts)); // lparent + Exp exp = new Exp(this.ts); + exp.parse(errors); + addChild(exp); + if (getCurrToken().getType() == TokenType.RPARENT) { + addChild(new TokenNode(ts)); // rparent + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); + } + } else if (getCurrToken().getType() == TokenType.IDENFR) { + LVal lval = new LVal(this.ts); + lval.parse(errors); + addChild(lval); + } else { + NumberExp num = new NumberExp(this.ts); + num.parse(errors); + addChild(num); + } + } + + public int getType() { + if (getChild(0) instanceof TokenNode) { + return ((Exp) getChild(1)).getType(); + } else if (getChild(0) instanceof LVal) { + return ((LVal) getChild(0)).getType(); + } else { + return 0; + } + } + + public int getValue() { + if (getChild(0) instanceof TokenNode) { + return ((Exp) getChild(1)).getValue(); + } else if (getChild(0) instanceof LVal) { + return ((LVal) getChild(0)).getValue(); + } else { + return ((NumberExp) getChild(0)).getValue(); + } + } +} diff --git a/frontend/ast/exp/RelExp.java b/frontend/ast/exp/RelExp.java old mode 100644 new mode 100755 index 4d244f5..9f55ffb --- a/frontend/ast/exp/RelExp.java +++ b/frontend/ast/exp/RelExp.java @@ -1,50 +1,50 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.NodeStack; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import error.Errors; - -public class RelExp extends Node { - public RelExp(TokenStream ts) { - super(SyntaxType.REL_EXP, ts); - } - - public void parse(Errors errors) { - NodeStack stack = new NodeStack(); - while (true) { - AddExp addexp = new AddExp(this.ts); - addexp.parse(errors); - stack.push(addexp); - if (isRelOp()) { - stack.push(new TokenNode(ts)); // relop - } else { - break; - } - } - if (stack.size() == 1) { - this.addChild((AddExp)stack.pop()); - } else { - RelExp temp = this; - while(stack.size() > 1) { - RelExp rexp = new RelExp(this.ts); - AddExp addexp = (AddExp)stack.pop(); - TokenNode relop = (TokenNode)stack.pop(); - temp.addChild(rexp); - temp.addChild(relop); - temp.addChild(addexp); - temp = rexp; - } - temp.addChild((AddExp)stack.pop()); - } - } - - public boolean isRelOp() { - TokenType t = getCurrToken().getType(); - return t == TokenType.LSS || t == TokenType.GRE - || t == TokenType.LEQ || t == TokenType.GEQ; - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.NodeStack; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import error.Errors; + +public class RelExp extends Node { + public RelExp(TokenStream ts) { + super(SyntaxType.REL_EXP, ts); + } + + public void parse(Errors errors) { + NodeStack stack = new NodeStack(); + while (true) { + AddExp addexp = new AddExp(this.ts); + addexp.parse(errors); + stack.push(addexp); + if (isRelOp()) { + stack.push(new TokenNode(ts)); // relop + } else { + break; + } + } + if (stack.size() == 1) { + this.addChild((AddExp)stack.pop()); + } else { + RelExp temp = this; + while(stack.size() > 1) { + RelExp rexp = new RelExp(this.ts); + AddExp addexp = (AddExp)stack.pop(); + TokenNode relop = (TokenNode)stack.pop(); + temp.addChild(rexp); + temp.addChild(relop); + temp.addChild(addexp); + temp = rexp; + } + temp.addChild((AddExp)stack.pop()); + } + } + + public boolean isRelOp() { + TokenType t = getCurrToken().getType(); + return t == TokenType.LSS || t == TokenType.GRE + || t == TokenType.LEQ || t == TokenType.GEQ; + } +} diff --git a/frontend/ast/exp/UnaryExp.java b/frontend/ast/exp/UnaryExp.java old mode 100644 new mode 100755 index bd5f3a7..e236c29 --- a/frontend/ast/exp/UnaryExp.java +++ b/frontend/ast/exp/UnaryExp.java @@ -1,124 +1,124 @@ -package frontend.ast.exp; - -import java.util.ArrayList; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import frontend.ast.token.TokenNode; -import frontend.ast.func.FuncRParams; -import midend.symbol.FuncSymbol; -import midend.symbol.SymbolManager; -import error.Errors; - -import error.Error; -import error.ErrorType; - -public class UnaryExp extends Node { - public UnaryExp(TokenStream ts) { - super(SyntaxType.UNARY_EXP, ts); - } - - public void parse(Errors errors) { - if (isUnaryOp()) { - UnaryOp uop = new UnaryOp(ts); - uop.parse(errors); - addChild(uop); - UnaryExp uep = new UnaryExp(ts); - uep.parse(errors); - addChild(uep); - } else if (getCurrToken().getType() == TokenType.IDENFR - && this.ts.peek(1).getType() == TokenType.LPARENT) { - addChild(new TokenNode(ts)); // idenfr - addChild(new TokenNode(ts)); // lparent - if (isExp()) { - FuncRParams frp = new FuncRParams(ts); - frp.parse(errors); - addChild(frp); - } - if (getCurrToken().getType() == TokenType.RPARENT) { - addChild(new TokenNode(ts)); // rparent - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); - } - } else { - PrimaryExp pme = new PrimaryExp(ts); - pme.parse(errors); - addChild(pme); - } - } - - public boolean isUnaryOp() { - return getCurrToken().getType() == TokenType.PLUS - || getCurrToken().getType() == TokenType.MINU - || getCurrToken().getType() == TokenType.NOT; - } - - public boolean isExp() { - TokenType t = getCurrToken().getType(); - return t == TokenType.PLUS || t == TokenType.MINU || t == TokenType.NOT - || t == TokenType.IDENFR || t == TokenType.LPARENT || t == TokenType.INTCON; - } - - public void handleFuncCall(Errors errors) { // 当其为函数调用形式时才会调用 - TokenNode funcIdenfr = (TokenNode) getChild(0); - if (funcIdenfr.getName().equals("getint")) { - if (getChildren().size() == 4) { - errors.addError(new Error(funcIdenfr.getLine(), ErrorType.d)); - } - return; - } - FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol(funcIdenfr.getName()); - if (funcSymbol == null) { - errors.addError(new Error(funcIdenfr.getLine(), ErrorType.c)); - return; - } - int fparaNum = funcSymbol.getParamNum(); - int rparaNum = 0; - if (getChildren().size() >= 3 && getChild(2) instanceof FuncRParams) { - FuncRParams frp = (FuncRParams) getChild(2); - rparaNum = frp.getParamNum(); - if (rparaNum == fparaNum) { - frp.checkParamType(funcSymbol, errors, funcIdenfr.getLine()); - } - } - if (fparaNum != rparaNum) { - errors.addError(new Error(funcIdenfr.getLine(), ErrorType.d)); - } - } - - public int getType() { - if (getChild(0) instanceof PrimaryExp) { - return ((PrimaryExp) getChild(0)).getType(); - } else if (getChild(0) instanceof TokenNode) { - return 0; - } else { - return ((UnaryExp) getChild(1)).getType(); - } - } - - public int getValue() { - if (getChild(0) instanceof UnaryOp) { - UnaryOp uop = (UnaryOp) getChild(0); - TokenNode opToken = (TokenNode) uop.getChild(0); - return opToken.getType() == TokenType.PLUS ? ((UnaryExp) getChild(1)).getValue() - : -((UnaryExp) getChild(1)).getValue(); - } else if (getChild(0) instanceof PrimaryExp) { - return ((PrimaryExp) getChild(0)).getValue(); - } else { - return 0; // 0表示这个是函数,getvalue只是对于常量或常量表达式取值,所以正常情况调用getvalue函数时是不会跳转到这个分支的 - } - } - - public ArrayList getParamList() { - if (!(getChild(0) instanceof TokenNode)) { - return null; - } else { - if (getChildren().size() >= 3 && (getChild(2) instanceof FuncRParams)) { - return ((FuncRParams) getChild(2)).getParamList(); - } - return new ArrayList(); - } - } -} +package frontend.ast.exp; + +import java.util.ArrayList; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import frontend.ast.token.TokenNode; +import frontend.ast.func.FuncRParams; +import midend.symbol.FuncSymbol; +import midend.symbol.SymbolManager; +import error.Errors; + +import error.Error; +import error.ErrorType; + +public class UnaryExp extends Node { + public UnaryExp(TokenStream ts) { + super(SyntaxType.UNARY_EXP, ts); + } + + public void parse(Errors errors) { + if (isUnaryOp()) { + UnaryOp uop = new UnaryOp(ts); + uop.parse(errors); + addChild(uop); + UnaryExp uep = new UnaryExp(ts); + uep.parse(errors); + addChild(uep); + } else if (getCurrToken().getType() == TokenType.IDENFR + && this.ts.peek(1).getType() == TokenType.LPARENT) { + addChild(new TokenNode(ts)); // idenfr + addChild(new TokenNode(ts)); // lparent + if (isExp()) { + FuncRParams frp = new FuncRParams(ts); + frp.parse(errors); + addChild(frp); + } + if (getCurrToken().getType() == TokenType.RPARENT) { + addChild(new TokenNode(ts)); // rparent + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.j)); + } + } else { + PrimaryExp pme = new PrimaryExp(ts); + pme.parse(errors); + addChild(pme); + } + } + + public boolean isUnaryOp() { + return getCurrToken().getType() == TokenType.PLUS + || getCurrToken().getType() == TokenType.MINU + || getCurrToken().getType() == TokenType.NOT; + } + + public boolean isExp() { + TokenType t = getCurrToken().getType(); + return t == TokenType.PLUS || t == TokenType.MINU || t == TokenType.NOT + || t == TokenType.IDENFR || t == TokenType.LPARENT || t == TokenType.INTCON; + } + + public void handleFuncCall(Errors errors) { // 当其为函数调用形式时才会调用 + TokenNode funcIdenfr = (TokenNode) getChild(0); + if (funcIdenfr.getName().equals("getint")) { + if (getChildren().size() == 4) { + errors.addError(new Error(funcIdenfr.getLine(), ErrorType.d)); + } + return; + } + FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol(funcIdenfr.getName()); + if (funcSymbol == null) { + errors.addError(new Error(funcIdenfr.getLine(), ErrorType.c)); + return; + } + int fparaNum = funcSymbol.getParamNum(); + int rparaNum = 0; + if (getChildren().size() >= 3 && getChild(2) instanceof FuncRParams) { + FuncRParams frp = (FuncRParams) getChild(2); + rparaNum = frp.getParamNum(); + if (rparaNum == fparaNum) { + frp.checkParamType(funcSymbol, errors, funcIdenfr.getLine()); + } + } + if (fparaNum != rparaNum) { + errors.addError(new Error(funcIdenfr.getLine(), ErrorType.d)); + } + } + + public int getType() { + if (getChild(0) instanceof PrimaryExp) { + return ((PrimaryExp) getChild(0)).getType(); + } else if (getChild(0) instanceof TokenNode) { + return 0; + } else { + return ((UnaryExp) getChild(1)).getType(); + } + } + + public int getValue() { + if (getChild(0) instanceof UnaryOp) { + UnaryOp uop = (UnaryOp) getChild(0); + TokenNode opToken = (TokenNode) uop.getChild(0); + return opToken.getType() == TokenType.PLUS ? ((UnaryExp) getChild(1)).getValue() + : -((UnaryExp) getChild(1)).getValue(); + } else if (getChild(0) instanceof PrimaryExp) { + return ((PrimaryExp) getChild(0)).getValue(); + } else { + return 0; // 0表示这个是函数,getvalue只是对于常量或常量表达式取值,所以正常情况调用getvalue函数时是不会跳转到这个分支的 + } + } + + public ArrayList getParamList() { + if (!(getChild(0) instanceof TokenNode)) { + return null; + } else { + if (getChildren().size() >= 3 && (getChild(2) instanceof FuncRParams)) { + return ((FuncRParams) getChild(2)).getParamList(); + } + return new ArrayList(); + } + } +} diff --git a/frontend/ast/exp/UnaryOp.java b/frontend/ast/exp/UnaryOp.java old mode 100644 new mode 100755 index b5931ff..271b5c9 --- a/frontend/ast/exp/UnaryOp.java +++ b/frontend/ast/exp/UnaryOp.java @@ -1,17 +1,17 @@ -package frontend.ast.exp; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import error.Errors; -import frontend.ast.token.TokenNode; - -public class UnaryOp extends Node { - public UnaryOp(TokenStream ts) { - super(SyntaxType.UNARY_OP, ts); - } - - public void parse(Errors errors) { - addChild(new TokenNode(ts)); // unary op - } -} +package frontend.ast.exp; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import error.Errors; +import frontend.ast.token.TokenNode; + +public class UnaryOp extends Node { + public UnaryOp(TokenStream ts) { + super(SyntaxType.UNARY_OP, ts); + } + + public void parse(Errors errors) { + addChild(new TokenNode(ts)); // unary op + } +} diff --git a/frontend/ast/func/FuncDef.java b/frontend/ast/func/FuncDef.java old mode 100644 new mode 100755 diff --git a/frontend/ast/func/FuncFParam.java b/frontend/ast/func/FuncFParam.java old mode 100644 new mode 100755 index 18e9929..dc027c5 --- a/frontend/ast/func/FuncFParam.java +++ b/frontend/ast/func/FuncFParam.java @@ -1,49 +1,49 @@ -package frontend.ast.func; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; - -import midend.symbol.Symbol; -import midend.symbol.SymbolType; -import midend.symbol.ArraySymbol; - -import error.Errors; -import frontend.ast.token.TokenNode; -import error.ErrorType; -import error.Error; - -public class FuncFParam extends Node { - public FuncFParam(TokenStream ts) { - super(SyntaxType.FUNC_FORMAL_PARAM, ts); - } - - public void parse(Errors errors) { - TokenNode intkk = new TokenNode(this.ts); - addChild(intkk); - TokenNode ident = new TokenNode(this.ts); - addChild(ident); - if (getCurrToken().getType() == TokenType.LBRACK) { - TokenNode lbrack = new TokenNode(this.ts); - addChild(lbrack); - if (getCurrToken().getType() == TokenType.RBRACK) { - TokenNode rbrack = new TokenNode(this.ts); - addChild(rbrack); - } else { - errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.k)); - } - } - } - - public Symbol getSymbol() { - if (getChildren().size() == 2) { - TokenNode tn = (TokenNode) getChild(1); - return new Symbol(tn.getName(), SymbolType.INT, tn.getLine()); - } else { - TokenNode tn = (TokenNode) getChild(1); - return new ArraySymbol(tn.getName(), SymbolType.INT_ARRAY, tn.getLine(), -1); - //这里不求维数,因为函数形参为数组只是相当于一个指针 - } - } +package frontend.ast.func; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; + +import midend.symbol.Symbol; +import midend.symbol.SymbolType; +import midend.symbol.ArraySymbol; + +import error.Errors; +import frontend.ast.token.TokenNode; +import error.ErrorType; +import error.Error; + +public class FuncFParam extends Node { + public FuncFParam(TokenStream ts) { + super(SyntaxType.FUNC_FORMAL_PARAM, ts); + } + + public void parse(Errors errors) { + TokenNode intkk = new TokenNode(this.ts); + addChild(intkk); + TokenNode ident = new TokenNode(this.ts); + addChild(ident); + if (getCurrToken().getType() == TokenType.LBRACK) { + TokenNode lbrack = new TokenNode(this.ts); + addChild(lbrack); + if (getCurrToken().getType() == TokenType.RBRACK) { + TokenNode rbrack = new TokenNode(this.ts); + addChild(rbrack); + } else { + errors.addError(new Error(this.ts.peek(-1).getLine(), ErrorType.k)); + } + } + } + + public Symbol getSymbol() { + if (getChildren().size() == 2) { + TokenNode tn = (TokenNode) getChild(1); + return new Symbol(tn.getName(), SymbolType.INT, tn.getLine()); + } else { + TokenNode tn = (TokenNode) getChild(1); + return new ArraySymbol(tn.getName(), SymbolType.INT_ARRAY, tn.getLine(), -1); + //这里不求维数,因为函数形参为数组只是相当于一个指针 + } + } } \ No newline at end of file diff --git a/frontend/ast/func/FuncFParams.java b/frontend/ast/func/FuncFParams.java old mode 100644 new mode 100755 diff --git a/frontend/ast/func/FuncRParams.java b/frontend/ast/func/FuncRParams.java old mode 100644 new mode 100755 index 9839bbf..a42f2a0 --- a/frontend/ast/func/FuncRParams.java +++ b/frontend/ast/func/FuncRParams.java @@ -1,57 +1,57 @@ -package frontend.ast.func; - -import java.util.ArrayList; - -import frontend.ast.Node; -import frontend.ast.SyntaxType; -import frontend.lexer.TokenStream; -import frontend.lexer.TokenType; -import error.Errors; -import error.Error; -import error.ErrorType; -import frontend.ast.token.TokenNode; -import frontend.ast.exp.Exp; -import midend.symbol.FuncSymbol; - -public class FuncRParams extends Node { - public FuncRParams(TokenStream ts) { - super(SyntaxType.FUNC_REAL_PARAM_S, ts); - } - - public void parse(Errors errors) { - while (true) { - Exp ep = new Exp(ts); - ep.parse(errors); - addChild(ep); - if (getCurrToken().getType() == TokenType.COMMA) { - addChild(new TokenNode(ts)); // comma - } else { - break; - } - } - } - - public int getParamNum() { - return (getChildren().size() + 1) / 2; - } - - public void checkParamType(FuncSymbol funcSymbol, Errors errors, int line) { - int fparaNum = funcSymbol.getParamNum(); - int rparaNum = getParamNum(); - int size = rparaNum < fparaNum ? rparaNum : fparaNum; - for (int i = 0; i < size; i++) { - Exp exp = (Exp) getChild(i * 2); - if (exp.getType() != funcSymbol.getParamType(i)) { - errors.addError(new Error(line, ErrorType.e)); - } - } - } - - public ArrayList getParamList() { - ArrayList paramList = new ArrayList(); - for (int i = 0; i < getChildren().size(); i += 2) { - paramList.add((Exp) getChild(i)); - } - return paramList; - } -} +package frontend.ast.func; + +import java.util.ArrayList; + +import frontend.ast.Node; +import frontend.ast.SyntaxType; +import frontend.lexer.TokenStream; +import frontend.lexer.TokenType; +import error.Errors; +import error.Error; +import error.ErrorType; +import frontend.ast.token.TokenNode; +import frontend.ast.exp.Exp; +import midend.symbol.FuncSymbol; + +public class FuncRParams extends Node { + public FuncRParams(TokenStream ts) { + super(SyntaxType.FUNC_REAL_PARAM_S, ts); + } + + public void parse(Errors errors) { + while (true) { + Exp ep = new Exp(ts); + ep.parse(errors); + addChild(ep); + if (getCurrToken().getType() == TokenType.COMMA) { + addChild(new TokenNode(ts)); // comma + } else { + break; + } + } + } + + public int getParamNum() { + return (getChildren().size() + 1) / 2; + } + + public void checkParamType(FuncSymbol funcSymbol, Errors errors, int line) { + int fparaNum = funcSymbol.getParamNum(); + int rparaNum = getParamNum(); + int size = rparaNum < fparaNum ? rparaNum : fparaNum; + for (int i = 0; i < size; i++) { + Exp exp = (Exp) getChild(i * 2); + if (exp.getType() != funcSymbol.getParamType(i)) { + errors.addError(new Error(line, ErrorType.e)); + } + } + } + + public ArrayList getParamList() { + ArrayList paramList = new ArrayList(); + for (int i = 0; i < getChildren().size(); i += 2) { + paramList.add((Exp) getChild(i)); + } + return paramList; + } +} diff --git a/frontend/ast/func/FuncType.java b/frontend/ast/func/FuncType.java old mode 100644 new mode 100755 diff --git a/frontend/ast/func/MainFuncDef.java b/frontend/ast/func/MainFuncDef.java old mode 100644 new mode 100755 diff --git a/frontend/ast/token/TokenNode.java b/frontend/ast/token/TokenNode.java old mode 100644 new mode 100755 diff --git a/frontend/ast/val/ConstInitVal.java b/frontend/ast/val/ConstInitVal.java old mode 100644 new mode 100755 diff --git a/frontend/ast/val/InitVal.java b/frontend/ast/val/InitVal.java old mode 100644 new mode 100755 diff --git a/frontend/lexer/Lexer.java b/frontend/lexer/Lexer.java old mode 100644 new mode 100755 index ac4b0d7..cc00d38 --- a/frontend/lexer/Lexer.java +++ b/frontend/lexer/Lexer.java @@ -1,245 +1,245 @@ -package frontend.lexer; - -import java.util.ArrayList; - -import error.Error; -import error.ErrorType; -import error.Errors; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.io.IOException; - -public class Lexer { - private String input; - private ArrayList tokens; - private int position; - private int line; - private char currentChar; - - public Lexer(String input) { - this.input = input; - this.tokens = new ArrayList(); - this.position = 0; - this.line = 1; - } - - public void lex(Errors errors) { - int sigComment = 0; - while (this.position < this.input.length()) { - currentChar = this.input.charAt(this.position); - if (currentChar == ' ' || currentChar == '\t') { - this.position++; - continue; - } - if (currentChar == '\n' || currentChar == '\r') { - if (currentChar == '\r') { - if (this.position + 1 < this.input.length() && - this.input.charAt(this.position + 1) == '\n') { - this.position++; - } - } - this.line++; - this.position++; - if (sigComment == 1) { - sigComment = 0; - } - continue; - } - if (sigComment == 0) { - if (currentChar == '/') { - if (this.position + 1 < this.input.length() && - this.input.charAt(this.position + 1) == '/') { - sigComment = 1; - this.position += 2; - continue; - } - if (this.position + 1 < this.input.length() && - this.input.charAt(this.position + 1) == '*') { - sigComment = 2; - this.position += 2; - continue; - } - } - if (this.isIntCons()) { - lexInt(); - continue; - } - if (this.isStrCons()) { - lexStr(); - continue; - } - if (this.isIdenfr()) { - lexIdenfr(); - continue; - } - lexOp(errors); - } - if (sigComment == 2) { - if (this.position + 1 < this.input.length() && - this.currentChar == '*' && this.input.charAt(this.position + 1) == '/') { - sigComment = 0; - this.position += 2; - continue; - } - } - if (sigComment != 0) { - this.position++; - } - } - } - - public boolean isIntCons() { - return Character.isDigit(this.currentChar); - } - - public boolean isStrCons() { - return this.currentChar == '"'; - } - - public boolean isIdenfr() { - return Character.isLowerCase(this.currentChar) || Character.isUpperCase(this.currentChar) - || this.currentChar == '_'; - } - - public boolean isNotWp() { - return !Character.isWhitespace(this.currentChar); - } - - public boolean isOp() { - return !this.isIntCons() && !this.isStrCons() && !this.isIdenfr(); - } - - public void lexInt() { - StringBuilder sb = new StringBuilder(); - while (this.position < this.input.length() && this.isIntCons()) { - sb.append(this.currentChar); - this.position++; - updateCurrentChar(); - } - this.tokens.add(new Token(sb.toString(), this.line)); - } - - public void lexStr() { - StringBuilder sb = new StringBuilder(); - sb.append(this.currentChar); - this.position++; - updateCurrentChar(); - while (this.position < this.input.length() && this.currentChar != '"') { - sb.append(this.currentChar); - this.position++; - updateCurrentChar(); - } - if (this.position < this.input.length() && this.currentChar == '"') { - sb.append(this.currentChar); - this.position++; - } - this.tokens.add(new Token(sb.toString(), this.line)); - } - - public void lexIdenfr() { - StringBuilder sb = new StringBuilder(); - while (this.position < this.input.length() && (this.isIdenfr() || this.isIntCons())) { - sb.append(this.currentChar); - this.position++; - updateCurrentChar(); - } - this.tokens.add(new Token(sb.toString(), this.line)); - } - - public void lexOp(Errors errors) { - StringBuilder sb = new StringBuilder(); - if (this.currentChar == '/' && this.position + 1 < this.input.length() && - (this.input.charAt(this.position + 1) == '/' || - this.input.charAt(this.position + 1) == '*')) { - return; - } - sb.append(this.currentChar); - switch (this.currentChar) { - case '&': - readAnd(sb); - break; - case '|': - readOr(sb); - break; - case '<': - readEq(sb); - break; - case '>': - readEq(sb); - break; - case '=': - readEq(sb); - break; - case '!': - readEq(sb); - break; - default: - break; - } - this.position++; - if (sb.toString().equals("&") || sb.toString().equals("|")) { - errors.addError(new Error(this.line, ErrorType.a)); - } - this.tokens.add(new Token(sb.toString(), this.line)); - } - - public void readAnd(StringBuilder sb) { - if (this.position + 1 < this.input.length() && - this.input.charAt(this.position + 1) == '&') { - this.position++; - currentChar = this.input.charAt(this.position); - sb.append(currentChar); - } - } - - public void readOr(StringBuilder sb) { - if (this.position + 1 < this.input.length() && - this.input.charAt(this.position + 1) == '|') { - this.position++; - currentChar = this.input.charAt(this.position); - sb.append(currentChar); - } - } - - public void readEq(StringBuilder sb) { - if (this.position + 1 < this.input.length() && - this.input.charAt(this.position + 1) == '=') { - this.position++; - currentChar = this.input.charAt(this.position); - sb.append(currentChar); - } - } - - public void updateCurrentChar() { - if (this.position < this.input.length()) { - currentChar = this.input.charAt(this.position); - } - } - - public void printTokens() { - for (Token token : this.tokens) { - token.adjustType(); - System.out.println(token.getType() + " " + token.getValue() + " " + token.getLine()); - } - } - - public void writeToFile(String fileName) { - try { - StringBuilder sb = new StringBuilder(); - for (Token token : this.tokens) { - token.adjustType(); - sb.append(token.toString()); - } - Files.write(Paths.get(fileName), sb.toString().getBytes()); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public ArrayList getTokens() { - for (Token token : this.tokens) { - token.adjustType(); - } - return this.tokens; - } -} +package frontend.lexer; + +import java.util.ArrayList; + +import error.Error; +import error.ErrorType; +import error.Errors; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.io.IOException; + +public class Lexer { + private String input; + private ArrayList tokens; + private int position; + private int line; + private char currentChar; + + public Lexer(String input) { + this.input = input; + this.tokens = new ArrayList(); + this.position = 0; + this.line = 1; + } + + public void lex(Errors errors) { + int sigComment = 0; + while (this.position < this.input.length()) { + currentChar = this.input.charAt(this.position); + if (currentChar == ' ' || currentChar == '\t') { + this.position++; + continue; + } + if (currentChar == '\n' || currentChar == '\r') { + if (currentChar == '\r') { + if (this.position + 1 < this.input.length() && + this.input.charAt(this.position + 1) == '\n') { + this.position++; + } + } + this.line++; + this.position++; + if (sigComment == 1) { + sigComment = 0; + } + continue; + } + if (sigComment == 0) { + if (currentChar == '/') { + if (this.position + 1 < this.input.length() && + this.input.charAt(this.position + 1) == '/') { + sigComment = 1; + this.position += 2; + continue; + } + if (this.position + 1 < this.input.length() && + this.input.charAt(this.position + 1) == '*') { + sigComment = 2; + this.position += 2; + continue; + } + } + if (this.isIntCons()) { + lexInt(); + continue; + } + if (this.isStrCons()) { + lexStr(); + continue; + } + if (this.isIdenfr()) { + lexIdenfr(); + continue; + } + lexOp(errors); + } + if (sigComment == 2) { + if (this.position + 1 < this.input.length() && + this.currentChar == '*' && this.input.charAt(this.position + 1) == '/') { + sigComment = 0; + this.position += 2; + continue; + } + } + if (sigComment != 0) { + this.position++; + } + } + } + + public boolean isIntCons() { + return Character.isDigit(this.currentChar); + } + + public boolean isStrCons() { + return this.currentChar == '"'; + } + + public boolean isIdenfr() { + return Character.isLowerCase(this.currentChar) || Character.isUpperCase(this.currentChar) + || this.currentChar == '_'; + } + + public boolean isNotWp() { + return !Character.isWhitespace(this.currentChar); + } + + public boolean isOp() { + return !this.isIntCons() && !this.isStrCons() && !this.isIdenfr(); + } + + public void lexInt() { + StringBuilder sb = new StringBuilder(); + while (this.position < this.input.length() && this.isIntCons()) { + sb.append(this.currentChar); + this.position++; + updateCurrentChar(); + } + this.tokens.add(new Token(sb.toString(), this.line)); + } + + public void lexStr() { + StringBuilder sb = new StringBuilder(); + sb.append(this.currentChar); + this.position++; + updateCurrentChar(); + while (this.position < this.input.length() && this.currentChar != '"') { + sb.append(this.currentChar); + this.position++; + updateCurrentChar(); + } + if (this.position < this.input.length() && this.currentChar == '"') { + sb.append(this.currentChar); + this.position++; + } + this.tokens.add(new Token(sb.toString(), this.line)); + } + + public void lexIdenfr() { + StringBuilder sb = new StringBuilder(); + while (this.position < this.input.length() && (this.isIdenfr() || this.isIntCons())) { + sb.append(this.currentChar); + this.position++; + updateCurrentChar(); + } + this.tokens.add(new Token(sb.toString(), this.line)); + } + + public void lexOp(Errors errors) { + StringBuilder sb = new StringBuilder(); + if (this.currentChar == '/' && this.position + 1 < this.input.length() && + (this.input.charAt(this.position + 1) == '/' || + this.input.charAt(this.position + 1) == '*')) { + return; + } + sb.append(this.currentChar); + switch (this.currentChar) { + case '&': + readAnd(sb); + break; + case '|': + readOr(sb); + break; + case '<': + readEq(sb); + break; + case '>': + readEq(sb); + break; + case '=': + readEq(sb); + break; + case '!': + readEq(sb); + break; + default: + break; + } + this.position++; + if (sb.toString().equals("&") || sb.toString().equals("|")) { + errors.addError(new Error(this.line, ErrorType.a)); + } + this.tokens.add(new Token(sb.toString(), this.line)); + } + + public void readAnd(StringBuilder sb) { + if (this.position + 1 < this.input.length() && + this.input.charAt(this.position + 1) == '&') { + this.position++; + currentChar = this.input.charAt(this.position); + sb.append(currentChar); + } + } + + public void readOr(StringBuilder sb) { + if (this.position + 1 < this.input.length() && + this.input.charAt(this.position + 1) == '|') { + this.position++; + currentChar = this.input.charAt(this.position); + sb.append(currentChar); + } + } + + public void readEq(StringBuilder sb) { + if (this.position + 1 < this.input.length() && + this.input.charAt(this.position + 1) == '=') { + this.position++; + currentChar = this.input.charAt(this.position); + sb.append(currentChar); + } + } + + public void updateCurrentChar() { + if (this.position < this.input.length()) { + currentChar = this.input.charAt(this.position); + } + } + + public void printTokens() { + for (Token token : this.tokens) { + token.adjustType(); + System.out.println(token.getType() + " " + token.getValue() + " " + token.getLine()); + } + } + + public void writeToFile(String fileName) { + try { + StringBuilder sb = new StringBuilder(); + for (Token token : this.tokens) { + token.adjustType(); + sb.append(token.toString()); + } + Files.write(Paths.get(fileName), sb.toString().getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public ArrayList getTokens() { + for (Token token : this.tokens) { + token.adjustType(); + } + return this.tokens; + } +} diff --git a/frontend/lexer/Token.java b/frontend/lexer/Token.java old mode 100644 new mode 100755 index 6f2952c..af1cbde --- a/frontend/lexer/Token.java +++ b/frontend/lexer/Token.java @@ -1,42 +1,42 @@ -package frontend.lexer; - -public class Token { - private TokenType type; - private String value; - private int line; - - public Token(String value, int line) { - this.value = value; - this.type = TokenType.isWhatType(value); - this.line = line; - } - - public void adjustType() { - if (this.type == TokenType.IDENFR) { - if (this.value.charAt(0) == '\"' && - this.value.charAt(this.value.length() - 1) == '\"') { - this.type = TokenType.STRCON; - } - String regex = "^\\d+$"; - if (this.value.matches(regex)) { - this.type = TokenType.INTCON; - } - } - } - - public String getValue() { - return this.value; - } - - public TokenType getType() { - return this.type; - } - - public int getLine() { - return this.line; - } - - public String toString() { - return this.type + " " + this.value + "\n"; - } -} +package frontend.lexer; + +public class Token { + private TokenType type; + private String value; + private int line; + + public Token(String value, int line) { + this.value = value; + this.type = TokenType.isWhatType(value); + this.line = line; + } + + public void adjustType() { + if (this.type == TokenType.IDENFR) { + if (this.value.charAt(0) == '\"' && + this.value.charAt(this.value.length() - 1) == '\"') { + this.type = TokenType.STRCON; + } + String regex = "^\\d+$"; + if (this.value.matches(regex)) { + this.type = TokenType.INTCON; + } + } + } + + public String getValue() { + return this.value; + } + + public TokenType getType() { + return this.type; + } + + public int getLine() { + return this.line; + } + + public String toString() { + return this.type + " " + this.value + "\n"; + } +} diff --git a/frontend/lexer/TokenStream.java b/frontend/lexer/TokenStream.java old mode 100644 new mode 100755 diff --git a/frontend/lexer/TokenType.java b/frontend/lexer/TokenType.java old mode 100644 new mode 100755 index 8cb8d5a..3ab4010 --- a/frontend/lexer/TokenType.java +++ b/frontend/lexer/TokenType.java @@ -1,123 +1,123 @@ -package frontend.lexer; - -public enum TokenType { - IDENFR, - INTCON, - STRCON, - CONSTTK, - INTTK, - STATICTK, - BREAKTK, - CONTINUETK, - IFTK, - MAINTK, - ELSETK, - NOT, - AND, - OR, - FORTK, - RETURNTK, - VOIDTK, - PLUS, - MINU, - PRINTFTK, - MULT, - DIV, - MOD, - LSS, - LEQ, - GRE, - GEQ, - EQL, - NEQ, - SEMICN, - COMMA, - LPARENT, - RPARENT, - LBRACK, - RBRACK, - LBRACE, - RBRACE, - ASSIGN; - - public static TokenType isWhatType(String str) { - switch (str) { - case "const": - return TokenType.CONSTTK; - case "int": - return TokenType.INTTK; - case "static": - return TokenType.STATICTK; - case "break": - return TokenType.BREAKTK; - case "continue": - return TokenType.CONTINUETK; - case "if": - return TokenType.IFTK; - case "main": - return TokenType.MAINTK; - case "else": - return TokenType.ELSETK; - case "!": - return TokenType.NOT; - case "&&": - return TokenType.AND; - case "&": - return TokenType.AND; - case "||": - return TokenType.OR; - case "|": - return TokenType.OR; - case "for": - return TokenType.FORTK; - case "return": - return TokenType.RETURNTK; - case "void": - return TokenType.VOIDTK; - case "+": - return TokenType.PLUS; - case "-": - return TokenType.MINU; - case "printf": - return TokenType.PRINTFTK; - case "*": - return TokenType.MULT; - case "/": - return TokenType.DIV; - case "%": - return TokenType.MOD; - case "<": - return TokenType.LSS; - case "<=": - return TokenType.LEQ; - case ">": - return TokenType.GRE; - case ">=": - return TokenType.GEQ; - case "==": - return TokenType.EQL; - case "!=": - return TokenType.NEQ; - case ";": - return TokenType.SEMICN; - case ",": - return TokenType.COMMA; - case "(": - return TokenType.LPARENT; - case ")": - return TokenType.RPARENT; - case "[": - return TokenType.LBRACK; - case "]": - return TokenType.RBRACK; - case "{": - return TokenType.LBRACE; - case "}": - return TokenType.RBRACE; - case "=": - return TokenType.ASSIGN; - default: - return TokenType.IDENFR; - } - } -} +package frontend.lexer; + +public enum TokenType { + IDENFR, + INTCON, + STRCON, + CONSTTK, + INTTK, + STATICTK, + BREAKTK, + CONTINUETK, + IFTK, + MAINTK, + ELSETK, + NOT, + AND, + OR, + FORTK, + RETURNTK, + VOIDTK, + PLUS, + MINU, + PRINTFTK, + MULT, + DIV, + MOD, + LSS, + LEQ, + GRE, + GEQ, + EQL, + NEQ, + SEMICN, + COMMA, + LPARENT, + RPARENT, + LBRACK, + RBRACK, + LBRACE, + RBRACE, + ASSIGN; + + public static TokenType isWhatType(String str) { + switch (str) { + case "const": + return TokenType.CONSTTK; + case "int": + return TokenType.INTTK; + case "static": + return TokenType.STATICTK; + case "break": + return TokenType.BREAKTK; + case "continue": + return TokenType.CONTINUETK; + case "if": + return TokenType.IFTK; + case "main": + return TokenType.MAINTK; + case "else": + return TokenType.ELSETK; + case "!": + return TokenType.NOT; + case "&&": + return TokenType.AND; + case "&": + return TokenType.AND; + case "||": + return TokenType.OR; + case "|": + return TokenType.OR; + case "for": + return TokenType.FORTK; + case "return": + return TokenType.RETURNTK; + case "void": + return TokenType.VOIDTK; + case "+": + return TokenType.PLUS; + case "-": + return TokenType.MINU; + case "printf": + return TokenType.PRINTFTK; + case "*": + return TokenType.MULT; + case "/": + return TokenType.DIV; + case "%": + return TokenType.MOD; + case "<": + return TokenType.LSS; + case "<=": + return TokenType.LEQ; + case ">": + return TokenType.GRE; + case ">=": + return TokenType.GEQ; + case "==": + return TokenType.EQL; + case "!=": + return TokenType.NEQ; + case ";": + return TokenType.SEMICN; + case ",": + return TokenType.COMMA; + case "(": + return TokenType.LPARENT; + case ")": + return TokenType.RPARENT; + case "[": + return TokenType.LBRACK; + case "]": + return TokenType.RBRACK; + case "{": + return TokenType.LBRACE; + case "}": + return TokenType.RBRACE; + case "=": + return TokenType.ASSIGN; + default: + return TokenType.IDENFR; + } + } +} diff --git a/frontend/parser/Parser.java b/frontend/parser/Parser.java old mode 100644 new mode 100755 index 8a8cda6..92c52a0 --- a/frontend/parser/Parser.java +++ b/frontend/parser/Parser.java @@ -1,38 +1,38 @@ -package frontend.parser; - -import frontend.ast.CompUnit; -import frontend.lexer.TokenStream; - -import java.nio.file.Files; - -import error.Errors; - -import java.nio.file.Paths; -import java.io.IOException; - -public class Parser { - private TokenStream ts; - private CompUnit compUnit; - - public Parser(TokenStream ts) { - this.ts = ts; - this.compUnit = new CompUnit(this.ts); - } - - public void parse(Errors errors) { - compUnit.parse(errors); - } - - public CompUnit getCompUnit() { - return compUnit; - } - - public void writeToFile(String fileName) { - try { - String info = this.compUnit.getInfo(); - Files.write(Paths.get(fileName), info.getBytes()); - } catch (IOException e) { - e.printStackTrace(); - } - } -} +package frontend.parser; + +import frontend.ast.CompUnit; +import frontend.lexer.TokenStream; + +import java.nio.file.Files; + +import error.Errors; + +import java.nio.file.Paths; +import java.io.IOException; + +public class Parser { + private TokenStream ts; + private CompUnit compUnit; + + public Parser(TokenStream ts) { + this.ts = ts; + this.compUnit = new CompUnit(this.ts); + } + + public void parse(Errors errors) { + compUnit.parse(errors); + } + + public CompUnit getCompUnit() { + return compUnit; + } + + public void writeToFile(String fileName) { + try { + String info = this.compUnit.getInfo(); + Files.write(Paths.get(fileName), info.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/midend/Midend.java b/midend/Midend.java old mode 100644 new mode 100755 index c6d0c15..6997e93 --- a/midend/Midend.java +++ b/midend/Midend.java @@ -1,31 +1,36 @@ -package midend; - -import java.nio.file.Files; -import java.nio.file.Paths; -import frontend.ast.CompUnit; -import midend.llvm.IrBuilder; -import midend.llvm.IrModule; -import midend.visit.Visitor; - -public class Midend { - private IrModule module; - private Visitor visitor; - - public Midend(CompUnit compUnit) { - this.module = new IrModule(); - this.visitor = new Visitor(compUnit); - } - - public void generateLLvmIr() { - IrBuilder.setCurrentModule(module); - visitor.visit(); - } - - public void writeToFile(String fileName) { - try { - Files.write(Paths.get(fileName), module.toString().getBytes()); - } catch (Exception e) { - e.printStackTrace(); - } - } -} +package midend; + +import java.nio.file.Files; +import java.nio.file.Paths; +import frontend.ast.CompUnit; +import midend.llvm.IrBuilder; +import midend.llvm.IrModule; +import midend.visit.Visitor; + +public class Midend { + private IrModule module; + private Visitor visitor; + + public Midend(CompUnit compUnit) { + this.module = new IrModule(); + this.visitor = new Visitor(compUnit); + } + + public void generateLLvmIr() { + IrBuilder.setCurrentModule(module); + visitor.visit(); + } + + public IrModule getModule() { + return module; + } + + public void writeToFile(String fileName) { + try { + Files.write(Paths.get(fileName), module.toString().getBytes()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} +// diff --git a/midend/errorhandle/ErrorHandler.java b/midend/errorhandle/ErrorHandler.java old mode 100644 new mode 100755 index a973d41..c23c2d7 --- a/midend/errorhandle/ErrorHandler.java +++ b/midend/errorhandle/ErrorHandler.java @@ -1,32 +1,32 @@ -package midend.errorhandle; - -import frontend.ast.CompUnit; - -import midend.symbol.SymbolManager; - -import error.Errors; - -import java.nio.file.Files; -import java.nio.file.Paths; - -public class ErrorHandler { - private CompUnit compUnit; - - public ErrorHandler(CompUnit compUnit) { - this.compUnit = compUnit; - SymbolManager.init(); - } - - public void visit(Errors errors) { - compUnit.fillSymbolTable(false, false, errors); - } - - public void writeToFile(String fileName) { - try { - String info = SymbolManager.getSymbolTableInfo(); - Files.write(Paths.get(fileName), info.getBytes()); - } catch (Exception e) { - e.printStackTrace(); - } - } -} +package midend.errorhandle; + +import frontend.ast.CompUnit; + +import midend.symbol.SymbolManager; + +import error.Errors; + +import java.nio.file.Files; +import java.nio.file.Paths; + +public class ErrorHandler { + private CompUnit compUnit; + + public ErrorHandler(CompUnit compUnit) { + this.compUnit = compUnit; + SymbolManager.init(); + } + + public void visit(Errors errors) { + compUnit.fillSymbolTable(false, false, errors); + } + + public void writeToFile(String fileName) { + try { + String info = SymbolManager.getSymbolTableInfo(); + Files.write(Paths.get(fileName), info.getBytes()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/midend/llvm/IrBuilder.java b/midend/llvm/IrBuilder.java old mode 100644 new mode 100755 index f8f4de8..041dadb --- a/midend/llvm/IrBuilder.java +++ b/midend/llvm/IrBuilder.java @@ -1,143 +1,143 @@ -package midend.llvm; - -import java.util.HashMap; -import java.util.Stack; - -import midend.llvm.value.IrFuncValue; -import midend.llvm.value.IrBasicBlock; -import midend.llvm.value.IrLoop; -import midend.llvm.type.IrType; -import midend.llvm.constant.IrConstant; -import midend.llvm.value.IrGlobalValue; -import midend.llvm.constant.IrConstantStr; -import midend.llvm.instr.IrInstr; - -public class IrBuilder { - private static final String prebb = "b_"; - private static final String prestr = "@s_"; - private static final String prefunc = "@f_"; - private static final String preglobal = "@g_"; - private static final String prelocal = "%v_"; - - private static IrModule module = null; - private static IrFuncValue currentFunc = null; - private static IrBasicBlock currentBB = null; - private static int strId = 0; - private static int globalId = 0; - private static int bblockId = 0; - private static HashMap funcIdMap = new HashMap<>(); // func, localId - private static Stack loopStack = new Stack<>(); - - public static void setCurrentModule(IrModule module) { - IrBuilder.module = module; - } - - public static void addNewFunc(String name, IrType retType) { - IrFuncValue func = new IrFuncValue(geFuncName(name), retType); - module.addFunc(func); - funcIdMap.put(func, 0); - currentFunc = func; - IrBasicBlock entryBB = new IrBasicBlock(getBlockName(), func); - func.addBBlock(entryBB); - currentBB = entryBB; - } - - public static void addNewFunc(IrFuncValue func) { - module.addFunc(func); - funcIdMap.put(func, 0); - currentFunc = func; - IrBasicBlock entryBB = new IrBasicBlock(getBlockName(), func); - func.addBBlock(entryBB); - currentBB = entryBB; - } - - public static void addNewBB() { - IrBasicBlock bb = new IrBasicBlock(getBlockName(), currentFunc); - currentFunc.addBBlock(bb); - } - - public static void addNewBB(IrBasicBlock bb) { - currentFunc.addBBlock(bb); - } - - public static void setCurrentBBlock(IrBasicBlock bb) { - currentBB = bb; - } - - public static void addNewGlobal(IrType type, boolean isConstant, IrConstant initVal) { - IrGlobalValue global = new IrGlobalValue(type, getGlobalName(), isConstant, initVal); - module.addGlobalVar(global); - } - - public static void addNewGlobal(IrGlobalValue global) { - module.addGlobalVar(global); - } - - public static void addNewStr(String str) { - if (module.containStr(str)) { - return; - } - module.addStr(new IrConstantStr(str, getStrName())); - } - - public static void addNewStr(IrConstantStr str) { - module.addStr(str); - } - - public static void addInstr(IrInstr instr) { - currentBB.addInstr(instr); - instr.setBBlock(currentBB); - } - - public static String geFuncName(String name) { - return name.equals("main") ? "@main" : prefunc + name; - } - - public static String getBlockName() { - return prebb + bblockId++; - } - - public static String getStrName() { - return prestr + strId++; - } - - public static String getGlobalName() { - return preglobal + globalId++; - } - - public static String getLocalName() { - int id = funcIdMap.get(currentFunc); - funcIdMap.put(currentFunc, id + 1); - return prelocal + id; - } - - public static String getLocalName(IrFuncValue func) { - int id = funcIdMap.get(func); - funcIdMap.put(func, id + 1); - return prelocal + id; - } - - public static IrModule getCurrentModule() { - return module; - } - - public static IrFuncValue getCurrentFunc() { - return currentFunc; - } - - public static IrBasicBlock getCurrentBB() { - return currentBB; - } - - public static void pushLoop(IrLoop loop) { - loopStack.push(loop); - } - - public static IrLoop popLoop() { - return loopStack.pop(); - } - - public static IrLoop getCurrentLoop() { - return loopStack.peek(); - } -} +package midend.llvm; + +import java.util.HashMap; +import java.util.Stack; + +import midend.llvm.value.IrFuncValue; +import midend.llvm.value.IrBasicBlock; +import midend.llvm.value.IrLoop; +import midend.llvm.type.IrType; +import midend.llvm.constant.IrConstant; +import midend.llvm.value.IrGlobalValue; +import midend.llvm.constant.IrConstantStr; +import midend.llvm.instr.IrInstr; + +public class IrBuilder { + private static final String prebb = "b_"; + private static final String prestr = "@s_"; + private static final String prefunc = "@f_"; + private static final String preglobal = "@g_"; + private static final String prelocal = "%v_"; + + private static IrModule module = null; + private static IrFuncValue currentFunc = null; + private static IrBasicBlock currentBB = null; + private static int strId = 0; + private static int globalId = 0; + private static int bblockId = 0; + private static HashMap funcIdMap = new HashMap<>(); // func, localId + private static Stack loopStack = new Stack<>(); + + public static void setCurrentModule(IrModule module) { + IrBuilder.module = module; + } + + public static void addNewFunc(String name, IrType retType) { + IrFuncValue func = new IrFuncValue(geFuncName(name), retType); + module.addFunc(func); + funcIdMap.put(func, 0); + currentFunc = func; + IrBasicBlock entryBB = new IrBasicBlock(getBlockName(), func); + func.addBBlock(entryBB); + currentBB = entryBB; + } + + public static void addNewFunc(IrFuncValue func) { + module.addFunc(func); + funcIdMap.put(func, 0); + currentFunc = func; + IrBasicBlock entryBB = new IrBasicBlock(getBlockName(), func); + func.addBBlock(entryBB); + currentBB = entryBB; + } + + public static void addNewBB() { + IrBasicBlock bb = new IrBasicBlock(getBlockName(), currentFunc); + currentFunc.addBBlock(bb); + } + + public static void addNewBB(IrBasicBlock bb) { + currentFunc.addBBlock(bb); + } + + public static void setCurrentBBlock(IrBasicBlock bb) { + currentBB = bb; + } + + public static void addNewGlobal(IrType type, boolean isConstant, IrConstant initVal) { + IrGlobalValue global = new IrGlobalValue(type, getGlobalName(), isConstant, initVal); + module.addGlobalVar(global); + } + + public static void addNewGlobal(IrGlobalValue global) { + module.addGlobalVar(global); + } + + public static void addNewStr(String str) { + if (module.containStr(str)) { + return; + } + module.addStr(new IrConstantStr(str, getStrName())); + } + + public static void addNewStr(IrConstantStr str) { + module.addStr(str); + } + + public static void addInstr(IrInstr instr) { + currentBB.addInstr(instr); + instr.setBBlock(currentBB); + } + + public static String geFuncName(String name) { + return name.equals("main") ? "@main" : prefunc + name; + } + + public static String getBlockName() { + return prebb + bblockId++; + } + + public static String getStrName() { + return prestr + strId++; + } + + public static String getGlobalName() { + return preglobal + globalId++; + } + + public static String getLocalName() { + int id = funcIdMap.get(currentFunc); + funcIdMap.put(currentFunc, id + 1); + return prelocal + id; + } + + public static String getLocalName(IrFuncValue func) { + int id = funcIdMap.get(func); + funcIdMap.put(func, id + 1); + return prelocal + id; + } + + public static IrModule getCurrentModule() { + return module; + } + + public static IrFuncValue getCurrentFunc() { + return currentFunc; + } + + public static IrBasicBlock getCurrentBB() { + return currentBB; + } + + public static void pushLoop(IrLoop loop) { + loopStack.push(loop); + } + + public static IrLoop popLoop() { + return loopStack.pop(); + } + + public static IrLoop getCurrentLoop() { + return loopStack.peek(); + } +} diff --git a/midend/llvm/IrModule.java b/midend/llvm/IrModule.java old mode 100644 new mode 100755 index e50f9ad..eadd467 --- a/midend/llvm/IrModule.java +++ b/midend/llvm/IrModule.java @@ -1,100 +1,125 @@ -package midend.llvm; - -import java.util.ArrayList; -import java.util.HashMap; - -import midend.llvm.constant.IrConstantStr; -import midend.llvm.value.IrFuncValue; -import midend.llvm.value.IrGlobalValue; -import midend.llvm.instr.GetIntInstr; -import midend.llvm.instr.PutChInstr; -import midend.llvm.instr.PutIntInstr; -import midend.llvm.instr.PutStrInstr; - -public class IrModule { - private ArrayList decls; - private HashMap strs; - private ArrayList globalVars; - private ArrayList funcs; - - public IrModule() { - decls = new ArrayList<>(); - strs = new HashMap<>(); - globalVars = new ArrayList<>(); - funcs = new ArrayList<>(); - decls.add(GetIntInstr.getIntDecl()); - decls.add(PutChInstr.putChDecl()); - decls.add(PutIntInstr.putIntDecl()); - decls.add(PutStrInstr.putStrDecl()); - } - - public ArrayList getDecls() { - return decls; - } - - public HashMap getStrs() { - return strs; - } - - public ArrayList getGlobalVars() { - return globalVars; - } - - public ArrayList getFuncs() { - return funcs; - } - - public void addFunc(IrFuncValue func) { - funcs.add(func); - } - - public void addStr(IrConstantStr str) { - if (strs.containsKey(str.getValue())) { - return; - } - strs.put(str.getValue(), str); - } - - public boolean containStr(String str) { - return strs.containsKey(str); - } - - public IrConstantStr getStr(String str) { - if (containStr(str)) { - return strs.get(str); - } - return null; - } - - public void addGlobalVar(IrGlobalValue globalVar) { - globalVars.add(globalVar); - } - - public IrFuncValue getMainFunc() { - for (IrFuncValue func : funcs) { - if (func.isMain()) { - return func; - } - } - return null; - } - - //TODO: toString()方法编写 - public String toString() { - StringBuilder sb = new StringBuilder(); - for (String decl : decls) { - sb.append(decl).append("\n"); - } - for (IrConstantStr str : strs.values()) { - sb.append(str.toString()).append("\n"); - } - for (IrGlobalValue globalVar : globalVars) { - sb.append(globalVar.toString()).append("\n"); - } - for (IrFuncValue func : funcs) { - sb.append(func.toString()).append("\n"); - } - // System.out.println(funcs.size()); - return sb.toString(); - } -} +package midend.llvm; + +import java.util.ArrayList; +import java.util.HashMap; + +import backend.mips.Register; +import backend.mips.instr.MipsAnnotation; +import backend.mips.instr.MipsJump; +import backend.mips.instr.MipsLabel; +import backend.mips.instr.fake.MipsLi; +import backend.mips.instr.MipsSyscall; +import backend.mips.instr.type.MipsJumpType; +import midend.llvm.constant.IrConstantStr; +import midend.llvm.value.IrFuncValue; +import midend.llvm.value.IrGlobalValue; +import midend.llvm.instr.GetIntInstr; +import midend.llvm.instr.PutChInstr; +import midend.llvm.instr.PutIntInstr; +import midend.llvm.instr.PutStrInstr; + +public class IrModule { + private ArrayList decls; + private HashMap strs; + private ArrayList globalVars; + private ArrayList funcs; + + public IrModule() { + decls = new ArrayList<>(); + strs = new HashMap<>(); + globalVars = new ArrayList<>(); + funcs = new ArrayList<>(); + decls.add(GetIntInstr.getIntDecl()); + decls.add(PutChInstr.putChDecl()); + decls.add(PutIntInstr.putIntDecl()); + decls.add(PutStrInstr.putStrDecl()); + } + + public ArrayList getDecls() { + return decls; + } + + public HashMap getStrs() { + return strs; + } + + public ArrayList getGlobalVars() { + return globalVars; + } + + public ArrayList getFuncs() { + return funcs; + } + + public void addFunc(IrFuncValue func) { + funcs.add(func); + } + + public void addStr(IrConstantStr str) { + if (strs.containsKey(str.getValue())) { + return; + } + strs.put(str.getValue(), str); + } + + public boolean containStr(String str) { + return strs.containsKey(str); + } + + public IrConstantStr getStr(String str) { + if (containStr(str)) { + return strs.get(str); + } + return null; + } + + public void addGlobalVar(IrGlobalValue globalVar) { + globalVars.add(globalVar); + } + + public IrFuncValue getMainFunc() { + for (IrFuncValue func : funcs) { + if (func.isMain()) { + return func; + } + } + return null; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + for (String decl : decls) { + sb.append(decl).append("\n"); + } + for (IrConstantStr str : strs.values()) { + sb.append(str.toString()).append("\n"); + } + for (IrGlobalValue globalVar : globalVars) { + sb.append(globalVar.toString()).append("\n"); + } + for (IrFuncValue func : funcs) { + sb.append(func.toString()).append("\n"); + } + // System.out.println(funcs.size()); + return sb.toString(); + } + + public void toMips() { + for (IrGlobalValue globalVar : this.globalVars) { + globalVar.toMips(); + } + for (IrConstantStr str : this.strs.values()) { + str.toMips(str.getMipsLabel()); + } + new MipsAnnotation("jump to main"); + new MipsJump(MipsJumpType.JAL, "main"); + new MipsJump(MipsJumpType.J, "end"); + + for (IrFuncValue irFunction : this.funcs) { + irFunction.toMips(); + } + new MipsLabel("end"); + new MipsLi(Register.V0, 10); + new MipsSyscall(); + } +} diff --git a/midend/llvm/constant/IrConstant.java b/midend/llvm/constant/IrConstant.java old mode 100644 new mode 100755 index fabfbeb..2922fd3 --- a/midend/llvm/constant/IrConstant.java +++ b/midend/llvm/constant/IrConstant.java @@ -11,4 +11,8 @@ public class IrConstant extends IrValue { public String toString() { return ""; } + + public void toMips(String label) { + + } } diff --git a/midend/llvm/constant/IrConstantArray.java b/midend/llvm/constant/IrConstantArray.java old mode 100644 new mode 100755 index ca8318d..53f352a --- a/midend/llvm/constant/IrConstantArray.java +++ b/midend/llvm/constant/IrConstantArray.java @@ -2,6 +2,8 @@ package midend.llvm.constant; import java.util.ArrayList; +import backend.mips.instr.data.MipsSpace; +import backend.mips.instr.data.MipsWord; import midend.llvm.type.IrInterType; import midend.llvm.type.IrArrayType; @@ -44,4 +46,19 @@ public class IrConstantArray extends IrConstant { } return sb.toString(); } + + public void toMips(String label) { + ArrayList values = new ArrayList<>(); + if (elements.size() == 0) { + new MipsSpace(size * 4, label); + } else { + for (IrConstant element : elements) { + values.add(((IrConstantInt) element).getValue()); + } + for (int i = 0; i < size - elements.size(); i++) { + values.add(0); + } + new MipsWord(label, values); + } + } } diff --git a/midend/llvm/constant/IrConstantInt.java b/midend/llvm/constant/IrConstantInt.java old mode 100644 new mode 100755 index f7c1c1a..b5f5920 --- a/midend/llvm/constant/IrConstantInt.java +++ b/midend/llvm/constant/IrConstantInt.java @@ -1,5 +1,6 @@ package midend.llvm.constant; +import backend.mips.instr.data.MipsWord; import midend.llvm.type.IrInterType; public class IrConstantInt extends IrConstant { @@ -17,4 +18,8 @@ public class IrConstantInt extends IrConstant { public String toString() { return "i32 " + value; } + + public void toMips(String label) { + new MipsWord(label, value); + } } diff --git a/midend/llvm/constant/IrConstantStr.java b/midend/llvm/constant/IrConstantStr.java old mode 100644 new mode 100755 index 1e6e4b6..e22bb48 --- a/midend/llvm/constant/IrConstantStr.java +++ b/midend/llvm/constant/IrConstantStr.java @@ -1,53 +1,58 @@ -package midend.llvm.constant; - -import midend.llvm.type.IrArrayType; -import midend.llvm.type.IrPointerType; -import midend.llvm.type.IrInterType; - -public class IrConstantStr extends IrConstant { - private String value; - - public IrConstantStr(String value, String name) { - super(new IrPointerType( - new IrArrayType(IrInterType.INT8, getLen(value) + 1)), name); - this.value = value; - } - - public String getValue() { - return value; - } - - public static int getLen(String value) { - int len = 0; - for (int i = 0; i < value.length(); i++) { - if (value.charAt(i) == '\\') { - i++; - } else if (value.charAt(i) == '"') { - continue; - } - len++; - } - return len; - } - - public static String getRealStr(String str) { - boolean start = str.charAt(0) == '"'; - boolean end = str.charAt(str.length() - 1) == '"'; - if (start && end) { - return str.substring(1, str.length() - 1); - } else if (start) { - return str.substring(1); - } else if (end) { - return str.substring(0, str.length() - 1); - } - return str; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getName() + " = constant " + ((IrPointerType) getType()).getPointeeType()); - sb.append(" c\"" + getRealStr(value).replace("\\n", "\\0A")); - sb.append("\\00\""); - return sb.toString(); - } -} +package midend.llvm.constant; + +import backend.mips.instr.data.MipsAsciiz; +import midend.llvm.type.IrArrayType; +import midend.llvm.type.IrPointerType; +import midend.llvm.type.IrInterType; + +public class IrConstantStr extends IrConstant { + private String value; + + public IrConstantStr(String value, String name) { + super(new IrPointerType( + new IrArrayType(IrInterType.INT8, getLen(value) + 1)), name); + this.value = value; + } + + public String getValue() { + return value; + } + + public static int getLen(String value) { + int len = 0; + for (int i = 0; i < value.length(); i++) { + if (value.charAt(i) == '\\') { + i++; + } else if (value.charAt(i) == '"') { + continue; + } + len++; + } + return len; + } + + public static String getRealStr(String str) { + boolean start = str.charAt(0) == '"'; + boolean end = str.charAt(str.length() - 1) == '"'; + if (start && end) { + return str.substring(1, str.length() - 1); + } else if (start) { + return str.substring(1); + } else if (end) { + return str.substring(0, str.length() - 1); + } + return str; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getName() + " = constant " + ((IrPointerType) getType()).getPointeeType()); + sb.append(" c\"" + getRealStr(value).replace("\\n", "\\0A")); + sb.append("\\00\""); + return sb.toString(); + } + + public void toMips(String label) { + new MipsAsciiz(label, getRealStr(value)); + } +} diff --git a/midend/llvm/instr/AllocateInstr.java b/midend/llvm/instr/AllocateInstr.java old mode 100644 new mode 100755 index a6e3d25..46b86c5 --- a/midend/llvm/instr/AllocateInstr.java +++ b/midend/llvm/instr/AllocateInstr.java @@ -1,21 +1,49 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrPointerType; -import midend.llvm.type.IrType; - -public class AllocateInstr extends IrInstr { - private IrType pointeeType; - - public AllocateInstr(IrType pointeeType, String name) { // name即为局部变量的name,因为要声明一个局部变量 - super(new IrPointerType(pointeeType), name, IrInstrType.ALLOCA); - this.pointeeType = pointeeType; - } - - public IrType getPointeeType() { - return pointeeType; - } - - public String toString() { - return getName() + " = alloca " + this.pointeeType; - } -} +package midend.llvm.instr; + +import backend.mips.MipsBuilder; +import midend.llvm.type.IrArrayType; +import midend.llvm.type.IrPointerType; +import midend.llvm.type.IrType; +import backend.mips.Register; +import backend.mips.instr.MipsAlu; +import backend.mips.instr.MipsLs; +import backend.mips.instr.type.MipsAluType; +import backend.mips.instr.type.MipsLsType; + +public class AllocateInstr extends IrInstr { + private IrType pointeeType; + + public AllocateInstr(IrType pointeeType, String name) { // name即为局部变量的name,因为要声明一个局部变量 + super(new IrPointerType(pointeeType), name, IrInstrType.ALLOCA); + this.pointeeType = pointeeType; + } + + public IrType getPointeeType() { + return pointeeType; + } + + public String toString() { + return getName() + " = alloca " + this.pointeeType; + } + + public void toMips() { + // 想法:在栈上分配数据所需要的空间,再分配四字节的指针,这就是个指针,将其当作指针就好理解了 + if (pointeeType instanceof IrArrayType) { + MipsBuilder.allocaOffset(4 * ((IrArrayType) pointeeType).getSize()); + } else { + MipsBuilder.allocaOffset(4); + } + + Register reg = MipsBuilder.getRegister(this); + if (reg == null) { // 未分配寄存器情况 + int offset = MipsBuilder.getOffset(); + new MipsAlu(MipsAluType.ADDI, Register.K0, Register.SP, offset); + MipsBuilder.allocaOffset(this); // 将该变量的偏移量设置为其指针的偏移量,后续取值先取指针,再根据指针取值 + offset = MipsBuilder.getOffset(); + new MipsLs(MipsLsType.SW, Register.K0, Register.SP, offset); + } else { + int offset = MipsBuilder.getOffset(); + new MipsAlu(MipsAluType.ADDI, reg, Register.SP, offset); + } + } +} diff --git a/midend/llvm/instr/AluInstr.java b/midend/llvm/instr/AluInstr.java old mode 100644 new mode 100755 index c214d66..5b93b59 --- a/midend/llvm/instr/AluInstr.java +++ b/midend/llvm/instr/AluInstr.java @@ -1,24 +1,61 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrInterType; -import midend.llvm.value.IrValue; - -public class AluInstr extends IrInstr { - private AluType alutype; - - public AluInstr(String name, String op, IrValue left, IrValue right) { - super(IrInterType.INT32, name, IrInstrType.ALU); - this.alutype = AluType.getAluType(op); - addUse(left); - addUse(right); - } - - public AluType getAluType() { - return alutype; - } - - public String toString() { - return getName() + " = " + alutype.toString() + " " + getType() - + " " + getUse(0).getName() + ", " + getUse(1).getName(); - } -} +package midend.llvm.instr; + +import backend.mips.MipsBuilder; +import backend.mips.instr.MipsAlu; +import backend.mips.instr.MipsMd; +import backend.mips.instr.type.MipsAluType; +import backend.mips.instr.type.MipsMdType; +import backend.mips.Register; + +import midend.llvm.type.IrInterType; +import midend.llvm.value.IrValue; + +public class AluInstr extends IrInstr { + private AluType alutype; + + public AluInstr(String name, String op, IrValue left, IrValue right) { + super(IrInterType.INT32, name, IrInstrType.ALU); + this.alutype = AluType.getAluType(op); + addUse(left); + addUse(right); + } + + public AluType getAluType() { + return alutype; + } + + public String toString() { + return getName() + " = " + alutype.toString() + " " + getType() + + " " + getUse(0).getName() + ", " + getUse(1).getName(); + } + + public void toMips() { + IrValue left = getUse(0); + IrValue right = getUse(1); + Register leftReg = MipsBuilder.getRegister(left) != null ? MipsBuilder.getRegister(left) : Register.K0; + Register rightReg = MipsBuilder.getRegister(right) != null ? MipsBuilder.getRegister(right) : Register.K1; + Register resultReg = MipsBuilder.getRegister(this) != null ? MipsBuilder.getRegister(this) : Register.K1; + loadValueToReg(left, leftReg); + loadValueToReg(right, rightReg); + + if (getAluType() == AluType.ADD) { + new MipsAlu(MipsAluType.ADDU, resultReg, leftReg, rightReg); + } else if (getAluType() == AluType.SUB) { + new MipsAlu(MipsAluType.SUBU, resultReg, leftReg, rightReg); + } else if (getAluType() == AluType.AND) { + new MipsAlu(MipsAluType.AND, resultReg, leftReg, rightReg); + } else if (getAluType() == AluType.OR) { + new MipsAlu(MipsAluType.OR, resultReg, leftReg, rightReg); + } else if (getAluType() == AluType.MUL) { + new MipsMd(MipsMdType.MULT, leftReg, rightReg); + new MipsMd(MipsMdType.MFLO, resultReg); + } else if (getAluType() == AluType.SDIV) { + new MipsMd(MipsMdType.DIV, leftReg, rightReg); + new MipsMd(MipsMdType.MFLO, resultReg); + } else if (getAluType() == AluType.SREM) { + new MipsMd(MipsMdType.DIV, leftReg, rightReg); + new MipsMd(MipsMdType.MFHI, resultReg); + } + saveResult(this, resultReg); + } +} diff --git a/midend/llvm/instr/AluType.java b/midend/llvm/instr/AluType.java old mode 100644 new mode 100755 index 2138ab8..0161327 --- a/midend/llvm/instr/AluType.java +++ b/midend/llvm/instr/AluType.java @@ -1,53 +1,53 @@ -package midend.llvm.instr; - -public enum AluType { - ADD, - SUB, - MUL, - SDIV, - SREM, - AND, - OR; - - public static AluType getAluType(String op) { - switch (op) { - case "+": - return ADD; - case "-": - return SUB; - case "*": - return MUL; - case "/": - return SDIV; - case "%": - return SREM; - case "&": - return AND; - case "|": - return OR; - default: - return null; - } - } - - public String toString() { - switch (this) { - case ADD: - return "add"; - case SUB: - return "sub"; - case MUL: - return "mul"; - case SDIV: - return "sdiv"; - case SREM: - return "srem"; - case AND: - return "and"; - case OR: - return "or"; - default: - return null; - } - } +package midend.llvm.instr; + +public enum AluType { + ADD, + SUB, + MUL, + SDIV, + SREM, + AND, + OR; + + public static AluType getAluType(String op) { + switch (op) { + case "+": + return ADD; + case "-": + return SUB; + case "*": + return MUL; + case "/": + return SDIV; + case "%": + return SREM; + case "&": + return AND; + case "|": + return OR; + default: + return null; + } + } + + public String toString() { + switch (this) { + case ADD: + return "add"; + case SUB: + return "sub"; + case MUL: + return "mul"; + case SDIV: + return "sdiv"; + case SREM: + return "srem"; + case AND: + return "and"; + case OR: + return "or"; + default: + return null; + } + } } \ No newline at end of file diff --git a/midend/llvm/instr/BranchInstr.java b/midend/llvm/instr/BranchInstr.java old mode 100644 new mode 100755 index 9fe2d68..7d26beb --- a/midend/llvm/instr/BranchInstr.java +++ b/midend/llvm/instr/BranchInstr.java @@ -1,33 +1,48 @@ -package midend.llvm.instr; - -import midend.llvm.value.IrBasicBlock; -import midend.llvm.value.IrValue; -import midend.llvm.type.IrInterType; - -public class BranchInstr extends IrInstr { - public BranchInstr(String name, IrValue cond, IrBasicBlock trueBB, IrBasicBlock falseBB) { - super(IrInterType.VOID, name, IrInstrType.BR); - addUse(cond); - addUse(trueBB); - addUse(falseBB); - } - - public IrValue getCond() { - return getUse(0); - } - - public IrBasicBlock getTrueBB() { - return (IrBasicBlock) getUse(1); - } - - public IrBasicBlock getFalseBB() { - return (IrBasicBlock) getUse(2); - } - - public String toString() { - return "br i1 " + getCond().getName() + - ", label %" + getTrueBB().getName() + - ", label %" + getFalseBB().getName(); - } - -} +package midend.llvm.instr; + +import midend.llvm.value.IrBasicBlock; +import midend.llvm.value.IrValue; +import backend.mips.MipsBuilder; +import backend.mips.Register; +import backend.mips.instr.MipsBranch; +import backend.mips.instr.type.MipsBranchType; +import backend.mips.instr.type.MipsJumpType; +import backend.mips.instr.MipsJump; +import midend.llvm.type.IrInterType; + +public class BranchInstr extends IrInstr { + public BranchInstr(String name, IrValue cond, IrBasicBlock trueBB, IrBasicBlock falseBB) { + super(IrInterType.VOID, name, IrInstrType.BR); + addUse(cond); + addUse(trueBB); + addUse(falseBB); + } + + public IrValue getCond() { + return getUse(0); + } + + public IrBasicBlock getTrueBB() { + return (IrBasicBlock) getUse(1); + } + + public IrBasicBlock getFalseBB() { + return (IrBasicBlock) getUse(2); + } + + public String toString() { + return "br i1 " + getCond().getName() + + ", label %" + getTrueBB().getName() + + ", label %" + getFalseBB().getName(); + } + + public void toMips() { + Register condReg = MipsBuilder.getRegister(getCond()); + if (condReg == null) { + condReg = Register.K0; + } + loadValueToReg(getCond(), condReg); + new MipsBranch(MipsBranchType.BNE, condReg, Register.ZERO, getTrueBB().getMipsLabel()); + new MipsJump(MipsJumpType.J, getFalseBB().getMipsLabel()); + } +} diff --git a/midend/llvm/instr/CallInstr.java b/midend/llvm/instr/CallInstr.java old mode 100644 new mode 100755 index 29c1fae..c7e961d --- a/midend/llvm/instr/CallInstr.java +++ b/midend/llvm/instr/CallInstr.java @@ -1,48 +1,117 @@ -package midend.llvm.instr; - -import java.util.ArrayList; - -import midend.llvm.value.IrFuncValue; -import midend.llvm.value.IrValue; - -public class CallInstr extends IrInstr { - public CallInstr(String name, IrFuncValue func, ArrayList args) { - super(func.getRetType(), name, IrInstrType.CALL); - addUse(func); - for (IrValue arg : args) { - addUse(arg); - } - } - - public boolean callVoid() { - return getType().isVoid(); - } - - public IrFuncValue getCalledFunc() { - return (IrFuncValue) getUse(0); - } - - public ArrayList getArgs() { - ArrayList args = new ArrayList<>(); - for (int i = 1; i < getNumUses(); i++) { - args.add(getUse(i)); - } - return args; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - if (!callVoid()) { - sb.append(getName() + " = "); - } - sb.append("call " + getType() + " " + getCalledFunc().getName() + "("); - for (int i = 1; i < getNumUses(); i++) { - sb.append(getUse(i).getType() + " " + getUse(i).getName()); - if (i < getNumUses() - 1) { - sb.append(", "); - } - } - sb.append(")"); - return sb.toString(); - } -} +package midend.llvm.instr; + +import java.util.ArrayList; + +import backend.mips.Register; +import backend.mips.instr.MipsAlu; +import backend.mips.instr.MipsJump; +import backend.mips.instr.MipsLs; +import backend.mips.instr.type.MipsAluType; +import backend.mips.instr.type.MipsJumpType; +import backend.mips.instr.type.MipsLsType; +import backend.mips.MipsBuilder; +import midend.llvm.value.IrFuncValue; +import midend.llvm.value.IrValue; + +public class CallInstr extends IrInstr { + public CallInstr(String name, IrFuncValue func, ArrayList args) { + super(func.getRetType(), name, IrInstrType.CALL); + addUse(func); + for (IrValue arg : args) { + addUse(arg); + } + } + + public boolean callVoid() { + return getType().isVoid(); + } + + public IrFuncValue getCalledFunc() { + return (IrFuncValue) getUse(0); + } + + public ArrayList getArgs() { + ArrayList args = new ArrayList<>(); + for (int i = 1; i < getNumUses(); i++) { + args.add(getUse(i)); + } + return args; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + if (!callVoid()) { + sb.append(getName() + " = "); + } + sb.append("call " + getType() + " " + getCalledFunc().getName() + "("); + for (int i = 1; i < getNumUses(); i++) { + sb.append(getUse(i).getType() + " " + getUse(i).getName()); + if (i < getNumUses() - 1) { + sb.append(", "); + } + } + sb.append(")"); + return sb.toString(); + } + + public void toMips() { + ArrayList usedRegisters = MipsBuilder.getUsedRegisters(); + int offset = MipsBuilder.getOffset(); + save(usedRegisters, offset); + ArrayList args = getArgs(); + saveArgs(args, offset, usedRegisters); + offset -= (usedRegisters.size() + 2) * 4; + new MipsAlu(MipsAluType.ADDI, Register.SP, Register.SP, offset); + new MipsJump(MipsJumpType.JAL, getCalledFunc().getMipsLabel()); + offset += (usedRegisters.size() + 2) * 4; + recover(usedRegisters, offset); + saveResult(this, Register.V0); + } + + public void save(ArrayList usedRegisters, int offset) { + int num = 0; + for (Register reg : usedRegisters) { + num++; + new MipsLs(MipsLsType.SW, reg, Register.SP, offset - num * 4); + } + new MipsLs(MipsLsType.SW, Register.SP, Register.SP, offset - (num + 1) * 4); + new MipsLs(MipsLsType.SW, Register.RA, Register.SP, offset - (num + 2) * 4); + } + + public void saveArgs(ArrayList args, int offset, ArrayList usedRegisters) { + int num = 0; + ArrayList argRegs = new ArrayList<>(); + argRegs.add(Register.A1); + argRegs.add(Register.A2); + argRegs.add(Register.A3); + for (IrValue arg : args) { + num++; + if (num <= 3) { // 分配到A1、A2、A3 + if (argRegs.contains(MipsBuilder.getRegister(arg))) { + int index = usedRegisters.indexOf(MipsBuilder.getRegister(arg)); + new MipsLs(MipsLsType.LW, argRegs.get(num - 1), Register.SP, offset - (index + 1) * 4); + } else { + loadValueToReg(arg, argRegs.get(num - 1)); + } + } else { + if (MipsBuilder.getRegister(arg) == Register.K0 || argRegs.contains(MipsBuilder.getRegister(arg))) { + int index = usedRegisters.indexOf(MipsBuilder.getRegister(arg)); + new MipsLs(MipsLsType.LW, Register.K0, Register.SP, offset - (index + 1) * 4); + } else { + loadValueToReg(arg, Register.K0); + } + new MipsLs(MipsLsType.SW, Register.K0, Register.SP, offset - (usedRegisters.size() + num + 2) * 4); + } + } + } + + public void recover(ArrayList usedRegisters, int offset) { + new MipsLs(MipsLsType.LW, Register.RA, Register.SP, 0); + new MipsLs(MipsLsType.LW, Register.SP, Register.SP, 4); + int num = 0; + for (Register reg : usedRegisters) { + num++; + new MipsLs(MipsLsType.LW, reg, Register.SP, offset - num * 4); + } + } +} diff --git a/midend/llvm/instr/CmpInstr.java b/midend/llvm/instr/CmpInstr.java old mode 100644 new mode 100755 index 99bdcef..d8b553e --- a/midend/llvm/instr/CmpInstr.java +++ b/midend/llvm/instr/CmpInstr.java @@ -1,32 +1,58 @@ -package midend.llvm.instr; - -import midend.llvm.value.IrValue; -import midend.llvm.type.IrInterType; - -public class CmpInstr extends IrInstr { - private CmpType cmpType; - - public CmpInstr(String name, String op, IrValue lhs, IrValue rhs) { - super(IrInterType.BOOL, name, IrInstrType.CMP); - cmpType = CmpType.getCmpType(op); - addUse(lhs); - addUse(rhs); - } - - public CmpType getCmpType() { - return cmpType; - } - - public IrValue getLhs() { - return getUse(0); - } - - public IrValue getRhs() { - return getUse(1); - } - - public String toString() { - return getName() + " = " + "icmp " + cmpType.toString() - + " i32 " + getLhs().getName() + ", " + getRhs().getName(); - } -} +package midend.llvm.instr; + +import midend.llvm.value.IrValue; +import backend.mips.Register; +import backend.mips.instr.MipsComp; +import backend.mips.instr.type.MipsCompareType; +import midend.llvm.type.IrInterType; +import backend.mips.MipsBuilder; + +public class CmpInstr extends IrInstr { + private CmpType cmpType; + + public CmpInstr(String name, String op, IrValue lhs, IrValue rhs) { + super(IrInterType.BOOL, name, IrInstrType.CMP); + cmpType = CmpType.getCmpType(op); + addUse(lhs); + addUse(rhs); + } + + public CmpType getCmpType() { + return cmpType; + } + + public IrValue getLhs() { + return getUse(0); + } + + public IrValue getRhs() { + return getUse(1); + } + + public String toString() { + return getName() + " = " + "icmp " + cmpType.toString() + + " i32 " + getLhs().getName() + ", " + getRhs().getName(); + } + + public void toMips() { + Register leftReg = MipsBuilder.getRegister(getLhs()) != null ? MipsBuilder.getRegister(getLhs()) : Register.K0; + Register rightReg = MipsBuilder.getRegister(getRhs()) != null ? MipsBuilder.getRegister(getRhs()) : Register.K1; + Register resultReg = MipsBuilder.getRegister(this) != null ? MipsBuilder.getRegister(this) : Register.K1; + loadValueToReg(getLhs(), leftReg); + loadValueToReg(getRhs(), rightReg); + if (getCmpType() == CmpType.EQ) { + new MipsComp(MipsCompareType.SEQ, resultReg, leftReg, rightReg); + } else if (getCmpType() == CmpType.NE) { + new MipsComp(MipsCompareType.SNE, resultReg, leftReg, rightReg); + } else if (getCmpType() == CmpType.SGE) { + new MipsComp(MipsCompareType.SGE, resultReg, leftReg, rightReg); + } else if (getCmpType() == CmpType.SLE) { + new MipsComp(MipsCompareType.SLE, resultReg, leftReg, rightReg); + } else if (getCmpType() == CmpType.SGT) { + new MipsComp(MipsCompareType.SGT, resultReg, leftReg, rightReg); + } else if (getCmpType() == CmpType.SLT) { + new MipsComp(MipsCompareType.SLT, resultReg, leftReg, rightReg); + } + saveResult(this, resultReg); + } +} diff --git a/midend/llvm/instr/CmpType.java b/midend/llvm/instr/CmpType.java old mode 100644 new mode 100755 index 921a5ec..e0ad009 --- a/midend/llvm/instr/CmpType.java +++ b/midend/llvm/instr/CmpType.java @@ -1,48 +1,48 @@ -package midend.llvm.instr; - -public enum CmpType { - EQ, - NE, - SGT, - SGE, - SLT, - SLE; - - public static CmpType getCmpType(String op) { - switch (op) { - case "==": - return EQ; - case "!=": - return NE; - case ">": - return SGT; - case ">=": - return SGE; - case "<": - return SLT; - case "<=": - return SLE; - default: - return null; - } - } - - public String toString() { - switch (this) { - case EQ: - return "eq"; - case NE: - return "ne"; - case SGT: - return "sgt"; - case SGE: - return "sge"; - case SLT: - return "slt"; - case SLE: - return "sle"; - default: - return null; - } - } -} +package midend.llvm.instr; + +public enum CmpType { + EQ, + NE, + SGT, + SGE, + SLT, + SLE; + + public static CmpType getCmpType(String op) { + switch (op) { + case "==": + return EQ; + case "!=": + return NE; + case ">": + return SGT; + case ">=": + return SGE; + case "<": + return SLT; + case "<=": + return SLE; + default: + return null; + } + } + + public String toString() { + switch (this) { + case EQ: + return "eq"; + case NE: + return "ne"; + case SGT: + return "sgt"; + case SGE: + return "sge"; + case SLT: + return "slt"; + case SLE: + return "sle"; + default: + return null; + } + } +} diff --git a/midend/llvm/instr/ExtendInstr.java b/midend/llvm/instr/ExtendInstr.java old mode 100644 new mode 100755 index 4ce886d..e9e15ca --- a/midend/llvm/instr/ExtendInstr.java +++ b/midend/llvm/instr/ExtendInstr.java @@ -1,31 +1,42 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrType; -import midend.llvm.value.IrValue; - -public class ExtendInstr extends IrInstr { - private IrType targetType; - - public ExtendInstr(String name, IrType targetType, IrValue src) { - super(targetType, name, IrInstrType.EXTEND); - this.targetType = targetType; - addUse(src); - } - - public IrValue getSrc() { - return getUse(0); - } - - public IrType getTargetType() { - return this.targetType; - } - - public IrType getSrcType() { - return getSrc().getType(); - } - - public String toString() { - return getName() + " = zext " + getSrc().getType() - + " " + getSrc().getName() + " to " + getTargetType(); - } -} +package midend.llvm.instr; + +import backend.mips.MipsBuilder; +import backend.mips.Register; +import midend.llvm.type.IrType; +import midend.llvm.value.IrValue; + +public class ExtendInstr extends IrInstr { + private IrType targetType; + + public ExtendInstr(String name, IrType targetType, IrValue src) { + super(targetType, name, IrInstrType.EXTEND); + this.targetType = targetType; + addUse(src); + } + + public IrValue getSrc() { + return getUse(0); + } + + public IrType getTargetType() { + return this.targetType; + } + + public IrType getSrcType() { + return getSrc().getType(); + } + + public String toString() { + return getName() + " = zext " + getSrc().getType() + + " " + getSrc().getName() + " to " + getTargetType(); + } + + public void toMips() { + Register reg = MipsBuilder.getRegister(this); + if (reg == null) { + reg = Register.K0; + } + loadValueToReg(getSrc(), reg); + saveResult(this, reg); + } +} diff --git a/midend/llvm/instr/GepInstr.java b/midend/llvm/instr/GepInstr.java old mode 100644 new mode 100755 index 825463c..35b45e4 --- a/midend/llvm/instr/GepInstr.java +++ b/midend/llvm/instr/GepInstr.java @@ -1,57 +1,86 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrArrayType; -import midend.llvm.type.IrPointerType; -import midend.llvm.type.IrType; -import midend.llvm.value.IrValue; - -public class GepInstr extends IrInstr { - public GepInstr(IrValue pointer, IrValue offset, String name) { - super(new IrPointerType(getTargetType(pointer)), name, IrInstrType.GEP); - addUse(pointer); - addUse(offset); - } - - public IrValue getPointer() { - return getUse(0); - } - - public IrValue getOffset() { - return getUse(1); - } - - public String toString() { - IrValue pointer = this.getPointer(); - IrValue offset = this.getOffset(); - - IrPointerType pointerType = (IrPointerType) pointer.getType(); - IrType targetType = pointerType.getPointeeType(); - - if (targetType instanceof IrArrayType arrayType) { - return getName() + " = getelementptr inbounds " + - arrayType + ", " + - pointerType + " " + - pointer.getName() + ", i32 0, " + - offset.getType() + " " + - offset.getName(); - } else { - return getName() + " = getelementptr inbounds " + - targetType + ", " + - pointerType + " " + - pointer.getName() + ", " + - offset.getType() + " " + - offset.getName(); - } - } - - public static IrType getTargetType(IrValue pointer) { - IrType targetType = ((IrPointerType) pointer.getType()).getPointeeType(); - if (targetType instanceof IrArrayType arrayType) { - return arrayType.getElementType(); - } else if (targetType instanceof IrPointerType pointerType) { - return pointerType.getPointeeType(); - } else { - return targetType; - } - } -} +package midend.llvm.instr; + +import backend.mips.MipsBuilder; +import backend.mips.Register; +import backend.mips.instr.MipsAlu; +import backend.mips.instr.type.MipsAluType; +import midend.llvm.constant.IrConstantInt; +import midend.llvm.type.IrArrayType; +import midend.llvm.type.IrPointerType; +import midend.llvm.type.IrType; +import midend.llvm.value.IrValue; + +public class GepInstr extends IrInstr { + public GepInstr(IrValue pointer, IrValue offset, String name) { + super(new IrPointerType(getTargetType(pointer)), name, IrInstrType.GEP); + addUse(pointer); + addUse(offset); + } + + public IrValue getPointer() { + return getUse(0); + } + + public IrValue getOffset() { + return getUse(1); + } + + public String toString() { + IrValue pointer = this.getPointer(); + IrValue offset = this.getOffset(); + + IrPointerType pointerType = (IrPointerType) pointer.getType(); + IrType targetType = pointerType.getPointeeType(); + + if (targetType instanceof IrArrayType arrayType) { + return getName() + " = getelementptr inbounds " + + arrayType + ", " + + pointerType + " " + + pointer.getName() + ", i32 0, " + + offset.getType() + " " + + offset.getName(); + } else { + return getName() + " = getelementptr inbounds " + + targetType + ", " + + pointerType + " " + + pointer.getName() + ", " + + offset.getType() + " " + + offset.getName(); + } + } + + public static IrType getTargetType(IrValue pointer) { + IrType targetType = ((IrPointerType) pointer.getType()).getPointeeType(); + if (targetType instanceof IrArrayType arrayType) { + return arrayType.getElementType(); + } else if (targetType instanceof IrPointerType pointerType) { + return pointerType.getPointeeType(); + } else { + return targetType; + } + } + + public void toMips() { + Register pointerReg = MipsBuilder.getRegister(getPointer()); + if (pointerReg == null) { + pointerReg = Register.K0; + } + loadValueToReg(getPointer(), pointerReg); + Register offsetReg = MipsBuilder.getRegister(getOffset()); + if (offsetReg == null) { + offsetReg = Register.K1; + } + Register resultReg = MipsBuilder.getRegister(this); + if (resultReg == null) { + resultReg = Register.K1; + } + if (getOffset() instanceof IrConstantInt intOffset) { + new MipsAlu(MipsAluType.ADDI, resultReg, pointerReg, 4 * intOffset.getValue()); + } else { + loadValueToReg(getOffset(), offsetReg); + new MipsAlu(MipsAluType.SLL, resultReg, offsetReg, 2); + new MipsAlu(MipsAluType.ADDU, resultReg, resultReg, pointerReg); + } + saveResult(this, resultReg); + } +} diff --git a/midend/llvm/instr/GetIntInstr.java b/midend/llvm/instr/GetIntInstr.java old mode 100644 new mode 100755 index 7b860f1..6d21ba5 --- a/midend/llvm/instr/GetIntInstr.java +++ b/midend/llvm/instr/GetIntInstr.java @@ -1,17 +1,26 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrInterType; - -public class GetIntInstr extends IrInstr { - public GetIntInstr(String name) { - super(IrInterType.INT32, name, IrInstrType.IO); - } - - public String toString() { - return getName() + " = call i32 @getint()"; - } - - public static String getIntDecl() { - return "declare i32 @getint()"; - } -} +package midend.llvm.instr; + +import backend.mips.Register; +import backend.mips.instr.MipsSyscall; +import backend.mips.instr.fake.MipsLi; +import midend.llvm.type.IrInterType; + +public class GetIntInstr extends IrInstr { + public GetIntInstr(String name) { + super(IrInterType.INT32, name, IrInstrType.IO); + } + + public String toString() { + return getName() + " = call i32 @getint()"; + } + + public static String getIntDecl() { + return "declare i32 @getint()"; + } + + public void toMips() { + new MipsLi(Register.V0, 5); + new MipsSyscall(); + saveResult(this, Register.V0); + } +} diff --git a/midend/llvm/instr/IrInstr.java b/midend/llvm/instr/IrInstr.java old mode 100644 new mode 100755 index 1a701e9..45b9c50 --- a/midend/llvm/instr/IrInstr.java +++ b/midend/llvm/instr/IrInstr.java @@ -1,28 +1,75 @@ -package midend.llvm.instr; - -import midend.llvm.use.IrUser; -import midend.llvm.value.IrBasicBlock; -import midend.llvm.type.IrType; - -public class IrInstr extends IrUser { - private IrInstrType type; - private IrBasicBlock block; - - public IrInstr(IrType type, String name, IrInstrType instrType) { - super(type, name); - this.type = instrType; - this.block = null; - } - - public IrInstrType getInstrType() { - return type; - } - - public IrBasicBlock getBBlock() { - return block; - } - - public void setBBlock(IrBasicBlock block) { - this.block = block; - } -} +package midend.llvm.instr; + +import midend.llvm.use.IrUser; +import midend.llvm.value.IrBasicBlock; +import midend.llvm.value.IrGlobalValue; +import midend.llvm.value.IrValue; +import midend.llvm.constant.IrConstantInt; +import backend.mips.MipsBuilder; +import backend.mips.Register; +import backend.mips.instr.MipsLs; +import backend.mips.instr.fake.MipsLa; +import backend.mips.instr.fake.MipsLi; +import backend.mips.instr.fake.MipsMove; +import backend.mips.instr.type.MipsLsType; +import midend.llvm.type.IrType; + +public class IrInstr extends IrUser { + private IrInstrType type; + private IrBasicBlock block; + + public IrInstr(IrType type, String name, IrInstrType instrType) { + super(type, name); + this.type = instrType; + this.block = null; + } + + public IrInstrType getInstrType() { + return type; + } + + public IrBasicBlock getBBlock() { + return block; + } + + public void setBBlock(IrBasicBlock block) { + this.block = block; + } + + public void saveResult(IrValue value, Register reg) { + Register valueReg = MipsBuilder.getRegister(value); + if (valueReg == null) { + Integer offset = MipsBuilder.getOffset(value); + if (offset == null) { + MipsBuilder.allocaOffset(value); + offset = MipsBuilder.getOffset(value); + } + new MipsLs(MipsLsType.SW, reg, Register.SP, offset); + } else { + new MipsMove(valueReg, reg); + } + } + + public void loadValueToReg(IrValue value, Register reg) { + if (value instanceof IrGlobalValue) { + new MipsLa(reg, value.getMipsLabel()); + return; + } + if (value instanceof IrConstantInt) { + new MipsLi(reg, ((IrConstantInt) value).getValue()); + return; + } + + Register valueReg = MipsBuilder.getRegister(value); + if (valueReg != null) { + new MipsMove(reg, valueReg); + return; + } + Integer offset = MipsBuilder.getOffset(value); + if (offset == null) { + MipsBuilder.allocaOffset(value); + offset = MipsBuilder.getOffset(value); + } + new MipsLs(MipsLsType.LW, reg, Register.SP, offset); + } +} diff --git a/midend/llvm/instr/IrInstrType.java b/midend/llvm/instr/IrInstrType.java old mode 100644 new mode 100755 index cfcce36..8b3203b --- a/midend/llvm/instr/IrInstrType.java +++ b/midend/llvm/instr/IrInstrType.java @@ -1,18 +1,18 @@ -package midend.llvm.instr; - -public enum IrInstrType { - ALU, - CMP, - CALL, - ALLOCA, - LOAD, - STORE, - GEP, - PHI, - EXTEND, - TRUNC, - BR, - RET, - JUMP, - IO -} +package midend.llvm.instr; + +public enum IrInstrType { + ALU, + CMP, + CALL, + ALLOCA, + LOAD, + STORE, + GEP, + PHI, + EXTEND, + TRUNC, + BR, + RET, + JUMP, + IO +} diff --git a/midend/llvm/instr/JumpInstr.java b/midend/llvm/instr/JumpInstr.java old mode 100644 new mode 100755 index 9c00ea7..d3fab45 --- a/midend/llvm/instr/JumpInstr.java +++ b/midend/llvm/instr/JumpInstr.java @@ -1,20 +1,25 @@ -package midend.llvm.instr; - -import midend.llvm.value.IrBasicBlock; -import midend.llvm.type.IrInterType; - -public class JumpInstr extends IrInstr { - public JumpInstr(IrBasicBlock targetBlock) { - super(IrInterType.VOID, "jump", IrInstrType.JUMP); - addUse(targetBlock); - } - - public IrBasicBlock getTargetBlock() { - return (IrBasicBlock) getUse(0); - } - - public String toString() { - return "br label " + "%" + getTargetBlock().getName(); - } -} -// TODO:所有的指令的基本块设置还需完善 \ No newline at end of file +package midend.llvm.instr; + +import midend.llvm.value.IrBasicBlock; +import backend.mips.instr.MipsJump; +import backend.mips.instr.type.MipsJumpType; +import midend.llvm.type.IrInterType; + +public class JumpInstr extends IrInstr { + public JumpInstr(IrBasicBlock targetBlock) { + super(IrInterType.VOID, "jump", IrInstrType.JUMP); + addUse(targetBlock); + } + + public IrBasicBlock getTargetBlock() { + return (IrBasicBlock) getUse(0); + } + + public String toString() { + return "br label " + "%" + getTargetBlock().getName(); + } + + public void toMips() { + new MipsJump(MipsJumpType.J, getTargetBlock().getMipsLabel()); //TODO: 该用JAL吗? + } +} diff --git a/midend/llvm/instr/LoadInstr.java b/midend/llvm/instr/LoadInstr.java old mode 100644 new mode 100755 index f9c4c23..2cce934 --- a/midend/llvm/instr/LoadInstr.java +++ b/midend/llvm/instr/LoadInstr.java @@ -1,20 +1,39 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrPointerType; -import midend.llvm.value.IrValue; - -public class LoadInstr extends IrInstr { - public LoadInstr(IrValue pointer, String name) { - super(((IrPointerType) pointer.getType()).getPointeeType(), name, IrInstrType.LOAD); - addUse(pointer); - } - - public IrValue getPointer() { - return getUse(0); - } - - public String toString() { - return getName() + " = load " + getType() + ", " - + getPointer().getType() + " " + getPointer().getName(); - } -} +package midend.llvm.instr; + +import backend.mips.MipsBuilder; +import backend.mips.Register; +import backend.mips.instr.MipsLs; +import backend.mips.instr.type.MipsLsType; +import midend.llvm.type.IrPointerType; +import midend.llvm.value.IrValue; + +public class LoadInstr extends IrInstr { + public LoadInstr(IrValue pointer, String name) { + super(((IrPointerType) pointer.getType()).getPointeeType(), name, IrInstrType.LOAD); + addUse(pointer); + } + + public IrValue getPointer() { + return getUse(0); + } + + public String toString() { + return getName() + " = load " + getType() + ", " + + getPointer().getType() + " " + getPointer().getName(); + } + + public void toMips() { + IrValue pointer = getPointer(); + Register reg = MipsBuilder.getRegister(pointer); + if (reg == null) { // 未分配寄存器情况 + reg = Register.K0; + } + loadValueToReg(pointer, reg); + Register resultReg = MipsBuilder.getRegister(this); + if (resultReg == null) { + resultReg = Register.K1; + } + new MipsLs(MipsLsType.LW, resultReg, reg, 0); + saveResult(this, resultReg); + } +} diff --git a/midend/llvm/instr/PutChInstr.java b/midend/llvm/instr/PutChInstr.java old mode 100644 new mode 100755 index db9fff5..de47b3d --- a/midend/llvm/instr/PutChInstr.java +++ b/midend/llvm/instr/PutChInstr.java @@ -1,19 +1,28 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrInterType; -import midend.llvm.value.IrValue; - -public class PutChInstr extends IrInstr { - public PutChInstr(String name, IrValue putValue) { - super(IrInterType.VOID, name, IrInstrType.IO); - addUse(putValue); - } - - public String toString() { - return "call void @putch(i32 " + getUses().get(0).getName() + ")"; - } - - public static String putChDecl() { - return "declare void @putch(i32)"; - } -} +package midend.llvm.instr; + +import midend.llvm.type.IrInterType; +import midend.llvm.value.IrValue; +import backend.mips.Register; +import backend.mips.instr.fake.MipsLi; +import backend.mips.instr.MipsSyscall; + +public class PutChInstr extends IrInstr { + public PutChInstr(String name, IrValue putValue) { + super(IrInterType.VOID, name, IrInstrType.IO); + addUse(putValue); + } + + public String toString() { + return "call void @putch(i32 " + getUses().get(0).getName() + ")"; + } + + public static String putChDecl() { + return "declare void @putch(i32)"; + } + + public void toMips() { + loadValueToReg(getUse(0), Register.A0); + new MipsLi(Register.V0, 11); + new MipsSyscall(); + } +} diff --git a/midend/llvm/instr/PutIntInstr.java b/midend/llvm/instr/PutIntInstr.java old mode 100644 new mode 100755 index f24d12d..423b02b --- a/midend/llvm/instr/PutIntInstr.java +++ b/midend/llvm/instr/PutIntInstr.java @@ -1,19 +1,28 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrInterType; -import midend.llvm.value.IrValue; - -public class PutIntInstr extends IrInstr { - public PutIntInstr(String name, IrValue putValue) { - super(IrInterType.VOID, name, IrInstrType.IO); - addUse(putValue); - } - - public String toString() { - return "call void @putint(i32 " + getUses().get(0).getName() + ")"; - } - - public static String putIntDecl() { - return "declare void @putint(i32)"; - } -} +package midend.llvm.instr; + +import midend.llvm.type.IrInterType; +import midend.llvm.value.IrValue; +import backend.mips.Register; +import backend.mips.instr.fake.MipsLi; +import backend.mips.instr.MipsSyscall; + +public class PutIntInstr extends IrInstr { + public PutIntInstr(String name, IrValue putValue) { + super(IrInterType.VOID, name, IrInstrType.IO); + addUse(putValue); + } + + public String toString() { + return "call void @putint(i32 " + getUses().get(0).getName() + ")"; + } + + public static String putIntDecl() { + return "declare void @putint(i32)"; + } + + public void toMips() { + loadValueToReg(getUse(0), Register.A0); + new MipsLi(Register.V0, 1); + new MipsSyscall(); + } +} diff --git a/midend/llvm/instr/PutStrInstr.java b/midend/llvm/instr/PutStrInstr.java old mode 100644 new mode 100755 index a913114..3664af9 --- a/midend/llvm/instr/PutStrInstr.java +++ b/midend/llvm/instr/PutStrInstr.java @@ -1,26 +1,36 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrInterType; -import midend.llvm.type.IrPointerType; -import midend.llvm.constant.IrConstantStr; - -public class PutStrInstr extends IrInstr { - private IrConstantStr strVal; - - public PutStrInstr(String name, IrConstantStr putValue) { - super(IrInterType.VOID, name, IrInstrType.IO); - addUse(putValue); - strVal = putValue; - } - - public static String putStrDecl() { - return "declare void @putstr(i8*)"; - } - - public String toString() { - IrPointerType ptrType = (IrPointerType) strVal.getType(); - return "call void @putstr(i8* getelementptr inbounds (" - + ptrType.getPointeeType() + ", " + ptrType + - " " + strVal.getName() + ", i32 0, i32 0))"; - } -} +package midend.llvm.instr; + +import midend.llvm.type.IrInterType; +import midend.llvm.type.IrPointerType; +import backend.mips.instr.fake.MipsLa; +import midend.llvm.constant.IrConstantStr; +import backend.mips.instr.fake.MipsLi; +import backend.mips.instr.MipsSyscall; +import backend.mips.Register; + +public class PutStrInstr extends IrInstr { + private IrConstantStr strVal; + + public PutStrInstr(String name, IrConstantStr putValue) { + super(IrInterType.VOID, name, IrInstrType.IO); + addUse(putValue); + strVal = putValue; + } + + public static String putStrDecl() { + return "declare void @putstr(i8*)"; + } + + public String toString() { + IrPointerType ptrType = (IrPointerType) strVal.getType(); + return "call void @putstr(i8* getelementptr inbounds (" + + ptrType.getPointeeType() + ", " + ptrType + + " " + strVal.getName() + ", i32 0, i32 0))"; + } + + public void toMips() { + new MipsLa(Register.A0, strVal.getMipsLabel()); + new MipsLi(Register.V0, 4); + new MipsSyscall(); + } +} diff --git a/midend/llvm/instr/ReturnInstr.java b/midend/llvm/instr/ReturnInstr.java old mode 100644 new mode 100755 index e4b80f5..2fd98f7 --- a/midend/llvm/instr/ReturnInstr.java +++ b/midend/llvm/instr/ReturnInstr.java @@ -1,20 +1,38 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrInterType; -import midend.llvm.value.IrValue; - -public class ReturnInstr extends IrInstr { - public ReturnInstr(IrValue retValue) { - super(IrInterType.VOID, "ret", IrInstrType.RET); - addUse(retValue); - } - - public IrValue getRetValue() { - return getUse(0); - } - - public String toString() { - return getName() + (getRetValue() == null ? " void" : - " " + getRetValue().getType() + " " + getRetValue().getName()); - } -} +package midend.llvm.instr; + +import backend.mips.MipsBuilder; +import backend.mips.Register; +import backend.mips.instr.MipsJump; +import backend.mips.instr.fake.MipsMove; +import backend.mips.instr.type.MipsJumpType; +import midend.llvm.type.IrInterType; +import midend.llvm.value.IrValue; + +public class ReturnInstr extends IrInstr { + public ReturnInstr(IrValue retValue) { + super(IrInterType.VOID, "ret", IrInstrType.RET); + addUse(retValue); + } + + public IrValue getRetValue() { + return getUse(0); + } + + public String toString() { + return getName() + + (getRetValue() == null ? " void" : " " + getRetValue().getType() + " " + getRetValue().getName()); + } + + public void toMips() { + if (getRetValue() != null) { + Register reg = MipsBuilder.getRegister(getRetValue()); + if (reg == null) { + loadValueToReg(getRetValue(), Register.V0); + } else { + new MipsMove(Register.V0, reg); + } + } + new MipsJump(MipsJumpType.JR, Register.RA); + + } +} diff --git a/midend/llvm/instr/StoreInstr.java b/midend/llvm/instr/StoreInstr.java old mode 100644 new mode 100755 index cd8b229..6bf6a8b --- a/midend/llvm/instr/StoreInstr.java +++ b/midend/llvm/instr/StoreInstr.java @@ -1,25 +1,43 @@ -package midend.llvm.instr; - -import midend.llvm.value.IrValue; -import midend.llvm.type.IrInterType; - -public class StoreInstr extends IrInstr { - public StoreInstr(IrValue value, IrValue pointer) { - super(IrInterType.VOID, "store", IrInstrType.STORE); - addUse(value); - addUse(pointer); - } - - public IrValue getValue() { - return getUse(0); - } - - public IrValue getPointer() { - return getUse(1); - } - - public String toString() { - return getName() + " " + getValue().getType() + " " + getValue().getName() - + ", " + getPointer().getType() + " " + getPointer().getName(); - } -} +package midend.llvm.instr; + +import midend.llvm.value.IrValue; +import backend.mips.MipsBuilder; +import backend.mips.Register; +import midend.llvm.type.IrInterType; +import backend.mips.instr.MipsLs; +import backend.mips.instr.type.MipsLsType; + +public class StoreInstr extends IrInstr { + public StoreInstr(IrValue value, IrValue pointer) { + super(IrInterType.VOID, "store", IrInstrType.STORE); + addUse(value); + addUse(pointer); + } + + public IrValue getValue() { + return getUse(0); + } + + public IrValue getPointer() { + return getUse(1); + } + + public String toString() { + return getName() + " " + getValue().getType() + " " + getValue().getName() + + ", " + getPointer().getType() + " " + getPointer().getName(); + } + + public void toMips() { + Register valueReg = MipsBuilder.getRegister(getValue()); + if (valueReg == null) { + valueReg = Register.K0; + } + loadValueToReg(getValue(), valueReg); + Register pointerReg = MipsBuilder.getRegister(getPointer()); + if (pointerReg == null) { + pointerReg = Register.K1; + } + loadValueToReg(getPointer(), pointerReg); + new MipsLs(MipsLsType.SW, valueReg, pointerReg, 0); + } +} diff --git a/midend/llvm/instr/TruncInstr.java b/midend/llvm/instr/TruncInstr.java old mode 100644 new mode 100755 index c359a6e..5e173dc --- a/midend/llvm/instr/TruncInstr.java +++ b/midend/llvm/instr/TruncInstr.java @@ -1,31 +1,50 @@ -package midend.llvm.instr; - -import midend.llvm.type.IrType; -import midend.llvm.value.IrValue; - -public class TruncInstr extends IrInstr { - private IrType targetType; - - public TruncInstr(IrType targetType, IrValue value, String name) { - super(targetType, name, IrInstrType.TRUNC); - addUse(value); - this.targetType = targetType; - } - - public IrValue getSrc() { - return getUse(0); - } - - public IrType getTargetType() { - return targetType; - } - - public IrType getSrcType() { - return getSrc().getType(); - } - - public String toString() { - return getName() + " = trunc " + getSrcType() - + " " + getSrc().getName() + " to " + getTargetType(); - } -} +package midend.llvm.instr; + +import backend.mips.MipsBuilder; +import backend.mips.Register; +import backend.mips.instr.MipsAlu; +import backend.mips.instr.type.MipsAluType; + +import midend.llvm.type.IrType; +import midend.llvm.value.IrValue; + +public class TruncInstr extends IrInstr { + private IrType targetType; + + public TruncInstr(IrType targetType, IrValue value, String name) { + super(targetType, name, IrInstrType.TRUNC); + addUse(value); + this.targetType = targetType; + } + + public IrValue getSrc() { + return getUse(0); + } + + public IrType getTargetType() { + return targetType; + } + + public IrType getSrcType() { + return getSrc().getType(); + } + + public String toString() { + return getName() + " = trunc " + getSrcType() + + " " + getSrc().getName() + " to " + getTargetType(); + } + + public void toMips() { + Register reg = MipsBuilder.getRegister(getSrc()); + if (reg == null) { + reg = Register.K0; + } + loadValueToReg(getSrc(), reg); + if (this.targetType.isInt8()) { + new MipsAlu(MipsAluType.ANDI, reg, reg, 0xFF); + } else if (this.targetType.isBool()) { + new MipsAlu(MipsAluType.ANDI, reg, reg, 0x1); + } + saveResult(this, reg); + } +} diff --git a/midend/llvm/type/IrArrayType.java b/midend/llvm/type/IrArrayType.java old mode 100644 new mode 100755 diff --git a/midend/llvm/type/IrBasicBlockType.java b/midend/llvm/type/IrBasicBlockType.java old mode 100644 new mode 100755 diff --git a/midend/llvm/type/IrFuncType.java b/midend/llvm/type/IrFuncType.java old mode 100644 new mode 100755 diff --git a/midend/llvm/type/IrInterType.java b/midend/llvm/type/IrInterType.java old mode 100644 new mode 100755 diff --git a/midend/llvm/type/IrPointerType.java b/midend/llvm/type/IrPointerType.java old mode 100644 new mode 100755 diff --git a/midend/llvm/type/IrType.java b/midend/llvm/type/IrType.java old mode 100644 new mode 100755 index 037a9e4..566eac0 --- a/midend/llvm/type/IrType.java +++ b/midend/llvm/type/IrType.java @@ -4,9 +4,7 @@ import midend.llvm.IrBuilder; import midend.llvm.constant.IrConstantInt; import midend.llvm.instr.CmpInstr; import midend.llvm.instr.ExtendInstr; -import midend.llvm.instr.TruncInstr; import midend.llvm.value.IrValue; -import midend.llvm.instr.ExtendInstr; public class IrType { public boolean isInt32() { diff --git a/midend/llvm/use/IrUse.java b/midend/llvm/use/IrUse.java old mode 100644 new mode 100755 diff --git a/midend/llvm/use/IrUser.java b/midend/llvm/use/IrUser.java old mode 100644 new mode 100755 diff --git a/midend/llvm/value/IrBasicBlock.java b/midend/llvm/value/IrBasicBlock.java old mode 100644 new mode 100755 index 2bf2100..17ca7b0 --- a/midend/llvm/value/IrBasicBlock.java +++ b/midend/llvm/value/IrBasicBlock.java @@ -1,120 +1,128 @@ -package midend.llvm.value; - -import java.util.ArrayList; -import java.util.HashSet; - -import midend.llvm.instr.IrInstr; -import midend.llvm.instr.ReturnInstr; -import midend.llvm.type.IrBasicBlockType; - -public class IrBasicBlock extends IrValue { - private ArrayList instrs; - private IrFuncValue func; - private ArrayList preds; //前驱 - private ArrayList succs; //后继 - private HashSet domied; //支配该节点 - private IrBasicBlock directDomi; - private HashSet directDomies; //该节点直接支配 - private HashSet domiFrontier; - - public IrBasicBlock(String name, IrFuncValue func) { - super(new IrBasicBlockType(), name); - this.func = func; - instrs = new ArrayList<>(); - preds = new ArrayList<>(); - succs = new ArrayList<>(); - domied = new HashSet<>(); - directDomi = null; - directDomies = new HashSet<>(); - domiFrontier = new HashSet<>(); - } - - public void addInstr(IrInstr instr) { - instrs.add(instr); - instr.setBBlock(this); - } - - public IrFuncValue getFunc() { - return func; - } - - public boolean isEmpty() { - return instrs.isEmpty(); - } - - public boolean isEntry() { - return this.func.getBBlock(0) == this; - } - - public ArrayList getPreds() { - return preds; - } - - public ArrayList getSuccs() { - return succs; - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getName() + ":\n\t"); - for (IrInstr instr : instrs) { - sb.append(instr.toString()); - if (instr != instrs.get(instrs.size() - 1)) { - sb.append("\n\t"); - } - } - return sb.toString(); - } - - public boolean lastIsReturn() { - if (instrs.isEmpty()) { - return false; - } - return instrs.get(instrs.size() - 1) instanceof ReturnInstr; - } - - public void clearCfg() { - this.preds.clear(); - this.succs.clear(); - domied.clear(); - directDomi = null; - directDomies.clear(); - domiFrontier.clear(); - } - - public ArrayList getInstrs() { - return instrs; - } - - public void addPred(IrBasicBlock bb) { - this.preds.add(bb); - } - - public void addSucc(IrBasicBlock bb) { - this.succs.add(bb); - } - - public void addDomied(IrBasicBlock bb) { - this.domied.add(bb); - } - - public void addDirectDomies(IrBasicBlock bb) { - this.directDomies.add(bb); - } - - public void addDomiFrontier(IrBasicBlock bb) { - this.domiFrontier.add(bb); - } - - public void setDirectDomi(IrBasicBlock bb) { - this.directDomi = bb; - } - - public HashSet getDomied() { - return domied; - } - - public IrBasicBlock getDirectDomi() { - return this.directDomi; - } -} +package midend.llvm.value; + +import java.util.ArrayList; +import java.util.HashSet; + +import backend.mips.instr.MipsLabel; +import midend.llvm.instr.IrInstr; +import midend.llvm.instr.ReturnInstr; +import midend.llvm.type.IrBasicBlockType; + +public class IrBasicBlock extends IrValue { + private ArrayList instrs; + private IrFuncValue func; + private ArrayList preds; //前驱 + private ArrayList succs; //后继 + private HashSet domied; //支配该节点 + private IrBasicBlock directDomi; + private HashSet directDomies; //该节点直接支配 + private HashSet domiFrontier; + + public IrBasicBlock(String name, IrFuncValue func) { + super(new IrBasicBlockType(), name); + this.func = func; + instrs = new ArrayList<>(); + preds = new ArrayList<>(); + succs = new ArrayList<>(); + domied = new HashSet<>(); + directDomi = null; + directDomies = new HashSet<>(); + domiFrontier = new HashSet<>(); + } + + public void addInstr(IrInstr instr) { + instrs.add(instr); + instr.setBBlock(this); + } + + public IrFuncValue getFunc() { + return func; + } + + public boolean isEmpty() { + return instrs.isEmpty(); + } + + public boolean isEntry() { + return this.func.getBBlock(0) == this; + } + + public ArrayList getPreds() { + return preds; + } + + public ArrayList getSuccs() { + return succs; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getName() + ":\n\t"); + for (IrInstr instr : instrs) { + sb.append(instr.toString()); + if (instr != instrs.get(instrs.size() - 1)) { + sb.append("\n\t"); + } + } + return sb.toString(); + } + + public boolean lastIsReturn() { + if (instrs.isEmpty()) { + return false; + } + return instrs.get(instrs.size() - 1) instanceof ReturnInstr; + } + + public void clearCfg() { + this.preds.clear(); + this.succs.clear(); + domied.clear(); + directDomi = null; + directDomies.clear(); + domiFrontier.clear(); + } + + public ArrayList getInstrs() { + return instrs; + } + + public void addPred(IrBasicBlock bb) { + this.preds.add(bb); + } + + public void addSucc(IrBasicBlock bb) { + this.succs.add(bb); + } + + public void addDomied(IrBasicBlock bb) { + this.domied.add(bb); + } + + public void addDirectDomies(IrBasicBlock bb) { + this.directDomies.add(bb); + } + + public void addDomiFrontier(IrBasicBlock bb) { + this.domiFrontier.add(bb); + } + + public void setDirectDomi(IrBasicBlock bb) { + this.directDomi = bb; + } + + public HashSet getDomied() { + return domied; + } + + public IrBasicBlock getDirectDomi() { + return this.directDomi; + } + + public void toMips() { + new MipsLabel(getMipsLabel()); + for (IrInstr instr : instrs) { + instr.toMips(); + } + } +} diff --git a/midend/llvm/value/IrFuncValue.java b/midend/llvm/value/IrFuncValue.java old mode 100644 new mode 100755 index bb570c3..60a60d6 --- a/midend/llvm/value/IrFuncValue.java +++ b/midend/llvm/value/IrFuncValue.java @@ -1,71 +1,124 @@ -package midend.llvm.value; - -import java.util.ArrayList; -import midend.llvm.type.IrType; -import midend.llvm.IrBuilder; -import midend.llvm.instr.ReturnInstr; -import midend.llvm.type.IrFuncType; - -public class IrFuncValue extends IrValue { - private ArrayList params; - private ArrayList bblocks; - - public IrFuncValue(String name, IrType retType) { - super(new IrFuncType(retType), name); - params = new ArrayList<>(); - bblocks = new ArrayList<>(); - } - - public ArrayList getParams() { - return params; - } - - public ArrayList getBBlocks() { - return bblocks; - } - - public IrBasicBlock getBBlock(int index) { - return bblocks.get(index); - } - - public void addParam(IrValue param) { - params.add(param); - } - - public void addBBlock(IrBasicBlock bblock) { - bblocks.add(bblock); - } - - public boolean isMain() { - return getName().equals("@main"); - } - - public IrType getRetType() { - return ((IrFuncType) getType()).getReturnType(); - } - - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("define dso_local " + this.getRetType() + " " + this.getName() + "("); - for (int i = 0; i < params.size(); i++) { - sb.append(params.get(i).getType() + " " + params.get(i).getName()); - if (i < params.size() - 1) { - sb.append(", "); - } - } - sb.append(") {\n"); - for (IrBasicBlock bblock : bblocks) { - sb.append(bblock.toString() + "\n"); - } - sb.append("}\n"); - return sb.toString(); - } - - public void checkReturn() { - IrBasicBlock currentBB = IrBuilder.getCurrentBB(); - if (!currentBB.lastIsReturn()) { - ReturnInstr returnInstr = new ReturnInstr(null); // 确保没有return的情况只有void - IrBuilder.addInstr(returnInstr); - } - } -} +package midend.llvm.value; + +import java.util.ArrayList; +import java.util.HashMap; + +import midend.llvm.type.IrType; +import midend.llvm.IrBuilder; +import midend.llvm.instr.ReturnInstr; +import midend.llvm.type.IrFuncType; +import backend.mips.MipsBuilder; +import backend.mips.Register; +import backend.mips.instr.MipsLabel; + +public class IrFuncValue extends IrValue { + private ArrayList params; + private ArrayList bblocks; + private HashMap valueRegisterMap; + private HashMap valueOffsetMap; + + public IrFuncValue(String name, IrType retType) { + super(new IrFuncType(retType), name); + params = new ArrayList<>(); + bblocks = new ArrayList<>(); + valueRegisterMap = new HashMap<>(); + valueOffsetMap = new HashMap<>(); + } + + public ArrayList getParams() { + return params; + } + + public ArrayList getBBlocks() { + return bblocks; + } + + public IrBasicBlock getBBlock(int index) { + return bblocks.get(index); + } + + public void addParam(IrValue param) { + params.add(param); + } + + public void addBBlock(IrBasicBlock bblock) { + bblocks.add(bblock); + } + + public Register getRegister(IrValue value) { + return valueRegisterMap.get(value); + } + + public int getOffset(IrValue value) { + return valueOffsetMap.get(value); + } + + public void setRegister(IrValue value, Register reg) { + valueRegisterMap.put(value, reg); + } + + public void setOffset(IrValue value, int offset) { + valueOffsetMap.put(value, offset); + } + + public HashMap getValueRegisterMap() { + return valueRegisterMap; + } + + public HashMap getValueOffsetMap() { + return valueOffsetMap; + } + + public boolean isMain() { + return getName().equals("@main"); + } + + public IrType getRetType() { + return ((IrFuncType) getType()).getReturnType(); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("define dso_local " + this.getRetType() + " " + this.getName() + "("); + for (int i = 0; i < params.size(); i++) { + sb.append(params.get(i).getType() + " " + params.get(i).getName()); + if (i < params.size() - 1) { + sb.append(", "); + } + } + sb.append(") {\n"); + for (IrBasicBlock bblock : bblocks) { + sb.append(bblock.toString() + "\n"); + } + sb.append("}\n"); + return sb.toString(); + } + + public void checkReturn() { + IrBasicBlock currentBB = IrBuilder.getCurrentBB(); + if (!currentBB.lastIsReturn()) { + ReturnInstr returnInstr = new ReturnInstr(null); // 确保没有return的情况只有void + IrBuilder.addInstr(returnInstr); + } + } + + public void toMips() { + new MipsLabel(getMipsLabel()); + MipsBuilder.enterNewFunc(this); + int num = 0; + ArrayList paramRegs = new ArrayList<>(); + paramRegs.add(Register.A1); + paramRegs.add(Register.A2); + paramRegs.add(Register.A3); + for (IrValue param : params) { + num++; + if (num <= 3) { + MipsBuilder.allocaRegister(param, paramRegs.get(num - 1)); + } + MipsBuilder.allocaOffset(param); + } + for (IrBasicBlock bblock : bblocks) { + bblock.toMips(); + } + } +} diff --git a/midend/llvm/value/IrGlobalValue.java b/midend/llvm/value/IrGlobalValue.java old mode 100644 new mode 100755 index 60fa33c..93b08ee --- a/midend/llvm/value/IrGlobalValue.java +++ b/midend/llvm/value/IrGlobalValue.java @@ -25,4 +25,8 @@ public class IrGlobalValue extends IrValue { return isConstant ? getName() + " = dso_local constant " + initVal.toString() : getName() + " = dso_local global " + initVal.toString(); } + + public void toMips() { + initVal.toMips(getMipsLabel()); + } } diff --git a/midend/llvm/value/IrLoop.java b/midend/llvm/value/IrLoop.java old mode 100644 new mode 100755 index 9101af4..5fa04919 --- a/midend/llvm/value/IrLoop.java +++ b/midend/llvm/value/IrLoop.java @@ -1,32 +1,32 @@ -package midend.llvm.value; - -public class IrLoop { - private IrBasicBlock condBB; - private IrBasicBlock bodyBB; - private IrBasicBlock stepBB; - private IrBasicBlock followBB; - - public IrLoop(IrBasicBlock condBB, IrBasicBlock bodyBB, - IrBasicBlock stepBB, IrBasicBlock followBB) { - this.condBB = condBB; - this.bodyBB = bodyBB; - this.stepBB = stepBB; - this.followBB = followBB; - } - - public IrBasicBlock getCondBB() { - return condBB; - } - - public IrBasicBlock getBodyBB() { - return bodyBB; - } - - public IrBasicBlock getStepBB() { - return stepBB; - } - - public IrBasicBlock getFollowBB() { - return followBB; - } -} +package midend.llvm.value; + +public class IrLoop { + private IrBasicBlock condBB; + private IrBasicBlock bodyBB; + private IrBasicBlock stepBB; + private IrBasicBlock followBB; + + public IrLoop(IrBasicBlock condBB, IrBasicBlock bodyBB, + IrBasicBlock stepBB, IrBasicBlock followBB) { + this.condBB = condBB; + this.bodyBB = bodyBB; + this.stepBB = stepBB; + this.followBB = followBB; + } + + public IrBasicBlock getCondBB() { + return condBB; + } + + public IrBasicBlock getBodyBB() { + return bodyBB; + } + + public IrBasicBlock getStepBB() { + return stepBB; + } + + public IrBasicBlock getFollowBB() { + return followBB; + } +} diff --git a/midend/llvm/value/IrValue.java b/midend/llvm/value/IrValue.java old mode 100644 new mode 100755 index 8bb31c4..f365032 --- a/midend/llvm/value/IrValue.java +++ b/midend/llvm/value/IrValue.java @@ -35,4 +35,12 @@ public class IrValue { public String toString() { return type.toString() + " " + name; } + + public void toMips() { + // 子类实现 + } + + public String getMipsLabel() { + return name.substring(1); + } } diff --git a/midend/optimize/CfgMake.java b/midend/optimize/CfgMake.java old mode 100644 new mode 100755 index b8cd586..6ab6f2a --- a/midend/optimize/CfgMake.java +++ b/midend/optimize/CfgMake.java @@ -1,112 +1,112 @@ -package midend.optimize; - -import java.util.HashSet; - -import midend.llvm.instr.IrInstr; -import midend.llvm.instr.IrInstrType; -import midend.llvm.instr.JumpInstr; -import midend.llvm.value.IrBasicBlock; -import midend.llvm.value.IrFuncValue; -import midend.llvm.instr.BranchInstr; - -public class CfgMake extends Optimizer { - public void optimize() { - for (IrFuncValue func : getIrModule().getFuncs()) { - for (IrBasicBlock bb : func.getBBlocks()) { - bb.clearCfg(); - } - } - makeCfg(); - } - - public void makeCfg() { - for (IrFuncValue func : getIrModule().getFuncs()) { - for (IrBasicBlock bb : func.getBBlocks()) { - for (IrInstr instr : bb.getInstrs()) { - if (instr.getInstrType() == IrInstrType.BR) { - BranchInstr branchInstr = (BranchInstr) instr; - IrBasicBlock trueBlock = branchInstr.getTrueBB(); - IrBasicBlock falseBlock = branchInstr.getFalseBB(); - bb.addSucc(trueBlock); - bb.addSucc(falseBlock); - trueBlock.addPred(bb); - falseBlock.addPred(bb); - } else if (instr.getInstrType() == IrInstrType.JUMP) { - JumpInstr jumpInstr = (JumpInstr) instr; - IrBasicBlock jumpBlock = jumpInstr.getTargetBlock(); - bb.addSucc(jumpBlock); - jumpBlock.addPred(bb); - } - } - } - } - } - - public void makeDomination() { - for (IrFuncValue func : getIrModule().getFuncs()) { - for (IrBasicBlock bb : func.getBBlocks()) { - HashSet canArrive = new HashSet<>(); - handleArrive(func.getBBlock(0), bb, canArrive); - for (IrBasicBlock block : func.getBBlocks()) { - if (!canArrive.contains(block)) { - block.addDomied(bb); - } - } - } - } - } - - public void handleArrive(IrBasicBlock entryBlock, - IrBasicBlock deleteBlock, HashSet canArrive) { - if (entryBlock == deleteBlock) { - return; - } else { - if (!canArrive.contains(entryBlock)) { - canArrive.add(entryBlock); - } - for (IrBasicBlock succ : entryBlock.getSuccs()) { - if (succ != deleteBlock && !canArrive.contains(succ)) { - handleArrive(succ, deleteBlock, canArrive); - } - } - } - } - - public void makeDirectDomi() { - for (IrFuncValue func : getIrModule().getFuncs()) { - for (IrBasicBlock bb : func.getBBlocks()) { - for (IrBasicBlock domi : bb.getDomied()) { - HashSet bbDomi = bb.getDomied(); - HashSet domiDomi = domi.getDomied(); - for (IrBasicBlock domiDomiBB : domiDomi) { - if (bbDomi.contains(domiDomiBB)) { - bbDomi.remove(domiDomiBB); - } - } - if (bbDomi.size() == 1 && bbDomi.contains(bb)) { - bb.setDirectDomi(domi); - domi.addDirectDomies(bb); - break; - } - } - } - } - } - - public void makeDomiFrontier() { - for (IrFuncValue func : getIrModule().getFuncs()) { - for (IrBasicBlock bb : func.getBBlocks()) { - for (IrBasicBlock succ : bb.getSuccs()) { - IrBasicBlock currentBB = bb; - while (!succ.getDomied().contains(currentBB) || currentBB == succ) { - currentBB.addDomiFrontier(succ); - currentBB = currentBB.getDirectDomi(); - if (currentBB == null) { - break; - } - } - } - } - } - } -} +package midend.optimize; + +import java.util.HashSet; + +import midend.llvm.instr.IrInstr; +import midend.llvm.instr.IrInstrType; +import midend.llvm.instr.JumpInstr; +import midend.llvm.value.IrBasicBlock; +import midend.llvm.value.IrFuncValue; +import midend.llvm.instr.BranchInstr; + +public class CfgMake extends Optimizer { + public void optimize() { + for (IrFuncValue func : getIrModule().getFuncs()) { + for (IrBasicBlock bb : func.getBBlocks()) { + bb.clearCfg(); + } + } + makeCfg(); + } + + public void makeCfg() { + for (IrFuncValue func : getIrModule().getFuncs()) { + for (IrBasicBlock bb : func.getBBlocks()) { + for (IrInstr instr : bb.getInstrs()) { + if (instr.getInstrType() == IrInstrType.BR) { + BranchInstr branchInstr = (BranchInstr) instr; + IrBasicBlock trueBlock = branchInstr.getTrueBB(); + IrBasicBlock falseBlock = branchInstr.getFalseBB(); + bb.addSucc(trueBlock); + bb.addSucc(falseBlock); + trueBlock.addPred(bb); + falseBlock.addPred(bb); + } else if (instr.getInstrType() == IrInstrType.JUMP) { + JumpInstr jumpInstr = (JumpInstr) instr; + IrBasicBlock jumpBlock = jumpInstr.getTargetBlock(); + bb.addSucc(jumpBlock); + jumpBlock.addPred(bb); + } + } + } + } + } + + public void makeDomination() { + for (IrFuncValue func : getIrModule().getFuncs()) { + for (IrBasicBlock bb : func.getBBlocks()) { + HashSet canArrive = new HashSet<>(); + handleArrive(func.getBBlock(0), bb, canArrive); + for (IrBasicBlock block : func.getBBlocks()) { + if (!canArrive.contains(block)) { + block.addDomied(bb); + } + } + } + } + } + + public void handleArrive(IrBasicBlock entryBlock, + IrBasicBlock deleteBlock, HashSet canArrive) { + if (entryBlock == deleteBlock) { + return; + } else { + if (!canArrive.contains(entryBlock)) { + canArrive.add(entryBlock); + } + for (IrBasicBlock succ : entryBlock.getSuccs()) { + if (succ != deleteBlock && !canArrive.contains(succ)) { + handleArrive(succ, deleteBlock, canArrive); + } + } + } + } + + public void makeDirectDomi() { + for (IrFuncValue func : getIrModule().getFuncs()) { + for (IrBasicBlock bb : func.getBBlocks()) { + for (IrBasicBlock domi : bb.getDomied()) { + HashSet bbDomi = bb.getDomied(); + HashSet domiDomi = domi.getDomied(); + for (IrBasicBlock domiDomiBB : domiDomi) { + if (bbDomi.contains(domiDomiBB)) { + bbDomi.remove(domiDomiBB); + } + } + if (bbDomi.size() == 1 && bbDomi.contains(bb)) { + bb.setDirectDomi(domi); + domi.addDirectDomies(bb); + break; + } + } + } + } + } + + public void makeDomiFrontier() { + for (IrFuncValue func : getIrModule().getFuncs()) { + for (IrBasicBlock bb : func.getBBlocks()) { + for (IrBasicBlock succ : bb.getSuccs()) { + IrBasicBlock currentBB = bb; + while (!succ.getDomied().contains(currentBB) || currentBB == succ) { + currentBB.addDomiFrontier(succ); + currentBB = currentBB.getDirectDomi(); + if (currentBB == null) { + break; + } + } + } + } + } + } +} diff --git a/midend/optimize/Optimizer.java b/midend/optimize/Optimizer.java old mode 100644 new mode 100755 index 8528aef..abc317f --- a/midend/optimize/Optimizer.java +++ b/midend/optimize/Optimizer.java @@ -1,19 +1,19 @@ -package midend.optimize; - -import midend.llvm.IrModule; - -public class Optimizer { - private static IrModule irModule; - - public void setIrModule(IrModule irModule) { - Optimizer.irModule = irModule; - } - - public static IrModule getIrModule() { - return irModule; - } - - public void optimize() { - - } -} +package midend.optimize; + +import midend.llvm.IrModule; + +public class Optimizer { + private static IrModule irModule; + + public void setIrModule(IrModule irModule) { + Optimizer.irModule = irModule; + } + + public static IrModule getIrModule() { + return irModule; + } + + public void optimize() { + + } +} diff --git a/midend/symbol/ArraySymbol.java b/midend/symbol/ArraySymbol.java old mode 100644 new mode 100755 index 6eb2a26..7302a83 --- a/midend/symbol/ArraySymbol.java +++ b/midend/symbol/ArraySymbol.java @@ -1,20 +1,20 @@ -package midend.symbol; - -public class ArraySymbol extends Symbol { - private int dim; // -1 means unknown - - public ArraySymbol(String name, SymbolType type, int line, int dim) { - super(name, type, line); - this.dim = dim; - } - - public int getDim() { - return dim; - } - - public void fullValue() { - for (int i = getValueList().size(); i < dim; i++) { - addValue(0); - } - } -} +package midend.symbol; + +public class ArraySymbol extends Symbol { + private int dim; // -1 means unknown + + public ArraySymbol(String name, SymbolType type, int line, int dim) { + super(name, type, line); + this.dim = dim; + } + + public int getDim() { + return dim; + } + + public void fullValue() { + for (int i = getValueList().size(); i < dim; i++) { + addValue(0); + } + } +} diff --git a/midend/symbol/FuncSymbol.java b/midend/symbol/FuncSymbol.java old mode 100644 new mode 100755 index 5a80b36..2d932d9 --- a/midend/symbol/FuncSymbol.java +++ b/midend/symbol/FuncSymbol.java @@ -1,50 +1,50 @@ -package midend.symbol; - -import java.util.ArrayList; - -public class FuncSymbol extends Symbol { - private int returnType; // 0 for void, 1 for int - private ArrayList paramList; // 0 for var, 1 for array - private ArrayList paramSymbolList; - - public FuncSymbol(String name, SymbolType type, int line, int returnType) { - super(name, type, line); - paramList = new ArrayList<>(); - paramSymbolList = new ArrayList<>(); - this.returnType = returnType; - } - - public void addParam(int param) { - paramList.add(param); - } - - public void addParamSymbol(Symbol paramSymbol) { - paramSymbolList.add(paramSymbol); - } - - public int getParamNum() { - return paramList.size(); - } - - public int getReturnType() { - return returnType; - } - - public int getParamType(int index) { - return paramList.get(index); - } - - public void printParams() { - for (int i = 0; i < paramList.size(); i++) { - System.out.print(paramList.get(i) + " "); - } - } - - public ArrayList getParamList() { - return paramList; - } - - public ArrayList getParamSymbolList() { - return paramSymbolList; - } -} +package midend.symbol; + +import java.util.ArrayList; + +public class FuncSymbol extends Symbol { + private int returnType; // 0 for void, 1 for int + private ArrayList paramList; // 0 for var, 1 for array + private ArrayList paramSymbolList; + + public FuncSymbol(String name, SymbolType type, int line, int returnType) { + super(name, type, line); + paramList = new ArrayList<>(); + paramSymbolList = new ArrayList<>(); + this.returnType = returnType; + } + + public void addParam(int param) { + paramList.add(param); + } + + public void addParamSymbol(Symbol paramSymbol) { + paramSymbolList.add(paramSymbol); + } + + public int getParamNum() { + return paramList.size(); + } + + public int getReturnType() { + return returnType; + } + + public int getParamType(int index) { + return paramList.get(index); + } + + public void printParams() { + for (int i = 0; i < paramList.size(); i++) { + System.out.print(paramList.get(i) + " "); + } + } + + public ArrayList getParamList() { + return paramList; + } + + public ArrayList getParamSymbolList() { + return paramSymbolList; + } +} diff --git a/midend/symbol/Symbol.java b/midend/symbol/Symbol.java old mode 100644 new mode 100755 index e9ceb3d..31fdad2 --- a/midend/symbol/Symbol.java +++ b/midend/symbol/Symbol.java @@ -1,77 +1,77 @@ -package midend.symbol; - -import java.util.ArrayList; - -import midend.llvm.value.IrValue; - -public class Symbol { - private String name; - private SymbolType type; - private int line; - private ArrayList valueList; - private IrValue irValue; - - public Symbol(String name, SymbolType type, int line) { - this.name = name; - this.type = type; - this.line = line; - valueList = new ArrayList<>(); - irValue = null; - } - - public void setIrValue(IrValue irValue) { - this.irValue = irValue; - } - - public IrValue getIrValue() { - return irValue; - } - - public void addValue(int value) { - valueList.add(value); - } - - public void addValue(ArrayList valueList) { - this.valueList.addAll(valueList); - } - - public ArrayList getValueList() { - return valueList; - } - - public int getValue(int index) { - return valueList.get(index); - } - - public String getName() { - return name; - } - - public String getTypeStr() { - return type.toString(); - } - - public SymbolType getType() { - return type; - } - - public int getLine() { - return line; - } - - public String toString() { - return name + " " + type.toString() + "\n"; - } - - public boolean isThatType(int type) { // 0 for normal var, 1 for array, 2 for func - if (type == 1) { - return this.type == SymbolType.INT_ARRAY || this.type == SymbolType.CONST_INT_ARRAY - || this.type == SymbolType.STATIC_INT_ARRAY; - } else if (type == 2) { - return this.type == SymbolType.INT_FUNC || this.type == SymbolType.VOID_FUNC; - } else { - return this.type == SymbolType.INT || this.type == SymbolType.CONST_INT - || this.type == SymbolType.STATIC_INT; - } - } -} +package midend.symbol; + +import java.util.ArrayList; + +import midend.llvm.value.IrValue; + +public class Symbol { + private String name; + private SymbolType type; + private int line; + private ArrayList valueList; + private IrValue irValue; + + public Symbol(String name, SymbolType type, int line) { + this.name = name; + this.type = type; + this.line = line; + valueList = new ArrayList<>(); + irValue = null; + } + + public void setIrValue(IrValue irValue) { + this.irValue = irValue; + } + + public IrValue getIrValue() { + return irValue; + } + + public void addValue(int value) { + valueList.add(value); + } + + public void addValue(ArrayList valueList) { + this.valueList.addAll(valueList); + } + + public ArrayList getValueList() { + return valueList; + } + + public int getValue(int index) { + return valueList.get(index); + } + + public String getName() { + return name; + } + + public String getTypeStr() { + return type.toString(); + } + + public SymbolType getType() { + return type; + } + + public int getLine() { + return line; + } + + public String toString() { + return name + " " + type.toString() + "\n"; + } + + public boolean isThatType(int type) { // 0 for normal var, 1 for array, 2 for func + if (type == 1) { + return this.type == SymbolType.INT_ARRAY || this.type == SymbolType.CONST_INT_ARRAY + || this.type == SymbolType.STATIC_INT_ARRAY; + } else if (type == 2) { + return this.type == SymbolType.INT_FUNC || this.type == SymbolType.VOID_FUNC; + } else { + return this.type == SymbolType.INT || this.type == SymbolType.CONST_INT + || this.type == SymbolType.STATIC_INT; + } + } +} diff --git a/midend/symbol/SymbolManager.java b/midend/symbol/SymbolManager.java old mode 100644 new mode 100755 index f5db4a0..a7144bd --- a/midend/symbol/SymbolManager.java +++ b/midend/symbol/SymbolManager.java @@ -1,136 +1,136 @@ -package midend.symbol; - -import java.util.ArrayList; - -import error.Errors; - -public class SymbolManager { - public static ArrayList symbolTableList; - public static ArrayList sequence; - public static SymbolTable currentTable; - public static int currentSequence; - - public static void init() { - symbolTableList = new ArrayList<>(); - sequence = new ArrayList<>(); - currentTable = null; - currentSequence = -1; - } - - public static void addSymbolTable() { - SymbolTable symbolTable = new SymbolTable(symbolTableList.size() + 1); - symbolTableList.add(symbolTable); - sequence.add(symbolTable.getTableId()); - currentSequence++; - if (currentTable != null) { - symbolTable.setParentTable(currentTable); - } - currentTable = symbolTable; - } - - public static ArrayList getSymbolTableList() { - return symbolTableList; - } - - public static void releaseSymbolTable(int tableId) { - symbolTableList.get(tableId - 1).release(); - currentTable = null; - for (int i = symbolTableList.size() - 1; i >= 0; i--) { - if (!symbolTableList.get(i).isReleased()) { - currentTable = symbolTableList.get(i); - currentSequence++; - sequence.add(currentTable.getTableId()); - break; - } - } - } - - public static void releaseSymbolTable() { - releaseSymbolTable(currentTable.getTableId()); - } - - public static int getSymbolTableSize() { - return symbolTableList.size(); - } - - public static void addSymbol(Symbol symbol, Errors errors) { - currentTable.addSymbol(symbol, errors); - } - - public static String getSymbolTableInfo() { - String info = ""; - for (SymbolTable symbolTable : symbolTableList) { - info += symbolTable.toString(); - } - return info; - } - - public static Symbol getSymbol(String name) { - SymbolTable stable = currentTable; - Symbol symbol = null; - while (stable != null) { - symbol = stable.getSymbol(name); - if (symbol != null) { - break; - } - stable = stable.getParentTable(); - } - return symbol; - } - - public static Symbol getSymbol(String name, boolean defined) { - SymbolTable stable = currentTable; - Symbol symbol = null; - while (stable != null) { - symbol = stable.getSymbol(name); - if (symbol != null && symbol.getIrValue() != null) { - break; - } - stable = stable.getParentTable(); - } - return symbol; - } - - public static void nextTable() { - currentSequence++; - if (currentSequence >= sequence.size()) { - return; - } - currentTable = symbolTableList.get(sequence.get(currentSequence) - 1); - } - - public static void lastTable() { - currentSequence--; - if (currentSequence < 0) { - currentSequence = 0; - currentTable = symbolTableList.get(0); - return; - } - currentTable = symbolTableList.get(sequence.get(currentSequence) - 1); - } - - public static void reset() { - currentSequence = -1; - currentTable = null; - } - - public static boolean IsGlobal() { - return currentTable.getTableId() == 1; - } - - public static ArrayList getSequence() { - return sequence; - } - - public static int getCurrentSequence() { - return currentSequence; - } - - public static int getCurrentTableId() { - return sequence.get(currentSequence); - } - - public static SymbolTable getCurrentTable() { - return currentTable; - } -} +package midend.symbol; + +import java.util.ArrayList; + +import error.Errors; + +public class SymbolManager { + public static ArrayList symbolTableList; + public static ArrayList sequence; + public static SymbolTable currentTable; + public static int currentSequence; + + public static void init() { + symbolTableList = new ArrayList<>(); + sequence = new ArrayList<>(); + currentTable = null; + currentSequence = -1; + } + + public static void addSymbolTable() { + SymbolTable symbolTable = new SymbolTable(symbolTableList.size() + 1); + symbolTableList.add(symbolTable); + sequence.add(symbolTable.getTableId()); + currentSequence++; + if (currentTable != null) { + symbolTable.setParentTable(currentTable); + } + currentTable = symbolTable; + } + + public static ArrayList getSymbolTableList() { + return symbolTableList; + } + + public static void releaseSymbolTable(int tableId) { + symbolTableList.get(tableId - 1).release(); + currentTable = null; + for (int i = symbolTableList.size() - 1; i >= 0; i--) { + if (!symbolTableList.get(i).isReleased()) { + currentTable = symbolTableList.get(i); + currentSequence++; + sequence.add(currentTable.getTableId()); + break; + } + } + } + + public static void releaseSymbolTable() { + releaseSymbolTable(currentTable.getTableId()); + } + + public static int getSymbolTableSize() { + return symbolTableList.size(); + } + + public static void addSymbol(Symbol symbol, Errors errors) { + currentTable.addSymbol(symbol, errors); + } + + public static String getSymbolTableInfo() { + String info = ""; + for (SymbolTable symbolTable : symbolTableList) { + info += symbolTable.toString(); + } + return info; + } + + public static Symbol getSymbol(String name) { + SymbolTable stable = currentTable; + Symbol symbol = null; + while (stable != null) { + symbol = stable.getSymbol(name); + if (symbol != null) { + break; + } + stable = stable.getParentTable(); + } + return symbol; + } + + public static Symbol getSymbol(String name, boolean defined) { + SymbolTable stable = currentTable; + Symbol symbol = null; + while (stable != null) { + symbol = stable.getSymbol(name); + if (symbol != null && symbol.getIrValue() != null) { + break; + } + stable = stable.getParentTable(); + } + return symbol; + } + + public static void nextTable() { + currentSequence++; + if (currentSequence >= sequence.size()) { + return; + } + currentTable = symbolTableList.get(sequence.get(currentSequence) - 1); + } + + public static void lastTable() { + currentSequence--; + if (currentSequence < 0) { + currentSequence = 0; + currentTable = symbolTableList.get(0); + return; + } + currentTable = symbolTableList.get(sequence.get(currentSequence) - 1); + } + + public static void reset() { + currentSequence = -1; + currentTable = null; + } + + public static boolean IsGlobal() { + return currentTable.getTableId() == 1; + } + + public static ArrayList getSequence() { + return sequence; + } + + public static int getCurrentSequence() { + return currentSequence; + } + + public static int getCurrentTableId() { + return sequence.get(currentSequence); + } + + public static SymbolTable getCurrentTable() { + return currentTable; + } +} diff --git a/midend/symbol/SymbolTable.java b/midend/symbol/SymbolTable.java old mode 100644 new mode 100755 index 1b01a61..157d4d0 --- a/midend/symbol/SymbolTable.java +++ b/midend/symbol/SymbolTable.java @@ -1,68 +1,68 @@ -package midend.symbol; - -import java.util.ArrayList; -import java.util.HashMap; - -import error.Error; -import error.ErrorType; -import error.Errors; - -public class SymbolTable { - private ArrayList symbolList; - private HashMap symbolMap; - private int tableId; - private boolean isReleased; - private SymbolTable parentTable; - - public SymbolTable(int tableId) { - this.tableId = tableId; - isReleased = false; - symbolList = new ArrayList<>(); - symbolMap = new HashMap<>(); - parentTable = null; - } - - public int getTableId() { - return tableId; - } - - public boolean isReleased() { - return isReleased; - } - - public void release() { - isReleased = true; - } - - public void addSymbol(Symbol symbol, Errors errors) { - if (symbolMap.containsKey(symbol.getName())) { - errors.addError(new Error(symbol.getLine(), ErrorType.b)); - return; - } - symbolList.add(symbol); - symbolMap.put(symbol.getName(), symbol); - } - - public void setParentTable(SymbolTable parentTable) { - this.parentTable = parentTable; - } - - public SymbolTable getParentTable() { - return parentTable; - } - - public Symbol getSymbol(String name) { - if (symbolMap.containsKey(name)) { - return symbolMap.get(name); - } - return null; - } - - public String toString() { - String info = ""; - for (Symbol symbol : symbolList) { - info += tableId + " " + symbol.toString(); - } - return info; - } -} +package midend.symbol; + +import java.util.ArrayList; +import java.util.HashMap; + +import error.Error; +import error.ErrorType; +import error.Errors; + +public class SymbolTable { + private ArrayList symbolList; + private HashMap symbolMap; + private int tableId; + private boolean isReleased; + private SymbolTable parentTable; + + public SymbolTable(int tableId) { + this.tableId = tableId; + isReleased = false; + symbolList = new ArrayList<>(); + symbolMap = new HashMap<>(); + parentTable = null; + } + + public int getTableId() { + return tableId; + } + + public boolean isReleased() { + return isReleased; + } + + public void release() { + isReleased = true; + } + + public void addSymbol(Symbol symbol, Errors errors) { + if (symbolMap.containsKey(symbol.getName())) { + errors.addError(new Error(symbol.getLine(), ErrorType.b)); + return; + } + symbolList.add(symbol); + symbolMap.put(symbol.getName(), symbol); + } + + public void setParentTable(SymbolTable parentTable) { + this.parentTable = parentTable; + } + + public SymbolTable getParentTable() { + return parentTable; + } + + public Symbol getSymbol(String name) { + if (symbolMap.containsKey(name)) { + return symbolMap.get(name); + } + return null; + } + + public String toString() { + String info = ""; + for (Symbol symbol : symbolList) { + info += tableId + " " + symbol.toString(); + } + return info; + } +} diff --git a/midend/symbol/SymbolType.java b/midend/symbol/SymbolType.java old mode 100644 new mode 100755 index 855c010..1dadaa4 --- a/midend/symbol/SymbolType.java +++ b/midend/symbol/SymbolType.java @@ -1,22 +1,22 @@ -package midend.symbol; - -public enum SymbolType { - CONST_INT("ConstInt"), - CONST_INT_ARRAY("ConstIntArray"), - STATIC_INT("StaticInt"), - INT("Int"), - INT_ARRAY("IntArray"), - STATIC_INT_ARRAY("StaticIntArray"), - VOID_FUNC("VoidFunc"), - INT_FUNC("IntFunc"); - - private final String type; - SymbolType(String type) { - this.type = type; - } - - @Override - public String toString() { - return type; - } -} +package midend.symbol; + +public enum SymbolType { + CONST_INT("ConstInt"), + CONST_INT_ARRAY("ConstIntArray"), + STATIC_INT("StaticInt"), + INT("Int"), + INT_ARRAY("IntArray"), + STATIC_INT_ARRAY("StaticIntArray"), + VOID_FUNC("VoidFunc"), + INT_FUNC("IntFunc"); + + private final String type; + SymbolType(String type) { + this.type = type; + } + + @Override + public String toString() { + return type; + } +} diff --git a/midend/visit/Visitor.java b/midend/visit/Visitor.java old mode 100644 new mode 100755 index 2b902d5..c0c475f --- a/midend/visit/Visitor.java +++ b/midend/visit/Visitor.java @@ -1,36 +1,36 @@ -package midend.visit; - -import java.util.ArrayList; - -import frontend.ast.CompUnit; -import frontend.ast.decl.Decl; -import frontend.ast.func.FuncDef; -import frontend.ast.func.MainFuncDef; -import midend.symbol.SymbolManager; - -public class Visitor { - private CompUnit compUnit; - - public Visitor(CompUnit compUnit) { - this.compUnit = compUnit; - SymbolManager.reset(); - SymbolManager.nextTable(); - } - - public void visit() { - ArrayList decls = this.compUnit.GetDecls(); - ArrayList funcDefs = this.compUnit.GetFuncDefs(); - MainFuncDef mainFuncDef = this.compUnit.GetMainFuncDef(); - - for (Decl decl : decls) { - VisitorDecl.visitDecl(decl); - } - - for (FuncDef funcDef : funcDefs) { - VisitorFuncDef.visitFuncDef(funcDef); - } - - VisitorFuncDef.visitMainFuncDef(mainFuncDef); - } - //:TODO:符号表的变换,什么时候往前进一个符号表,这需要人工手工来操作 -} +package midend.visit; + +import java.util.ArrayList; + +import frontend.ast.CompUnit; +import frontend.ast.decl.Decl; +import frontend.ast.func.FuncDef; +import frontend.ast.func.MainFuncDef; +import midend.symbol.SymbolManager; + +public class Visitor { + private CompUnit compUnit; + + public Visitor(CompUnit compUnit) { + this.compUnit = compUnit; + SymbolManager.reset(); + SymbolManager.nextTable(); + } + + public void visit() { + ArrayList decls = this.compUnit.GetDecls(); + ArrayList funcDefs = this.compUnit.GetFuncDefs(); + MainFuncDef mainFuncDef = this.compUnit.GetMainFuncDef(); + + for (Decl decl : decls) { + VisitorDecl.visitDecl(decl); + } + + for (FuncDef funcDef : funcDefs) { + VisitorFuncDef.visitFuncDef(funcDef); + } + + VisitorFuncDef.visitMainFuncDef(mainFuncDef); + } + //:TODO:符号表的变换,什么时候往前进一个符号表,这需要人工手工来操作 +} diff --git a/midend/visit/VisitorBlock.java b/midend/visit/VisitorBlock.java old mode 100644 new mode 100755 index 05c2930..b201206 --- a/midend/visit/VisitorBlock.java +++ b/midend/visit/VisitorBlock.java @@ -1,35 +1,35 @@ -package midend.visit; - -import java.util.ArrayList; - -import frontend.ast.block.Block; -import frontend.ast.block.BlockItem; -import frontend.ast.block.Stmt; -import frontend.ast.decl.Decl; -import midend.symbol.SymbolManager; - -public class VisitorBlock { - public static void visitBlock(Block block) { - if (!block.isFuncBlock()) { - SymbolManager.nextTable(); - } - // System.out.println("(block)now table: " + SymbolManager.getCurrentTableId()); - // System.out.println("bsequence: " + SymbolManager.getCurrentSequence());//TODO:debug - ArrayList blockItems = block.getBlockItems(); - for (BlockItem blockItem : blockItems) { - visitBlockItem(blockItem); - } - if (!block.isFuncBlock()) { - SymbolManager.nextTable(); - } - // System.out.println("(block)now table: " + SymbolManager.getCurrentTableId());//TODO:debug - } - - public static void visitBlockItem(BlockItem blockItem) { - if (blockItem.getChild(0) instanceof Decl) { - VisitorDecl.visitDecl((Decl) blockItem.getChild(0)); - } else { - VisitorStmt.visitStmt((Stmt) blockItem.getChild(0)); - } - } -} +package midend.visit; + +import java.util.ArrayList; + +import frontend.ast.block.Block; +import frontend.ast.block.BlockItem; +import frontend.ast.block.Stmt; +import frontend.ast.decl.Decl; +import midend.symbol.SymbolManager; + +public class VisitorBlock { + public static void visitBlock(Block block) { + if (!block.isFuncBlock()) { + SymbolManager.nextTable(); + } + // System.out.println("(block)now table: " + SymbolManager.getCurrentTableId()); + // System.out.println("bsequence: " + SymbolManager.getCurrentSequence());//TODO:debug + ArrayList blockItems = block.getBlockItems(); + for (BlockItem blockItem : blockItems) { + visitBlockItem(blockItem); + } + if (!block.isFuncBlock()) { + SymbolManager.nextTable(); + } + // System.out.println("(block)now table: " + SymbolManager.getCurrentTableId());//TODO:debug + } + + public static void visitBlockItem(BlockItem blockItem) { + if (blockItem.getChild(0) instanceof Decl) { + VisitorDecl.visitDecl((Decl) blockItem.getChild(0)); + } else { + VisitorStmt.visitStmt((Stmt) blockItem.getChild(0)); + } + } +} diff --git a/midend/visit/VisitorDecl.java b/midend/visit/VisitorDecl.java old mode 100644 new mode 100755 index 601a771..9e28e0d --- a/midend/visit/VisitorDecl.java +++ b/midend/visit/VisitorDecl.java @@ -1,167 +1,167 @@ -package midend.visit; - -import java.util.ArrayList; - -import frontend.ast.decl.ConstDecl; -import frontend.ast.decl.ConstDef; -import frontend.ast.decl.Decl; -import frontend.ast.decl.VarDecl; -import frontend.ast.decl.VarDef; -import frontend.ast.exp.ConstExp; -import frontend.ast.exp.Exp; -import frontend.ast.token.TokenNode; -import frontend.lexer.Token; -import midend.llvm.IrBuilder; -import midend.llvm.constant.IrConstant; -import midend.llvm.constant.IrConstantArray; -import midend.llvm.constant.IrConstantInt; -import midend.llvm.instr.AllocateInstr; -import midend.llvm.instr.StoreInstr; -import midend.llvm.instr.GepInstr; -import midend.llvm.type.IrArrayType; -import midend.llvm.type.IrFuncType; -import midend.llvm.type.IrInterType; -import midend.llvm.type.IrPointerType; -import midend.llvm.type.IrType; -import midend.llvm.value.IrGlobalValue; -import midend.llvm.value.IrValue; -import midend.symbol.SymbolType; -import midend.symbol.ArraySymbol; -import midend.symbol.Symbol; -import midend.symbol.SymbolManager; - -public class VisitorDecl { - public static void visitDecl(Decl decl) { - if (decl.getChild(0) instanceof ConstDecl) { - visitConstDecl((ConstDecl) decl.getChild(0)); - } else { - visitVarDecl((VarDecl) decl.getChild(0)); - } - } - - public static void visitConstDecl(ConstDecl constDecl) { - ArrayList constDefs = constDecl.GetConstDefs(); - for (ConstDef constDef : constDefs) { - visitConstDef(constDef); - } - } - - public static void visitVarDecl(VarDecl varDecl) { - ArrayList varDefs = varDecl.GetVarDefs(); - for (VarDef varDef : varDefs) { - visitVarDef(varDef); - } - } - - public static void visitConstDef(ConstDef constDef) { - Symbol symbol = SymbolManager.getSymbol(((TokenNode) constDef.getChild(0)).getValue()); - if (SymbolManager.IsGlobal()) { // 全局变量下直接声明 - IrGlobalValue irGlobalValue = new IrGlobalValue( - new IrPointerType(getSymbolIrType(symbol)), - IrBuilder.getGlobalName(), true, getSymbolIrConst(symbol)); - IrBuilder.addNewGlobal(irGlobalValue); - symbol.setIrValue(irGlobalValue); - } else { // 局部变量需要分配地址再存值 - AllocateInstr allocateInstr = new AllocateInstr(getSymbolIrType(symbol), - IrBuilder.getLocalName()); - IrBuilder.addInstr(allocateInstr); - symbol.setIrValue(allocateInstr); - ArrayList valueList = symbol.getValueList(); - if (!(symbol instanceof ArraySymbol)) { - StoreInstr storeInstr = new StoreInstr(getSymbolIrConst(symbol), - allocateInstr); - IrBuilder.addInstr(storeInstr); - } else { - for (int i = 0; i < valueList.size(); i++) { - GepInstr gepInstr = new GepInstr(allocateInstr, - new IrConstantInt(i), IrBuilder.getLocalName()); - IrBuilder.addInstr(gepInstr); - IrValue initValue = new IrConstantInt(valueList.get(i)); - StoreInstr storeInstr = new StoreInstr(initValue, gepInstr); - IrBuilder.addInstr(storeInstr); - } - } - } - } - - private static void visitVarDef(VarDef varDef) { - Symbol symbol = SymbolManager.getSymbol(((TokenNode) varDef.getChild(0)).getValue()); - if (SymbolManager.IsGlobal()) { - IrGlobalValue irGlobalValue = new IrGlobalValue( - new IrPointerType(getSymbolIrType(symbol)), - IrBuilder.getGlobalName(), false, getSymbolIrConst(symbol)); - IrBuilder.addNewGlobal(irGlobalValue); - symbol.setIrValue(irGlobalValue); - } else { // Think:static修饰的变量该如何实现 - visitLocalVarDef(varDef, symbol); - } - } - - private static void visitLocalVarDef(VarDef varDef, Symbol symbol) { - if (symbol.getType().equals(SymbolType.STATIC_INT) || - symbol.getType().equals(SymbolType.STATIC_INT_ARRAY)) { - // 当为局部变量且为static修饰的变量的时候,将其作为全局变量处理 - IrGlobalValue irGlobalValue = new IrGlobalValue( - new IrPointerType(getSymbolIrType(symbol)), - IrBuilder.getGlobalName(), false, getSymbolIrConst(symbol)); - IrBuilder.addNewGlobal(irGlobalValue); - symbol.setIrValue(irGlobalValue); - return; - } - AllocateInstr allocateInstr = new AllocateInstr( - getSymbolIrType(symbol), IrBuilder.getLocalName()); - IrBuilder.addInstr(allocateInstr); - if (!(symbol instanceof ArraySymbol)) { // 非数组变量 - if (varDef.HaveInitVal()) { - Exp exp = varDef.getInitVal().getExpList().get(0); - IrValue irExp = VisitorExp.visitExp(exp); - StoreInstr storeInstr = new StoreInstr(irExp, allocateInstr); - IrBuilder.addInstr(storeInstr); - } - } else { // 数组变量 - if (varDef.HaveInitVal()) { - ArrayList expList = varDef.getInitVal().getExpList(); - for (int i = 0; i < expList.size(); i++) { - IrValue irExp = VisitorExp.visitExp(expList.get(i)); - irExp = IrType.convertType(irExp, IrInterType.INT32); - GepInstr gepInstr = new GepInstr(allocateInstr, - new IrConstantInt(i), IrBuilder.getLocalName()); - IrBuilder.addInstr(gepInstr); - StoreInstr storeInstr = new StoreInstr(irExp, gepInstr); - IrBuilder.addInstr(storeInstr); - } - } - } - symbol.setIrValue(allocateInstr); - } - - public static IrType getSymbolIrType(Symbol symbol) { - SymbolType st = symbol.getType(); - if (st.equals(SymbolType.INT) || st.equals(SymbolType.CONST_INT) - || st.equals(SymbolType.STATIC_INT)) { - return IrInterType.INT32; - } else if (st.equals(SymbolType.INT_ARRAY) || st.equals(SymbolType.CONST_INT_ARRAY) - || st.equals(SymbolType.STATIC_INT_ARRAY)) { - return new IrArrayType(IrInterType.INT32, ((ArraySymbol) symbol).getDim()); - } else { - if (st.equals(SymbolType.INT_FUNC)) { - return new IrFuncType(IrInterType.INT32); - } else { - return new IrFuncType(IrInterType.VOID); - } - } - } - - public static IrConstant getSymbolIrConst(Symbol symbol) { - ArrayList valueList = symbol.getValueList(); - if (symbol instanceof ArraySymbol) { - ArrayList elements = new ArrayList<>(); - for (int i = 0; i < valueList.size(); i++) { - elements.add(new IrConstantInt(valueList.get(i))); - } - return new IrConstantArray(symbol.getName(), elements, ((ArraySymbol) symbol).getDim()); - } else { - return valueList.isEmpty() ? new IrConstantInt(0) : new IrConstantInt(valueList.get(0)); - } - } -} +package midend.visit; + +import java.util.ArrayList; + +import frontend.ast.decl.ConstDecl; +import frontend.ast.decl.ConstDef; +import frontend.ast.decl.Decl; +import frontend.ast.decl.VarDecl; +import frontend.ast.decl.VarDef; +import frontend.ast.exp.ConstExp; +import frontend.ast.exp.Exp; +import frontend.ast.token.TokenNode; +import frontend.lexer.Token; +import midend.llvm.IrBuilder; +import midend.llvm.constant.IrConstant; +import midend.llvm.constant.IrConstantArray; +import midend.llvm.constant.IrConstantInt; +import midend.llvm.instr.AllocateInstr; +import midend.llvm.instr.StoreInstr; +import midend.llvm.instr.GepInstr; +import midend.llvm.type.IrArrayType; +import midend.llvm.type.IrFuncType; +import midend.llvm.type.IrInterType; +import midend.llvm.type.IrPointerType; +import midend.llvm.type.IrType; +import midend.llvm.value.IrGlobalValue; +import midend.llvm.value.IrValue; +import midend.symbol.SymbolType; +import midend.symbol.ArraySymbol; +import midend.symbol.Symbol; +import midend.symbol.SymbolManager; + +public class VisitorDecl { + public static void visitDecl(Decl decl) { + if (decl.getChild(0) instanceof ConstDecl) { + visitConstDecl((ConstDecl) decl.getChild(0)); + } else { + visitVarDecl((VarDecl) decl.getChild(0)); + } + } + + public static void visitConstDecl(ConstDecl constDecl) { + ArrayList constDefs = constDecl.GetConstDefs(); + for (ConstDef constDef : constDefs) { + visitConstDef(constDef); + } + } + + public static void visitVarDecl(VarDecl varDecl) { + ArrayList varDefs = varDecl.GetVarDefs(); + for (VarDef varDef : varDefs) { + visitVarDef(varDef); + } + } + + public static void visitConstDef(ConstDef constDef) { + Symbol symbol = SymbolManager.getSymbol(((TokenNode) constDef.getChild(0)).getValue()); + if (SymbolManager.IsGlobal()) { // 全局变量下直接声明 + IrGlobalValue irGlobalValue = new IrGlobalValue( + new IrPointerType(getSymbolIrType(symbol)), + IrBuilder.getGlobalName(), true, getSymbolIrConst(symbol)); + IrBuilder.addNewGlobal(irGlobalValue); + symbol.setIrValue(irGlobalValue); + } else { // 局部变量需要分配地址再存值 + AllocateInstr allocateInstr = new AllocateInstr(getSymbolIrType(symbol), + IrBuilder.getLocalName()); + IrBuilder.addInstr(allocateInstr); + symbol.setIrValue(allocateInstr); + ArrayList valueList = symbol.getValueList(); + if (!(symbol instanceof ArraySymbol)) { + StoreInstr storeInstr = new StoreInstr(getSymbolIrConst(symbol), + allocateInstr); + IrBuilder.addInstr(storeInstr); + } else { + for (int i = 0; i < valueList.size(); i++) { + GepInstr gepInstr = new GepInstr(allocateInstr, + new IrConstantInt(i), IrBuilder.getLocalName()); + IrBuilder.addInstr(gepInstr); + IrValue initValue = new IrConstantInt(valueList.get(i)); + StoreInstr storeInstr = new StoreInstr(initValue, gepInstr); + IrBuilder.addInstr(storeInstr); + } + } + } + } + + private static void visitVarDef(VarDef varDef) { + Symbol symbol = SymbolManager.getSymbol(((TokenNode) varDef.getChild(0)).getValue()); + if (SymbolManager.IsGlobal()) { + IrGlobalValue irGlobalValue = new IrGlobalValue( + new IrPointerType(getSymbolIrType(symbol)), + IrBuilder.getGlobalName(), false, getSymbolIrConst(symbol)); + IrBuilder.addNewGlobal(irGlobalValue); + symbol.setIrValue(irGlobalValue); + } else { // Think:static修饰的变量该如何实现 + visitLocalVarDef(varDef, symbol); + } + } + + private static void visitLocalVarDef(VarDef varDef, Symbol symbol) { + if (symbol.getType().equals(SymbolType.STATIC_INT) || + symbol.getType().equals(SymbolType.STATIC_INT_ARRAY)) { + // 当为局部变量且为static修饰的变量的时候,将其作为全局变量处理 + IrGlobalValue irGlobalValue = new IrGlobalValue( + new IrPointerType(getSymbolIrType(symbol)), + IrBuilder.getGlobalName(), false, getSymbolIrConst(symbol)); + IrBuilder.addNewGlobal(irGlobalValue); + symbol.setIrValue(irGlobalValue); + return; + } + AllocateInstr allocateInstr = new AllocateInstr( + getSymbolIrType(symbol), IrBuilder.getLocalName()); + IrBuilder.addInstr(allocateInstr); + if (!(symbol instanceof ArraySymbol)) { // 非数组变量 + if (varDef.HaveInitVal()) { + Exp exp = varDef.getInitVal().getExpList().get(0); + IrValue irExp = VisitorExp.visitExp(exp); + StoreInstr storeInstr = new StoreInstr(irExp, allocateInstr); + IrBuilder.addInstr(storeInstr); + } + } else { // 数组变量 + if (varDef.HaveInitVal()) { + ArrayList expList = varDef.getInitVal().getExpList(); + for (int i = 0; i < expList.size(); i++) { + IrValue irExp = VisitorExp.visitExp(expList.get(i)); + irExp = IrType.convertType(irExp, IrInterType.INT32); + GepInstr gepInstr = new GepInstr(allocateInstr, + new IrConstantInt(i), IrBuilder.getLocalName()); + IrBuilder.addInstr(gepInstr); + StoreInstr storeInstr = new StoreInstr(irExp, gepInstr); + IrBuilder.addInstr(storeInstr); + } + } + } + symbol.setIrValue(allocateInstr); + } + + public static IrType getSymbolIrType(Symbol symbol) { + SymbolType st = symbol.getType(); + if (st.equals(SymbolType.INT) || st.equals(SymbolType.CONST_INT) + || st.equals(SymbolType.STATIC_INT)) { + return IrInterType.INT32; + } else if (st.equals(SymbolType.INT_ARRAY) || st.equals(SymbolType.CONST_INT_ARRAY) + || st.equals(SymbolType.STATIC_INT_ARRAY)) { + return new IrArrayType(IrInterType.INT32, ((ArraySymbol) symbol).getDim()); + } else { + if (st.equals(SymbolType.INT_FUNC)) { + return new IrFuncType(IrInterType.INT32); + } else { + return new IrFuncType(IrInterType.VOID); + } + } + } + + public static IrConstant getSymbolIrConst(Symbol symbol) { + ArrayList valueList = symbol.getValueList(); + if (symbol instanceof ArraySymbol) { + ArrayList elements = new ArrayList<>(); + for (int i = 0; i < valueList.size(); i++) { + elements.add(new IrConstantInt(valueList.get(i))); + } + return new IrConstantArray(symbol.getName(), elements, ((ArraySymbol) symbol).getDim()); + } else { + return valueList.isEmpty() ? new IrConstantInt(0) : new IrConstantInt(valueList.get(0)); + } + } +} diff --git a/midend/visit/VisitorExp.java b/midend/visit/VisitorExp.java old mode 100644 new mode 100755 index e91c251..aeb1e75 --- a/midend/visit/VisitorExp.java +++ b/midend/visit/VisitorExp.java @@ -1,264 +1,264 @@ -package midend.visit; - -import frontend.ast.exp.Exp; -import frontend.ast.exp.LAndExp; -import frontend.ast.exp.LOrExp; -import frontend.ast.exp.LVal; - -import java.util.ArrayList; - -import frontend.ast.exp.AddExp; -import frontend.ast.exp.EqExp; -import frontend.ast.exp.MulExp; -import frontend.ast.exp.NumberExp; -import frontend.ast.exp.PrimaryExp; -import frontend.ast.exp.RelExp; -import frontend.ast.exp.UnaryExp; -import frontend.ast.exp.UnaryOp; -import frontend.ast.exp.Cond; -import frontend.ast.token.TokenNode; -import midend.llvm.IrBuilder; -import midend.llvm.constant.IrConstantInt; -import midend.llvm.instr.AluInstr; -import midend.llvm.instr.BranchInstr; -import midend.llvm.instr.CallInstr; -import midend.llvm.instr.CmpInstr; -import midend.llvm.instr.ExtendInstr; -import midend.llvm.instr.GepInstr; -import midend.llvm.instr.GetIntInstr; -import midend.llvm.instr.LoadInstr; -import midend.llvm.type.IrInterType; -import midend.llvm.type.IrType; -import midend.llvm.value.IrBasicBlock; -import midend.llvm.value.IrFuncValue; -import midend.llvm.value.IrValue; -import midend.symbol.*; - -public class VisitorExp { - public static IrValue visitExp(Exp exp) { - return visitAddExp((AddExp) exp.getChild(0)); - } - - public static IrValue visitAddExp(AddExp addExp) { - if (addExp.getChildren().size() == 1) { - return visitMulExp((MulExp) addExp.getChild(0)); - } else { - IrValue left = visitAddExp((AddExp) addExp.getChild(0)); - TokenNode op = (TokenNode) addExp.getChild(1); - IrValue right = visitMulExp((MulExp) addExp.getChild(2)); - left = IrType.convertType(left, IrInterType.INT32); - right = IrType.convertType(right, IrInterType.INT32); - AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op.getValue(), left, right); - IrBuilder.addInstr(aluInstr); - return aluInstr; - } - } - - public static IrValue visitMulExp(MulExp mulExp) { - if (mulExp.getChildren().size() == 1) { - return visitUnaryExp((UnaryExp) mulExp.getChild(0)); - } else { - IrValue left = visitMulExp((MulExp) mulExp.getChild(0)); - TokenNode op = (TokenNode) mulExp.getChild(1); - IrValue right = visitUnaryExp((UnaryExp) mulExp.getChild(2)); - left = IrType.convertType(left, IrInterType.INT32); - right = IrType.convertType(right, IrInterType.INT32); - AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op.getValue(), left, right); - IrBuilder.addInstr(aluInstr); - return aluInstr; - } - } - - public static IrValue visitUnaryExp(UnaryExp unaryExp) { - if (unaryExp.getChild(0) instanceof PrimaryExp) { - return visitPrimaryExp((PrimaryExp) unaryExp.getChild(0)); - } else if (unaryExp.getChild(0) instanceof TokenNode) { - return visitFuncCall((TokenNode) unaryExp.getChild(0), unaryExp.getParamList()); - } else { - return visitOpUnaryExp((UnaryOp) unaryExp.getChild(0), (UnaryExp) unaryExp.getChild(1)); - } - } - - public static IrValue visitOpUnaryExp(UnaryOp uop, UnaryExp unaryExp) { - String op = ((TokenNode) uop.getChild(0)).getValue(); - IrValue operand = visitUnaryExp(unaryExp); - IrConstantInt zero = new IrConstantInt(0); - if (op.equals("+")) { - return operand; - } else if (op.equals("-")) { - AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op, zero, operand); - IrBuilder.addInstr(aluInstr); - return aluInstr; - } else { - operand = IrType.convertType(operand, IrInterType.INT32); - CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), "==", zero, operand); - IrBuilder.addInstr(cmpInstr); - ExtendInstr extendInstr = new ExtendInstr( - IrBuilder.getLocalName(), IrInterType.INT32, cmpInstr); - IrBuilder.addInstr(extendInstr); - return extendInstr; - } - } - - public static IrValue visitPrimaryExp(PrimaryExp primaryExp) { - if (primaryExp.getChild(0) instanceof TokenNode) { - return visitExp((Exp) primaryExp.getChild(1)); - } else if (primaryExp.getChild(0) instanceof LVal) { - return visitLVal((LVal) primaryExp.getChild(0), false); - } else { - return new IrConstantInt(((NumberExp) primaryExp.getChild(0)).getValue()); - } - } - - public static IrValue visitFuncCall(TokenNode funcName, ArrayList paramList) { - if (funcName.getValue().equals("getint")) { - GetIntInstr getIntInstr = new GetIntInstr(IrBuilder.getLocalName()); - IrBuilder.addInstr(getIntInstr); - return getIntInstr; - } - FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol(funcName.getName(), true); - IrFuncValue irFunction = (IrFuncValue) funcSymbol.getIrValue(); - ArrayList args = new ArrayList<>(); - for (Exp param : paramList) { - args.add(visitExp(param)); - } - CallInstr callInstr = new CallInstr(IrBuilder.getLocalName(), irFunction, args); - IrBuilder.addInstr(callInstr); - return callInstr; - } - - public static IrValue visitLVal(LVal lval, boolean assign) { - if (assign) { - Symbol symbol = SymbolManager.getSymbol(((TokenNode) lval.getChild(0)).getName(), true); - if (!(symbol instanceof ArraySymbol)) { - return symbol.getIrValue(); - } else { - Exp exp = (Exp) lval.getChild(2); - IrValue pointer = symbol.getIrValue(); - GepInstr gepInstr = new GepInstr( - pointer, visitExp(exp), IrBuilder.getLocalName()); - IrBuilder.addInstr(gepInstr); - return gepInstr; - } - } else { - Symbol symbol = SymbolManager.getSymbol(((TokenNode) lval.getChild(0)).getName(), true); - // if (symbol == null) { - // System.out.println(((TokenNode)lval.getChild(0)).getLine() + " " + - // ((TokenNode)lval.getChild(0)).getValue()); - // SymbolTable table = SymbolManager.getCurrentTable(); - // System.out.println(table.toString()); - // // TODO:报错 - // } - if (!(symbol instanceof ArraySymbol)) { - LoadInstr loadInstr = new LoadInstr(symbol.getIrValue(), IrBuilder.getLocalName()); - IrBuilder.addInstr(loadInstr); - return loadInstr; - } else { - if (lval.getChildren().size() == 1) { - GepInstr gepInstr = new GepInstr( - symbol.getIrValue(), new IrConstantInt(0), IrBuilder.getLocalName()); - IrBuilder.addInstr(gepInstr); - return gepInstr; - } else { - Exp exp = (Exp) lval.getChild(2); - GepInstr gepInstr = new GepInstr( - symbol.getIrValue(), visitExp(exp), IrBuilder.getLocalName()); - IrBuilder.addInstr(gepInstr); - LoadInstr loadInstr = new LoadInstr(gepInstr, IrBuilder.getLocalName()); - IrBuilder.addInstr(loadInstr); - return loadInstr; - } - } - } - } - - // TODO:条件表达式的实现 - public static IrValue visitRelExp(RelExp relExp) { - if (relExp.getChildren().size() == 1) { - return visitAddExp((AddExp) relExp.getChild(0)); - } else { - IrValue left = visitRelExp((RelExp) relExp.getChild(0)); - IrValue right = visitAddExp((AddExp) relExp.getChild(2)); - String op = ((TokenNode) relExp.getChild(1)).getValue(); - left = IrType.convertType(left, IrInterType.INT32); - right = IrType.convertType(right, IrInterType.INT32); - CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), op, left, right); - IrBuilder.addInstr(cmpInstr); - return cmpInstr; - } - } - - public static IrValue visitEqExp(EqExp eqExp) { - if (eqExp.getChildren().size() == 1) { - return visitRelExp((RelExp) eqExp.getChild(0)); - } else { - IrValue left = visitEqExp((EqExp) eqExp.getChild(0)); - IrValue right = visitRelExp((RelExp) eqExp.getChild(2)); - String op = ((TokenNode) eqExp.getChild(1)).getValue(); - left = IrType.convertType(left, IrInterType.INT32); - right = IrType.convertType(right, IrInterType.INT32); - CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), op, left, right); - IrBuilder.addInstr(cmpInstr); - return cmpInstr; - } - } - - public static IrValue visitLAndExp(LAndExp landExp, - IrBasicBlock trueBlock, IrBasicBlock falseBlock) { - if (landExp.getChildren().size() == 1) { - IrValue eqIrValue = visitEqExp((EqExp) landExp.getChild(0)); - eqIrValue = IrType.convertType(eqIrValue, IrInterType.BOOL); - BranchInstr branchInstr = new BranchInstr( - IrBuilder.getLocalName(), eqIrValue, trueBlock, falseBlock); - IrBuilder.addInstr(branchInstr); - return eqIrValue; - } else { - IrBasicBlock nextBB = new IrBasicBlock( - IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); - IrBuilder.addNewBB(nextBB); - IrValue left = visitLAndExp((LAndExp) landExp.getChild(0), nextBB, falseBlock); - IrBuilder.setCurrentBBlock(nextBB); - IrValue right = visitEqExp((EqExp) landExp.getChild(2)); - right = IrType.convertType(right, IrInterType.BOOL); - BranchInstr branchInstr2 = new BranchInstr( - IrBuilder.getLocalName(), right, trueBlock, falseBlock); - IrBuilder.addInstr(branchInstr2); - return right; - } - } - - public static void visitLOrExp(LOrExp lorExp, IrBasicBlock trueBB, IrBasicBlock falseBB) { - if (lorExp.getChildren().size() == 1) { - IrValue landIrValue = visitLAndExp((LAndExp) lorExp.getChild(0), trueBB, falseBB); - } else { - IrBasicBlock nextBB = new IrBasicBlock( - IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); - IrBuilder.addNewBB(nextBB); - visitLOrExp((LOrExp) lorExp.getChild(0), trueBB, nextBB); - IrBuilder.setCurrentBBlock(nextBB); - IrValue right = visitLAndExp((LAndExp) lorExp.getChild(2), trueBB, falseBB); - } - } - - public static void visitCond(Cond cond, IrBasicBlock trueBB, IrBasicBlock falseBB) { - visitLOrExp((LOrExp) cond.getChild(0), trueBB, falseBB); - } -} - - - - - - - - - - - - - - - - - - +package midend.visit; + +import frontend.ast.exp.Exp; +import frontend.ast.exp.LAndExp; +import frontend.ast.exp.LOrExp; +import frontend.ast.exp.LVal; + +import java.util.ArrayList; + +import frontend.ast.exp.AddExp; +import frontend.ast.exp.EqExp; +import frontend.ast.exp.MulExp; +import frontend.ast.exp.NumberExp; +import frontend.ast.exp.PrimaryExp; +import frontend.ast.exp.RelExp; +import frontend.ast.exp.UnaryExp; +import frontend.ast.exp.UnaryOp; +import frontend.ast.exp.Cond; +import frontend.ast.token.TokenNode; +import midend.llvm.IrBuilder; +import midend.llvm.constant.IrConstantInt; +import midend.llvm.instr.AluInstr; +import midend.llvm.instr.BranchInstr; +import midend.llvm.instr.CallInstr; +import midend.llvm.instr.CmpInstr; +import midend.llvm.instr.ExtendInstr; +import midend.llvm.instr.GepInstr; +import midend.llvm.instr.GetIntInstr; +import midend.llvm.instr.LoadInstr; +import midend.llvm.type.IrInterType; +import midend.llvm.type.IrType; +import midend.llvm.value.IrBasicBlock; +import midend.llvm.value.IrFuncValue; +import midend.llvm.value.IrValue; +import midend.symbol.*; + +public class VisitorExp { + public static IrValue visitExp(Exp exp) { + return visitAddExp((AddExp) exp.getChild(0)); + } + + public static IrValue visitAddExp(AddExp addExp) { + if (addExp.getChildren().size() == 1) { + return visitMulExp((MulExp) addExp.getChild(0)); + } else { + IrValue left = visitAddExp((AddExp) addExp.getChild(0)); + TokenNode op = (TokenNode) addExp.getChild(1); + IrValue right = visitMulExp((MulExp) addExp.getChild(2)); + left = IrType.convertType(left, IrInterType.INT32); + right = IrType.convertType(right, IrInterType.INT32); + AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op.getValue(), left, right); + IrBuilder.addInstr(aluInstr); + return aluInstr; + } + } + + public static IrValue visitMulExp(MulExp mulExp) { + if (mulExp.getChildren().size() == 1) { + return visitUnaryExp((UnaryExp) mulExp.getChild(0)); + } else { + IrValue left = visitMulExp((MulExp) mulExp.getChild(0)); + TokenNode op = (TokenNode) mulExp.getChild(1); + IrValue right = visitUnaryExp((UnaryExp) mulExp.getChild(2)); + left = IrType.convertType(left, IrInterType.INT32); + right = IrType.convertType(right, IrInterType.INT32); + AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op.getValue(), left, right); + IrBuilder.addInstr(aluInstr); + return aluInstr; + } + } + + public static IrValue visitUnaryExp(UnaryExp unaryExp) { + if (unaryExp.getChild(0) instanceof PrimaryExp) { + return visitPrimaryExp((PrimaryExp) unaryExp.getChild(0)); + } else if (unaryExp.getChild(0) instanceof TokenNode) { + return visitFuncCall((TokenNode) unaryExp.getChild(0), unaryExp.getParamList()); + } else { + return visitOpUnaryExp((UnaryOp) unaryExp.getChild(0), (UnaryExp) unaryExp.getChild(1)); + } + } + + public static IrValue visitOpUnaryExp(UnaryOp uop, UnaryExp unaryExp) { + String op = ((TokenNode) uop.getChild(0)).getValue(); + IrValue operand = visitUnaryExp(unaryExp); + IrConstantInt zero = new IrConstantInt(0); + if (op.equals("+")) { + return operand; + } else if (op.equals("-")) { + AluInstr aluInstr = new AluInstr(IrBuilder.getLocalName(), op, zero, operand); + IrBuilder.addInstr(aluInstr); + return aluInstr; + } else { + operand = IrType.convertType(operand, IrInterType.INT32); + CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), "==", zero, operand); + IrBuilder.addInstr(cmpInstr); + ExtendInstr extendInstr = new ExtendInstr( + IrBuilder.getLocalName(), IrInterType.INT32, cmpInstr); + IrBuilder.addInstr(extendInstr); + return extendInstr; + } + } + + public static IrValue visitPrimaryExp(PrimaryExp primaryExp) { + if (primaryExp.getChild(0) instanceof TokenNode) { + return visitExp((Exp) primaryExp.getChild(1)); + } else if (primaryExp.getChild(0) instanceof LVal) { + return visitLVal((LVal) primaryExp.getChild(0), false); + } else { + return new IrConstantInt(((NumberExp) primaryExp.getChild(0)).getValue()); + } + } + + public static IrValue visitFuncCall(TokenNode funcName, ArrayList paramList) { + if (funcName.getValue().equals("getint")) { + GetIntInstr getIntInstr = new GetIntInstr(IrBuilder.getLocalName()); + IrBuilder.addInstr(getIntInstr); + return getIntInstr; + } + FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol(funcName.getName(), true); + IrFuncValue irFunction = (IrFuncValue) funcSymbol.getIrValue(); + ArrayList args = new ArrayList<>(); + for (Exp param : paramList) { + args.add(visitExp(param)); + } + CallInstr callInstr = new CallInstr(IrBuilder.getLocalName(), irFunction, args); + IrBuilder.addInstr(callInstr); + return callInstr; + } + + public static IrValue visitLVal(LVal lval, boolean assign) { + if (assign) { + Symbol symbol = SymbolManager.getSymbol(((TokenNode) lval.getChild(0)).getName(), true); + if (!(symbol instanceof ArraySymbol)) { + return symbol.getIrValue(); + } else { + Exp exp = (Exp) lval.getChild(2); + IrValue pointer = symbol.getIrValue(); + GepInstr gepInstr = new GepInstr( + pointer, visitExp(exp), IrBuilder.getLocalName()); + IrBuilder.addInstr(gepInstr); + return gepInstr; + } + } else { + Symbol symbol = SymbolManager.getSymbol(((TokenNode) lval.getChild(0)).getName(), true); + // if (symbol == null) { + // System.out.println(((TokenNode)lval.getChild(0)).getLine() + " " + + // ((TokenNode)lval.getChild(0)).getValue()); + // SymbolTable table = SymbolManager.getCurrentTable(); + // System.out.println(table.toString()); + // // TODO:报错 + // } + if (!(symbol instanceof ArraySymbol)) { + LoadInstr loadInstr = new LoadInstr(symbol.getIrValue(), IrBuilder.getLocalName()); + IrBuilder.addInstr(loadInstr); + return loadInstr; + } else { + if (lval.getChildren().size() == 1) { + GepInstr gepInstr = new GepInstr( + symbol.getIrValue(), new IrConstantInt(0), IrBuilder.getLocalName()); + IrBuilder.addInstr(gepInstr); + return gepInstr; + } else { + Exp exp = (Exp) lval.getChild(2); + GepInstr gepInstr = new GepInstr( + symbol.getIrValue(), visitExp(exp), IrBuilder.getLocalName()); + IrBuilder.addInstr(gepInstr); + LoadInstr loadInstr = new LoadInstr(gepInstr, IrBuilder.getLocalName()); + IrBuilder.addInstr(loadInstr); + return loadInstr; + } + } + } + } + + // TODO:条件表达式的实现 + public static IrValue visitRelExp(RelExp relExp) { + if (relExp.getChildren().size() == 1) { + return visitAddExp((AddExp) relExp.getChild(0)); + } else { + IrValue left = visitRelExp((RelExp) relExp.getChild(0)); + IrValue right = visitAddExp((AddExp) relExp.getChild(2)); + String op = ((TokenNode) relExp.getChild(1)).getValue(); + left = IrType.convertType(left, IrInterType.INT32); + right = IrType.convertType(right, IrInterType.INT32); + CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), op, left, right); + IrBuilder.addInstr(cmpInstr); + return cmpInstr; + } + } + + public static IrValue visitEqExp(EqExp eqExp) { + if (eqExp.getChildren().size() == 1) { + return visitRelExp((RelExp) eqExp.getChild(0)); + } else { + IrValue left = visitEqExp((EqExp) eqExp.getChild(0)); + IrValue right = visitRelExp((RelExp) eqExp.getChild(2)); + String op = ((TokenNode) eqExp.getChild(1)).getValue(); + left = IrType.convertType(left, IrInterType.INT32); + right = IrType.convertType(right, IrInterType.INT32); + CmpInstr cmpInstr = new CmpInstr(IrBuilder.getLocalName(), op, left, right); + IrBuilder.addInstr(cmpInstr); + return cmpInstr; + } + } + + public static IrValue visitLAndExp(LAndExp landExp, + IrBasicBlock trueBlock, IrBasicBlock falseBlock) { + if (landExp.getChildren().size() == 1) { + IrValue eqIrValue = visitEqExp((EqExp) landExp.getChild(0)); + eqIrValue = IrType.convertType(eqIrValue, IrInterType.BOOL); + BranchInstr branchInstr = new BranchInstr( + IrBuilder.getLocalName(), eqIrValue, trueBlock, falseBlock); + IrBuilder.addInstr(branchInstr); + return eqIrValue; + } else { + IrBasicBlock nextBB = new IrBasicBlock( + IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); + IrBuilder.addNewBB(nextBB); + IrValue left = visitLAndExp((LAndExp) landExp.getChild(0), nextBB, falseBlock); + IrBuilder.setCurrentBBlock(nextBB); + IrValue right = visitEqExp((EqExp) landExp.getChild(2)); + right = IrType.convertType(right, IrInterType.BOOL); + BranchInstr branchInstr2 = new BranchInstr( + IrBuilder.getLocalName(), right, trueBlock, falseBlock); + IrBuilder.addInstr(branchInstr2); + return right; + } + } + + public static void visitLOrExp(LOrExp lorExp, IrBasicBlock trueBB, IrBasicBlock falseBB) { + if (lorExp.getChildren().size() == 1) { + IrValue landIrValue = visitLAndExp((LAndExp) lorExp.getChild(0), trueBB, falseBB); + } else { + IrBasicBlock nextBB = new IrBasicBlock( + IrBuilder.getBlockName(), IrBuilder.getCurrentFunc()); + IrBuilder.addNewBB(nextBB); + visitLOrExp((LOrExp) lorExp.getChild(0), trueBB, nextBB); + IrBuilder.setCurrentBBlock(nextBB); + IrValue right = visitLAndExp((LAndExp) lorExp.getChild(2), trueBB, falseBB); + } + } + + public static void visitCond(Cond cond, IrBasicBlock trueBB, IrBasicBlock falseBB) { + visitLOrExp((LOrExp) cond.getChild(0), trueBB, falseBB); + } +} + + + + + + + + + + + + + + + + + + diff --git a/midend/visit/VisitorFuncDef.java b/midend/visit/VisitorFuncDef.java old mode 100644 new mode 100755 index b6584d1..3e1b74a --- a/midend/visit/VisitorFuncDef.java +++ b/midend/visit/VisitorFuncDef.java @@ -1,80 +1,80 @@ -package midend.visit; - -import java.util.ArrayList; - -import frontend.ast.block.Block; -import frontend.ast.func.FuncDef; -import frontend.ast.func.MainFuncDef; -import frontend.ast.token.TokenNode; -import midend.llvm.IrBuilder; -import midend.llvm.instr.AllocateInstr; -import midend.llvm.instr.StoreInstr; -import midend.llvm.type.IrInterType; -import midend.llvm.type.IrPointerType; -import midend.llvm.value.IrFuncValue; -import midend.llvm.value.IrValue; - -import midend.symbol.Symbol; -import midend.symbol.FuncSymbol; -import midend.symbol.SymbolManager; - -public class VisitorFuncDef { - public static void visitFuncDef(FuncDef funcDef) { - FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol( - ((TokenNode) funcDef.getChild(1)).getName()); - IrInterType returnType = funcSymbol.getReturnType() == 1 - ? IrInterType.INT32 - : IrInterType.VOID; - IrFuncValue funcValue = new IrFuncValue( - IrBuilder.geFuncName(funcSymbol.getName()), returnType); - IrBuilder.addNewFunc(funcValue); - funcSymbol.setIrValue(funcValue); - // 进入函数作用域 - SymbolManager.nextTable(); - // System.out.println("(func)now table: " + SymbolManager.getCurrentTableId());//TODO:debug - ArrayList paramList = funcSymbol.getParamList(); - ArrayList paramSymbolList = funcSymbol.getParamSymbolList(); - ArrayList irParamList = new ArrayList<>(); - for (int i = 0; i < paramList.size(); i++) { - if (paramList.get(i) == 0) { - IrValue param = new IrValue(IrInterType.INT32, IrBuilder.getLocalName()); - irParamList.add(param); - funcValue.addParam(param); - } else { - IrValue param = new IrValue( - new IrPointerType(IrInterType.INT32), IrBuilder.getLocalName()); - irParamList.add(param); - funcValue.addParam(param); - paramSymbolList.get(i).setIrValue(param); - } - } - for (int i = 0; i < irParamList.size(); i++) { - if (paramList.get(i) == 1) { - continue; // 数组参数不分配内存 - } - AllocateInstr allocateInstr = new AllocateInstr( - irParamList.get(i).getType(), IrBuilder.getLocalName()); - IrBuilder.addInstr(allocateInstr); - StoreInstr storeInstr = new StoreInstr(irParamList.get(i), allocateInstr); - IrBuilder.addInstr(storeInstr); - paramSymbolList.get(i).setIrValue(allocateInstr); - } //这里貌似可以不用allocate?函数形参似乎可以直接拿来用? - Block block = (Block) funcDef.getChild(funcDef.getChildren().size() - 1); - VisitorBlock.visitBlock(block); - // TODO:check return? - funcValue.checkReturn(); - SymbolManager.nextTable(); - // System.out.println("(func)now table: " + SymbolManager.getCurrentTableId());//TODO:debug - } - - public static void visitMainFuncDef(MainFuncDef mainFuncDef) { - IrFuncValue mainFuncValue = new IrFuncValue( - IrBuilder.geFuncName("main"), IrInterType.INT32); - IrBuilder.addNewFunc(mainFuncValue); - SymbolManager.nextTable(); - // System.out.println("(mainfunc)now table: " + SymbolManager.getCurrentTableId());//TODO:debug - Block block = (Block) mainFuncDef.getChild(mainFuncDef.getChildren().size() - 1); - VisitorBlock.visitBlock(block); - SymbolManager.nextTable(); - } +package midend.visit; + +import java.util.ArrayList; + +import frontend.ast.block.Block; +import frontend.ast.func.FuncDef; +import frontend.ast.func.MainFuncDef; +import frontend.ast.token.TokenNode; +import midend.llvm.IrBuilder; +import midend.llvm.instr.AllocateInstr; +import midend.llvm.instr.StoreInstr; +import midend.llvm.type.IrInterType; +import midend.llvm.type.IrPointerType; +import midend.llvm.value.IrFuncValue; +import midend.llvm.value.IrValue; + +import midend.symbol.Symbol; +import midend.symbol.FuncSymbol; +import midend.symbol.SymbolManager; + +public class VisitorFuncDef { + public static void visitFuncDef(FuncDef funcDef) { + FuncSymbol funcSymbol = (FuncSymbol) SymbolManager.getSymbol( + ((TokenNode) funcDef.getChild(1)).getName()); + IrInterType returnType = funcSymbol.getReturnType() == 1 + ? IrInterType.INT32 + : IrInterType.VOID; + IrFuncValue funcValue = new IrFuncValue( + IrBuilder.geFuncName(funcSymbol.getName()), returnType); + IrBuilder.addNewFunc(funcValue); + funcSymbol.setIrValue(funcValue); + // 进入函数作用域 + SymbolManager.nextTable(); + // System.out.println("(func)now table: " + SymbolManager.getCurrentTableId());//TODO:debug + ArrayList paramList = funcSymbol.getParamList(); + ArrayList paramSymbolList = funcSymbol.getParamSymbolList(); + ArrayList irParamList = new ArrayList<>(); + for (int i = 0; i < paramList.size(); i++) { + if (paramList.get(i) == 0) { + IrValue param = new IrValue(IrInterType.INT32, IrBuilder.getLocalName()); + irParamList.add(param); + funcValue.addParam(param); + } else { + IrValue param = new IrValue( + new IrPointerType(IrInterType.INT32), IrBuilder.getLocalName()); + irParamList.add(param); + funcValue.addParam(param); + paramSymbolList.get(i).setIrValue(param); + } + } + for (int i = 0; i < irParamList.size(); i++) { + if (paramList.get(i) == 1) { + continue; // 数组参数不分配内存 + } + AllocateInstr allocateInstr = new AllocateInstr( + irParamList.get(i).getType(), IrBuilder.getLocalName()); + IrBuilder.addInstr(allocateInstr); + StoreInstr storeInstr = new StoreInstr(irParamList.get(i), allocateInstr); + IrBuilder.addInstr(storeInstr); + paramSymbolList.get(i).setIrValue(allocateInstr); + } //这里貌似可以不用allocate?函数形参似乎可以直接拿来用? + Block block = (Block) funcDef.getChild(funcDef.getChildren().size() - 1); + VisitorBlock.visitBlock(block); + // TODO:check return? + funcValue.checkReturn(); + SymbolManager.nextTable(); + // System.out.println("(func)now table: " + SymbolManager.getCurrentTableId());//TODO:debug + } + + public static void visitMainFuncDef(MainFuncDef mainFuncDef) { + IrFuncValue mainFuncValue = new IrFuncValue( + IrBuilder.geFuncName("main"), IrInterType.INT32); + IrBuilder.addNewFunc(mainFuncValue); + SymbolManager.nextTable(); + // System.out.println("(mainfunc)now table: " + SymbolManager.getCurrentTableId());//TODO:debug + Block block = (Block) mainFuncDef.getChild(mainFuncDef.getChildren().size() - 1); + VisitorBlock.visitBlock(block); + SymbolManager.nextTable(); + } } \ No newline at end of file diff --git a/midend/visit/VisitorStmt.java b/midend/visit/VisitorStmt.java old mode 100644 new mode 100755 index 0eb0d15..08a80c2 --- a/midend/visit/VisitorStmt.java +++ b/midend/visit/VisitorStmt.java @@ -1,271 +1,271 @@ -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); - } -} +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); + } +}