// Método de entrada do Codegen public String translate(Program p, Env env) { codeGenerator = new Codegen(); // Preenchendo a Tabela de Símbolos // Quem quiser usar 'env', apenas comente essa linha // codeGenerator.symTab.FillTabSymbol(p); // Formato da String para o System.out.printlnijava "%d\n" codeGenerator.assembler.add( new LlvmConstantDeclaration( "@.formatting.string", "private constant [4 x i8] c\"%d\\0A\\00\"")); // NOTA: sempre que X.accept(Y), então Y.visit(X); // NOTA: Logo, o comando abaixo irá chamar codeGenerator.visit(Program), linha 75 p.accept(codeGenerator); // Link do printf List<LlvmType> pts = new LinkedList<LlvmType>(); pts.add(new LlvmPointer(LlvmPrimitiveType.I8)); pts.add(LlvmPrimitiveType.DOTDOTDOT); codeGenerator.assembler.add(new LlvmExternalDeclaration("@printf", LlvmPrimitiveType.I32, pts)); List<LlvmType> mallocpts = new LinkedList<LlvmType>(); mallocpts.add(LlvmPrimitiveType.I32); codeGenerator.assembler.add( new LlvmExternalDeclaration("@malloc", new LlvmPointer(LlvmPrimitiveType.I8), mallocpts)); String r = new String(); for (LlvmInstruction instr : codeGenerator.assembler) r += instr + "\n"; return r; }
public LlvmValue visit(Print n) { LlvmValue v = n.exp.accept(this); // getelementptr: LlvmRegister lhs = new LlvmRegister(new LlvmPointer(LlvmPrimitiveType.I8)); LlvmRegister src = new LlvmNamedValue( "@.formatting.string", new LlvmPointer(new LlvmArray(4, LlvmPrimitiveType.I8))); List<LlvmValue> offsets = new LinkedList<LlvmValue>(); offsets.add(new LlvmIntegerLiteral(0)); offsets.add(new LlvmIntegerLiteral(0)); List<LlvmType> pts = new LinkedList<LlvmType>(); pts.add(new LlvmPointer(LlvmPrimitiveType.I8)); List<LlvmValue> args = new LinkedList<LlvmValue>(); args.add(lhs); args.add(v); assembler.add(new LlvmGetElementPointer(lhs, src, offsets)); pts = new LinkedList<LlvmType>(); pts.add(new LlvmPointer(LlvmPrimitiveType.I8)); pts.add(LlvmPrimitiveType.DOTDOTDOT); // printf: assembler.add( new LlvmCall( new LlvmRegister(LlvmPrimitiveType.I32), LlvmPrimitiveType.I32, pts, "@printf", args)); return null; }
public LlvmValue visit(Plus n) { LlvmValue v1 = n.lhs.accept(this); LlvmValue v2 = n.rhs.accept(this); LlvmRegister lhs = new LlvmRegister(LlvmPrimitiveType.I32); assembler.add(new LlvmPlus(lhs, LlvmPrimitiveType.I32, v1, v2)); return lhs; }
public LlvmValue visit(MainClass n) { // definicao do main assembler.add(new LlvmDefine("@main", LlvmPrimitiveType.I32, new LinkedList<LlvmValue>())); assembler.add(new LlvmLabel(new LlvmLabelValue("entry"))); LlvmRegister R1 = new LlvmRegister(new LlvmPointer(LlvmPrimitiveType.I32)); assembler.add(new LlvmAlloca(R1, LlvmPrimitiveType.I32, new LinkedList<LlvmValue>())); assembler.add(new LlvmStore(new LlvmIntegerLiteral(0), R1)); // Statement é uma classe abstrata // Portanto, o accept chamado é da classe que implementa Statement, por exemplo, a classe // "Print". n.stm.accept(this); // Final do Main LlvmRegister R2 = new LlvmRegister(LlvmPrimitiveType.I32); assembler.add(new LlvmLoad(R2, R1)); assembler.add(new LlvmRet(R2)); assembler.add(new LlvmCloseDefinition()); return null; }