/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package API; import common.Block; import common.Code; import common.Instruction; import common.IvannosysTargetArch; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; /** * * @author EUGENIO CARVALHO */ public abstract class TargetGen implements IvannosysTargetArch { protected HashMap exportMethods = new HashMap<>(); protected Code target; protected Code IR; protected Instruction prev = null, next = null; public TargetGen(String id) { BaseGenInit(id); } public void BaseGenInit(String id) { target = new Code(id); } public Code getTarget() { return target; } public void setTarget(Code target) { this.target = target; } public Code getIR() { return IR; } public ExportInterface GetExportMethod(String id) throws Exception { id = id.trim(); if (!exportMethods.containsKey(id)) { Set set = exportMethods.keySet(); String[] valids = new String[set.size()]; set.toArray(valids); throw new Exception(String.format( "O método de exportação '%s' não foi definido no alvo '%s'. Métodos disponiveis: %s", id, target.Name(), Utils.Join(valids, ", "))); } return exportMethods.get(id); } public HashMap GetExportMethods() { return exportMethods; } public IvannosysTargetArch SetTAC(Code tac) throws Exception { // Verifica se o codigo gerado vai ser util caso contrario aborta o processo; ArrayList methods = BuildParams.Get("export"); if (methods.isEmpty()) { throw new Exception(String.format("Nenhum método de exportação definido para o alvo '%s'", target.Name())); } IR = tac; target.GlobalData().copy(tac.GlobalData()); target.Parent = IR; return this; } protected Instruction Add(Instruction inst) { target.Block().Add(inst); return inst; } public TargetGen AddExportOption(String id, ExportInterface exp) { exportMethods.put(id.trim(), exp); return this; } @Override public IvannosysTargetArch Format() { try { String code = target.getCodeStream(); System.out.println("Target[" + target.Name() + "]:\n" + code); } catch (Exception ex) { Logger.getLogger(TargetGen.class.getName()).log(Level.SEVERE, null, ex); } return this; } @Override public IvannosysTargetArch Compile() { try { // Traduz o codigo intermediario para o alvo Translate(); } catch (Exception ex) { Logger.getLogger(TargetGen.class.getName()).log(Level.SEVERE, null, ex); } return this; } protected void Translate() throws Exception { String targetID = target.Name(), id; target.Parent = IR; CodeProcessor.Trigger(target, targetID, "BeforeTranslate"); for (Map.Entry b : IR.getBlocks().entrySet()) { id = b.getKey(); IR.Use(id); target.OpenBlock(id); CodeProcessor.Trigger(target, targetID, "BeforeTranslateBlock"); Prolog(id); TranslateBlock(b.getValue()); Epilog(id); target.CloseBlock(); target.UpdatePositions(); CodeProcessor.Trigger(target, targetID, "AfterTranslateBlock"); } CodeProcessor.Trigger(target, targetID, "AfterTranslate"); } @Override public IvannosysTargetArch Export() throws Exception { ArrayList methods = BuildParams.Get("export"); for (String method : methods) { GetExportMethod(method).Exec(IR, target); } return this; } protected void TranslateBlock(Block b) throws Exception { // System.out.println("Translate block:" + b.getName() + "::" + b.Instructions().size()); LinkedList instructions = b.Instructions(); Integer index = 0, limit = instructions.size(), nextIndex; for (Instruction inst : instructions) { nextIndex = index + 1; next = (nextIndex < limit) ? instructions.get(nextIndex) : null; // System.out.println("Translate: " + inst.Get("global.position") + "::read[" // + inst.Get("reg.dst.load") // + "|" // + inst.Get("reg.p1.load") // + "|" // + inst.Get("reg.p2.load") // + "] >> write[" // + inst.Get("reg.dst.store") // + "|" // + inst.Get("reg.p1.store") // + "|" // + inst.Get("reg.p2.store") // + "]" // + inst.Get("type") // ); // switch (inst.Get("type")) { case "label": if (!inst.Get("label").equals(getTarget().Block().getName())) { TranslateLabel(inst); } break; case "assign": TranslateAssign(inst); break; case "unary": TranslateUnary(inst); break; case "copy": TranslateCopy(inst); break; case "jump": TranslateJump(inst); break; case "call": TranslateCall(inst); break; case "return": TranslateReturn(inst); break; case "push_param": TranslatePushParam(inst); break; case "push_return": TranslatePushReturn(inst); break; case "pop_return": TranslatePopReturn(inst); break; case "pop_param": TranslatePopParam(inst); break; case "branch": TranslateBranch(inst); break; case "indexed_assign": TranslateIndexedAssignment(inst); break; case "pointer_assign": TranslatePointerAssignment(inst); break; case "store": TranslateStore(inst); break; case "load": TranslateLoad(inst); break; default: throw new Exception(String.format("TAC instruction type '%s' not defined", inst.Get("type"))); } prev = inst; index++; } } protected Instruction Next() { return next; } protected Instruction Prev() { return prev; } }