1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650 |
- package IntermediaryCode;
- import API.Api;
- import API.Functions;
- import API.Types;
- import API.Utils;
- import API.Variables;
- import ast.AbstractSyntaxTree;
- import ast.Node;
- import common.Block;
- import common.Code;
- import common.DataLayout;
- import common.Instruction;
- 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;
- /**
- *
- * @author Eugenio
- */
- public final class IRGenerator implements IRGenInterface {
- protected int jb = 0;
- protected int incLabel = 0;
- protected int tmpVarCount = 1;
- protected boolean inicializado = false;
- protected boolean enableOtimization = true;
- protected AbstractSyntaxTree ast;
- protected Code code;
- protected Node calEndAtt;
- protected String label;
- protected String calEndVar;
- protected String calEndSize;
- protected String calEndTipo;
- protected Pattern ArrayPatternRegex = Pattern.compile(".*\\[.*\\]");
- protected Stack<Node> master = new Stack<>();
- protected ArrayList<String> line = new ArrayList<>();
- protected LinkedList<Boolean> branckInvert = new LinkedList<>();
- protected HashMap<String, String> arrayAcesso = new HashMap<>();
- protected HashMap<String, String> varGenMap = new HashMap<>();
- protected HashMap<String, String> funcGenMap = new HashMap<>();
- protected HashMap<String, Integer> systemCalls = new HashMap<>();
- protected ArrayList<String> currentMatrixvalues = new ArrayList<>();
- protected HashMap<String, ArrayList<String>> matrixValues = new HashMap<>();
- protected HashMap<String, String> ArrayShiftMap = new HashMap<>();
- protected Stack<String> loopScope = new Stack<String>() {
- {
- push("");
- }
- };
- protected LinkedHashMap<String, Long> power2 = new LinkedHashMap<String, Long>() {
- {
- for (long i = 0; i < 31; i++) {
- put(Long.toString(Long.valueOf(1 << i)), Long.valueOf(i));
- }
- }
- };
- public static Pattern AddressOperator = Pattern.compile("(\\&|\\*)");
- public static Pattern TemporaryAlias = Pattern.compile("_(T|S)");
- protected String[] primitives = Types.getPrimitiveTypesList();
- public IRGenerator() throws Exception {
- }
- public IRGenerator(AbstractSyntaxTree ast) throws Exception {
- Ast(ast);
- }
- protected int calc(ArrayList<Integer> 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 void Ast(AbstractSyntaxTree ast) throws Exception {
- this.ast = ast;
- code = new Code("IR", ast);
- //Registra o bloco global
- code.OpenBlock("global");
- Block block = code.Block();
- // Seta o bloco como bloco de controle
- block.Type(Block.TYPE_CTRL);
- // Atribui o contexto do bloco ao contexto global
- code.GlobalContext(block.Context());
- // Encerra o bloco
- code.CloseBlock();
- code.ControlInstructions = "label,alloc".split(",");
- // Especifica o template engine
- code.Template(new IRTemplate());
- }
- @Override
- public Code Create(AbstractSyntaxTree ast) throws Exception {
- Ast(ast);
- Code code = run();
- // Executa todos os tratametos definidos apos geracao do codigo
- printVarMap();
- code.Print();
- return code;
- }
- protected Node visit(Node n) throws Exception {
- if (null == n || n.eq("visited", "true")) {
- return n;
- }
- n.Set("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().Set("msg", "DECVAR." + n));
- if (n.find("exprs") != null) {
- n.Set("class", "dec.var.short").Set("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);
- n.Set("_return", CreateVar(Variables.Get(n.getText())));
- }
- protected void test(Node n) throws Exception {
- Node x = null;
- ArrayList<Node> 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 = CreateVar(n.findByClass("selector"));
- operacao.Set("type", "assign")
- .Set("format", "assign")
- .Set("cat", "exp")
- .Set("_return", "exp")
- .Set("dst", dst)
- .Set("p1", dst)
- .Set("p2", "1")
- .Set("p1value", "" + Api.IsValue(dst))
- .Set("p2value", "true")
- .Set("op", n.findByClass("operator").eq("value", "++") ? "+" : "-");
- Add(operacao);
- }
- protected void Selector(Node n) throws Exception {
- String tmp;
- String shift = null;
- n.Set("copymode", "copy");
- switch (n.Get("subclass")) {
- case "operand":
- if (n.eq("classType", "value")) {
- // n.Set("value", Api.Value(n.getText()));
- n.Set("_return", Api.Value(n.getText()));
- } else {
- String v = CreateVar(n);
- if (n.eq("pointer", "*") && n.eq("access", "read")) {
- String t = CreateTmpVar();
- Copy(t, v, false);
- v = t;
- }
- n.Set("_return", v);
- }
- // System.out.println("Seletor operand:" + n);
- break;
- case "index":
- // shift = n.childrens().Get(0).GetInt("value");
- // shift = n.childrens().Get(0).GetInt("value");
- shift = ArrayShift(n);
- case "selector":
- if (shift == null) {
- shift = "" + Variables.Shift(n.getText());
- }
- tmp = CreateVar(n) + "[" + shift + "]";
- if (!n.eq("access", "write")) {
- String t = CreateTmpVar();
- Copy(t, tmp, false);
- tmp = t;
- }
- n.Set("_return", tmp);
- break;
- case "arguments":
- break;
- }
- }
- protected ArrayList<Integer> ShiftPath(int size) {
- ArrayList<Integer> ret = new ArrayList<>();
- FindShiftPath(size, ret);
- return ret;
- }
- protected ArrayList<Integer> ShiftInterval(int size) {
- ArrayList<Integer> 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 void FindShiftPath(int size, ArrayList<Integer> path) {
- size = Math.abs(size);
- ArrayList<Integer> shift = ShiftInterval(size);
- int op = shift.get(2), s1 = shift.get(op);
- // System.out.println("FindShiftPath:(" + power2.containsKey("" + s1) + "|" + size + "|" + s1 + ")\t\t" + shift);
- // System.out.println(power2);
- if (power2.containsKey("" + s1)) {
- path.add(s1);
- path.add(op);
- }
- if (size == 1) {
- // path.add(size);
- }
- // System.out.println("Pathj:" + path);
- 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 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()) {
- // System.out.println("ArrayShift:" + node);
- key += "_" + node.getText();
- }
- // System.out.println("@@@@@@@@@@ARRAY_SHIFT :" + key);
- // if (!ArrayShiftMap.containsKey(key)) {
- // String shift;
- Node var = Variables.Get(n.getText());
- // System.out.println("INDEX shift:" + n + var);
- for (int i = 0, j = 1; j < var.childrens().size(); j++) {
- n.childrens().get(i++).Set("collNumber", var.childrens().get(j).getText());
- }
- String ret = CalcArrayAddress(n.childrens(), Types.Size(var.Get("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, CreateAlias(n), ret);
- // shift = ret;
- // }
- // ArrayShiftMap.put(key, ret);
- // }
- ////
- // return ArrayShiftMap.get(key);
- return ret;
- }
- protected String GenShiftLeftLogical(String var, int size, boolean mps, boolean last) throws Exception {
- ArrayList<Integer> path = ShiftPath(size);
- ArrayList<Integer> 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, last);
- return var;
- }
- protected long pow2(long p) {
- return pow2("" + p);
- }
- protected long pow2(String p) {
- return power2.get(p);
- }
- protected String GSLL(String var, ArrayList<Integer> path, boolean mps, int size, boolean last) throws Exception {
- int op1, operacao, op2;
- // String T1 = CreateTmpVar(),
- String T1 = var,
- T2 = CreateTmpVar();
- // T3 = CreateTmpVar();
- switch (path.size()) {
- case 1:
- if (!mps) {
- // Copy(T1, var, false)
- // .Set("comment", "Copy value of index M1")
- // .Set("copy", "true");
- } else {
- T1 = var;
- }
- if (!last) {
- // System.out.println("GSLL:" + size + ":" + pow2(size));
- __exp("<<", T1, "" + pow2(size), T2);
- return T2;
- }
- return T1;
- case 3:
- op1 = path.remove(0);
- operacao = path.remove(0);
- op2 = path.remove(0);
- // String T4 = CreateTmpVar();
- if (!mps) {
- Copy(T1, var, false)
- .Set("comment", "Copy value of index M3")
- .Set("copy", "true");
- }
- if (op1 != 1) {
- __exp("<<", T1, "" + pow2(op1), T1);
- }
- // if (op2 == 1) {
- // } else {
- // Copy(T3, var, false).Set("comment", "Copy value of index");
- if (op2 != 1) {
- __exp("<<", T1, "" + (pow2(op2) - pow2(op1)), T2);
- // deve realizar um novo deslocamento
- } else {
- T2 = T1;
- }
- // Soma o deslocamento com o tamanho
- __exp("+", T1, T2, T1).Set("comment", "");
- return T1;
- default:
- // op1 = path.remove(0);
- // operacao = path.remove(0);
- //
- // T2 = GSLL(var, path);
- //
- // Copy(T1, var, false).Set("comment", "Copy value of index");
- //
- // __exp("<<", T1, "" + pow2(op1), T1).Set("comment", "");
- // __exp("+", T1, T2, T1).Set("comment", "");
- }
- return var;
- }
- protected String CalcArrayAddress(ArrayList<Node> 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, false);
- }
- }
- protected Integer CalcArrayAddressNumber(ArrayList<Node> 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<Node> childrens, int Size) throws Exception {
- // boolean multPerSize = true;
- int collNumber;
- Node ind, nextIndex;
- ind = childrens.remove(0);
- // System.out.println("CalcArrayAddressAux:" + childrens.size() + ":" + Size + "\n" + ind);
- String current, varname;
- if (ind.eq("class", "expr")) {
- varname = CreateTmpVar();
- Node p1 = visit(ind.childrens().get(0)),
- p2 = visit(ind.childrens().get(1));
- __exp(ind.getText(), p1.Get("_return"), p2.Get("_return"), varname);
- } else {
- varname = CreateVar(ind);
- }
- // if (ind)
- // ultimo elemento da idexacao
- if (childrens.size() == 0) {
- if (Utils.IsNumber(ind.getText())) {
- return "" + ind.GetInt("value");
- } else {
- return GenShiftLeftLogical(varname, Size, false, true);
- }
- }
- 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);
- } else {
- current = GenShiftLeftLogical(varname, collNumber, false, false);
- }
- String ret = CalcArrayAddressAux(childrens, Size);
- __exp("+u", current, ret, current).Set("comment", "colls shift");
- return current;
- }
- /**
- * ProceSSa um node:<br>
- * Ordem:<br>
- * ->Primeiro filhoS;<br>
- * ->No principal;<br>
- *
- * @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:<br>
- * Ordem:<br>
- * ->Primeiro filho;<br>
- * ->No principal;<br>
- * ->Segundo filho;<br>
- *
- * @param n
- * @throws Exception
- */
- protected void visitNoMeio(Node n) throws Exception {
- visit(n.getFilho(0));
- processarNode(n);
- visit(n.getFilho(1));
- }
- /**
- * ProceSSa um node:<br>
- * Ordem:<br>
- * ->No princial;<br>
- * ->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<br>
- * [inteiro, booleano e char]
- *
- * @param n
- * @throws Exception
- */
- protected void gerarConstante(Node n) throws Exception {
- // System.out.println("Gerando constant:" + n.childrens().Get(0) + n.childrens().Get(1));
- // CreateAlias(n.Get(label, label));
- // getLabel("C", n);
- // if (n.closest("block", "class") != null) {
- // code.registerVar(n.Get("_return"), 1, DataLayout.TYPE_VAR);
- // }
- }
- /**
- * Executa a extração fo block principal
- *
- * @throws Exception
- */
- public boolean main() throws Exception {
- Node main = ast.getMain();
- if (main != null) {
- // main.Set("_return", Threads.getId("main"));
- Node stmts = main.find("stmts");
- if (stmts.childrens().size() > 0 && code.OpenBlock("main")) {
- // basicBlock.push("main");
- // basicBlockCount.push(0);
- PushLabel("main", "block");
- visit(stmts);
- PushLabel("main-end", "block");
- // basicBlock.pop();
- // basicBlockCount.pop();
- code.CloseBlock();
- return true;
- }
- }
- return false;
- }
- public Code run() throws Exception {
- if (!inicializado) {
- inicializado = true;
- if (!main()) {
- //Se a função main não possui statments gera o codigo para as outras funcoes
- ArrayList<Node> functions = ast.getRoot().findAll("dec.func", "class", 0);
- for (Node n : functions) {
- // System.out.println("Gen Func:" + funcGenMap + n);
- // genFunction("main." + n.getText(), n);
- genFunction(n.getText(), n);
- }
- }
- }
- // Atualiza as posivos de todas as instruções e labels
- code.UpdatePositions();
- return code;
- }
- // Atualiza as posivos de todas as instruções e labels
- protected void UpdatePositions() {
- Block b;
- // Reseta a posicao inicial;
- code.PosicaoLabel = 0;
- for (Map.Entry<String, Block> x : code.Blocks().entrySet()) {
- b = x.getValue();
- b.CurrentAddress = 0;
- for (Instruction n : b.Instructions()) {
- // System.out.println("Update->:" + CurrentAddress + ":" + code.Position());
- switch (n.Get("type")) {
- case "label":
- n.Set("reference.position", b.CurrentAddress)
- .Set("global.reference.position", code.Position());
- code.RegisterLabelAddress(n.Get("label"));
- case "alloc":
- break;
- default:
- n.Set("block.position", b.CurrentAddress)
- .Set("block.position.origin", b.CurrentAddress++)
- .Set("global.position", code.PositionInc());
- }
- }
- }
- }
- /**
- * ProceSSa If (ElSe'Set)*
- *
- * @param n
- * @throws Exception
- */
- protected void IfStmts(Node n) throws Exception {
- String end = gerarLabel(), next;
- int size = n.childrens().size(), last = size - 1, current = 0;
- boolean ifChain = size > 1;
- //(If)+ (else)?
- next = ifChain ? gerarLabel() : end;
- n.Set("next", next).Set("end", end);
- for (Node stmt : n.childrens()) {
- switch (stmt.Class()) {
- case "if.case.stmt":
- IfCaseStmt(n, stmt, ifChain, (current == last));
- current++;
- break;
- // Else case
- case "stmts":
- // String next = gerarLabel();
- // n.Set("next", next);
- visit(stmt.Set("next", next));
- // Cria um PushLabel final
- // PushLabel(n.Get("end"), "branch");
- // PushLabel(end);
- break;
- }
- }
- // Cria um PushLabel final
- // System.out.println("Label end:" + n.Get("end"));
- PushLabel(n.Get("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, boolean last) throws Exception {
- Node test = _if.first();
- String testType = "jb";
- if (test.childrens().size() > 1) {
- visit(test.childrens().get(0));
- test = test.last();
- } else {
- test = test.first();
- }
- Node stmts = _if.find("stmts");
- // Se o teste falha deve saltar o bloco
- n.Set("start", gerarLabel());
- test.Set("test.type", testType).Copy("next,start,end", n);
- Branch(test, 0);
- // marca com um label o inicio do bloco do if
- PushLabel(n.Get("start"), "branch");
- // gera as instruções do bloco
- visit(stmts);
- // se for uma cadeia de condiçoes com ou sem else
- if (ifChain) {
- if (!last) {
- // Salta os outros testes
- _goto(n.Get("end"));
- }
- //Adiciona o label de proximo elemento da cadeia de if's e else
- PushLabel(n.Get("next"), "branch");
- //Atualiza o ponteiro para o proximo elemento
- n.Set("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 {
- visit(n.childrens().get(0));
- visit(n.childrens().get(1));
- // System.out.println("VisitExpr:" + n);
- switch (n.Get("subclass")) {
- case "arith":// ( + | - | * | / ) integer
- genExpArith(n);
- break;
- }
- }
- protected void BranchAnd(Node n, int index) throws Exception {
- // int pos = 0;
- // if (n.parent == null) {
- // System.out.println("BranchAnd:" + n);
- // }
- // OrTestAndOccurrence++;
- Instruction instruction = null;
- ArrayList<Node> x = n.childrens();
- Node op1 = x.get(0), op2 = x.get(1);
- String type = n.Get("test.type"),
- step = gerarLabel(),
- attrs = "next,end,inc,test.type,skip.test";
- n.Set("skip.test", step);
- op1.Copy(attrs, n);
- op2.Copy(attrs, n);
- instruction = Branch(op1, 1);
- if (instruction != null) {
- switch (type) {
- case "jtb":
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- if (n.parent != null && n.parent.eq("value", "||")) {
- if (index == 1) {
- UpdateLabel(instruction, n.parent.Get("skip.test"));
- } else if (index == 2) {
- UpdateLabel(instruction, n.parent.Get("end"));
- }
- // } else if (n.parent.eq("value", "&&")) {
- } else {
- UpdateLabel(instruction, n.Get("end"));
- }
- break;
- case "jb":
- // if (n.parent != null) {
- if (n.parent != null && n.parent.eq("value", "||")) {
- if (index <= 1) {
- UpdateLabel(instruction, n.parent.Get("skip.test"));
- } else if (index == 2) {
- // instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("next"));
- }
- }
- // } else {
- // }
- }
- }
- // System.out.println("instruction Branch 1:" + instruction + "\n" + op1);
- // if (index == 0 || (op1.in("value", new String[]{"||", "&&"}) && !n.eq("value", op1.Get("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 != null && n.parent.eq("value", "||")) {
- if (index == 1) { // teste 1 do parametro 2 com pai ||
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("end"));
- } else if (index == 2) { // teste 2 do parametro 2
- UpdateLabel(instruction, n.Get("next"));
- }
- // } 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.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- // UpdateLabel(instruction, n.Get("end"));
- // }
- } else {
- if (index == 1) { // teste 1 do parametro 2 geral
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("end"));
- } else if (index == 2) {
- // throw new Exception("teste 2 do parametro 2 geral");
- }
- }
- break;
- case "jb":
- // System.out.println("I(jb:and:2)[" + index + "]\n" + instruction + "\n" + n);
- // if (n.parent != null) {
- if (n.parent != null && n.parent.eq("value", "||")) {
- if (index <= 1) {
- // UpdateLabel(instruction, n.parent.Get("skip.test"));
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("start"));
- } else if (index == 2) {
- // instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("next"));
- }
- }
- // } else {
- // }// } else {
- // }
- }
- }
- }
- public void UpdateLabel(Instruction I, String label) {
- String copy = I.Get("label");
- if (!copy.equals("")) {
- code.RemoveLabelReference(copy);
- }
- I.Set("label", label);
- code.AddLabelReference(label);
- }
- protected void BranchOr(Node n, int index) throws Exception {
- // if (n.parent == null) {
- // System.out.println("BranchOr:" + n);
- // }
- // int pos = 0;
- // OrTestAndOccurrence++;
- Instruction instruction = null;
- ArrayList<Node> x = n.childrens();
- Node op1 = x.get(0), op2 = x.get(1);
- String type = n.Get("test.type"),
- step = gerarLabel(),
- attrs = "next,start,end,inc,test.type,skip.test";
- n.Set("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 != null && n.parent.eq("value", "&&")) {
- if (index == 1) {
- UpdateLabel(instruction, n.parent.Get("skip.test"));
- }
- }
- break;
- case "jb":
- // System.out.println("I(jb:1)[" + index + "]\n" + instruction + "\n" + n);
- // System.out.println("Entrei no jb ||" + (jb++) + instruction + n.parent);
- // if (n.parent != null) {
- if (n.parent != null && n.parent.eq("value", "||")) {
- // if (index == 2) {
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("start"));
- // }
- } else if (n.parent != null && n.parent.eq("value", "&&")) {
- if (index <= 1) {
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.parent.Get("skip.test"));
- } else if (index == 2) {
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.parent.Get("start"));
- }
- // }
- } else {
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- if (index <= 1) {
- UpdateLabel(instruction, n.Get("start"));
- } else if (index == 2) {
- }
- }
- }
- }
- // 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 != null && n.parent.eq("value", "&&")) {
- if (index == 1) {
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.parent.Get("end"));
- }
- }
- break;
- case "jb":
- // if (n.parent != null) {
- if (n.parent != null && n.parent.eq("value", "||")) {
- if (index <= 1) {
- instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("start"));
- } else if (index == 2) {
- //
- // instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- UpdateLabel(instruction, n.Get("next"));
- }
- } else if (n.parent != null && n.parent.eq("value", "&&")) {
- if (index == 1) {
- // instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- // UpdateLabel(instruction, n.parent.Get("start"));
- } else if (index == 2) {
- // instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- // UpdateLabel(instruction, n.parent.Get("start"));
- }
- // }
- } else {
- // instruction.Set("op", Utils.ComplementOperation(instruction.Get("op")));
- // UpdateLabel(instruction, n.Get("next"));
- }
- }
- }
- }
- protected Instruction BranchTest(Node n, int index) throws Exception {
- ArrayList<Node> x = n.childrens();
- String type = n.Get("test.type");
- boolean invert = false;
- String op, p0, p1;
- switch (type) {
- case "jb":
- invert = true;
- break;
- case "jtb":
- 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.Get("_return");
- p1 = "1";
- } else { //(<, <=, >, >=, ==, !=)
- op = n.getText();
- p0 = visit(x.get(0)).Get("_return");
- p1 = visit(x.get(1)).Get("_return");
- }
- // Inverte o teste e salta o bloco
- if (invert) {
- op = Utils.ComplementOperation(op);
- }
- // return Branch(op, p0, p1, next);
- Instruction r1 = new Instruction().Set("label", n.Get("next"));
- Boolean p0IsValue = Api.IsValue(p0), p1IsValue = Api.IsValue(p1);
- if (p0IsValue && p1IsValue) {
- // Se a expressão for resolvivel e o resultado é positivo
- // A instrução de saldo é adicionada
- if (Utils.ResolveExprBool(op, p0, p1)) {
- Add(r1.Set("type", "jump").Set("format", "jump"));
- }
- } else {
- Add(r1.Set("format", "branch")
- .Set("type", "branch")
- .Set("op", op)
- .Set("p1", p0)
- .Set("p2", p1)
- .Set("p1value", "" + p0IsValue)
- .Set("p2value", "" + Api.IsValue(p1)));
- }
- // System.out.println("Add branch:" + branckInvert.peek() + branckInvert + ">>" + (!branckInvert.isEmpty() && branckInvert.peek()) + "\n" + r1);
- return r1;
- }
- protected Instruction Store(String addr, String src) throws Exception {
- Instruction add = Add(new Instruction()
- .Set("type", "store")
- .Set("format", "store")
- .Set("dst", blockVarAliasCtx.peek().Reverse(addr))
- .Set("p1", src));
- if (!addr.equals(src)) {
- // System.out.println("Store:" + addr + ":" + src);
- blockVarAliasCtx.peek().SetLoaded(addr, false);
- }
- return add;
- }
- protected Instruction Load(String attr, String dst) throws Exception {
- blockVarAliasCtx.peek().SetLoaded(attr);
- return Add(new Instruction()
- .Set("type", "load")
- .Set("format", "load")
- .Set("dst", dst)
- .Set("p1", blockVarAliasCtx.peek().Reverse(attr)));
- }
- protected Instruction Branch(Node n, int index) throws Exception {
- Instruction instruction = null;
- switch (n.getText()) {
- case "&&":
- BranchAnd(n, index);
- break;
- case "||":
- BranchOr(n, index);
- break;
- default:
- instruction = BranchTest(n, index);
- }
- return instruction;
- }
- /**
- * 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.Set("label", label)
- .Set("type", "jump")
- .Set("format", "jump")
- .Set("locker", getIdMaster());
- 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<Node> returns = n.find("exprs").childrens();
- for (Node ret : returns) {
- // System.out.println("Return p:" + ret);
- nreg = new Instruction()
- .Set("type", "push_return")
- .Set("format", "push_return")
- .Set("p1value", "" + Api.IsValue(ret.getText()))
- .Set("p1", ret.Get("_return"));
- nreg.Set("locker", getIdMaster());
- Add(nreg);
- }
- Add(new Instruction()
- .Set("type", "return")
- .Set("format", "return")
- .Set("p1", returns.size())
- .Set("p1value", "true")
- .Set("locker", getIdMaster()));
- }
- /**
- * Gera todoS oS SaltoS de um loop for
- *
- * @param n
- * @throws Exception
- */
- protected void genFor(Node n) throws Exception {
- String attrs = "next,end,inc,test";
- loopScope.push(n.Get("scope"));
- setMaster(n);
- String next = gerarLabel(),
- // next = gerarLabel(),
- end = gerarLabel(),
- inc = gerarLabel(),
- testLabel = gerarLabel();
- n.Set("next", next)
- .Set("end", end)
- .Set("inc", inc)
- .Set("test", testLabel);
- Node stmt = n.find("stmts");
- stmt.Copy(attrs, n);
- boolean hasTest = false;
- Node t = n.find("test"), test = null;
- if (t.childrens().size() > 0) {
- hasTest = true;
- test = t.first();
- test.Copy(attrs, n).Set("test.type", "jtb");
- }
- /*Inicializacoes e atribuicoes*/
- visit(n.find("initialization"));
- if (hasTest) {
- /*Salta para o teste do laco*/
- _goto(testLabel);
- }
- /*Marca o inicio do bloco do laco*/
- PushLabel(next, "branch");
- /*Executa o bloco do for*/
- visit(stmt);
- /*Label que marca os incrementos dos laco*/
- if (code.CountReferenceLabel(inc) > 0) {
- PushLabel(inc, "branch");
- }
- /*Executa os incrementos*/
- visit(n.find("increment"));
- // test.type = ((JumpToBlock in LOOP) | (JumpBlock in IF || SWITCH))
- // test.type = JumpToBlock
- // test.Set("test.type", "for").Set("next", next).Set("end", end).Set("or", next);
- // System.out.println("Teste:" + test);
- if (hasTest) {
- /*Label que marca o teste do laco*/
- PushLabel(testLabel, "branch");
- Branch(test, 0);
- } else {
- _goto(next);
- }
- if (code.CountReferenceLabel(end) > 0) {
- PushLabel(end, "branch");
- }
- setNullMaster();
- loopScope.pop();
- }
- // protected void genFor(Node n) throws Exception {
- // setMaster(n);
- // String start = gerarLabel(), next = gerarLabel();
- //
- // n.Set("next", next);
- // n.Set("start", start);
- //
- // Node stmt = n.find("stmts");
- // stmt.Set("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.Set("true", gerarLabel());
- //// test.Set("false", n.Get("next"));
- //// test.Set("true", next);
- //// test.Set("false", n.Get("next"));
- // test.Set("and", next);
- // test.Set("next", next);
- // test.Set("or", gerarLabel());
- //
- // Branch(test);
- //
- // if (test.Has("or")) {
- // PushLabel(test.Get("or"), "branch");
- // }
- //
- //// PushLabel(test.Get("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.Get("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();
- // System.out.println("Gen genExpArith:" + _op);
- //
- //
- // // se os dois valores são
- // if (op1.eq("type", "value") && op2.eq("type", "value")) {
- //
- // n.Set("_return", resolveExpr(_op, op1.Get("value"), op2.Get("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.Get("_return");
- String _p2 = op2.Get("_return");
- String _return = CreateTmpVar();
- n.Set("_return", _return);
- Instruction instruction = __exp(_op, _p1, _p2, _return);
- if (instruction.eq("type", "copy")) {
- n.Set("_p1", instruction.Get("p1")).Set("value", instruction.Get("p1"));
- } else {
- n.Set("_op", _op).Set("_p1", _p1).Set("_p2", _p2);
- }
- }
- /**
- * Para cima verificado <==>
- */
- protected void genArray(Node n) {
- if (n.eq("raiz", "t")) {
- currentMatrixvalues = new ArrayList<String>();
- matrixValues.put(n.Get("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<String> initValues(Node n) {
- ArrayList<String> values = new ArrayList<>();
- switch (n.Get("class")) {
- case "_array":
- values = matrixValues.get(n.Get("id"));
- break;
- /*valores e constantes*/
- default:
- String _return = n.Get("_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.Get("_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 start,
- next,
- end = gerarLabel(),
- dst = null;
- n.Set("next", end);
- Node test = n.find("test");
- // Verifica se existe entrada para selecao
- if (test.childrens().size() > 0) {
- test = test.first();
- visit(test);
- dst = test.Get("_return");
- }
- // test;
- ArrayList<Node> cases = n.findAll("def.case", "class", 1);
- int current = 0, last = cases.size() - 1;
- for (Node _case : cases) {
- start = gerarLabel();
- next = gerarLabel();
- _case.Set("start", start)
- .Set("_input", dst)
- .Set("next", next)
- .Set("end", end)
- .Set("test.type", "jb");
- genCase(_case, current == last);
- current++;
- }
- /*Marca o endereço final para sair do switch*/
- PushLabel(end, "branch");
- }
- /**
- * Gera oS caSeS de um Switch
- *
- * @param n
- */
- protected void genCase(Node n, Boolean last) throws Exception {
- ArrayList<Node> exprs;
- Node test;
- // System.out.println("GEN_CASE:" + n);
- // String start = n.Has("start") ? n.Get("start") : gerarLabel();
- // String next = gerarLabel(), end;
- //
- //// System.out.println("GenCase:" + start + ":" + next);
- ArrayList<Node> itens = n.childrens();
- Node stmts = n.find("stmts");
- // Node or;
- //
- if (itens.size() >= 2) { // Tem teste
- test = n.first();
- String input = n.Get("_input"),
- start = n.Get("start"),
- end = n.Get("end"),
- next = n.Get("next");
- //
- if (input != null) {
- exprs = ExprsEq(test, new Node(input).Set("_return", input));
- } else {
- exprs = test.childrens();
- }
- // // Atualiza o PushLabel de sucesso das exprs
- for (Node expr : exprs) {
- expr.Copy("start,next,end,test.type", n);
- }
- //
- Branch(OR(exprs).Set("next", next), 0);
- /*Se nenhum dos casos for compativel salta para o proximo*/
- /*Marca o PushLabel inicial do caso*/
- PushLabel(start, "branch");
- /*Visita o bloco do case*/
- visit(stmts);
- // System.out.println("Gen case :" + last);
- 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);
- }
- // String start = n.Has("start") ? n.Get("start") : gerarLabel();
- // String next = gerarLabel(), end;
- //
- //// System.out.println("GenCase:" + start + ":" + next);
- // ArrayList<Node> itens = n.childrens();
- // Node stmts = n.find("stmts");
- // Node or;
- //
- // if (itens.size() >= 2) { // Tem teste
- // String input = n.Get("_input");
- // Node test = n.first();
- // ArrayList<Node> exprs;
- //
- // if (input != null) {
- // exprs = ExprsEq(test, new Node(input).Set("_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.Set("next", end);
- // } else {
- // end = n.Get("end");
- // }
- //
- // // Atualiza o PushLabel de sucesso das exprs
- // for (Node expr : exprs) {
- // expr.Set("true", !last ? next : end);
- //// expr.Set("false", next);
- //// expr.Set("false", start);
- // }
- //
- // Branch(OR(exprs).Set("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 NodeBoolExpr(String op, Node e1, Node e2) {
- return new Node(op)
- .Set("type", "bool")
- .Set("class", "expr")
- .Set("subclass", "bool")
- .addFilho(e1)
- .addFilho(e2);
- }
- protected ArrayList<Node> ExprsEq(Node n, Node input) throws Exception {
- ArrayList<Node> 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;
- }
- protected Node OR(ArrayList<Node> 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("start,next,end,test.type", 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 {
- // System.out.println("GENAssign :" + n);
- ArrayList<Node> localExpr = new ArrayList<>();
- ArrayList<String> localAttribs = new ArrayList<>(),
- // copymode = new ArrayList<>(),
- // operators = new ArrayList<>(),
- returns;
- ArrayList<Boolean> copyaddress = new ArrayList<>();
- String p1,
- modify = n.Get("modify"),
- declare = "" + n.getText().equals("dec.var.short");
- // System.out.println("genAssign:" + n.childrens().Get(0).childrens().Get(0));
- 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()) {
- // System.out.println(">n:" + attrib);
- visit(attrib);
- // System.out.println("n:" + attrib);
- // System.out.println("genAssign:" + attrib.Get("class") + ":" + attrib.Get("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.Get("subclass")) {
- case "array":
- for (Node element : attrib.find("exprs").childrens()) {
- visit(element);
- copyaddress.add(element.eq("subclass", "address"));
- localAttribs.add(element.Get("_return"));
- }
- break;
- }
- } else {
- // System.out.println("Assign:" + attrib);
- copyaddress.add(attrib.eq("subclass", "address"));
- localAttribs.add(attrib.Get("_return"));
- }
- localExpr.add(attrib);
- }
- }
- // 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);
- Node attrib;
- // Executa a copia dos valores
- for (int dstPosition = 0, i = 0; i < localAttribs.size(); dstPosition++) {
- Node d = dsts.childrens().get(dstPosition);
- d.Set("declare", declare);
- visit(d);
- // System.out.println("D:" + d);
- if (d.eq("class", "unary") && d.eq("dst.pointer", "*")) {
- p1 = localAttribs.get(i);
- Add(new Instruction()
- .Set("format", "pointer_assign")
- .Set("type", "pointer_assign")
- .Set("dst", d.childrens().get(1).Get("_return"))
- .Set("p1", p1)
- .Set("p1value", "" + Api.IsValue(p1))
- .Set("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.Get("_return") + "[" + j + "]" + " -- " + localAttribs.Get(i));
- // Copy(d.Get("_return") + "[" + j + "]", localAttribs.get(i), copyaddress.get(i));
- Store(
- d.Get("_return") + "[" + j + "]",
- localAttribs.get(i)
- );
- }
- } else {
- // Copia valor para endereco
- // System.out.println("Attrib[" + modify + ":" + (modify.equals("")) + "]:" + d.Get("_return") + "<" + localAttribs.Get(i));
- if (!modify.equals("")) {
- __exp(modify, d.Get("_return"), localAttribs.get(i), d.Get("_return")).Set("comment", "");
- } else {
- attrib = localExpr.get(i);
- //// if (attrib.eq("class", "expr")) {
- ////// System.out.println("Attrib:" + attrib);
- //// __exp(attrib.Get("_op"), attrib.Get("_p1"), attrib.Get("_p2"), d.Get("_return")).Set("comment", "");
- //// } else {
- // Copy(d.Get("_return"), localAttribs.get(i), copyaddress.get(i));
- //// }
- // System.out.println("blockVarAliasCtx.peek(" + d.Get("_return") + "):" + blockVarAliasCtx.peek().Reverse(d.Get("_return")));
- Store(
- d.Get("_return"),
- localAttribs.get(i)
- );
- }
- i++;
- }
- }
- }
- protected void __genParam(String param) throws Exception {
- Instruction r = new Instruction();
- r.Set("format", "push_param")
- .Set("type", "push_param")
- .Set("p1", param)
- .Set("p1value", "" + Api.IsValue(param))
- .Set("locker", getIdMaster());
- Add(r);
- }
- protected void genFunction(String id, Node func) throws Exception {
- if (!funcGenMap.containsKey(id)) {
- funcGenMap.put(id, "true");
- // Empilha um novo contexto de variaveis
- blockVarAliasCtx.add(new BlockVarMap());
- Node block = func.find("stmts");
- // basicBlock.push(id);
- // basicBlockCount.push(0);
- 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(Variables.printScope(func.Get("scope")));
- /*Processa o bloco de instrucoes*/
- visit(block);
- /*Cria a PushLabel final da funcao*/
- PushLabel(id + "-end", "block");
- code.CloseBlock();
- //Desempilha o contexto de variaveis para a funcao anteriro
- blockVarAliasCtx.pop();
- // basicBlock.pop();
- // basicBlockCount.pop();
- }
- }
- 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 = Variables.Get(n.Get("ctx"));
- // System.out.println("");
- // __genParam("&" + CreateAlias(var));
- // Add(new Instruction()
- // .Set("", PushLabel));
- // CreateAlias(var)
- __genParam(CreateVar(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.Get("_return"));
- }
- argsNum += args.getChildrenCount();
- }
- // System.out.println("GetMETHOD" + n.getText());
- Node def = Functions.Get(n.getText());
- String id = def.getText();
- // System.out.println("GenCall:" + id + "\n" + def);
- genFunction(id, def);
- code.Block().AddDependence(id);
- // Cria a instrução de chamada
- Instruction r = __gerarCall(id, "" + 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 <br>
- * (&|*)addreSS - operacao de ponteiroS <br>
- * (-) addreSS|value - negação aritimetica <br>
- * (!) 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.Get("_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.Set("dst.pointer", op);
- } else {
- // System.out.println("N:[" + n.Get("id") + "]");
- _ret = CreateTmpVar();
- // System.out.println("Unary:" + n.childrens().Get(1));
- String type;
- if (AddressOperator.matcher(op).matches()) {
- type = "pointer_assign";
- } else {
- type = "unary";
- }
- Instruction r = new Instruction()
- .Set("type", type)
- .Set("format", type)
- .Set("dst", _ret)
- .Set("p1", _val)
- .Set("op", op)
- .Set("copymode", "unary")
- .Set("p1value", "" + Api.IsValue(_val))
- .Set("locker", getIdMaster());
- Add(r);
- // System.out.println("N:" + n);
- // throw new Exception("Unary Stmt not defined");
- }
- n.Set("_return", _ret);
- // System.out.println("UnaryStmt:[" + _val + ":" + op + "]" + n);
- }
- 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.Set("type", "copy")
- .Set("format", "copy")
- .Set("p1value", "true")
- .Set("p1", "" + Utils.ResolveExpr(op, p1, p2));
- } else {
- r.Set("type", "assign")
- .Set("format", "assign")
- .Set("cat", "exp")
- .Set("p1", p1)
- .Set("p2", p2)
- .Set("copymode", "assign")
- .Set("p1value", "" + p1value)
- .Set("p2value", "" + p2value);
- // System.out.println("__EXP:" + r);
- }
- r.Set("dst", ret)
- .Set("op", op)
- .Set("op.unsigned", unsigned)
- .Set("locker", getIdMaster());
- return Add(r);
- }
- /**
- * Gera Salto para inStruçõeS de continue e break;
- *
- * @param n
- * @throws Exception
- */
- protected void ctrlStmt(Node n) throws Exception {
- String go;
- Node ctn = n.closest("for.stmt,switch.stmt", "class");
- switch (n.getText()) {
- case "continue":
- go = ctn.Get(ctn.eq("class", "for.stmt") ? "inc" : "end");
- break;
- case "break":
- go = ctn.Get("end");
- break;
- case "goto":
- go = n.Get("label");
- break;
- default:
- throw new Exception("Undefined ctrl stmt '" + n.getText() + "'.");
- }
- _goto(go);
- }
- /**
- * 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, id;
- /**
- * 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, CreateAlias(receive.childrens().Get(0)));
- destino = CreateVar(receive.childrens().get(0));
- // copy_pointer?
- // Copy(Api.clearID(destino), __popParam().Get("_return"), false);
- __popParam(destino);
- }
- 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, CreateAlias(arg));
- // copy_pointer?
- // id = Api.clearID(CreateAlias(arg));
- // Copy(id, __popParam(id).Get("_return"), false);
- __popParam(CreateVar(arg));
- }
- }
- }
- protected Instruction __popParam(String varname) throws Exception {
- // String varname = CreateTmpVar();
- // varname = Api.clearID(varname);
- varname = blockVarAliasCtx.peek().Reverse(varname);
- // System.out.println("Pop_Param:::::::" + varname + "::" + blockVarAliasCtx.peek());
- Instruction param = Add(new Instruction()
- .Set("type", "pop_param")
- .Set("format", "pop_param")
- .Set("p1", varname)
- // .Set("p1", blockVarAliasCtx.peek().Reverse(varname))
- .Set("p1value", "false")
- .Set("_return", varname));
- // System.out.println("POP_PARAM:" + param);
- return param;
- }
- // 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 {
- // String type;
- // Boolean dstIndexed = ArrayPatternRegex.matcher(dst).matches(),
- // srcIndexed = ArrayPatternRegex.matcher(src).matches();
- // if (dstIndexed || srcIndexed) {
- //
- // type = "indexed_assign";
- //
- //// inst.Set("src_indexed", srcIndexed);
- // inst.Set("src.indexed", srcIndexed);
- // inst.Set("dst.indexed", dstIndexed);
- //
- // if (srcIndexed) {
- // inst.Set("p1.indice", Api.getIndice(src));
- // inst.Set("indice", Api.getIndice(src));
- // }
- //
- // if (dstIndexed) {
- // inst.Set("dst.indice", Api.getIndice(dst));
- // }
- if (ArrayPatternRegex.matcher(dst).matches()) {
- // System.out.println("@@@@Copy Store:" + dst + ":" + src);
- return Store(dst, src).Set("comment", String.format("Indexed copy %s <- %s", dst, src));
- } else if (ArrayPatternRegex.matcher(src).matches()) {
- // System.out.println("@@@Load Store:" + dst + ":" + src);
- return Load(src, dst);
- } else {
- // Identifica que o valor copiado é um endereco ou valor
- return Add(new Instruction()
- .Set("format", "copy")
- .Set("type", "copy")
- .Set("src.address", address)
- .Set("dst", dst)
- .Set("p1", src));
- }
- }
- /**
- * Gera um PuShLabel unico
- *
- * @return
- */
- 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()
- .Set("label", label)
- .Set("type", "label")
- .Set("label_type", type)
- .Set("format", "label")
- .Set("locker", getIdMaster());
- return Add(r);
- }
- /**
- * Gera um nome de variavel unico,
- *
- * @param pre prefixo da variavel
- * @param n
- * @return
- */
- protected String CreateAlias(String pre) {
- return "_" + pre + (tmpVarCount++);
- }
- protected String CreateTmpVar() {
- return CreateAlias("T");
- }
- protected String CreateSavedVar() {
- return CreateAlias("S");
- }
- protected String CreateVar(Node n) throws Exception {
- String id = n.getText(), alias;
- String[] g;
- if (!varGenMap.containsKey(id)) {
- g = SetNewVar(id, n);
- alias = g[0];
- // System.out.println("id:" + id + "|g:" + alias);
- // if (alias.equals("_G5")) {
- // System.out.println("@@@@@@@@@@@@@@@ :" + id + " >>> " + alias + "::" + n.Get("id"));
- // }
- varGenMap.put(id, alias);
- if (varGenMap.containsKey(alias)) {
- if (id.length() < varGenMap.get(alias).length()) {
- varGenMap.put(alias, id);
- }
- } else {
- varGenMap.put(alias, id);
- }
- // Se for uma constante
- if (g[1].equals("t")) {
- return alias;
- }
- }
- id = varGenMap.get(id);
- BlockVarMap block = blockVarAliasCtx.peek();
- if (!block.Defined(id)) {
- block.Put(id, CreateSavedVar());
- // System.out.println("SET VAR (" + id + ")" + block.Get(id));
- }
- return block.Get(id);
- }
- protected String[] SetNewVar(String id, Node n) throws Exception {
- Node var = Variables.Get(id);
- String uniqPath, alias, prefix;
- Integer elementCount;
- if (var == null) {
- throw new Exception(String.format("Var %s não definida", id));
- }
- // Se for uma constante retorna o valor
- if (var.eq("constant", "true")) {
- return new String[]{var.Get("default.value"), "t"};
- }
- // uniqPath = var.Get("scope") + "." + var.Get("name");
- uniqPath = var.Get("name");
- // System.out.println("UNIQUEPATH:" + uniqPath);
- // uniqPath = id;
- // System.out.println("$$$$$$$$$$$$4 VarName:" + uniqPath + "\n\n" + var);
- if (var.Has("alias")) {
- // Se a variavel possui um alias definido
- alias = var.Get("alias");
- } else if (varGenMap.containsKey(uniqPath)) {
- // Se a variavel possui um alias definido no mapa de variaveis
- alias = varGenMap.get(uniqPath);
- } else {
- // Cria um novo alias para a variavel
- if (var.eq("global", "true")) {
- prefix = "G";
- } else {
- // System.out.println("SETVAR" + var);
- String[] nameparts = var.Get("name").split("\\.");
- prefix = "V" + nameparts[nameparts.length - 1]
- .toUpperCase()
- .replace("_", "")
- .replace(" ", "");
- }
- alias = CreateAlias(prefix);
- varGenMap.put(uniqPath, alias);
- if (varGenMap.containsKey(alias)) {
- if (uniqPath.length() < varGenMap.get(alias).length()) {
- varGenMap.put(alias, uniqPath);
- }
- } else {
- varGenMap.put(alias, uniqPath);
- }
- var.Set("alias", alias);
- // .Set("size", Types.Size(var.Get("type")));
- n.Copy("pointer,alias", var);
- // vn = var.Get("scope");
- elementCount = 1;
- // System.out.println("var:" + var);
- // System.out.println("gerarVariavelSetVAR:" + var);
- // Se for um array considera os filhos como index
- if (var.eq("array", "true") && var.childrens().size() > 0) {
- for (Node node : var.childrens()) {
- elementCount *= (node.eq("constant", "true")
- ? node.GetInt("default.value")
- : node.GetInt("value"));
- }
- }
- Alloc(var, elementCount);
- // System.out.println(">>>>>>>>>gerarVariavelSet(" + alias + "):" + var);
- // if (!isConstant || !var.in("type", primitives)) {
- // // Adiciona variaveis no frame global ou da funcao
- // } else {
- // alias = var.Get("default.value");
- // }
- }
- return new String[]{alias, "f"};
- }
- //
- // protected void DefineAliasInScope(String id, String alias, String scope) {
- //
- // String tmp = id.replace(scope, ""),
- // path = scope + "",
- // ;
- //
- //
- //// Matcher matcher = Pattern.compile(Variables.VARNAME).matcher(id);
- //// if (matcher.find()) {
- //// varname = matcher.group();
- //// }
- //// System.out.println("DefineAliasInScope:\n " + id + ":\n " + scope + "\n: " + tmp + "\n: '" + varname + "'");
- ////
- //// matcher = Pattern.compile(Variables.SCOPE_LEVE).matcher(tmp);
- ////
- //// while (matcher.find()) {
- //// scope += matcher.group(0);
- //// System.out.println("parh:" + scope);
- //// path = scope;
- //// }
- // }
- protected void Alloc(Node var, Integer numElements) throws Exception {
- DataLayout ctx;
- Instruction alloc;
- String alias = var.Get("alias"), type = var.Get("type");
- Boolean global = alias.contains("_G");
- if (global) {
- ctx = code.GlobalContext();
- } else {
- ctx = code.Block().Context();
- }
- if (!ctx.contains(alias)) {
- // System.out.println("Alloc(" + code.Block().getName() + "):" + alias + " > Numero:" + numElements);
- alloc = new Instruction()
- .Set("type", "alloc")
- .Set("format", "alloc")
- .Set("p1", alias)
- .Set("p1.type", type)
- .Set("numElements", numElements)
- .Set("locker", getIdMaster());
- if (global) {
- // Adiciona a alocacao no bloco global
- code.Blocks().get("global").Add(alloc);
- } else {
- // Adiciona a alocacao no bloco atual
- code.Add(1, alloc);
- }
- ctx.Add(alias, type, numElements);
- }
- }
- /**
- * 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<String, String> e : varGenMap.entrySet()) {
- s.append(e.getKey() + " : " + e.getValue() + "\n");
- }
- System.out.println("Var Map:\n" + s.toString());
- return varGenMap.toString();
- }
- 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<String> rts = new ArrayList<>();
- String t;
- for (Node r : returns.childrens()) {
- t = CreateTmpVar();
- rts.add(t);
- Add(new Instruction()
- .Set("type", "pop_return")
- .Set("format", "pop_return")
- .Set("p1value", "false")
- .Set("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.Set("format", "call")
- .Set("type", "call")
- .Set("funcname", funcname)
- .Set("numParams", numparam).Set("locker", idMaster);
- Add(r);
- return r;
- }
- // protected void basicBlockSet(Instruction inst) throws Exception {
- //// String type = inst.Get("type");
- //
- // if (resetOnNextAdd || inst.eq("type", "label")) {
- // System.out.println("Reset por (" + resetOnNextAdd + ") or era label");
- // blockVarAliasCtx.peek().Reset();
- // resetOnNextAdd = false;
- // return;
- // }
- //// switch (inst.Get("type")) {
- //// case "jump":
- //// case "call":
- //// case "goto":
- //// case "branch":
- //// resetOnNextAdd = true;
- //// }
- // }
- protected Instruction Add(Instruction inst) throws Exception {
- Instruction load = null;
- String value;
- String[] parts;
- String type, paramValue;
- // basicBlockSet(inst);
- if (inst.eq("type", "label")) {
- blockVarAliasCtx.peek().Reset();
- ArrayShiftMap = new HashMap<>();
- }
- boolean temporary,
- ignore = !inst.in("type", new String[]{"jump", "goto", "label"});
- // Inseri a carga dos parametros
- if (ignore) {
- //Update types of address
- for (String param : new String[]{"dst", "p1", "p2"}) {
- if (!inst.Has(param)) {
- continue;
- }
- type = "int32";
- paramValue = inst.Get(param);
- if (varGenMap.containsKey(paramValue)) {
- type = Variables.TypeOf(varGenMap.get(paramValue));
- // System.out.println("Check type for " + paramValue + "|" + varGenMap.get(paramValue) + "|" + type);
- }
- inst.Set(param + ".type", type);
- if (!inst.Has(param + "value")) {
- inst.Set(param + "value", Api.IsValue(paramValue) + "");
- }
- }
- // if (!inst.in("type", "load,store".split(","))) {
- if (!inst.in("type", "load,pop_param".split(","))) {
- // load params when necessary
- for (String param : new String[]{"p1", "p2"}) {
- if (!inst.Has(param)) {
- continue;
- }
- temporary = inst.contem(param, "_T");
- paramValue = inst.Get(param);
- // temporary = paramValue.matches("_(T|S)\\d*");
- // System.out.println("Temporary(" + paramValue + "):" + temporary);
- // System.out.println("Param(" + param + "|" + paramValue + "):" + inst.eq(param + "value", "false"));
- if (!temporary && !inst.eq(param + "value", "true")) {
- if (!blockVarAliasCtx.peek().Loaded(paramValue)) {
- load = Load(
- paramValue, // Esse atributo sera reverdido para o endereco da variavel
- paramValue
- ).Set("comment", "Load param (" + param + ":" + paramValue + ")");
- }
- }
- }
- }
- }
- // Se a instrução adicionada for uma copia e o parametro foi carregado
- // Atualiza o destino para o destino da copia e não adiciona a copia
- if (inst.eq("type", "copy") && load != null) {
- load.Set("dst", inst.Get("dst"));
- return load;
- } else {
- // Adiciona a instrução
- code.Add(inst
- .Set("inloop", loopScope.peek())
- .Set("locker", getIdMaster())
- );
- }
- //
- // if (inst.eq("type", "store")) {
- // System.out.println("Add store" + inst);
- // blockVarAliasCtx.peek().SetLoaded(inst.Get("p1"), false);
- // }
- // System.out.println("entrei do loop - " + inst.Get("type"));
- for (String param : "dst,p1,p2".split(",")) {
- if (inst.Has(param)) {
- value = inst.Get(param);
- // System.out.println("value:(" + param + ")" + value + ":" + inst);
- parts = value.split("\\[");
- if (parts.length > 1) {
- // System.out.println("Set " + param + ".indexed: true");
- // System.out.println("Set " + param + ".indice:" + parts[1].replace("]", ""));
- // System.out.println("param.concat(\".indexed\"):" + param.concat(".indexed"));
- inst.Set(param.concat(".indexed"), "true")
- .Set(param.concat(".indice"), parts[1].replace("]", ""));
- //// i.Set(param + ".indice", parts[1].replace("]", ""));
- }
- }
- }
- if (!inst.in("type", "store,load".split(","))) {
- // Se existe um destino e ele não for temporario
- // persiste o valor copiado para o destino
- // if (inst.Has("dst") && !inst.Get("dst").split("\\[")[0].contains("_T")) {
- if (inst.Has("dst") && !inst.Get("dst").split("\\[")[0].contains("_T")) {
- // if (i.Has("dst") && !i.Get("dst").matches("^_T\\d+(\\[\\w+\\])?")) {
- // String dst = Utils.clearName(inst.Get("dst"));
- // dst = blockVarAliasCtx.peek().Reverse(dst);
- // System.out.println("dst:" + dst);
- // System.out.println("TYPE OF1:" + dst);
- // System.out.println("TYPE OF2:" + varGenMap.get(dst));
- // System.out.println("TYPE OF3" + Variables.TypeOf(varGenMap.get(dst)));
- Store(inst.Get("dst"), inst.Get("p1"));
- if (inst.eq("dst.indexed", "true")) {
- // //Se o destino for indexdo sempre é um byte
- inst.Set("dst.type", "byte");
- // i.Set("dst.type", "byte");
- }
- }
- }
- switch (inst.Get("type")) {
- case "jump":
- case "call":
- case "goto":
- case "branch":
- // resetOnNextAdd = true;
- blockVarAliasCtx.peek().Reset();
- ArrayShiftMap = new HashMap<>();
- }
- return inst;
- }
- protected Stack<BlockVarMap> blockVarAliasCtx = new Stack<BlockVarMap>() {
- {
- add(new BlockVarMap());
- }
- };
- protected boolean resetOnNextAdd = false;
- private static class BlockVarMap {
- protected static String prefix = "@";
- protected HashMap<String, String> map = new HashMap<>();
- protected HashMap<String, Boolean> loaded = new HashMap<>();
- public BlockVarMap() {
- }
- public void Put(String var, String alias) {
- // System.out.println("$$$$$$$$$$$$$$$$ PUT " + var + " : " + alias);
- var = Utils.clearName(var);
- map.put(var, alias);
- map.put(prefix + alias, var);
- }
- public boolean Defined(String var) {
- var = Utils.clearName(var);
- return map.containsKey(var) || map.containsKey(prefix + var);
- }
- public String Get(String var) {
- var = Utils.clearName(var);
- return map.get(var) + FixIndex(var);
- }
- public String Reverse(String alias) {
- // System.out.println("$$$$$$$$$$$$$$$$ Get Reverse of " + (prefix + Utils.clearName(alias)) + " | " + map);
- return map.get(prefix + Utils.clearName(alias)) + FixIndex(alias);
- }
- public void Reset() {
- // System.out.println("$$$$$$$$$$$$$$$$ RESET ");
- map = new HashMap<>();
- loaded = new HashMap<>();
- }
- @Override
- public String toString() {
- return map.toString();
- }
- protected boolean Loaded(String alias) {
- // System.out.println("$$$$$$$$$$$$$$$$ LOADED " + alias + " : " + (loaded.containsKey(alias) && loaded.get(alias)));
- return loaded.containsKey(alias) && loaded.get(alias);
- }
- protected void SetLoaded(String alias) {
- SetLoaded(alias, true);
- }
- private void SetLoaded(String alias, boolean b) {
- // System.out.println("$$$$$$$$$$$$$$$$ SetLoaded:" + alias + ":" + b);
- loaded.put(alias, b);
- }
- protected String FixIndex(String alias) {
- String i = Api.getIndice(alias);
- if (!i.equals("")) {
- return "[" + i + "]";
- }
- return "";
- }
- }
- }
|