/* * 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 IntermediaryCode; import API.Api; import API.Functions; import API.Instruction; import API.Tipos; import API.Utils; import API.Variaveis; import ast.AbstractSyntaxTree; import ast.Node; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.Map; import java.util.Stack; import java.util.regex.Pattern; // a0 a1 // sync recebe mandando // exec recebe mandando // synexec recebe mandando /** * * @author Eugenio */ public final class BaseTacGen implements TacGenInterface { protected boolean inicializado = false; protected int incLabel = 0; protected int tmpVarCount = 1; protected int OrTestAndOccurrence = 0; protected AbstractSyntaxTree ast; protected Code code; protected Node calEndAtt; protected Node compileParams; protected String label; protected String calEndVar; protected String calEndSize; protected String calEndTipo; protected Stack master = new Stack<>(); protected ArrayList line = new ArrayList<>(); protected LinkedList branckInvert = new LinkedList<>(); protected HashMap arrayAcesso = new HashMap<>(); protected HashMap varGenMap = new HashMap<>(); protected HashMap funcGenMap = new HashMap<>(); protected HashMap systemCalls = new HashMap<>(); protected ArrayList currentMatrixvalues = new ArrayList<>(); protected HashMap> matrixValues = new HashMap<>(); // protected ArrayList afterCreate = new ArrayList(); protected HashMap Complements = new HashMap() { { put("!=", "=="); put("==", "!="); put("<", ">="); put("<=", ">"); put(">", "<="); put(">=", "<"); } }; public static Pattern AddressOperator = Pattern.compile("(\\&|\\*)"); protected boolean enableOtimization = true; protected HashMap ArrayShiftMap = new HashMap<>(); public BaseTacGen() throws Exception { for (long i = 0; i < 31; i++) { power2.put(Long.valueOf(1 << i), Long.valueOf(i)); } } protected int calc(ArrayList data) { Integer op1, op2, operacao; switch (data.size()) { case 1: return data.get(0); case 3: op1 = data.remove(0); operacao = data.remove(0); op2 = data.remove(0); if (operacao == 1) { return op1 - op2; // throw new Exception("Quantidade de entradas invalidas!" + data.size()); } else { return op1 + op2; } default: op1 = data.remove(0); operacao = data.remove(0); if (operacao == 1) { return op1 - calc(data); // throw new Exception("Quantidade de entradas invalidas!" + data.size()); } else { return op1 + calc(data); } } } public BaseTacGen(AbstractSyntaxTree ast) { Ast(ast); } public void Ast(AbstractSyntaxTree ast) { this.ast = ast; code = new Code("TAC", ast); code.AfterClose("clear.1", new CodeClearProcessor()); // code.AfterClose("oti.1", new CodeOtimizadorProcessor(enableOtimization)); // code.AfterClose("oti.1", new CodeOtimizadorProcessor(false)); compileParams = ast.BuildParams(); code.Template(new template.Template()) .Formats(new HashMap() { { String base = "{[PAD(global.position,_addressLen,' ')]':'}{[T(1)]}{[PAD(block.position,_addressLen,' ')]':'}{[T(2)]}"; String end = "{[T(2)]}{' T< '[type]' >'}"; put("label", "{[PAD(global.position,_addressLen,' ')]':'}{[T(2)]}{'<'[label]'>'}':'"); put("assign", base + "{[dst]}' := '{[p1]}{' '[op]' '}{[p2]}{' --'[comment]}" + end); put("pointer_assignment", base + "{[dst.pointer]}{[dst]' := '}{[op]}{[p1]}{' --'[comment]}" + end); put("unary", base + " {[dst]} ' := '{[op]' '}{[p1]} {' --'[comment]}" + end); put("copy", base + " {[dst]} ' := '{[p1]} {' --'[comment]}" + end); put("jump", base + " 'goto ' {'<'[label]'>'} {' --'[comment]}" + end); put("branch", base + " 'if '{[p1]} {' '[op]' '} {[p2]} ' goto ' {'<'[label]'>'} {' --'[comment]}" + end); put("call", base + " {[dst]' := '} 'call <' {[funcname]} '>, ' {[nump]} {' --'[comment]}" + end); put("return", base + " 'return ' {[p1]} {' --'[comment]}" + end); put("push_param", base + " 'push_param '{[p1]} {' --'[comment]}" + end); put("push_return", base + " 'push_return '{[p1]} {' --'[comment]}" + end); put("pop_param", base + " 'pop_param '{[p1]} {' --'[comment]}" + end); put("pop_return", base + " 'pop_return '{[p1]} {' --'[comment]}" + end); } }); } @Override public Code Create(AbstractSyntaxTree ast, HashMap settings) throws Exception { Ast(ast); // setOtimizacao(settings.G("clearCode").equals("true")); Code code = run(); // Executa todos os tratametos definidos apos geracao do codigo // AfterCreate(); printVarMap(); // code.PrintData(); code.Print(); code.printOcorrences(); return code; } protected Node visit(Node n) throws Exception { if (null == n || n.eq("visited", "true")) { return n; } n.S("visited", "true"); // System.out.println("Visit:" + n.Class()); switch (n.Class()) { case "dec.const": gerarConstante(n); break; case "if.stmt": IfStmts(n); break; case "selector": Selector(n); break; case "dec.var": // Log.PrintInfo("TAC", new Instruction().S("msg", "DECVAR." + n)); if (n.find("exprs") != null) { n.S("class", "dec.var.short") .S("value", "dec.var.short"); genAssign(n); break; } case "def.assign": genAssign(n); break; case "call": genCall(n); break; case "ID": genID(n); break; case "incdec": IncDecStmt(n); break; case "for.stmt": genFor(n); break; case "expr": _visitExpr(n); break; case "unary": unaryStmt(n); break; case "switch.stmt": switchStmt(n); break; case "test": test(n); break; case "return": visitChildrensFirst(n); break; default: visitRootFirst(n); break; } return n; } protected void genID(Node n) throws Exception { // System.out.println("GenId:" + n); Node var = Variaveis.Get(n.getText()); n.S("_return", gerarVariavel(var)); } protected void test(Node n) throws Exception { Node x = null; ArrayList chils = n.childrens(); int size = chils.size(); for (int i = 0; i < size; i++) { x = chils.get(i); visit(x); } n.copy("_return", x); } protected void IncDecStmt(Node n) throws Exception { Instruction operacao = new Instruction(); String dst = gerarVariavel(n.findByClass("selector")); operacao.S("type", "assign") .S("format", "assign") .S("cat", "exp") .S("_return", "exp") .S("dst", dst) .S("p1", dst) .S("p2", "1") .S("p1value", "" + Api.IsValue(dst)) .S("p2value", "true") .S("op", n.findByClass("operator").eq("value", "++") ? "+" : "-"); code.Add(operacao); } protected void Selector(Node n) throws Exception { String tmp; String shift = null; n.S("copymode", "copy"); switch (n.G("subclass")) { case "operand": if (n.eq("classType", "value")) { // n.S("value", Api.Value(n.getText())); n.S("_return", Api.Value(n.getText())); } else { String v = gerarVariavel(n); if (n.eq("pointer", "*") && n.eq("access", "read")) { String t = gerarVariavel("T"); Copy(t, v, false); v = t; } n.S("_return", v); } // System.out.println("Seletor operand:" + n); break; case "index": // shift = n.childrens().G(0).getInt("value"); // shift = n.childrens().G(0).getInt("value"); shift = ArrayShift(n); case "selector": if (shift == null) { shift = "" + Variaveis.Shift(n.getText()); } tmp = gerarVariavel(n) + "[" + shift + "]"; if (!n.eq("access", "write")) { String t = gerarVariavel("T"); Copy(t, tmp, false); tmp = t; } n.S("_return", tmp); break; case "arguments": break; } } protected ArrayList ShiftPath(int size) { ArrayList ret = new ArrayList<>(); FindShiftPath(size, ret); return ret; } protected ArrayList ShiftInterval(int size) { ArrayList ret = new ArrayList<>(); Integer op = 1, i = 1, after, before; // while (true) { after = 1 << (i++); if (after == size) { before = after; break; } else if (after > size) { before = after >> 1; break; } } // before = Math.abs(before - size); // after = Math.abs(after - size); if (Math.abs(before - size) <= Math.abs(after - size)) { // Se o valor anterios for menor que o posterior op = 0; } // else { // // Se o valor posterior for menor que o anterior // } ret.add(before); ret.add(after); ret.add(2, op); // System.out.println("Interval:{" + size + "}" + ret + "::" + op); return ret; } protected LinkedHashMap power2 = new LinkedHashMap(); protected void FindShiftPath(int size, ArrayList path) { size = Math.abs(size); ArrayList shift = ShiftInterval(size); int op = shift.get(2), s1 = shift.get(op); // System.out.println("FindShiftPath:(" + size + "|" + s1 + ")\t\t" + shift); if (power2.containsKey(s1)) { path.add(s1); path.add(op); } if (size == 1) { // path.add(size); } if (path.size() % 2 == 0 && Math.abs(size - s1) == 0) { path.remove(path.size() - 1); return; } FindShiftPath(size - s1, path); // int i = 1, after, before; // while (true) { // after = 1 << (i++); // if (after == size) { // // break; // } else if (after > size) { // break; // } // } // before = after >> 1; // // if (Math.abs(size - before) < Math.abs(after - size)) { // // Se o valor anterios for menor que o posterior // op = 1; // m4 = before; // } else { // // Se o valor posterior for menor que o anterior // op = 0; // m4 = after; // } // FindShiftPath(size, m4, op, path); } protected int Size(String type) { return Tipos.Size(type) * 4; } protected String ArrayShift(Node n) throws Exception { // Cria a chave para a ocorrencia de um acesso ao array, evitando recalcular o endereco String key = n.getText(); for (Node node : n.childrens()) { key += "_" + node.getText(); } if (!ArrayShiftMap.containsKey(key)) { // String shift; Node var = Variaveis.Get(n.getText()); // System.out.println("INDEX shift:" + n.childrens()); for (int i = 0, j = 1; j < var.childrens().size(); j++) { n.childrens().get(i++).S("collNumber", var.childrens().get(j).getText()); } String ret = CalcArrayAddress(n.childrens(), Size(var.G("type"))); // Se o offset for calculado em um inteiro atribui o mesmo como shift // if (Utils.isNumber(ret)) { // shift = ret; // } else { //// Se for um endereci faz a soma com o offset da varivel //// __exp("+", ret, gerarVariavel(n), ret); // shift = ret; // } ArrayShiftMap.put(key, ret); } return ArrayShiftMap.get(key); } protected String GenShiftLeftLogical(String var, int size, boolean mps) throws Exception { ArrayList path = ShiftPath(size); ArrayList reverse = new ArrayList<>(); for (int i = path.size() - 1; i >= 0; i--) { reverse.add(path.remove(i)); } System.out.println(">>>>>(var:" + var + ", size:" + size + ") arithpath:" + reverse); var = GSLL(var, reverse, mps, size); return var; } protected String GSLL(String var, ArrayList path, boolean mps, int size) throws Exception { int op1, operacao, op2; String T1 = gerarVariavel("T"), T2 = gerarVariavel("T"), T3 = gerarVariavel("T"); switch (path.size()) { case 1: if (!mps) { Copy(T1, var, false) .S("comment", "Copy value of index") .S("copy", "true"); } else { T1 = var; } if (mps) { __exp("<<", T1, "" + power2.get(size), T2).S("comment", ""); return T2; } return T1; case 3: op1 = path.remove(0); operacao = path.remove(0); op2 = path.remove(0); // String T4 = gerarVariavel("T"); if (!mps) { Copy(T1, var, false) .S("comment", "Copy value of index") .S("copy", "true"); } if (op1 != 1) { __exp("<<", T1, "" + power2.get(op1), T1).S("comment", ""); } // if (op2 == 1) { // } else { // Copy(T3, var, false).S("comment", "Copy value of index"); if (op2 != 1) { __exp("<<", T1, "" + (power2.get(op2) - power2.get(op1)), T2).S("comment", ""); // deve realizar um novo deslocamento } else { T2 = T1; } // Soma o deslocamento com o tamanho __exp("+", T1, T2, T1).S("comment", ""); return T1; default: // op1 = path.remove(0); // operacao = path.remove(0); // // T2 = GSLL(var, path); // // Copy(T1, var, false).S("comment", "Copy value of index"); // // __exp("<<", T1, "" + power2.get(op1), T1).S("comment", ""); // __exp("+", T1, T2, T1).S("comment", ""); } return var; } protected String CalcArrayAddress(ArrayList childrens, int Size) throws Exception { System.out.println("CalcArrayAddressINIT:" + Size); boolean onlyNumber = true; for (Node node : childrens) { if (!node.isNumber("value")) { onlyNumber = false; break; } } if (onlyNumber) { return "" + (CalcArrayAddressNumber(childrens, Size) * Size); } else { // System.out.println("CAA:" + childrens); String current = CalcArrayAddressAux(childrens, Size); System.out.println("Size {" + current + "}:----------->" + Size); // multiplica pelo tamanho return GenShiftLeftLogical(current, Size, true); } } protected Integer CalcArrayAddressNumber(ArrayList childrens, int Size) throws Exception { Node ind; ind = childrens.remove(0); Integer value = ind.getInt("value"); // ultimo elemento da idexacao if (childrens.size() == 0) { return value; } Integer collNumber = ind.getInt("collNumber"), ret = CalcArrayAddressNumber(childrens, Size); return ((value * collNumber) + ret); } protected String CalcArrayAddressAux(ArrayList childrens, int Size) throws Exception { String current; // boolean multPerSize = true; Node ind, nextIndex; ind = childrens.remove(0); System.out.println("CalcArrayAddressAux:" + childrens.size() + ":" + Size); // ultimo elemento da idexacao if (childrens.size() == 0) { if (Utils.isNumber(ind.getText())) { return "" + ind.getInt("value"); } else { return GenShiftLeftLogical(gerarVariavel(ind), Size, false); } } int collNumber = ind.getInt("collNumber"); nextIndex = childrens.get(0); if (ind.isNumber("value") && nextIndex.isNumber("value")) { // System.out.println("CalcArray:" + ind.getInt("value") + ":" + ind.getInt("collNumber") + ":" + Integer.parseInt(ret)); current = "" + (ind.getInt("value") * collNumber); // multPerSize = false; } else { // System.out.println("collNumber:" + collNumber); current = GenShiftLeftLogical(gerarVariavel(ind), collNumber, false); // System.out.println("Gerando index calc:" + retl); // current = GenShiftLeftLogical(retl, Size); // current = retl; } String ret = CalcArrayAddressAux(childrens, Size); __exp("+u", current, ret, current).S("comment", "colls shift"); // if (multPerSize) { // // Realiza a multiplicacao pelo tamanho do elemento // current = GenShiftLeftLogical(current, Size); // } return current; } // protected String CalcArrayAddress(ArrayList childrens, int Size, int index) throws Exception { // System.out.println("CalcArrayAddress:" + childrens.size() + ":" + Size); // // int nindex = index + 1; // String retl; // Node ind = childrens.remove(0); // if (childrens.size() >= 1) { // String ret = CalcArrayAddress(childrens, Size, nindex); // int collNumber = ind.getInt("collNumber"); // // if (Utils.isNumber(ret) && ind.isNumber("value")) { //// System.out.println("CalcArray:" + ind.getInt("value") + ":" + ind.getInt("collNumber") + ":" + Integer.parseInt(ret)); // return "" + ((ind.getInt("value") * collNumber) + Integer.parseInt(ret)); // } else { //// System.out.println("collNumber:" + collNumber); // // retl = GenShiftLeftLogical(gerarVariavel(ind), collNumber); // // retl = GenShiftLeftLogical(retl, Size); // // __exp("+", retl, ret, retl).S("comment", "colls shift"); // return retl; // } // // /* // Implementacao com mult ** // int collNumber = ind.getInt("collNumber"); // // if (Utils.isNumber(ret) && ind.isNumber("value")) { // System.out.println("CalcArray:" + ind.getInt("value") + ":" + collNumber + ":" + Integer.parseInt(ret)); // return "" + ((ind.getInt("value") * collNumber) + Integer.parseInt(ret)); // } else { // String retl = gerarVariavel("T"); // __exp("*", gerarVariavel(ind), "" + collNumber, retl) // .S("comment", "lines shift"); // __exp("+", retl, ret, retl) // .S("comment", "colls shift"); // return retl; // } // */ // } else { // // if (Utils.isNumber(ind.getText())) { // return ind.getText(); // } else { // // ultimo elemento da idexacao // // return GenShiftLeftLogical(gerarVariavel(ind), Size); // } // // } // } /** * ProceSSa um node:
* Ordem:
* ->Primeiro filhoS;
* ->No principal;
* * @param n * @throws Exception */ protected void visitChildrensFirst(Node n) throws Exception { // System.out.println("Visit:" + n.getText()); for (Node n1 : n.childrens()) { // System.out.println("Visit:" + n1.getText()); visit(n1); } // System.out.println("Process:" + n.getText()); processarNode(n); } /** * ProceSSa um node:
* Ordem:
* ->Primeiro filho;
* ->No principal;
* ->Segundo filho;
* * @param n * @throws Exception */ protected void visitNoMeio(Node n) throws Exception { visit(n.getFilho(0)); processarNode(n); visit(n.getFilho(1)); } /** * ProceSSa um node:
* Ordem:
* ->No princial;
* ->DepoiS oS filhoS * * @param n * @throws Exception */ protected void visitRootFirst(Node n) throws Exception { processarNode(n); for (Node n1 : n.childrens()) { visit(n1); } } /** * Aloca endereço no inicio da memoria para conStanteS ApenaS tipoS
* [inteiro, booleano e char] * * @param n * @throws Exception */ protected void gerarConstante(Node n) throws Exception { gerarVariavel(n); // getLabel("C", n); // if (n.closest("block", "class") != null) { // code.registerVar(n.G("_return"), 1, DataFrame.TYPE_VAR); // } } /** * Executa a extração fo block principal * * @throws Exception */ public void main() throws Exception { Node main = ast.getMain(); // main.S("_return", Threads.getId("main")); Node stmts = main.find("stmts"); if (code.OpenBlock("main")) { PushLabel("main", "block"); visit(stmts); PushLabel("main-end", "block"); code.CloseBlock(); } } public Code run() throws Exception { if (!inicializado) { inicializado = true; main(); } code.UpdatePositions(); return code; } /** * ProceSSa If (ElSe'S)* * * @param n * @throws Exception */ protected void IfStmts(Node n) throws Exception { String end = gerarLabel(), next; boolean ifChain = n.childrens().size() > 1; if (ifChain) { //(If)+ (else)? next = gerarLabel(); } else { next = end; } n.S("next", next).S("end", end); for (Node stmt : n.childrens()) { switch (stmt.Class()) { case "if.case.stmt": IfCaseStmt(n, stmt, ifChain); break; // Else case case "stmts": // String next = gerarLabel(); // n.S("next", next); visit(stmt.S("next", next)); // Cria um PushLabel final // PushLabel(n.G("end"), "branch"); // PushLabel(end); break; } } // Cria um PushLabel final // System.out.println("Label end:" + n.G("end")); PushLabel(n.G("end"), "branch"); } /** * ProceSSa If, eSSe metodo deve Ser chamado pelo metodo IfStmtS * * @param n * @param _if * @param ifChain * @throws Exception */ protected void IfCaseStmt(Node n, Node _if, boolean ifChain) throws Exception { Node test = _if.first().first(); Node stmts = _if.find("stmts"); n.S("start", gerarLabel()); test.copy("start,next,end", n); Branch(test, 0); // marca com um label o inicio do bloco do if PushLabel(n.G("start"), "branch"); // gera as instruções do bloco visit(stmts); // se for uma cadeia de condiçoes com ou sem else if (ifChain) { // Salta os outros testes _goto(n.G("end")); //Adiciona o label de proximo elemento da cadeia de if's e else PushLabel(n.G("next"), "branch"); //Atualiza o ponteiro para o proximo elemento n.S("next", gerarLabel()); } } /** * Executa tratamento de um no eSpecifico, Selecionado pelo atributo claSS * * @param n * @throws Exception */ protected void processarNode(Node n) throws Exception { switch (n.Class()) { case "return": genReturn(n); break; case "ctrl.stmt": ctrlStmt(n); break; case "label.stmt": PushLabel(n.getText(), "user"); break; } } protected void _visitExpr(Node n) throws Exception { // System.out.println("VisitExpr:" + n); visit(n.childrens().get(0)); visit(n.childrens().get(1)); switch (n.G("subclass")) { case "arith":// ( + | - | * | / ) integer genExpArith(n); break; } } protected void BranchAnd(Node n, int index) throws Exception { // int pos = 0; OrTestAndOccurrence++; Instruction instruction = null; ArrayList x = n.childrens(); Node op1 = x.get(0), op2 = x.get(1); String type = n.G("test.type"), step = gerarLabel(), attrs = "next,start,end,inc,test.type,skip.test"; n.S("skip.test", step); op1.copy(attrs, n); op2.copy(attrs, n); instruction = Branch(op1, 1); if (instruction != null) { switch (type) { case "jtb": instruction.S("op", Complement(instruction.G("op"))); if (n.parent.eq("value", "||")) { if (index == 1) { instruction.S("label", n.parent.G("skip.test")); } else if (index == 2) { instruction.S("label", n.parent.G("end")); } // } else if (n.parent.eq("value", "&&")) { } else { instruction.S("label", n.G("end")); } } } // System.out.println("instruction Branch 1:" + instruction + "\n" + op1); // if (index == 0 || (op1.in("value", new String[]{"||", "&&"}) && !n.eq("value", op1.G("value")))) { // Registra o label para o saldo dos testes do primeiro parametro PushLabel(step, "branch"); // } instruction = Branch(op2, 2); if (instruction != null) { switch (type) { case "jtb": if (n.parent.eq("value", "||")) { if (index == 1) { // teste 1 do parametro 2 com pai || instruction.S("op", Complement(instruction.G("op"))); instruction.S("label", n.G("end")); } else if (index == 2) { // teste 2 do parametro 2 instruction.S("label", n.G("start")); } // } else if (n.parent.eq("value", "&&")) { // if (index == 1) { // teste 1 do parametro 2 com pai && //// throw new Exception("// teste 1 do parametro 2 com pai &&"); // // } else if (index == 2) { // teste 2 do parametro 2 com pai && // instruction.S("op", Complement(instruction.G("op"))); // instruction.S("label", n.G("end")); // } } else { if (index == 1) { // teste 1 do parametro 2 geral instruction.S("op", Complement(instruction.G("op"))); instruction.S("label", n.G("end")); } else if (index == 2) { // throw new Exception("teste 2 do parametro 2 geral"); } } } } } protected void BranchOr(Node n, int index) throws Exception { // int pos = 0; OrTestAndOccurrence++; Instruction instruction = null; ArrayList x = n.childrens(); Node op1 = x.get(0), op2 = x.get(1); String type = n.G("test.type"), step = gerarLabel(), attrs = "next,start,end,inc,test.type,skip.test"; n.S("skip.test", step); op1.copy(attrs, n); op2.copy(attrs, n); System.out.println("BranchOr:" + n.parent); // Executa o lado esquerdo do || instruction = Branch(op1, 1); if (instruction != null) { switch (type) { case "jtb": if (n.parent.eq("value", "&&")) { if (index == 1) { instruction.S("label", n.parent.G("skip.test")); } } } } // System.out.println("instruction Branch 1:" + instruction + "\n" + op1); // Registra o label para o saldo dos testes do primeiro parametro PushLabel(step, "branch"); // Executa o lado direito do || instruction = Branch(op2, 2); if (instruction != null) { switch (type) { case "jtb": if (n.parent.eq("value", "&&")) { if (index == 1) { instruction.S("op", Complement(instruction.G("op"))); instruction.S("label", n.parent.G("end")); } } } } } protected Instruction BranchTest(Node n, int index) throws Exception { ArrayList x = n.childrens(); String type = n.G("test.type"); boolean invert = false; String op, p0, p1, next = ""; switch (type) { case "jb": invert = true; next = n.G("end"); break; case "jtb": next = n.G("start"); break; default: throw new Exception("test.type '".concat(type).concat("' not suported. Values {jtb,jb}")); } visit(n); // Resultado do test class ou acesso a um id ou bool if (!n.eq("class", "expr")) { op = "=="; p0 = n.G("_return"); p1 = "1"; } else { //(<, <=, >, >=, ==, !=) op = n.getText(); p0 = visit(x.get(0)).G("_return"); p1 = visit(x.get(1)).G("_return"); } // Inverte o teste e salta o bloco if (invert) { op = Complement(op); } return Branch(op, p0, p1, next); // switch (n.parent.G("value")) { // case "||": // if (index == 1) { // invert = false; // next = n.G("start"); // } // break; // case "&&": // break; // default: // // Sem combinação ( || / && ) // } // System.out.println("BranchTest:[" + index + ":" + op + ":" + invert // + ":" + n.eq("invert.test", "false") + "]" + n); // Instruction instruction = Branch(op, p0, p1, label); // instruction. ; // if (n.Has("false")) { // _goto(n.G("false")); // } // if (empty) { // branckInvert.pop(); // } } protected Instruction Branch(String op, final String p1, final String p2, String label) throws Exception { Instruction r1 = new Instruction(); r1.S("format", "branch") .S("type", "branch") .S("op", op) .S("p1", p1) .S("p2", p2) .S("p1value", "" + Api.IsValue(p1)) .S("p2value", "" + Api.IsValue(p2)) .S("label", label); // System.out.println("Add branch:" + branckInvert.peek() + branckInvert + ">>" + (!branckInvert.isEmpty() && branckInvert.peek()) + "\n" + r1); code.Add(r1); return r1; } protected Instruction Branch(Node n, int index) throws Exception { // ArrayList x = n.childrens(); Instruction instruction = null; switch (n.getText()) { case "&&": BranchAnd(n, index); break; case "||": BranchOr(n, index); break; default: instruction = BranchTest(n, index); } if (index == 0 && instruction != null) { } return instruction; // if (and) { // n.remove("or"); // } } protected String Complement(String op) { return Complements.get(op); } // /** // * ProceSSa um teSte logico AND // * // * @param n // * @throws Exception // */ // protected void _and(Node n) throws Exception { // String attrs = "next,start,end,test,skip.test"; // Node b1 = n.getFilho(0).copy(attrs, n); // Node b2 = n.getFilho(1).copy(attrs, n); // //// boolean isFor = n.eq("test.type", "for"); //// System.out.println("_AND{" + isFor + "}:" + n.G(isFor ? "and" : "next")); //// String l = n.G(n.eq("test.type", "for") ? "and" : "next"); // b1.S("true", n.G("next")); //// b1.S("false", b.G("false")); //// System.out.println("_AND:" + label + "-s" + b1); // b2.S("true", n.G("next")); //// b2.S("false", b.G("false")); //// b1.S("true", gerarLabel()); //// b1.S("false", b.G("false")); //// //// b2.S("true", b.G("true")); //// b2.S("false", b.G("false")); // } // /** // * ProceSSa um teSte logico OR // * // * @param n // * @throws Exception // */ // protected void _or(Node n) throws Exception { // // String attrs = "next,start,end,test,skip.test"; // Node b1 = n.getFilho(0).copy(attrs, n); // Node b2 = n.getFilho(1).copy(attrs, n); // // b1.S("true", n.G("start")); // b2.S("true", n.G("start")); // // } /** * Cria uma linha de Salto para PuShLabel eSpecificado no parametro. * * @param label * @throws Exception */ protected void _goto(String label) throws Exception { Instruction r = new Instruction(); r.S("label", label) .S("type", "jump") .S("format", "jump") .set("locker", getIdMaster()); code.Add(r); } /*Inicio das avaliacoes booleanas*/ /** * Gera um linha de inStrução de retorno no block de codigo * * @param n * @throws Exception */ protected void genReturn(Node n) throws Exception { Instruction nreg; ArrayList returns = n.find("exprs").childrens(); for (Node ret : returns) { // System.out.println("Return p:" + ret); nreg = new Instruction() .S("type", "push_return") .S("format", "push_return") .S("p1value", "" + Api.IsValue(ret.getText())) .S("p1", ret.G("_return")); nreg.set("locker", getIdMaster()); code.Add(nreg); } code.Add(new Instruction() .S("type", "return") .S("format", "return") .set("p1", returns.size()) .S("p1value", "true") .set("locker", getIdMaster())); } // // protected String updateLabel(Node n) { // String PushLabel = n.G("_return"); //// if (!PushLabel.substring(0, 1).equals("_R")) { //// } //// n.S("_return", PushLabel); // return PushLabel; // } /** * Gera todoS oS SaltoS de um loop for * * @param n * @throws Exception */ protected void genFor(Node n) throws Exception { String attrs = "next,start,end,inc,test"; Node test = n.find("test").first(); setMaster(n); String start = gerarLabel(), // next = gerarLabel(), end = gerarLabel(), inc = gerarLabel(), testLabel = gerarLabel(); n.S("start", start) .S("end", end) .S("inc", inc) .S("test", testLabel); Node stmt = n.find("stmts"); stmt.copy(attrs, n); test.copy(attrs, n).S("test.type", "jtb"); /*Inicializacoes e atribuicoes*/ visit(n.find("initialization")); /*Salta para o teste do laco*/ _goto(testLabel); /*Marca o inicio do bloco do laco*/ PushLabel(start, "branch"); /*Executa o bloco do for*/ visit(stmt); /*Label que marca os incrementos dos laco*/ PushLabel(inc, "branch"); /*Executa os incrementos*/ visit(n.find("increment")); /*Label que marca o teste do laco*/ PushLabel(testLabel, "branch"); // test.type = ((JumpToBlock in LOOP) | (JumpBlock in IF || SWITCH)) // test.type = JumpToBlock // test.S("test.type", "for").S("next", next).S("end", end).S("or", next); // System.out.println("Teste:" + test); Branch(test, 0); // if (n.Has("set.end_label")) { // PushLabel(n.G("end"), "branch"); PushLabel(end, "branch"); // } setNullMaster(); } // protected void genFor(Node n) throws Exception { // setMaster(n); // String start = gerarLabel(), next = gerarLabel(); // // n.S("next", next); // n.S("start", start); // // Node stmt = n.find("stmts"); // stmt.S("next", start); // /*Inicializacoes e atribuicoes*/ // visit(n.find("initialization")); // // Label que marca o inicio do for // PushLabel(start, "branch"); // // Node test = n.find("test").first(); //// if (test.hasChildrens()) //// test.S("true", gerarLabel()); //// test.S("false", n.G("next")); //// test.S("true", next); //// test.S("false", n.G("next")); // test.S("and", next); // test.S("next", next); // test.S("or", gerarLabel()); // // Branch(test); // // if (test.Has("or")) { // PushLabel(test.G("or"), "branch"); // } // //// PushLabel(test.G("true"), "branch"); // /*Executa o bloco do for*/ // visit(stmt); // /*Executa os incrementos*/ // visit(n.find("increment")); // /*Salta para inicio do laço*/ // _goto(start); // /*Marca o endereço final para sair do laço*/ // PushLabel(test.G("next"), "branch"); // // setNullMaster(); // } protected void genExpArith(Node n) throws Exception { Node op1 = n.childrens.get(0); Node op2 = n.childrens.get(1); String _op = n.getText(); // // // // se os dois valores são // if (op1.eq("type", "value") && op2.eq("type", "value")) { // // n.S("_return", resolveExpr(_op, op1.G("value"), op2.G("value"))); // } // if (op1.isNumber("value") && op2.isNumber("value")) { // // } else { // Inverte a ordem dos operandos se o segundo for seletor e o primeiro for valor if (op1.isNumber("value") && !op2.isNumber("value")) { Node aux = op1; op1 = op2; op2 = aux; } // System.out.println("GerarArit" + op1 + "-" + op2); String _p1 = op1.G("_return"); String _p2 = op2.G("_return"); String _return = gerarVariavel("T"); n.S("_return", _return); Instruction instruction = __exp(_op, _p1, _p2, _return); if (instruction.eq("type", "copy")) { n.S("_p1", instruction.G("p1")); n.S("value", instruction.G("p1")); } else { n.S("_op", _op); n.S("_p1", _p1); n.S("_p2", _p2); } } /** * Para cima verificado <==> */ protected void genArray(Node n) { if (n.eq("raiz", "t")) { currentMatrixvalues = new ArrayList(); matrixValues.put(n.G("id"), currentMatrixvalues); for (Node c : n.childrens()) { genArray(c); } } else if (n.eq("terminal", "t")) { currentMatrixvalues.add(n.getText()); } else { for (Node c : n.childrens()) { genArray(c); } } } protected ArrayList initValues(Node n) { ArrayList values = new ArrayList<>(); switch (n.G("class")) { case "_array": values = matrixValues.get(n.G("id")); break; /*valores e constantes*/ default: String _return = n.G("_return"); if (_return.matches("^_.*")) { _return = "0"; } values.add(_return); } return values; } /** * Gera a chamada para o metodo de deSalocacao de memoria * * @param n * @throws Exception */ protected void genDelete(Node n) throws Exception { for (Node address : n.childrens()) { visit(address); __genParam(address.G("_return")); __gerarCall(Functions.FREE, "1", getIdMaster()); } } /** * Gera a Switch caSe * * @param n */ protected void switchStmt(Node n) throws Exception { /*Label que sera consultado pelo break para sair do case*/ String end = gerarLabel(); String dst = null, next = null; Node test = n.find("test"); n.S("next", end); // Verifica se existe entrada para selecao if (test.childrens().size() > 0) { test = test.first(); visit(test); dst = test.G("_return"); } ArrayList cases = n.findAll("def.case", "class", 1); int id = 0, count = cases.size() - 1; for (Node _case : cases) { if (next != null) { _case.S("start", next); } _case.S("_input", dst); _case.S("end", end); genCase(_case, id == count); next = _case.G("next"); id++; } /*Marca o endereço final para sair do switch*/ PushLabel(end, "branch"); } protected Node NodeBoolExpr(String op, Node e1, Node e2) { return new Node(op) .S("type", "bool") .S("class", "expr") .S("subclass", "bool") .addFilho(e1) .addFilho(e2); } protected ArrayList ExprsEq(Node n, Node input) throws Exception { ArrayList list = new ArrayList<>(); switch (n.Class()) { case "exprs": for (Node e : n.childrens()) { list.add(NodeBoolExpr("==", input, e)); } break; default: list.add(NodeBoolExpr("==", input, n)); } return list; } /** * Gera oS caSeS de um Switch * * @param n */ protected void genCase(Node n, boolean last) throws Exception { String start = n.Has("start") ? n.G("start") : gerarLabel(); String next = gerarLabel(), end; // System.out.println("GenCase:" + start + ":" + next); ArrayList itens = n.childrens(); Node stmts = n.find("stmts"); Node or; if (itens.size() >= 2) { // Tem teste String input = n.G("_input"); Node test = n.first(); ArrayList exprs; if (input != null) { exprs = ExprsEq(test, new Node(input).S("_return", input)); } else { exprs = test.childrens(); } /*Seleciona o endereco de saida se é no proximo case ou no fim do switch*/ if (stmts.last().eq("value", "fallthrough")) { end = gerarLabel(); n.S("next", end); } else { end = n.G("end"); } // Atualiza o PushLabel de sucesso das exprs for (Node expr : exprs) { expr.S("true", !last ? next : end); // expr.S("false", next); // expr.S("false", start); } Branch(OR(exprs).S("next", next), 0); /*Se nenhum dos casos for compativel salta para o proximo*/ // _goto(!last ? next : end); /*Marca o PushLabel inicial do caso*/ PushLabel(start, "branch"); /*Visita o bloco do case*/ visit(stmts); if (!last) { /*Salta para o proximo case ou para o fim do switchcase*/ _goto(end); /*Label do inicio do proximo case*/ PushLabel(next, "branch"); } } else { // Default statiment visit(stmts); } } protected Node OR(ArrayList n) throws Exception { switch (n.size()) { case 0: return null; case 1: return n.get(0); default: Node x = n.get(0); n.remove(x); return NodeBoolExpr("||", x, OR(n)).copy("true,false", x); } } protected int qtdByIndex(Node n) throws Exception { Node indexes = n.find("indexes"); if (indexes == null) { return 1; } else { int sum = 0; for (Node index : indexes.childrens()) { sum += index.getInt("_return"); } return sum; } } /** * Gera inStrução de atribuicao * * @param n * @throws Exception */ protected void genAssign(Node n) throws Exception { ArrayList localAttribs = new ArrayList<>(), // copymode = new ArrayList<>(), // operators = new ArrayList<>(), returns; ArrayList copyaddress = new ArrayList<>(); String p1, declare = "" + n.getText().equals("dec.var.short"); Node dsts = n.childrens().get(0); if (n.in("value", new String[]{"dec.var.short", "def.assign"})) { for (Node attrib : n.childrens().get(1).childrens()) { visit(attrib); // System.out.println("n:" + n); // System.out.println("genAssign:" + attrib.G("class") + ":" + attrib.G("value")); if (attrib.eq("class", "call")) { returns = attrib.getList("returns"); if (returns != null) { for (String _return : returns) { localAttribs.add(_return); copyaddress.add(attrib.eq("subclass", "address")); } } } else if (attrib.eq("class", "index")) { // System.out.println("Attr <- :" + attrib); } else if (attrib.eq("class", "literal")) { // System.out.println("literal<- :" + attrib); switch (attrib.G("subclass")) { case "array": for (Node element : attrib.find("exprs").childrens()) { visit(element); copyaddress.add(element.eq("subclass", "address")); localAttribs.add(element.G("_return")); } break; } } else { // System.out.println("Assign:" + attrib); copyaddress.add(attrib.eq("subclass", "address")); localAttribs.add(attrib.G("_return")); } } } // System.out.println("Copy::" + localAttribs); // System.out.println("Lista de atribuicoes locais:\n" + dsts + "\n>>\n" + n); // System.out.println("Lista de atribuicoes locais:\n" + dsts + "\n>>\n" + localAttribs); // Executa a copia dos valores for (int dstPosition = 0, i = 0; i < localAttribs.size(); dstPosition++) { Node d = dsts.childrens().get(dstPosition); d.S("declare", declare); visit(d); // System.out.println("D:" + d.childrens()); if (d.eq("class", "unary") && d.eq("dst.pointer", "*")) { p1 = localAttribs.get(i); code.Add(new Instruction() .S("format", "pointer_assignment") .S("type", "pointer_assignment") .S("dst", d.childrens().get(1).G("_return")) .S("p1", p1) .S("p1value", "" + Api.IsValue(p1)) .S("dst.pointer", "*") .set("locker", getIdMaster())); i++; // Salva o valor em memoria } else if (d.eq("array", "true")) { for (int j = 0; j < d.getInt("array_size"); j++, i++) { // System.out.println("ARRAY:" + d.G("_return") + "[" + j + "]" + " -- " + localAttribs.get(i)); Copy(d.G("_return") + "[" + j + "]", localAttribs.get(i), copyaddress.get(i)); } } else { // Copia valor para endereco // System.out.println("Attrib:" + d.G("_return") + "<" + localAttribs.get(i)); Copy(d.G("_return"), localAttribs.get(i), copyaddress.get(i)); i++; } } } protected void __genParam(String param) throws Exception { Instruction r = new Instruction(); r.S("format", "push_param") .S("type", "push_param") .S("p1", param) .S("p1value", "" + Api.IsValue(param)) .set("locker", getIdMaster()); code.Add(r); } protected void genFunction(String id, Node func) throws Exception { if (!funcGenMap.containsKey(id)) { funcGenMap.put(id, "true"); Node block = func.find("stmts"); code.OpenBlock(id); /*Cria a PushLabel inicial da funcao*/ PushLabel(id, "block"); /*Declara as variaveis de parametro*/ genPopParams(func); /*Declara as variaveis de retorno caso sejam nomeadas*/ // visit(func.find("def::return")); // System.out.println(Variaveis.printScope(func.G("scope"))); /*Processa o bloco de instrucoes*/ visit(block); /*Cria a PushLabel final da funcao*/ PushLabel(id + "-end", "block"); code.CloseBlock(); } } protected void genCall(Node n) throws Exception { int argsNum = 0; // Se for metodo carrega o contexto no primeiro parametro // System.out.println("GenCall:" + n); if (!n.eq("ctx", "")) { Node var = Variaveis.Get(n.G("ctx")); // System.out.println(""); // __genParam("&" + gerarVariavel(var)); // code.Add(new Instruction() // .S("", PushLabel)); // gerarVariavel(var) __genParam(gerarVariavel(var)); argsNum++; } // Gera os argumentos Node args = n.find("arguments").find("exprs"); if (args != null) { for (Node param : args.childrens()) { // Processa o argumento para obter o _return visit(param); // Cria a instrução de parametro __genParam(param.G("_return")); } argsNum += args.getChildrenCount(); } // System.out.println("GenCall:" + n.getText()); Node def = Functions.Get(n.getText()); genFunction(n.getText(), def); // Cria a instrução de chamada Instruction r = __gerarCall(n.getText(), "" + argsNum, getIdMaster(), def.find("dec.return")); // System.out.println("CALL -> " + r.getList("returns")); n.addList("returns", r.getList("returns")); } protected String UnaryResolve(String op, String value) throws Exception { switch (op) { case "-": return "-" + value; case "!": return "" + (value.equalsIgnoreCase("false") || value.equals("0") ? "1" : "0"); } throw new Exception(String.format("Invalid [%s]%s ", op, value)); } /*Fim dos laços*/ /*Inicio das operacoes aritimeticas*/ /** * Unary pode Ser uma expreSSão do tipo
* (&|*)addreSS - operacao de ponteiroS
* (-) addreSS|value - negação aritimetica
* (!) addreSS|value - negação booleana * * @param n * @throws Exception */ protected void unaryStmt(Node n) throws Exception { String op = n.childrens().get(0).getText().trim(); Node value = n.childrens().get(1); visit(value); String _ret, _val = value.G("_return"); // Se for escrita verifica se é escrita no ponteir ou no lugar referenciado if (Api.IsValue(_val)) { _ret = UnaryResolve(op, _val); // } else { } else if (n.eq("access", "write")) { _ret = "ERR"; n.S("dst.pointer", op); } else { // System.out.println("N:[" + n.G("id") + "]"); _ret = gerarVariavel("T"); // System.out.println("Unary:" + n.childrens().G(1)); String type; if (AddressOperator.matcher(op).matches()) { type = "pointer_assignment"; } else { type = "unary"; } Instruction r = new Instruction() .S("type", type) .S("format", type) .S("dst", _ret) .S("p1", _val) .S("op", op) .S("copymode", "unary") .S("p1value", "" + Api.IsValue(_val)) .set("locker", getIdMaster()); code.Add(r); // System.out.println("N:" + n); // throw new Exception("Unary Stmt not defined"); } n.S("_return", _ret); // System.out.println("UnaryStmt:[" + _val + ":" + op + "]" + n); } protected Integer _ExprResolve(String op, String p1, String p2) throws Exception { int p1v = Integer.parseInt(p1), p2v = Integer.parseInt(p2); switch (op.substring(0, 1)) { case "+": return p1v + p2v; case "-": return p1v - p2v; case "*": return p1v * p2v; case "/": return p1v / p2v; case "%": return p1v % p2v; } return null; } protected Instruction __exp(String op, String p1, String p2, String ret) throws Exception { boolean p1value = Api.IsValue(p1), p2value = Api.IsValue(p2); String unsigned = "false"; if (op.contains("u")) { op = op.replace("u", ""); unsigned = "true"; } Instruction r = new Instruction(); if (p1value && p2value) { r.S("type", "copy") .S("format", "copy") .S("p1value", "true") .S("p1", "" + _ExprResolve(op, p1, p2)); } else { r.S("type", "assign") .S("format", "assign") .S("cat", "exp") .S("p1", p1) .S("p2", p2) .S("copymode", "assign") .S("p1value", "" + p1value) .S("p2value", "" + p2value); // System.out.println("__EXP:"+p1value+":"+p2value); } r.S("dst", ret) .S("op", op) .S("op.unsigned", unsigned) .set("locker", getIdMaster()); return code.Add(r); } /** * Gera Salto para inStruçõeS de continue e break; * * @param n * @throws Exception */ protected void ctrlStmt(Node n) throws Exception { Node container = n.closest("for.stmt,switch.stmt", "class"); switch (n.getText()) { case "continue": String go; if (container.eq("class", "for.stmt")) { go = container.G("inc"); } else { go = container.G("end"); } _goto(go); break; case "break": _goto(container.G("end")); break; case "goto": _goto(n.G("label")); break; } } /** * Executa a extração do codigo baSeado na aSt, e retorna um objeto * CodigoTreSEnderecoS contendo oS blockS em Formato de treS endereçoS. * * @return * @throws Exception */ public Code getCodigoDeTresEnderecos() throws Exception { return run(); } /** * Ativa ou deSativa a otimizacao * * @param lc */ public void setOtimizacao(boolean lc) { code.setOtimizacao(lc); } protected void setMaster(Node n) { master.push(n); } protected Node getMaster() { return master.peek(); } protected void setNullMaster() { master.pop(); } protected int getIdMaster() throws Exception { if (master.empty()) { return 0; } return master.peek().getInt("id"); } /** * Adiciona aS declaraçõeS bem como carregaoS parametroS e referenciaS * * @param n * @throws Exception */ protected void genPopParams(Node func) throws Exception { int reg = 0; String destino, atribuido; /** * Se for method declara e atribui o endereco a variavel */ Node receive = func.find("receive.type"); if (receive != null) { // atribuido = "_A" + (reg++); // destino = clearPointer(atribuido, gerarVariavel(receive.childrens().G(0))); destino = gerarVariavel(receive.childrens().get(0)); // copy_pointer? Copy(Api.clearID(destino), __popParam().G("_return"), false); } for (Node argument : func.find("arguments").childrens()) { for (Node arg : argument.find("ids").childrens()) { /** * Gera uma instrução de copia do registrador a{i},i = [0-4], * para o endereço de memoria dos parametros */ // atribuido = "_Ra" + (reg++); // atribuido = "_A" + (reg++); // System.out.println("PopArg:" + arg); // destino = clearPointer(atribuido, gerarVariavel(arg)); // copy_pointer? Copy(Api.clearID(gerarVariavel(arg)), __popParam().G("_return"), false); } } } protected Instruction __popParam() throws Exception { String varname = gerarVariavel("T"); Instruction r = new Instruction() .S("type", "pop_param") .S("format", "pop_param") .S("p1", varname) .S("p1value", "false") .S("_return", varname); r.set("locker", getIdMaster()); code.Add(r); return r; } // protected void inicializarVariaveis() throws Exception { //// System.out.println("INICIALIZAR VARIAVEIS:"); // // for (Node container : ast.getRoot().childrens()) { // for (Node constant : container.findAll("dec::const,dec::var", "class", 1)) { // visit(constant); // } // } // } protected Instruction Copy(String dst, String src, boolean address) throws Exception { // System.out.println("TAC:Copy:" + dst + "=" + src); String type, format, arrayPattern = ".*\\[.*\\]"; Instruction r = new Instruction(); if (dst.matches(arrayPattern) || src.matches(arrayPattern)) { type = "indexed_assign"; format = "copy"; if (Variaveis.isArray(src)) { r.S("src_indexed", "true"); r.S("p1.indice", Api.getIndice(src)); } if (Variaveis.isArray(dst)) { r.S("dst_indexed", "true"); r.S("dst.indice", Api.getIndice(dst)); } else { r.S("dst_indexed", "false"); } if (Variaveis.isArray(src)) { r.S("indice", Api.getIndice(src)); } } else { type = format = "copy"; } // Identifica que o valor copiado é um endereco ou valor if (address) { r.S("src.address", "true"); } r.S("format", format) .S("type", type) .S("dst", dst) .S("p1", src) .S("p1value", Api.IsValue(src) + "") .set("locker", getIdMaster()); code.Add(r); return r; } /** * Gera um PuShLabel unico * * @param n * @return */ protected String gerarLabel(Node n) { // return code.genLabel(); return code.getCurrentBlockName() + "+_i" + (incLabel++); } protected String gerarLabel() { // return code.genLabel(); return code.getCurrentBlockName() + "+_i" + (incLabel++); } /** * Cria uma linha de PuShLabel no block de codigo corrente * * @param label String * @throws Exception */ protected Instruction PushLabel(String label, String type) throws Exception { Instruction r = new Instruction() .S("label", label) .S("type", "label") .S("label_type", type) .S("format", "label") .set("locker", getIdMaster()); return code.Add(r); } /** * Gera um nome de variavel unico, * * @param pre prefixo da variavel * @param n * @return */ protected String gerarVariavel(String pre) { return "_" + pre + (tmpVarCount++); } protected String gerarVariavel(Node n) throws Exception { String id = n.getText(); if (!varGenMap.containsKey(id)) { varGenMap.put(id, gerarVariavelSet(id, n)); } return varGenMap.get(id); } protected String gerarVariavelSet(String id, Node n) throws Exception { Node var = Variaveis.Get(id); String varname, alias, vn; if (var.eq("constant", "true")) { varname = id; } else { varname = var.getText(); } // System.out.printf("GerarVariavelSet{%s\n,%s\n,%s\n}\n", id, varname, var); // if (var.eq("constant", "true")) { // System.out.printf("GerarVariavelSet{%s\n,%s\n,%s\n}\n", id, varname, var); // } if (varGenMap.containsKey(varname)) { alias = varGenMap.get(varname); // System.out.printf("GerarVariavelSet[MAPPED]{%s,%s}\n", varname, alias); } else { String prefix; // System.out.println("GerarVariavelSet\n" + varname + "\n" + id + "\n" + var); if (var.eq("class", "dec.const")) { prefix = "C"; } else if (var.eq("global", "true")) { prefix = "G"; } else { prefix = "V"; } // System.out.println("DecVar:" + var); // alias = var.G("pointer") + gerarVariavel(prefix); alias = gerarVariavel(prefix); n.S("alias", alias); n.copy("pointer", var); varGenMap.put(varname, alias); // vn = var.G("scope"); int size = Tipos.Size(var.G("type")), b = 1; // Se for um array considera os filhos como index if (!var.eq("constant", "true") && var.childrens().size() > 0) { for (Node node : var.childrens()) { b *= node.getInt("value"); } } size *= b; var.set("size", size); // System.out.println("gerarVariave[" + prefix + "|" + id + "]:" + var); (prefix.equals("G") ? code.GData() : code.Block().Data()).Add(alias, var); } return alias; } /** * Imprime o codigo de treS endereçoS * * @return */ @Override public String toString() { return printVarMap() + code.toString(); } public String printVarMap() { StringBuilder s = new StringBuilder(); for (Map.Entry e : varGenMap.entrySet()) { s.append(e.getKey() + " : " + e.getValue() + "\n"); } System.out.println("Var Map:\n" + s.toString()); return varGenMap.toString(); } /** * Executa a extração da aSt para codigo de treS endereçoS * * @throws Exception */ public void extrair() throws Exception { if (!inicializado) { inicializado = true; } // inicializarVariaveis(); // extrairTraps(); // extrairThreads(); // extractFunctions(); // extracMethods(); main(); } protected Instruction __gerarCall(String funcname, String numparam, int idMaster, Node returns) throws Exception { Instruction call = __gerarCall(funcname, numparam, idMaster); // Atribuição dos enderecos de retorn if (returns != null) { ArrayList rts = new ArrayList<>(); String t; for (Node r : returns.childrens()) { t = gerarVariavel("T"); rts.add(t); code.Add(new Instruction() .S("type", "pop_return") .S("format", "pop_return") .S("p1value", "false") .S("p1", t)); } call.addList("returns", rts); } return call; } /** * Gera inStrução de call * * @param funcname * @param numparam * @param idMaster * @param variavelRetorno * @throws Exception */ protected Instruction __gerarCall(String funcname, String numparam, int idMaster) throws Exception { Instruction r = new Instruction(); r.S("format", "call") .S("type", "call") .S("funcname", funcname) .S("nump", numparam).set("locker", idMaster); // if (!variavelRetorno.equals("")) { // r.S("dst", variavelRetorno); // } code.Add(r); return r; } } // case "||": // and = false; // // Não deve inverter operacao no caso de || // branckInvert.push(and); // // _or(n); // // Branch(x.get(0)); // Branch(x.get(1)); // // // Inverte a ultima operacao // if (n.parent.eq("value", "||")) { // } // //// if (!loop && branckInvert.size() == 1) { //// Instruction last = code.Last(); //// last.S("op", Complement(last.G("op"))).S("label", n.G("next")); //// } // if (!x.get(0).Has("and")) { // n.remove("and"); // } // branckInvert.pop(); // // break; // default: //// boolean empty = branckInvert.isEmpty(); //// //// if (empty) { //// branckInvert.push(true); //// } // // visit(n); // // Resultado do test class ou acesso a um id ou bool // if (!n.eq("class", "expr")) { // op = "=="; // p0 = n.G("_return"); // p1 = "1"; // } else { //(<, <=, >, >=, ==, !=) // p0 = visit(x.get(0)).G("_return"); // p1 = visit(x.get(1)).G("_return"); // } // // Instruction instruction = Branch(op, p0, p1, n.G("next")); //// instruction. ; //// if (n.Has("false")) { // // _goto(n.G("false")); // // } // // if (empty) { // // branckInvert.pop(); // // } // @Override // public TacGenInterface AfterCreate(CodeProcessing p) { // this.afterCreate.add(p); // return this; // } // // public TacGenInterface AfterCreate() throws Exception { // for (CodeProcessing x : afterCreate) { // x.Exec(code); // } // return this; // }