BaseTacGen.java 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package IntermediaryCode;
  7. import API.Api;
  8. import API.Functions;
  9. import API.Instruction;
  10. import API.Tipos;
  11. import API.Utils;
  12. import API.Variaveis;
  13. import ast.AbstractSyntaxTree;
  14. import ast.Node;
  15. import java.util.ArrayList;
  16. import java.util.HashMap;
  17. import java.util.LinkedHashMap;
  18. import java.util.LinkedList;
  19. import java.util.Map;
  20. import java.util.Stack;
  21. import java.util.regex.Pattern;
  22. // a0 a1
  23. // sync recebe mandando
  24. // exec recebe mandando
  25. // synexec recebe mandando
  26. // Atualizei as labels mas não atualizei as referencias por isso esta sendo removida quando faz a limpeza
  27. /**
  28. *
  29. * @author Eugenio
  30. */
  31. public final class BaseTacGen implements TacGenInterface {
  32. protected boolean inicializado = false;
  33. protected int incLabel = 0;
  34. protected int tmpVarCount = 1;
  35. // protected int OrTestAndOccurrence = 0;
  36. protected AbstractSyntaxTree ast;
  37. protected Code code;
  38. protected Node calEndAtt;
  39. protected Node compileParams;
  40. protected String label;
  41. protected String calEndVar;
  42. protected String calEndSize;
  43. protected String calEndTipo;
  44. protected Stack<Node> master = new Stack<>();
  45. protected ArrayList<String> line = new ArrayList<>();
  46. protected LinkedList<Boolean> branckInvert = new LinkedList<>();
  47. protected HashMap<String, String> arrayAcesso = new HashMap<>();
  48. protected HashMap<String, String> varGenMap = new HashMap<>();
  49. protected HashMap<String, String> funcGenMap = new HashMap<>();
  50. protected HashMap<String, Integer> systemCalls = new HashMap<>();
  51. protected ArrayList<String> currentMatrixvalues = new ArrayList<>();
  52. protected HashMap<String, ArrayList<String>> matrixValues = new HashMap<>();
  53. // protected ArrayList<CodeProcessing> afterCreate = new ArrayList<CodeProcessing>();
  54. protected HashMap<String, String> Complements = new HashMap<String, String>() {
  55. {
  56. put("!=", "==");
  57. put("==", "!=");
  58. put("<", ">=");
  59. put("<=", ">");
  60. put(">", "<=");
  61. put(">=", "<");
  62. }
  63. };
  64. public static Pattern AddressOperator = Pattern.compile("(\\&|\\*)");
  65. protected boolean enableOtimization = true;
  66. protected HashMap<String, String> ArrayShiftMap = new HashMap<>();
  67. private int jb = 0;
  68. public BaseTacGen() throws Exception {
  69. for (long i = 0; i < 31; i++) {
  70. power2.put(Long.toString(Long.valueOf(1 << i)), Long.valueOf(i));
  71. }
  72. }
  73. protected int calc(ArrayList<Integer> data) {
  74. Integer op1, op2, operacao;
  75. switch (data.size()) {
  76. case 1:
  77. return data.get(0);
  78. case 3:
  79. op1 = data.remove(0);
  80. operacao = data.remove(0);
  81. op2 = data.remove(0);
  82. if (operacao == 1) {
  83. return op1 - op2;
  84. // throw new Exception("Quantidade de entradas invalidas!" + data.size());
  85. } else {
  86. return op1 + op2;
  87. }
  88. default:
  89. op1 = data.remove(0);
  90. operacao = data.remove(0);
  91. if (operacao == 1) {
  92. return op1 - calc(data);
  93. // throw new Exception("Quantidade de entradas invalidas!" + data.size());
  94. } else {
  95. return op1 + calc(data);
  96. }
  97. }
  98. }
  99. public BaseTacGen(AbstractSyntaxTree ast) {
  100. for (long i = 0; i < 31; i++) {
  101. power2.put(Long.toString(Long.valueOf(1 << i)), Long.valueOf(i));
  102. }
  103. Ast(ast);
  104. }
  105. public void Ast(AbstractSyntaxTree ast) {
  106. this.ast = ast;
  107. code = new Code("TAC", ast);
  108. code.AfterClose("clear.1", new CodeClearProcessor());
  109. code.AfterClose("oti.1", new CodeOtimizadorProcessor(enableOtimization));
  110. // code.AfterClose("oti.1", new CodeOtimizadorProcessor(false));
  111. compileParams = ast.BuildParams();
  112. code.Template(new template.Template())
  113. .Formats(new HashMap<String, String>() {
  114. {
  115. String base = "{[PAD(global.position,_addressLen,' ')]':'}{[T(1)]}{[PAD(block.position,_addressLen,' ')]':'}{[T(2)]}";
  116. String end = "{[T(2)]}{' T< '[type]' >'}";
  117. put("label", "{[PAD(global.position,_addressLen,' ')]':'}{[T(2)]}{'<'[label]'>'}':'");
  118. put("assign", base + "{[dst]}' := '{[p1]}{' '[op]' '}{[p2]}{' --'[comment]}" + end);
  119. put("pointer_assignment", base + "{[dst.pointer]}{[dst]' := '}{[op]}{[p1]}{' --'[comment]}" + end);
  120. put("unary", base + " {[dst]} ' := '{[op]' '}{[p1]} {' --'[comment]}" + end);
  121. put("copy", base + " {[dst]} ' := '{[p1]} {' --'[comment]}" + end);
  122. put("jump", base + " 'goto ' {'<'[label]'>'} {' --'[comment]}" + end);
  123. put("branch", base + " 'if '{[p1]} {' '[op]' '} {[p2]} ' goto ' {'<'[label]'>'} {' --'[comment]}" + end);
  124. put("call", base + " {[dst]' := '} 'call <' {[funcname]} '>, ' {[nump]} {' --'[comment]}" + end);
  125. put("return", base + " 'return ' {[p1]} {' --'[comment]}" + end);
  126. put("push_param", base + " 'push_param '{[p1]} {' --'[comment]}" + end);
  127. put("push_return", base + " 'push_return '{[p1]} {' --'[comment]}" + end);
  128. put("pop_param", base + " 'pop_param '{[p1]} {' --'[comment]}" + end);
  129. put("pop_return", base + " 'pop_return '{[p1]} {' --'[comment]}" + end);
  130. }
  131. });
  132. }
  133. // public void DeclareConstants(Node root) throws Exception {
  134. //// System.out.println("DeclareConstants() ...");
  135. // for (Node constants : root.findAll("dec.const", "class", 0)) {
  136. //// System.out.println("Declare constant ..." + constants);
  137. // visit(constants);
  138. // }
  139. // }
  140. @Override
  141. public Code Create(AbstractSyntaxTree ast, HashMap<String, String> settings) throws Exception {
  142. Ast(ast);
  143. // DeclareConstants(ast.getRoot());
  144. // setOtimizacao(settings.G("clearCode").equals("true"));
  145. Code code = run();
  146. // Executa todos os tratametos definidos apos geracao do codigo
  147. // AfterCreate();
  148. printVarMap();
  149. // code.PrintData();
  150. code.Print();
  151. code.printOcorrences();
  152. return code;
  153. }
  154. protected Node visit(Node n) throws Exception {
  155. if (null == n || n.eq("visited", "true")) {
  156. return n;
  157. }
  158. n.S("visited", "true");
  159. // System.out.println("Visit:" + n.Class());
  160. switch (n.Class()) {
  161. case "dec.const":
  162. gerarConstante(n);
  163. break;
  164. case "if.stmt":
  165. IfStmts(n);
  166. break;
  167. case "selector":
  168. Selector(n);
  169. break;
  170. case "dec.var":
  171. // Log.PrintInfo("TAC", new Instruction().S("msg", "DECVAR." + n));
  172. if (n.find("exprs") != null) {
  173. n.S("class", "dec.var.short")
  174. .S("value", "dec.var.short");
  175. genAssign(n);
  176. break;
  177. }
  178. case "def.assign":
  179. genAssign(n);
  180. break;
  181. case "call":
  182. genCall(n);
  183. break;
  184. case "ID":
  185. genID(n);
  186. break;
  187. case "incdec":
  188. IncDecStmt(n);
  189. break;
  190. case "for.stmt":
  191. genFor(n);
  192. break;
  193. case "expr":
  194. _visitExpr(n);
  195. break;
  196. case "unary":
  197. unaryStmt(n);
  198. break;
  199. case "switch.stmt":
  200. switchStmt(n);
  201. break;
  202. case "test":
  203. test(n);
  204. break;
  205. case "return":
  206. visitChildrensFirst(n);
  207. break;
  208. default:
  209. visitRootFirst(n);
  210. break;
  211. }
  212. return n;
  213. }
  214. protected void genID(Node n) throws Exception {
  215. // System.out.println("GenId:" + n);
  216. Node var = Variaveis.Get(n.getText());
  217. n.S("_return", gerarVariavel(var));
  218. }
  219. protected void test(Node n) throws Exception {
  220. Node x = null;
  221. ArrayList<Node> chils = n.childrens();
  222. int size = chils.size();
  223. for (int i = 0; i < size; i++) {
  224. x = chils.get(i);
  225. visit(x);
  226. }
  227. n.copy("_return", x);
  228. }
  229. protected void IncDecStmt(Node n) throws Exception {
  230. Instruction operacao = new Instruction();
  231. String dst = gerarVariavel(n.findByClass("selector"));
  232. operacao.S("type", "assign")
  233. .S("format", "assign")
  234. .S("cat", "exp")
  235. .S("_return", "exp")
  236. .S("dst", dst)
  237. .S("p1", dst)
  238. .S("p2", "1")
  239. .S("p1value", "" + Api.IsValue(dst))
  240. .S("p2value", "true")
  241. .S("op", n.findByClass("operator").eq("value", "++") ? "+" : "-");
  242. code.Add(operacao);
  243. }
  244. protected void Selector(Node n) throws Exception {
  245. String tmp;
  246. String shift = null;
  247. n.S("copymode", "copy");
  248. switch (n.G("subclass")) {
  249. case "operand":
  250. if (n.eq("classType", "value")) {
  251. // n.S("value", Api.Value(n.getText()));
  252. n.S("_return", Api.Value(n.getText()));
  253. } else {
  254. String v = gerarVariavel(n);
  255. if (n.eq("pointer", "*") && n.eq("access", "read")) {
  256. String t = gerarVariavel("T");
  257. Copy(t, v, false);
  258. v = t;
  259. }
  260. n.S("_return", v);
  261. }
  262. // System.out.println("Seletor operand:" + n);
  263. break;
  264. case "index":
  265. // shift = n.childrens().G(0).getInt("value");
  266. // shift = n.childrens().G(0).getInt("value");
  267. shift = ArrayShift(n);
  268. case "selector":
  269. if (shift == null) {
  270. shift = "" + Variaveis.Shift(n.getText());
  271. }
  272. tmp = gerarVariavel(n) + "[" + shift + "]";
  273. if (!n.eq("access", "write")) {
  274. String t = gerarVariavel("T");
  275. Copy(t, tmp, false);
  276. tmp = t;
  277. }
  278. n.S("_return", tmp);
  279. break;
  280. case "arguments":
  281. break;
  282. }
  283. }
  284. protected ArrayList<Integer> ShiftPath(int size) {
  285. ArrayList<Integer> ret = new ArrayList<>();
  286. FindShiftPath(size, ret);
  287. return ret;
  288. }
  289. protected ArrayList<Integer> ShiftInterval(int size) {
  290. ArrayList<Integer> ret = new ArrayList<>();
  291. Integer op = 1, i = 1, after, before;
  292. //
  293. while (true) {
  294. after = 1 << (i++);
  295. if (after == size) {
  296. before = after;
  297. break;
  298. } else if (after > size) {
  299. before = after >> 1;
  300. break;
  301. }
  302. }
  303. // before = Math.abs(before - size);
  304. // after = Math.abs(after - size);
  305. if (Math.abs(before - size) <= Math.abs(after - size)) {
  306. // Se o valor anterios for menor que o posterior
  307. op = 0;
  308. }
  309. // else {
  310. // // Se o valor posterior for menor que o anterior
  311. // }
  312. ret.add(before);
  313. ret.add(after);
  314. ret.add(2, op);
  315. // System.out.println("Interval:{" + size + "}" + ret + "::" + op);
  316. return ret;
  317. }
  318. protected LinkedHashMap<String, Long> power2 = new LinkedHashMap<String, Long>();
  319. protected void FindShiftPath(int size, ArrayList<Integer> path) {
  320. size = Math.abs(size);
  321. ArrayList<Integer> shift = ShiftInterval(size);
  322. int op = shift.get(2), s1 = shift.get(op);
  323. // System.out.println("FindShiftPath:(" + power2.containsKey("" + s1) + "|" + size + "|" + s1 + ")\t\t" + shift);
  324. // System.out.println(power2);
  325. if (power2.containsKey("" + s1)) {
  326. path.add(s1);
  327. path.add(op);
  328. }
  329. if (size == 1) {
  330. // path.add(size);
  331. }
  332. // System.out.println("Pathj:" + path);
  333. if (path.size() % 2 == 0 && Math.abs(size - s1) == 0) {
  334. path.remove(path.size() - 1);
  335. return;
  336. }
  337. FindShiftPath(size - s1, path);
  338. // int i = 1, after, before;
  339. // while (true) {
  340. // after = 1 << (i++);
  341. // if (after == size) {
  342. //
  343. // break;
  344. // } else if (after > size) {
  345. // break;
  346. // }
  347. // }
  348. // before = after >> 1;
  349. //
  350. // if (Math.abs(size - before) < Math.abs(after - size)) {
  351. // // Se o valor anterios for menor que o posterior
  352. // op = 1;
  353. // m4 = before;
  354. // } else {
  355. // // Se o valor posterior for menor que o anterior
  356. // op = 0;
  357. // m4 = after;
  358. // }
  359. // FindShiftPath(size, m4, op, path);
  360. }
  361. protected int Size(String type) {
  362. return Tipos.Size(type) * 4;
  363. }
  364. protected String ArrayShift(Node n) throws Exception {
  365. // Cria a chave para a ocorrencia de um acesso ao array, evitando recalcular o endereco
  366. String key = n.getText();
  367. for (Node node : n.childrens()) {
  368. key += "_" + node.getText();
  369. }
  370. if (!ArrayShiftMap.containsKey(key)) {
  371. // String shift;
  372. Node var = Variaveis.Get(n.getText());
  373. // System.out.println("INDEX shift:" + n + var);
  374. for (int i = 0, j = 1; j < var.childrens().size(); j++) {
  375. n.childrens().get(i++).S("collNumber", var.childrens().get(j).getText());
  376. }
  377. String ret = CalcArrayAddress(n.childrens(), Size(var.G("type")));
  378. // Se o offset for calculado em um inteiro atribui o mesmo como shift
  379. // if (Utils.isNumber(ret)) {
  380. // shift = ret;
  381. // } else {
  382. //// Se for um endereci faz a soma com o offset da varivel
  383. //// __exp("+", ret, gerarVariavel(n), ret);
  384. // shift = ret;
  385. // }
  386. ArrayShiftMap.put(key, ret);
  387. }
  388. return ArrayShiftMap.get(key);
  389. }
  390. protected String GenShiftLeftLogical(String var, int size, boolean mps, boolean last) throws Exception {
  391. ArrayList<Integer> path = ShiftPath(size);
  392. ArrayList<Integer> reverse = new ArrayList<>();
  393. for (int i = path.size() - 1; i >= 0; i--) {
  394. reverse.add(path.remove(i));
  395. }
  396. // System.out.println(">>>>>(var:" + var + ", size:" + size + ") arithpath:" + reverse);
  397. var = GSLL(var, reverse, mps, size, last);
  398. return var;
  399. }
  400. protected long pow2(long p) {
  401. return pow2("" + p);
  402. }
  403. protected long pow2(String p) {
  404. return power2.get(p);
  405. }
  406. protected String GSLL(String var, ArrayList<Integer> path, boolean mps, int size, boolean last) throws Exception {
  407. int op1, operacao, op2;
  408. String T1 = gerarVariavel("T"),
  409. T2 = gerarVariavel("T"),
  410. T3 = gerarVariavel("T");
  411. switch (path.size()) {
  412. case 1:
  413. if (!mps) {
  414. Copy(T1, var, false)
  415. .S("comment", "Copy value of index")
  416. .S("copy", "true");
  417. } else {
  418. T1 = var;
  419. }
  420. if (!last) {
  421. __exp("<<", T1, "" + pow2(size), T2).S("comment", "");
  422. return T2;
  423. }
  424. return T1;
  425. case 3:
  426. op1 = path.remove(0);
  427. operacao = path.remove(0);
  428. op2 = path.remove(0);
  429. // String T4 = gerarVariavel("T");
  430. if (!mps) {
  431. Copy(T1, var, false)
  432. .S("comment", "Copy value of index")
  433. .S("copy", "true");
  434. }
  435. if (op1 != 1) {
  436. __exp("<<", T1, "" + pow2(op1), T1).S("comment", "");
  437. }
  438. // if (op2 == 1) {
  439. // } else {
  440. // Copy(T3, var, false).S("comment", "Copy value of index");
  441. if (op2 != 1) {
  442. // System.out.println("GSLL:" + op2 + ":" + op1);
  443. // System.out.println("GSLL:op2" + pow2(op2));
  444. // System.out.println("GSLL:op1" + pow2(op1));
  445. __exp("<<", T1, "" + (pow2(op2) - pow2(op1)), T2).S("comment", "");
  446. // deve realizar um novo deslocamento
  447. } else {
  448. T2 = T1;
  449. }
  450. // Soma o deslocamento com o tamanho
  451. __exp("+", T1, T2, T1).S("comment", "");
  452. return T1;
  453. default:
  454. // op1 = path.remove(0);
  455. // operacao = path.remove(0);
  456. //
  457. // T2 = GSLL(var, path);
  458. //
  459. // Copy(T1, var, false).S("comment", "Copy value of index");
  460. //
  461. // __exp("<<", T1, "" + pow2(op1), T1).S("comment", "");
  462. // __exp("+", T1, T2, T1).S("comment", "");
  463. }
  464. return var;
  465. }
  466. protected String CalcArrayAddress(ArrayList<Node> childrens, int Size) throws Exception {
  467. // System.out.println("CalcArrayAddressINIT(" + Size + "):");
  468. boolean onlyNumber = true;
  469. for (Node node : childrens) {
  470. if (!node.isNumber("value")) {
  471. onlyNumber = false;
  472. break;
  473. }
  474. }
  475. if (onlyNumber) {
  476. return "" + (CalcArrayAddressNumber(childrens, Size) * Size);
  477. } else {
  478. // System.out.println("CAA:" + childrens);
  479. String current = CalcArrayAddressAux(childrens, Size);
  480. // System.out.println("Size {" + current + "}:----------->" + Size);
  481. // multiplica pelo tamanho
  482. return GenShiftLeftLogical(current, Size, true, false);
  483. }
  484. }
  485. protected Integer CalcArrayAddressNumber(ArrayList<Node> childrens, int Size) throws Exception {
  486. Node ind;
  487. ind = childrens.remove(0);
  488. Integer value = ind.getInt("value");
  489. // ultimo elemento da idexacao
  490. if (childrens.size() == 0) {
  491. return value;
  492. }
  493. Integer collNumber = ind.getInt("collNumber"),
  494. ret = CalcArrayAddressNumber(childrens, Size);
  495. return ((value * collNumber) + ret);
  496. }
  497. protected String CalcArrayAddressAux(ArrayList<Node> childrens, int Size) throws Exception {
  498. // boolean multPerSize = true;
  499. Node ind, nextIndex;
  500. ind = childrens.remove(0);
  501. // System.out.println("CalcArrayAddressAux:" + childrens.size() + ":" + Size + "\n" + ind);
  502. String current, varname;
  503. if (ind.eq("class", "expr")) {
  504. varname = gerarVariavel(
  505. new Node(gerarVariavel("TMP"))
  506. .S("array", "false")
  507. .S("type", "int")
  508. .S("var.tmp", "true")
  509. );
  510. Node p1 = visit(ind.childrens().get(0)),
  511. p2 = visit(ind.childrens().get(1));
  512. __exp(ind.getText(), p1.G("_return"), p2.G("_return"), varname);
  513. } else {
  514. varname = gerarVariavel(ind);
  515. }
  516. // if (ind)
  517. // ultimo elemento da idexacao
  518. if (childrens.size() == 0) {
  519. if (Utils.isNumber(ind.getText())) {
  520. return "" + ind.getInt("value");
  521. } else {
  522. return GenShiftLeftLogical(varname, Size, false, true);
  523. }
  524. }
  525. int collNumber = ind.getInt("collNumber");
  526. nextIndex = childrens.get(0);
  527. if (ind.isNumber("value") && nextIndex.isNumber("value")) {
  528. // System.out.println("CalcArray:" + ind.getInt("value") + ":" + ind.getInt("collNumber") + ":" + Integer.parseInt(ret));
  529. current = "" + (ind.getInt("value") * collNumber);
  530. // multPerSize = false;
  531. } else {
  532. // System.out.println("collNumber:" + collNumber);
  533. // current = GenShiftLeftLogical(gerarVariavel(ind), collNumber, false, false);
  534. current = GenShiftLeftLogical(varname, collNumber, false, false);
  535. // System.out.println("Gerando index calc:" + retl);
  536. // current = GenShiftLeftLogical(retl, Size);
  537. // current = retl;
  538. }
  539. String ret = CalcArrayAddressAux(childrens, Size);
  540. __exp("+u", current, ret, current).S("comment", "colls shift");
  541. // if (multPerSize) {
  542. // // Realiza a multiplicacao pelo tamanho do elemento
  543. // current = GenShiftLeftLogical(current, Size);
  544. // }
  545. return current;
  546. }
  547. // protected String CalcArrayAddress(ArrayList<Node> childrens, int Size, int index) throws Exception {
  548. // System.out.println("CalcArrayAddress:" + childrens.size() + ":" + Size);
  549. //
  550. // int nindex = index + 1;
  551. // String retl;
  552. // Node ind = childrens.remove(0);
  553. // if (childrens.size() >= 1) {
  554. // String ret = CalcArrayAddress(childrens, Size, nindex);
  555. // int collNumber = ind.getInt("collNumber");
  556. //
  557. // if (Utils.isNumber(ret) && ind.isNumber("value")) {
  558. //// System.out.println("CalcArray:" + ind.getInt("value") + ":" + ind.getInt("collNumber") + ":" + Integer.parseInt(ret));
  559. // return "" + ((ind.getInt("value") * collNumber) + Integer.parseInt(ret));
  560. // } else {
  561. //// System.out.println("collNumber:" + collNumber);
  562. //
  563. // retl = GenShiftLeftLogical(gerarVariavel(ind), collNumber);
  564. //
  565. // retl = GenShiftLeftLogical(retl, Size);
  566. //
  567. // __exp("+", retl, ret, retl).S("comment", "colls shift");
  568. // return retl;
  569. // }
  570. //
  571. // /*
  572. // Implementacao com mult **
  573. // int collNumber = ind.getInt("collNumber");
  574. //
  575. // if (Utils.isNumber(ret) && ind.isNumber("value")) {
  576. // System.out.println("CalcArray:" + ind.getInt("value") + ":" + collNumber + ":" + Integer.parseInt(ret));
  577. // return "" + ((ind.getInt("value") * collNumber) + Integer.parseInt(ret));
  578. // } else {
  579. // String retl = gerarVariavel("T");
  580. // __exp("*", gerarVariavel(ind), "" + collNumber, retl)
  581. // .S("comment", "lines shift");
  582. // __exp("+", retl, ret, retl)
  583. // .S("comment", "colls shift");
  584. // return retl;
  585. // }
  586. // */
  587. // } else {
  588. //
  589. // if (Utils.isNumber(ind.getText())) {
  590. // return ind.getText();
  591. // } else {
  592. // // ultimo elemento da idexacao
  593. //
  594. // return GenShiftLeftLogical(gerarVariavel(ind), Size);
  595. // }
  596. //
  597. // }
  598. // }
  599. /**
  600. * ProceSSa um node:<br>
  601. * Ordem:<br>
  602. * ->Primeiro filhoS;<br>
  603. * ->No principal;<br>
  604. *
  605. * @param n
  606. * @throws Exception
  607. */
  608. protected void visitChildrensFirst(Node n) throws Exception {
  609. // System.out.println("Visit:" + n.getText());
  610. for (Node n1 : n.childrens()) {
  611. // System.out.println("Visit:" + n1.getText());
  612. visit(n1);
  613. }
  614. // System.out.println("Process:" + n.getText());
  615. processarNode(n);
  616. }
  617. /**
  618. * ProceSSa um node:<br>
  619. * Ordem:<br>
  620. * ->Primeiro filho;<br>
  621. * ->No principal;<br>
  622. * ->Segundo filho;<br>
  623. *
  624. * @param n
  625. * @throws Exception
  626. */
  627. protected void visitNoMeio(Node n) throws Exception {
  628. visit(n.getFilho(0));
  629. processarNode(n);
  630. visit(n.getFilho(1));
  631. }
  632. /**
  633. * ProceSSa um node:<br>
  634. * Ordem:<br>
  635. * ->No princial;<br>
  636. * ->DepoiS oS filhoS
  637. *
  638. * @param n
  639. * @throws Exception
  640. */
  641. protected void visitRootFirst(Node n) throws Exception {
  642. processarNode(n);
  643. for (Node n1 : n.childrens()) {
  644. visit(n1);
  645. }
  646. }
  647. /**
  648. * Aloca endereço no inicio da memoria para conStanteS ApenaS tipoS<br>
  649. * [inteiro, booleano e char]
  650. *
  651. * @param n
  652. * @throws Exception
  653. */
  654. protected void gerarConstante(Node n) throws Exception {
  655. // System.out.println("Gerando constant:" + n.childrens().get(0) + n.childrens().get(1));
  656. // gerarVariavel(n.get(label, label));
  657. // getLabel("C", n);
  658. // if (n.closest("block", "class") != null) {
  659. // code.registerVar(n.G("_return"), 1, DataFrame.TYPE_VAR);
  660. // }
  661. }
  662. /**
  663. * Executa a extração fo block principal
  664. *
  665. * @throws Exception
  666. */
  667. public void main() throws Exception {
  668. Node main = ast.getMain();
  669. // main.S("_return", Threads.getId("main"));
  670. Node stmts = main.find("stmts");
  671. if (code.OpenBlock("main")) {
  672. PushLabel("main", "block");
  673. visit(stmts);
  674. PushLabel("main-end", "block");
  675. code.CloseBlock();
  676. }
  677. }
  678. public Code run() throws Exception {
  679. if (!inicializado) {
  680. inicializado = true;
  681. main();
  682. }
  683. code.UpdatePositions();
  684. return code;
  685. }
  686. /**
  687. * ProceSSa If (ElSe'S)*
  688. *
  689. * @param n
  690. * @throws Exception
  691. */
  692. protected void IfStmts(Node n) throws Exception {
  693. String end = gerarLabel(), next;
  694. boolean ifChain = n.childrens().size() > 1;
  695. //(If)+ (else)?
  696. next = ifChain ? gerarLabel() : end;
  697. n.S("next", next).S("end", end);
  698. for (Node stmt : n.childrens()) {
  699. switch (stmt.Class()) {
  700. case "if.case.stmt":
  701. IfCaseStmt(n, stmt, ifChain);
  702. break;
  703. // Else case
  704. case "stmts":
  705. // String next = gerarLabel();
  706. // n.S("next", next);
  707. visit(stmt.S("next", next));
  708. // Cria um PushLabel final
  709. // PushLabel(n.G("end"), "branch");
  710. // PushLabel(end);
  711. break;
  712. }
  713. }
  714. // Cria um PushLabel final
  715. // System.out.println("Label end:" + n.G("end"));
  716. PushLabel(n.G("end"), "branch");
  717. }
  718. /**
  719. * ProceSSa If, eSSe metodo deve Ser chamado pelo metodo IfStmtS
  720. *
  721. * @param n
  722. * @param _if
  723. * @param ifChain
  724. * @throws Exception
  725. */
  726. protected void IfCaseStmt(Node n, Node _if, boolean ifChain) throws Exception {
  727. Node test = _if.first().first();
  728. Node stmts = _if.find("stmts");
  729. // Se o teste falha deve saltar o bloco
  730. n.S("start", gerarLabel());
  731. test.S("test.type", "jb").copy("next,start,end", n);
  732. Branch(test, 0);
  733. // marca com um label o inicio do bloco do if
  734. PushLabel(n.G("start"), "branch");
  735. // gera as instruções do bloco
  736. visit(stmts);
  737. // se for uma cadeia de condiçoes com ou sem else
  738. if (ifChain) {
  739. // Salta os outros testes
  740. _goto(n.G("end"));
  741. //Adiciona o label de proximo elemento da cadeia de if's e else
  742. PushLabel(n.G("next"), "branch");
  743. //Atualiza o ponteiro para o proximo elemento
  744. n.S("next", gerarLabel());
  745. }
  746. }
  747. /**
  748. * Executa tratamento de um no eSpecifico, Selecionado pelo atributo claSS
  749. *
  750. * @param n
  751. * @throws Exception
  752. */
  753. protected void processarNode(Node n) throws Exception {
  754. switch (n.Class()) {
  755. case "return":
  756. genReturn(n);
  757. break;
  758. case "ctrl.stmt":
  759. ctrlStmt(n);
  760. break;
  761. case "label.stmt":
  762. PushLabel(n.getText(), "user");
  763. break;
  764. }
  765. }
  766. protected void _visitExpr(Node n) throws Exception {
  767. // System.out.println("VisitExpr:" + n);
  768. visit(n.childrens().get(0));
  769. visit(n.childrens().get(1));
  770. switch (n.G("subclass")) {
  771. case "arith":// ( + | - | * | / ) integer
  772. genExpArith(n);
  773. break;
  774. }
  775. }
  776. protected void BranchAnd(Node n, int index) throws Exception {
  777. // int pos = 0;
  778. // if (n.parent == null) {
  779. // System.out.println("BranchAnd:" + n);
  780. // }
  781. // OrTestAndOccurrence++;
  782. Instruction instruction = null;
  783. ArrayList<Node> x = n.childrens();
  784. Node op1 = x.get(0), op2 = x.get(1);
  785. String type = n.G("test.type"),
  786. step = gerarLabel(),
  787. attrs = "next,end,inc,test.type,skip.test";
  788. n.S("skip.test", step);
  789. op1.copy(attrs, n);
  790. op2.copy(attrs, n);
  791. instruction = Branch(op1, 1);
  792. if (instruction != null) {
  793. switch (type) {
  794. case "jtb":
  795. instruction.S("op", Complement(instruction.G("op")));
  796. if (n.parent != null && n.parent.eq("value", "||")) {
  797. if (index == 1) {
  798. UpdateLabel(instruction, n.parent.G("skip.test"));
  799. } else if (index == 2) {
  800. UpdateLabel(instruction, n.parent.G("end"));
  801. }
  802. // } else if (n.parent.eq("value", "&&")) {
  803. } else {
  804. UpdateLabel(instruction, n.G("end"));
  805. }
  806. break;
  807. case "jb":
  808. // if (n.parent != null) {
  809. if (n.parent != null && n.parent.eq("value", "||")) {
  810. if (index <= 1) {
  811. UpdateLabel(instruction, n.parent.G("skip.test"));
  812. } else if (index == 2) {
  813. // instruction.S("op", Complement(instruction.G("op")));
  814. UpdateLabel(instruction, n.G("next"));
  815. }
  816. }
  817. // } else {
  818. // }
  819. }
  820. }
  821. // System.out.println("instruction Branch 1:" + instruction + "\n" + op1);
  822. // if (index == 0 || (op1.in("value", new String[]{"||", "&&"}) && !n.eq("value", op1.G("value")))) {
  823. // Registra o label para o saldo dos testes do primeiro parametro
  824. PushLabel(step, "branch");
  825. // }
  826. instruction = Branch(op2, 2);
  827. if (instruction != null) {
  828. switch (type) {
  829. case "jtb":
  830. if (n.parent != null && n.parent.eq("value", "||")) {
  831. if (index == 1) { // teste 1 do parametro 2 com pai ||
  832. instruction.S("op", Complement(instruction.G("op")));
  833. UpdateLabel(instruction, n.G("end"));
  834. } else if (index == 2) { // teste 2 do parametro 2
  835. UpdateLabel(instruction, n.G("next"));
  836. }
  837. // } else if (n.parent.eq("value", "&&")) {
  838. // if (index == 1) { // teste 1 do parametro 2 com pai &&
  839. //// throw new Exception("// teste 1 do parametro 2 com pai &&");
  840. //
  841. // } else if (index == 2) { // teste 2 do parametro 2 com pai &&
  842. // instruction.S("op", Complement(instruction.G("op")));
  843. // UpdateLabel(instruction, n.G("end"));
  844. // }
  845. } else {
  846. if (index == 1) { // teste 1 do parametro 2 geral
  847. instruction.S("op", Complement(instruction.G("op")));
  848. UpdateLabel(instruction, n.G("end"));
  849. } else if (index == 2) {
  850. // throw new Exception("teste 2 do parametro 2 geral");
  851. }
  852. }
  853. break;
  854. case "jb":
  855. // System.out.println("I(jb:and:2)[" + index + "]\n" + instruction + "\n" + n);
  856. // if (n.parent != null) {
  857. if (n.parent != null && n.parent.eq("value", "||")) {
  858. if (index <= 1) {
  859. // UpdateLabel(instruction, n.parent.G("skip.test"));
  860. instruction.S("op", Complement(instruction.G("op")));
  861. UpdateLabel(instruction, n.G("start"));
  862. } else if (index == 2) {
  863. // instruction.S("op", Complement(instruction.G("op")));
  864. UpdateLabel(instruction, n.G("next"));
  865. }
  866. }
  867. // } else {
  868. // }
  869. }
  870. }
  871. }
  872. public void UpdateLabel(Instruction I, String label) {
  873. String copy = I.G("label");
  874. if (!copy.equals("")) {
  875. code.RemoveLabelReference(copy);
  876. }
  877. I.S("label", label);
  878. code.AddLabelReference(label);
  879. }
  880. protected void BranchOr(Node n, int index) throws Exception {
  881. // if (n.parent == null) {
  882. // System.out.println("BranchOr:" + n);
  883. // }
  884. // int pos = 0;
  885. // OrTestAndOccurrence++;
  886. Instruction instruction = null;
  887. ArrayList<Node> x = n.childrens();
  888. Node op1 = x.get(0), op2 = x.get(1);
  889. String type = n.G("test.type"),
  890. step = gerarLabel(),
  891. attrs = "next,start,end,inc,test.type,skip.test";
  892. n.S("skip.test", step);
  893. op1.copy(attrs, n);
  894. op2.copy(attrs, n);
  895. // System.out.println("BranchOr:" + n.parent);
  896. // Executa o lado esquerdo do ||
  897. instruction = Branch(op1, 1);
  898. if (instruction != null) {
  899. switch (type) {
  900. case "jtb":
  901. if (n.parent != null && n.parent.eq("value", "&&")) {
  902. if (index == 1) {
  903. UpdateLabel(instruction, n.parent.G("skip.test"));
  904. }
  905. }
  906. break;
  907. case "jb":
  908. // System.out.println("I(jb:1)[" + index + "]\n" + instruction + "\n" + n);
  909. // System.out.println("Entrei no jb ||" + (jb++) + instruction + n.parent);
  910. // if (n.parent != null) {
  911. if (n.parent != null && n.parent.eq("value", "||")) {
  912. // if (index == 2) {
  913. instruction.S("op", Complement(instruction.G("op")));
  914. UpdateLabel(instruction, n.G("start"));
  915. // }
  916. } else if (n.parent != null && n.parent.eq("value", "&&")) {
  917. if (index <= 1) {
  918. instruction.S("op", Complement(instruction.G("op")));
  919. UpdateLabel(instruction, n.parent.G("skip.test"));
  920. } else if (index == 2) {
  921. instruction.S("op", Complement(instruction.G("op")));
  922. UpdateLabel(instruction, n.parent.G("start"));
  923. }
  924. // }
  925. } else {
  926. instruction.S("op", Complement(instruction.G("op")));
  927. if (index <= 1) {
  928. UpdateLabel(instruction, n.G("start"));
  929. } else if (index == 2) {
  930. }
  931. }
  932. }
  933. }
  934. // System.out.println("instruction Branch 1:" + instruction + "\n" + op1);
  935. // Registra o label para o saldo dos testes do primeiro parametro
  936. PushLabel(step, "branch");
  937. // Executa o lado direito do ||
  938. instruction = Branch(op2, 2);
  939. if (instruction != null) {
  940. switch (type) {
  941. case "jtb":
  942. if (n.parent != null && n.parent.eq("value", "&&")) {
  943. if (index == 1) {
  944. instruction.S("op", Complement(instruction.G("op")));
  945. UpdateLabel(instruction, n.parent.G("end"));
  946. }
  947. }
  948. break;
  949. case "jb":
  950. // if (n.parent != null) {
  951. if (n.parent != null && n.parent.eq("value", "||")) {
  952. if (index <= 1) {
  953. instruction.S("op", Complement(instruction.G("op")));
  954. UpdateLabel(instruction, n.G("start"));
  955. } else if (index == 2) {
  956. //
  957. // instruction.S("op", Complement(instruction.G("op")));
  958. UpdateLabel(instruction, n.G("next"));
  959. }
  960. } else if (n.parent != null && n.parent.eq("value", "&&")) {
  961. if (index == 1) {
  962. // instruction.S("op", Complement(instruction.G("op")));
  963. // UpdateLabel(instruction, n.parent.G("start"));
  964. } else if (index == 2) {
  965. // instruction.S("op", Complement(instruction.G("op")));
  966. // UpdateLabel(instruction, n.parent.G("start"));
  967. }
  968. // }
  969. } else {
  970. // instruction.S("op", Complement(instruction.G("op")));
  971. // UpdateLabel(instruction, n.G("next"));
  972. }
  973. }
  974. }
  975. }
  976. protected Instruction BranchTest(Node n, int index) throws Exception {
  977. ArrayList<Node> x = n.childrens();
  978. String type = n.G("test.type");
  979. boolean invert = false;
  980. String op, p0, p1;
  981. switch (type) {
  982. case "jb":
  983. invert = true;
  984. break;
  985. case "jtb":
  986. break;
  987. default:
  988. throw new Exception("test.type '".concat(type).concat("' not suported. Values {jtb,jb}"));
  989. }
  990. visit(n);
  991. // Resultado do test class ou acesso a um id ou bool
  992. if (!n.eq("class", "expr")) {
  993. op = "==";
  994. p0 = n.G("_return");
  995. p1 = "1";
  996. } else { //(<, <=, >, >=, ==, !=)
  997. op = n.getText();
  998. p0 = visit(x.get(0)).G("_return");
  999. p1 = visit(x.get(1)).G("_return");
  1000. }
  1001. // Inverte o teste e salta o bloco
  1002. if (invert) {
  1003. op = Complement(op);
  1004. }
  1005. // return Branch(op, p0, p1, next);
  1006. Instruction r1 = new Instruction();
  1007. r1.S("format", "branch")
  1008. .S("type", "branch")
  1009. .S("op", op)
  1010. .S("p1", p0)
  1011. .S("p2", p1)
  1012. .S("p1value", "" + Api.IsValue(p0))
  1013. .S("p2value", "" + Api.IsValue(p1))
  1014. .S("label", n.G("next"));
  1015. // System.out.println("Add branch:" + branckInvert.peek() + branckInvert + ">>" + (!branckInvert.isEmpty() && branckInvert.peek()) + "\n" + r1);
  1016. code.Add(r1);
  1017. return r1;
  1018. }
  1019. protected Instruction Branch(Node n, int index) throws Exception {
  1020. Instruction instruction = null;
  1021. switch (n.getText()) {
  1022. case "&&":
  1023. BranchAnd(n, index);
  1024. break;
  1025. case "||":
  1026. BranchOr(n, index);
  1027. break;
  1028. default:
  1029. instruction = BranchTest(n, index);
  1030. }
  1031. return instruction;
  1032. }
  1033. protected String Complement(String op) {
  1034. return Complements.get(op);
  1035. }
  1036. /**
  1037. * Cria uma linha de Salto para PuShLabel eSpecificado no parametro.
  1038. *
  1039. * @param label
  1040. * @throws Exception
  1041. */
  1042. protected void _goto(String label) throws Exception {
  1043. Instruction r = new Instruction();
  1044. r.S("label", label)
  1045. .S("type", "jump")
  1046. .S("format", "jump")
  1047. .set("locker", getIdMaster());
  1048. code.Add(r);
  1049. }
  1050. /*Inicio das avaliacoes booleanas*/
  1051. /**
  1052. * Gera um linha de inStrução de retorno no block de codigo
  1053. *
  1054. * @param n
  1055. * @throws Exception
  1056. */
  1057. protected void genReturn(Node n) throws Exception {
  1058. Instruction nreg;
  1059. ArrayList<Node> returns = n.find("exprs").childrens();
  1060. for (Node ret : returns) {
  1061. // System.out.println("Return p:" + ret);
  1062. nreg = new Instruction()
  1063. .S("type", "push_return")
  1064. .S("format", "push_return")
  1065. .S("p1value", "" + Api.IsValue(ret.getText()))
  1066. .S("p1", ret.G("_return"));
  1067. nreg.set("locker", getIdMaster());
  1068. code.Add(nreg);
  1069. }
  1070. code.Add(new Instruction()
  1071. .S("type", "return")
  1072. .S("format", "return")
  1073. .set("p1", returns.size())
  1074. .S("p1value", "true")
  1075. .set("locker", getIdMaster()));
  1076. }
  1077. /**
  1078. * Gera todoS oS SaltoS de um loop for
  1079. *
  1080. * @param n
  1081. * @throws Exception
  1082. */
  1083. protected void genFor(Node n) throws Exception {
  1084. String attrs = "next,end,inc,test";
  1085. Node test = n.find("test").first();
  1086. setMaster(n);
  1087. String next = gerarLabel(),
  1088. // next = gerarLabel(),
  1089. end = gerarLabel(),
  1090. inc = gerarLabel(),
  1091. testLabel = gerarLabel();
  1092. n.S("next", next)
  1093. .S("end", end)
  1094. .S("inc", inc)
  1095. .S("test", testLabel);
  1096. Node stmt = n.find("stmts");
  1097. stmt.copy(attrs, n);
  1098. test.copy(attrs, n).S("test.type", "jtb");
  1099. /*Inicializacoes e atribuicoes*/
  1100. visit(n.find("initialization"));
  1101. /*Salta para o teste do laco*/
  1102. _goto(testLabel);
  1103. /*Marca o inicio do bloco do laco*/
  1104. PushLabel(next, "branch");
  1105. /*Executa o bloco do for*/
  1106. visit(stmt);
  1107. /*Label que marca os incrementos dos laco*/
  1108. PushLabel(inc, "branch");
  1109. /*Executa os incrementos*/
  1110. visit(n.find("increment"));
  1111. /*Label que marca o teste do laco*/
  1112. PushLabel(testLabel, "branch");
  1113. // test.type = ((JumpToBlock in LOOP) | (JumpBlock in IF || SWITCH))
  1114. // test.type = JumpToBlock
  1115. // test.S("test.type", "for").S("next", next).S("end", end).S("or", next);
  1116. // System.out.println("Teste:" + test);
  1117. Branch(test, 0);
  1118. // if (n.Has("set.end_label")) {
  1119. // PushLabel(n.G("end"), "branch");
  1120. PushLabel(end, "branch");
  1121. // }
  1122. setNullMaster();
  1123. }
  1124. // protected void genFor(Node n) throws Exception {
  1125. // setMaster(n);
  1126. // String start = gerarLabel(), next = gerarLabel();
  1127. //
  1128. // n.S("next", next);
  1129. // n.S("start", start);
  1130. //
  1131. // Node stmt = n.find("stmts");
  1132. // stmt.S("next", start);
  1133. // /*Inicializacoes e atribuicoes*/
  1134. // visit(n.find("initialization"));
  1135. // // Label que marca o inicio do for
  1136. // PushLabel(start, "branch");
  1137. //
  1138. // Node test = n.find("test").first();
  1139. //// if (test.hasChildrens())
  1140. //// test.S("true", gerarLabel());
  1141. //// test.S("false", n.G("next"));
  1142. //// test.S("true", next);
  1143. //// test.S("false", n.G("next"));
  1144. // test.S("and", next);
  1145. // test.S("next", next);
  1146. // test.S("or", gerarLabel());
  1147. //
  1148. // Branch(test);
  1149. //
  1150. // if (test.Has("or")) {
  1151. // PushLabel(test.G("or"), "branch");
  1152. // }
  1153. //
  1154. //// PushLabel(test.G("true"), "branch");
  1155. // /*Executa o bloco do for*/
  1156. // visit(stmt);
  1157. // /*Executa os incrementos*/
  1158. // visit(n.find("increment"));
  1159. // /*Salta para inicio do laço*/
  1160. // _goto(start);
  1161. // /*Marca o endereço final para sair do laço*/
  1162. // PushLabel(test.G("next"), "branch");
  1163. //
  1164. // setNullMaster();
  1165. // }
  1166. protected void genExpArith(Node n) throws Exception {
  1167. Node op1 = n.childrens.get(0);
  1168. Node op2 = n.childrens.get(1);
  1169. String _op = n.getText();
  1170. //
  1171. //
  1172. // // se os dois valores são
  1173. // if (op1.eq("type", "value") && op2.eq("type", "value")) {
  1174. //
  1175. // n.S("_return", resolveExpr(_op, op1.G("value"), op2.G("value")));
  1176. // }
  1177. // if (op1.isNumber("value") && op2.isNumber("value")) {
  1178. //
  1179. // } else {
  1180. // Inverte a ordem dos operandos se o segundo for seletor e o primeiro for valor
  1181. if (op1.isNumber("value") && !op2.isNumber("value")) {
  1182. Node aux = op1;
  1183. op1 = op2;
  1184. op2 = aux;
  1185. }
  1186. // System.out.println("GerarArit" + op1 + "-" + op2);
  1187. String _p1 = op1.G("_return");
  1188. String _p2 = op2.G("_return");
  1189. String _return = gerarVariavel("T");
  1190. n.S("_return", _return);
  1191. Instruction instruction = __exp(_op, _p1, _p2, _return);
  1192. if (instruction.eq("type", "copy")) {
  1193. n.S("_p1", instruction.G("p1"));
  1194. n.S("value", instruction.G("p1"));
  1195. } else {
  1196. n.S("_op", _op);
  1197. n.S("_p1", _p1);
  1198. n.S("_p2", _p2);
  1199. }
  1200. }
  1201. /**
  1202. * Para cima verificado <==>
  1203. */
  1204. protected void genArray(Node n) {
  1205. if (n.eq("raiz", "t")) {
  1206. currentMatrixvalues = new ArrayList<String>();
  1207. matrixValues.put(n.G("id"), currentMatrixvalues);
  1208. for (Node c : n.childrens()) {
  1209. genArray(c);
  1210. }
  1211. } else if (n.eq("terminal", "t")) {
  1212. currentMatrixvalues.add(n.getText());
  1213. } else {
  1214. for (Node c : n.childrens()) {
  1215. genArray(c);
  1216. }
  1217. }
  1218. }
  1219. protected ArrayList<String> initValues(Node n) {
  1220. ArrayList<String> values = new ArrayList<>();
  1221. switch (n.G("class")) {
  1222. case "_array":
  1223. values = matrixValues.get(n.G("id"));
  1224. break;
  1225. /*valores e constantes*/
  1226. default:
  1227. String _return = n.G("_return");
  1228. if (_return.matches("^_.*")) {
  1229. _return = "0";
  1230. }
  1231. values.add(_return);
  1232. }
  1233. return values;
  1234. }
  1235. /**
  1236. * Gera a chamada para o metodo de deSalocacao de memoria
  1237. *
  1238. * @param n
  1239. * @throws Exception
  1240. */
  1241. protected void genDelete(Node n) throws Exception {
  1242. for (Node address : n.childrens()) {
  1243. visit(address);
  1244. __genParam(address.G("_return"));
  1245. __gerarCall(Functions.FREE, "1", getIdMaster());
  1246. }
  1247. }
  1248. /**
  1249. * Gera a Switch caSe
  1250. *
  1251. * @param n
  1252. */
  1253. protected void switchStmt(Node n) throws Exception {
  1254. /*Label que sera consultado pelo break para sair do case*/
  1255. String start,
  1256. next,
  1257. end = gerarLabel(),
  1258. dst = null;
  1259. n.S("next", end);
  1260. Node test = n.find("test");
  1261. // Verifica se existe entrada para selecao
  1262. if (test.childrens().size() > 0) {
  1263. test = test.first();
  1264. visit(test);
  1265. dst = test.G("_return");
  1266. }
  1267. // test;
  1268. ArrayList<Node> cases = n.findAll("def.case", "class", 1);
  1269. for (Node _case : cases) {
  1270. start = gerarLabel();
  1271. next = gerarLabel();
  1272. _case.S("start", start)
  1273. .S("_input", dst)
  1274. .S("next", next)
  1275. .S("end", end)
  1276. .S("test.type", "jb");
  1277. genCase(_case);
  1278. }
  1279. /*Marca o endereço final para sair do switch*/
  1280. PushLabel(end, "branch");
  1281. }
  1282. /**
  1283. * Gera oS caSeS de um Switch
  1284. *
  1285. * @param n
  1286. */
  1287. protected void genCase(Node n) throws Exception {
  1288. ArrayList<Node> exprs;
  1289. Node test;
  1290. // System.out.println("GEN_CASE:" + n);
  1291. // String start = n.Has("start") ? n.G("start") : gerarLabel();
  1292. // String next = gerarLabel(), end;
  1293. //
  1294. //// System.out.println("GenCase:" + start + ":" + next);
  1295. ArrayList<Node> itens = n.childrens();
  1296. Node stmts = n.find("stmts");
  1297. // Node or;
  1298. //
  1299. if (itens.size() >= 2) { // Tem teste
  1300. test = n.first();
  1301. String input = n.G("_input"),
  1302. start = n.G("start"),
  1303. end = n.G("end"),
  1304. next = n.G("next");
  1305. //
  1306. if (input != null) {
  1307. exprs = ExprsEq(test, new Node(input).S("_return", input));
  1308. } else {
  1309. exprs = test.childrens();
  1310. }
  1311. // /*Seleciona o endereco de saida se é no proximo case ou no fim do switch*/
  1312. // if (stmts.last().eq("value", "fallthrough")) {
  1313. // end = gerarLabel();
  1314. // n.S("next", end);
  1315. // } else {
  1316. // end = n.G("end");
  1317. // }
  1318. //
  1319. // // Atualiza o PushLabel de sucesso das exprs
  1320. for (Node expr : exprs) {
  1321. expr.copy("start,next,end,test.type", n);
  1322. }
  1323. //
  1324. Branch(OR(exprs).S("next", next), 0);
  1325. /*Se nenhum dos casos for compativel salta para o proximo*/
  1326. /*Marca o PushLabel inicial do caso*/
  1327. PushLabel(start, "branch");
  1328. /*Visita o bloco do case*/
  1329. visit(stmts);
  1330. /*Salta para o proximo case ou para o fim do switchcase*/
  1331. _goto(end);
  1332. /*Label do inicio do proximo case*/
  1333. PushLabel(next, "branch");
  1334. } else { // Default statiment
  1335. visit(stmts);
  1336. }
  1337. // String start = n.Has("start") ? n.G("start") : gerarLabel();
  1338. // String next = gerarLabel(), end;
  1339. //
  1340. //// System.out.println("GenCase:" + start + ":" + next);
  1341. // ArrayList<Node> itens = n.childrens();
  1342. // Node stmts = n.find("stmts");
  1343. // Node or;
  1344. //
  1345. // if (itens.size() >= 2) { // Tem teste
  1346. // String input = n.G("_input");
  1347. // Node test = n.first();
  1348. // ArrayList<Node> exprs;
  1349. //
  1350. // if (input != null) {
  1351. // exprs = ExprsEq(test, new Node(input).S("_return", input));
  1352. // } else {
  1353. // exprs = test.childrens();
  1354. // }
  1355. //
  1356. // /*Seleciona o endereco de saida se é no proximo case ou no fim do switch*/
  1357. // if (stmts.last().eq("value", "fallthrough")) {
  1358. // end = gerarLabel();
  1359. // n.S("next", end);
  1360. // } else {
  1361. // end = n.G("end");
  1362. // }
  1363. //
  1364. // // Atualiza o PushLabel de sucesso das exprs
  1365. // for (Node expr : exprs) {
  1366. // expr.S("true", !last ? next : end);
  1367. //// expr.S("false", next);
  1368. //// expr.S("false", start);
  1369. // }
  1370. //
  1371. // Branch(OR(exprs).S("next", next), 0);
  1372. //
  1373. // /*Se nenhum dos casos for compativel salta para o proximo*/
  1374. //// _goto(!last ? next : end);
  1375. // /*Marca o PushLabel inicial do caso*/
  1376. // PushLabel(start, "branch");
  1377. // /*Visita o bloco do case*/
  1378. // visit(stmts);
  1379. //
  1380. // if (!last) {
  1381. // /*Salta para o proximo case ou para o fim do switchcase*/
  1382. // _goto(end);
  1383. // /*Label do inicio do proximo case*/
  1384. // PushLabel(next, "branch");
  1385. // }
  1386. // } else { // Default statiment
  1387. // visit(stmts);
  1388. // }
  1389. }
  1390. protected Node NodeBoolExpr(String op, Node e1, Node e2) {
  1391. return new Node(op)
  1392. .S("type", "bool")
  1393. .S("class", "expr")
  1394. .S("subclass", "bool")
  1395. .addFilho(e1)
  1396. .addFilho(e2);
  1397. }
  1398. protected ArrayList<Node> ExprsEq(Node n, Node input) throws Exception {
  1399. ArrayList<Node> list = new ArrayList<>();
  1400. switch (n.Class()) {
  1401. case "exprs":
  1402. for (Node e : n.childrens()) {
  1403. list.add(NodeBoolExpr("==", input, e));
  1404. }
  1405. break;
  1406. default:
  1407. list.add(NodeBoolExpr("==", input, n));
  1408. }
  1409. return list;
  1410. }
  1411. protected Node OR(ArrayList<Node> n) throws Exception {
  1412. switch (n.size()) {
  1413. case 0:
  1414. return null;
  1415. case 1:
  1416. return n.get(0);
  1417. default:
  1418. Node x = n.get(0);
  1419. n.remove(x);
  1420. return NodeBoolExpr("||", x, OR(n)).copy("start,next,end,test.type", x);
  1421. }
  1422. }
  1423. protected int qtdByIndex(Node n) throws Exception {
  1424. Node indexes = n.find("indexes");
  1425. if (indexes == null) {
  1426. return 1;
  1427. } else {
  1428. int sum = 0;
  1429. for (Node index : indexes.childrens()) {
  1430. sum += index.getInt("_return");
  1431. }
  1432. return sum;
  1433. }
  1434. }
  1435. /**
  1436. * Gera inStrução de atribuicao
  1437. *
  1438. * @param n
  1439. * @throws Exception
  1440. */
  1441. protected void genAssign(Node n) throws Exception {
  1442. ArrayList<String> localAttribs = new ArrayList<>(),
  1443. // copymode = new ArrayList<>(),
  1444. // operators = new ArrayList<>(),
  1445. returns;
  1446. ArrayList<Boolean> copyaddress = new ArrayList<>();
  1447. String p1,
  1448. modify = n.G("modify"),
  1449. declare = "" + n.getText().equals("dec.var.short");
  1450. // System.out.println("genAssign:" + n.childrens().get(0).childrens().get(0));
  1451. Node dsts = n.childrens().get(0);
  1452. if (n.in("value", new String[]{"dec.var.short", "def.assign"})) {
  1453. for (Node attrib : n.childrens().get(1).childrens()) {
  1454. visit(attrib);
  1455. // System.out.println("n:" + n);
  1456. // System.out.println("genAssign:" + attrib.G("class") + ":" + attrib.G("value"));
  1457. if (attrib.eq("class", "call")) {
  1458. returns = attrib.getList("returns");
  1459. if (returns != null) {
  1460. for (String _return : returns) {
  1461. localAttribs.add(_return);
  1462. copyaddress.add(attrib.eq("subclass", "address"));
  1463. }
  1464. }
  1465. } else if (attrib.eq("class", "index")) {
  1466. // System.out.println("Attr <- :" + attrib);
  1467. } else if (attrib.eq("class", "literal")) {
  1468. // System.out.println("literal<- :" + attrib);
  1469. switch (attrib.G("subclass")) {
  1470. case "array":
  1471. for (Node element : attrib.find("exprs").childrens()) {
  1472. visit(element);
  1473. copyaddress.add(element.eq("subclass", "address"));
  1474. localAttribs.add(element.G("_return"));
  1475. }
  1476. break;
  1477. }
  1478. } else {
  1479. // System.out.println("Assign:" + attrib);
  1480. copyaddress.add(attrib.eq("subclass", "address"));
  1481. localAttribs.add(attrib.G("_return"));
  1482. }
  1483. }
  1484. }
  1485. // System.out.println("Copy::" + localAttribs);
  1486. // System.out.println("Lista de atribuicoes locais:\n" + dsts + "\n>>\n" + n);
  1487. // System.out.println("Lista de atribuicoes locais:\n" + dsts + "\n>>\n" + localAttribs);
  1488. // Executa a copia dos valores
  1489. for (int dstPosition = 0, i = 0; i < localAttribs.size(); dstPosition++) {
  1490. Node d = dsts.childrens().get(dstPosition);
  1491. d.S("declare", declare);
  1492. visit(d);
  1493. // System.out.println("D:" + d.childrens());
  1494. if (d.eq("class", "unary") && d.eq("dst.pointer", "*")) {
  1495. p1 = localAttribs.get(i);
  1496. code.Add(new Instruction()
  1497. .S("format", "pointer_assignment")
  1498. .S("type", "pointer_assignment")
  1499. .S("dst", d.childrens().get(1).G("_return"))
  1500. .S("p1", p1)
  1501. .S("p1value", "" + Api.IsValue(p1))
  1502. .S("dst.pointer", "*")
  1503. .set("locker", getIdMaster()));
  1504. i++;
  1505. // Salva o valor em memoria
  1506. } else if (d.eq("array", "true")) {
  1507. for (int j = 0; j < d.getInt("array_size"); j++, i++) {
  1508. // System.out.println("ARRAY:" + d.G("_return") + "[" + j + "]" + " -- " + localAttribs.get(i));
  1509. Copy(d.G("_return") + "[" + j + "]", localAttribs.get(i), copyaddress.get(i));
  1510. }
  1511. } else {
  1512. // Copia valor para endereco
  1513. // System.out.println("Attrib:" + d.G("_return") + "<" + localAttribs.get(i));
  1514. if (!modify.equals("")) {
  1515. __exp(modify, d.G("_return"), localAttribs.get(i), d.G("_return")).S("comment", "");
  1516. } else {
  1517. Copy(d.G("_return"), localAttribs.get(i), copyaddress.get(i));
  1518. }
  1519. i++;
  1520. }
  1521. }
  1522. }
  1523. protected void __genParam(String param) throws Exception {
  1524. Instruction r = new Instruction();
  1525. r.S("format", "push_param")
  1526. .S("type", "push_param")
  1527. .S("p1", param)
  1528. .S("p1value", "" + Api.IsValue(param))
  1529. .set("locker", getIdMaster());
  1530. code.Add(r);
  1531. }
  1532. protected void genFunction(String id, Node func) throws Exception {
  1533. if (!funcGenMap.containsKey(id)) {
  1534. funcGenMap.put(id, "true");
  1535. Node block = func.find("stmts");
  1536. code.OpenBlock(id);
  1537. /*Cria a PushLabel inicial da funcao*/
  1538. PushLabel(id, "block");
  1539. /*Declara as variaveis de parametro*/
  1540. genPopParams(func);
  1541. /*Declara as variaveis de retorno caso sejam nomeadas*/
  1542. // visit(func.find("def::return"));
  1543. // System.out.println(Variaveis.printScope(func.G("scope")));
  1544. /*Processa o bloco de instrucoes*/
  1545. visit(block);
  1546. /*Cria a PushLabel final da funcao*/
  1547. PushLabel(id + "-end", "block");
  1548. code.CloseBlock();
  1549. }
  1550. }
  1551. protected void genCall(Node n) throws Exception {
  1552. int argsNum = 0;
  1553. // Se for metodo carrega o contexto no primeiro parametro
  1554. // System.out.println("GenCall:" + n);
  1555. if (!n.eq("ctx", "")) {
  1556. Node var = Variaveis.Get(n.G("ctx"));
  1557. // System.out.println("");
  1558. // __genParam("&" + gerarVariavel(var));
  1559. // code.Add(new Instruction()
  1560. // .S("", PushLabel));
  1561. // gerarVariavel(var)
  1562. __genParam(gerarVariavel(var));
  1563. argsNum++;
  1564. }
  1565. // Gera os argumentos
  1566. Node args = n.find("arguments").find("exprs");
  1567. if (args != null) {
  1568. for (Node param : args.childrens()) {
  1569. // Processa o argumento para obter o _return
  1570. visit(param);
  1571. // Cria a instrução de parametro
  1572. __genParam(param.G("_return"));
  1573. }
  1574. argsNum += args.getChildrenCount();
  1575. }
  1576. // System.out.println("GenCall:" + n.getText());
  1577. Node def = Functions.Get(n.getText());
  1578. genFunction(n.getText(), def);
  1579. // Cria a instrução de chamada
  1580. Instruction r = __gerarCall(n.getText(), "" + argsNum, getIdMaster(), def.find("dec.return"));
  1581. // System.out.println("CALL -> " + r.getList("returns"));
  1582. n.addList("returns", r.getList("returns"));
  1583. }
  1584. protected String UnaryResolve(String op, String value) throws Exception {
  1585. switch (op) {
  1586. case "-":
  1587. return "-" + value;
  1588. case "!":
  1589. return "" + (value.equalsIgnoreCase("false") || value.equals("0") ? "1" : "0");
  1590. }
  1591. throw new Exception(String.format("Invalid [%s]%s ", op, value));
  1592. }
  1593. /*Fim dos laços*/
  1594. /*Inicio das operacoes aritimeticas*/
  1595. /**
  1596. * Unary pode Ser uma expreSSão do tipo <br>
  1597. * (&|*)addreSS - operacao de ponteiroS <br>
  1598. * (-) addreSS|value - negação aritimetica <br>
  1599. * (!) addreSS|value - negação booleana
  1600. *
  1601. * @param n
  1602. * @throws Exception
  1603. */
  1604. protected void unaryStmt(Node n) throws Exception {
  1605. String op = n.childrens().get(0).getText().trim();
  1606. Node value = n.childrens().get(1);
  1607. visit(value);
  1608. String _ret,
  1609. _val = value.G("_return");
  1610. // Se for escrita verifica se é escrita no ponteir ou no lugar referenciado
  1611. if (Api.IsValue(_val)) {
  1612. _ret = UnaryResolve(op, _val);
  1613. // } else {
  1614. } else if (n.eq("access", "write")) {
  1615. _ret = "ERR";
  1616. n.S("dst.pointer", op);
  1617. } else {
  1618. // System.out.println("N:[" + n.G("id") + "]");
  1619. _ret = gerarVariavel("T");
  1620. // System.out.println("Unary:" + n.childrens().G(1));
  1621. String type;
  1622. if (AddressOperator.matcher(op).matches()) {
  1623. type = "pointer_assignment";
  1624. } else {
  1625. type = "unary";
  1626. }
  1627. Instruction r = new Instruction()
  1628. .S("type", type)
  1629. .S("format", type)
  1630. .S("dst", _ret)
  1631. .S("p1", _val)
  1632. .S("op", op)
  1633. .S("copymode", "unary")
  1634. .S("p1value", "" + Api.IsValue(_val))
  1635. .set("locker", getIdMaster());
  1636. code.Add(r);
  1637. // System.out.println("N:" + n);
  1638. // throw new Exception("Unary Stmt not defined");
  1639. }
  1640. n.S("_return", _ret);
  1641. // System.out.println("UnaryStmt:[" + _val + ":" + op + "]" + n);
  1642. }
  1643. protected Integer _ExprResolve(String op, String p1, String p2) throws Exception {
  1644. int p1v = Integer.parseInt(p1),
  1645. p2v = Integer.parseInt(p2);
  1646. switch (op.substring(0, 1)) {
  1647. case "+":
  1648. return p1v + p2v;
  1649. case "-":
  1650. return p1v - p2v;
  1651. case "*":
  1652. return p1v * p2v;
  1653. case "/":
  1654. return p1v / p2v;
  1655. case "%":
  1656. return p1v % p2v;
  1657. }
  1658. return null;
  1659. }
  1660. protected Instruction __exp(String op, String p1, String p2, String ret) throws Exception {
  1661. boolean p1value = Api.IsValue(p1),
  1662. p2value = Api.IsValue(p2);
  1663. String unsigned = "false";
  1664. if (op.contains("u")) {
  1665. op = op.replace("u", "");
  1666. unsigned = "true";
  1667. }
  1668. Instruction r = new Instruction();
  1669. if (p1value && p2value) {
  1670. r.S("type", "copy")
  1671. .S("format", "copy")
  1672. .S("p1value", "true")
  1673. .S("p1", "" + _ExprResolve(op, p1, p2));
  1674. } else {
  1675. r.S("type", "assign")
  1676. .S("format", "assign")
  1677. .S("cat", "exp")
  1678. .S("p1", p1)
  1679. .S("p2", p2)
  1680. .S("copymode", "assign")
  1681. .S("p1value", "" + p1value)
  1682. .S("p2value", "" + p2value);
  1683. // System.out.println("__EXP:"+p1value+":"+p2value);
  1684. }
  1685. r.S("dst", ret)
  1686. .S("op", op)
  1687. .S("op.unsigned", unsigned)
  1688. .set("locker", getIdMaster());
  1689. return code.Add(r);
  1690. }
  1691. /**
  1692. * Gera Salto para inStruçõeS de continue e break;
  1693. *
  1694. * @param n
  1695. * @throws Exception
  1696. */
  1697. protected void ctrlStmt(Node n) throws Exception {
  1698. String go;
  1699. Node ctn = n.closest("for.stmt,switch.stmt", "class");
  1700. switch (n.getText()) {
  1701. case "continue":
  1702. go = ctn.G(ctn.eq("class", "for.stmt") ? "inc" : "end");
  1703. break;
  1704. case "break":
  1705. go = ctn.G("end");
  1706. break;
  1707. case "goto":
  1708. go = n.G("label");
  1709. break;
  1710. default:
  1711. throw new Exception("Undefined ctrl stmt '" + n.getText() + "'.");
  1712. }
  1713. _goto(go);
  1714. }
  1715. /**
  1716. * Executa a extração do codigo baSeado na aSt, e retorna um objeto
  1717. * CodigoTreSEnderecoS contendo oS blockS em Formato de treS endereçoS.
  1718. *
  1719. * @return
  1720. * @throws Exception
  1721. */
  1722. public Code getCodigoDeTresEnderecos() throws Exception {
  1723. return run();
  1724. }
  1725. /**
  1726. * Ativa ou deSativa a otimizacao
  1727. *
  1728. * @param lc
  1729. */
  1730. public void setOtimizacao(boolean lc) {
  1731. code.setOtimizacao(lc);
  1732. }
  1733. protected void setMaster(Node n) {
  1734. master.push(n);
  1735. }
  1736. protected Node getMaster() {
  1737. return master.peek();
  1738. }
  1739. protected void setNullMaster() {
  1740. master.pop();
  1741. }
  1742. protected int getIdMaster() throws Exception {
  1743. if (master.empty()) {
  1744. return 0;
  1745. }
  1746. return master.peek().getInt("id");
  1747. }
  1748. /**
  1749. * Adiciona aS declaraçõeS bem como carregaoS parametroS e referenciaS
  1750. *
  1751. * @param n
  1752. * @throws Exception
  1753. */
  1754. protected void genPopParams(Node func) throws Exception {
  1755. int reg = 0;
  1756. String destino, atribuido;
  1757. /**
  1758. * Se for method declara e atribui o endereco a variavel
  1759. */
  1760. Node receive = func.find("receive.type");
  1761. if (receive != null) {
  1762. // atribuido = "_A" + (reg++);
  1763. // destino = clearPointer(atribuido, gerarVariavel(receive.childrens().G(0)));
  1764. destino = gerarVariavel(receive.childrens().get(0));
  1765. // copy_pointer?
  1766. Copy(Api.clearID(destino), __popParam().G("_return"), false);
  1767. }
  1768. for (Node argument : func.find("arguments").childrens()) {
  1769. for (Node arg : argument.find("ids").childrens()) {
  1770. /**
  1771. * Gera uma instrução de copia do registrador a{i},i = [0-4],
  1772. * para o endereço de memoria dos parametros
  1773. */
  1774. // atribuido = "_Ra" + (reg++);
  1775. // atribuido = "_A" + (reg++);
  1776. // System.out.println("PopArg:" + arg);
  1777. // destino = clearPointer(atribuido, gerarVariavel(arg));
  1778. // copy_pointer?
  1779. Copy(Api.clearID(gerarVariavel(arg)), __popParam().G("_return"), false);
  1780. }
  1781. }
  1782. }
  1783. protected Instruction __popParam() throws Exception {
  1784. String varname = gerarVariavel("T");
  1785. Instruction r = new Instruction()
  1786. .S("type", "pop_param")
  1787. .S("format", "pop_param")
  1788. .S("p1", varname)
  1789. .S("p1value", "false")
  1790. .S("_return", varname);
  1791. r.set("locker", getIdMaster());
  1792. code.Add(r);
  1793. return r;
  1794. }
  1795. // protected void inicializarVariaveis() throws Exception {
  1796. //// System.out.println("INICIALIZAR VARIAVEIS:");
  1797. //
  1798. // for (Node container : ast.getRoot().childrens()) {
  1799. // for (Node constant : container.findAll("dec::const,dec::var", "class", 1)) {
  1800. // visit(constant);
  1801. // }
  1802. // }
  1803. // }
  1804. protected Instruction Copy(String dst, String src, boolean address) throws Exception {
  1805. // System.out.println("TAC:Copy:" + dst + "=" + src);
  1806. String type, format, arrayPattern = ".*\\[.*\\]";
  1807. Instruction r = new Instruction();
  1808. if (dst.matches(arrayPattern) || src.matches(arrayPattern)) {
  1809. type = "indexed_assign";
  1810. format = "copy";
  1811. if (Variaveis.isArray(src)) {
  1812. r.S("src_indexed", "true");
  1813. r.S("p1.indice", Api.getIndice(src));
  1814. }
  1815. if (Variaveis.isArray(dst)) {
  1816. r.S("dst_indexed", "true");
  1817. r.S("dst.indice", Api.getIndice(dst));
  1818. } else {
  1819. r.S("dst_indexed", "false");
  1820. }
  1821. if (Variaveis.isArray(src)) {
  1822. r.S("indice", Api.getIndice(src));
  1823. }
  1824. } else {
  1825. type = format = "copy";
  1826. }
  1827. // Identifica que o valor copiado é um endereco ou valor
  1828. if (address) {
  1829. r.S("src.address", "true");
  1830. }
  1831. r.S("format", format)
  1832. .S("type", type)
  1833. .S("dst", dst)
  1834. .S("p1", src)
  1835. .S("p1value", Api.IsValue(src) + "")
  1836. .set("locker", getIdMaster());
  1837. code.Add(r);
  1838. return r;
  1839. }
  1840. /**
  1841. * Gera um PuShLabel unico
  1842. *
  1843. * @param n
  1844. * @return
  1845. */
  1846. protected String gerarLabel(Node n) {
  1847. // return code.genLabel();
  1848. return code.getCurrentBlockName() + "+_i" + (incLabel++);
  1849. }
  1850. protected String gerarLabel() {
  1851. // return code.genLabel();
  1852. return code.getCurrentBlockName() + "+_i" + (incLabel++);
  1853. }
  1854. /**
  1855. * Cria uma linha de PuShLabel no block de codigo corrente
  1856. *
  1857. * @param label String
  1858. * @throws Exception
  1859. */
  1860. protected Instruction PushLabel(String label, String type) throws Exception {
  1861. Instruction r = new Instruction()
  1862. .S("label", label)
  1863. .S("type", "label")
  1864. .S("label_type", type)
  1865. .S("format", "label")
  1866. .set("locker", getIdMaster());
  1867. return code.Add(r);
  1868. }
  1869. /**
  1870. * Gera um nome de variavel unico,
  1871. *
  1872. * @param pre prefixo da variavel
  1873. * @param n
  1874. * @return
  1875. */
  1876. protected String gerarVariavel(String pre) {
  1877. return "_" + pre + (tmpVarCount++);
  1878. }
  1879. protected String gerarVariavel(Node n) throws Exception {
  1880. String id = n.getText();
  1881. if (!varGenMap.containsKey(id)) {
  1882. varGenMap.put(id, gerarVariavelSet(id, n));
  1883. }
  1884. return varGenMap.get(id);
  1885. }
  1886. protected String gerarVariavelSet(String id, Node n) throws Exception {
  1887. Node var = Variaveis.Get(id);
  1888. String varname, alias, vn;
  1889. if (var != null) {
  1890. if (var.eq("constant", "true")) {
  1891. varname = id;
  1892. } else {
  1893. varname = var.getText();
  1894. }
  1895. // System.out.println("Variavel definida:" + varname);
  1896. } else {
  1897. varname = n.getText();
  1898. var = n;
  1899. // System.out.println("Variavel do no consultado:" + varname);
  1900. // Variaveis.Add(id, n);
  1901. }
  1902. // System.out.printf("GerarVariavelSet{%s\n,%s\n,%s\n}\n", id, varname, var);
  1903. // if (var.eq("constant", "true")) {
  1904. // System.out.printf("GerarVariavelSet{%s\n,%s\n,%s\n}\n", id, varname, var);
  1905. // }
  1906. if (varGenMap.containsKey(varname)) {
  1907. alias = varGenMap.get(varname);
  1908. // System.out.printf("GerarVariavelSet[MAPPED]{%s,%s}\n", varname, alias);
  1909. } else {
  1910. String prefix;
  1911. // System.out.println("GerarVariavelSet\n" + varname + "\n" + id + "\n" + var);
  1912. if (var.eq("class", "dec.const")) {
  1913. prefix = "C";
  1914. } else if (var.eq("global", "true")) {
  1915. prefix = "G";
  1916. } else if (var.eq("var.tmp", "true")) {
  1917. prefix = "T";
  1918. } else {
  1919. prefix = "V";
  1920. }
  1921. // System.out.println("gerarVariavelSet:" + id + var);
  1922. // System.out.println("DecVar:" + var);
  1923. // alias = var.G("pointer") + gerarVariavel(prefix);
  1924. alias = gerarVariavel(prefix);
  1925. n.S("alias", alias);
  1926. n.copy("pointer", var);
  1927. varGenMap.put(varname, alias);
  1928. // vn = var.G("scope");
  1929. int size = Tipos.Size(var.G("type")), b = 1;
  1930. // System.out.println("gerarVariavelSetVAR:" + var);
  1931. // Se for um array considera os filhos como index
  1932. if (var.eq("array", "true") && var.childrens().size() > 0) {
  1933. for (Node node : var.childrens()) {
  1934. // System.out.println("gerarVariavelSetArray:"
  1935. // + node.eq("constant", "true")
  1936. // + "\n" + node
  1937. // + "\nVARIABLE:\n" + var
  1938. // );
  1939. b *= (node.eq("constant", "true")
  1940. ? node.getInt("valueConstant")
  1941. : node.getInt("value"));
  1942. }
  1943. }
  1944. size *= b;
  1945. var.set("size", size);
  1946. // System.out.println("gerarVariave[" + prefix + "|" + id + "]:" + var);
  1947. if (!var.eq("constant", "true") || !var.in("type", new String[]{"int", "char", "bool"})) {
  1948. (prefix.equals("G") ? code.GData() : code.Block().Data()).Add(alias, var);
  1949. } else {
  1950. // System.out.println("var:" + var);
  1951. alias = var.G("valueConstant");
  1952. }
  1953. }
  1954. return alias;
  1955. }
  1956. /**
  1957. * Imprime o codigo de treS endereçoS
  1958. *
  1959. * @return
  1960. */
  1961. @Override
  1962. public String toString() {
  1963. return printVarMap() + code.toString();
  1964. }
  1965. public String printVarMap() {
  1966. StringBuilder s = new StringBuilder();
  1967. for (Map.Entry<String, String> e : varGenMap.entrySet()) {
  1968. s.append(e.getKey() + " : " + e.getValue() + "\n");
  1969. }
  1970. System.out.println("Var Map:\n" + s.toString());
  1971. return varGenMap.toString();
  1972. }
  1973. /**
  1974. * Executa a extração da aSt para codigo de treS endereçoS
  1975. *
  1976. * @throws Exception
  1977. */
  1978. public void extrair() throws Exception {
  1979. if (!inicializado) {
  1980. inicializado = true;
  1981. }
  1982. // inicializarVariaveis();
  1983. // extrairTraps();
  1984. // extrairThreads();
  1985. // extractFunctions();
  1986. // extracMethods();
  1987. main();
  1988. }
  1989. protected Instruction __gerarCall(String funcname, String numparam, int idMaster, Node returns) throws Exception {
  1990. Instruction call = __gerarCall(funcname, numparam, idMaster);
  1991. // Atribuição dos enderecos de retorn
  1992. if (returns != null) {
  1993. ArrayList<String> rts = new ArrayList<>();
  1994. String t;
  1995. for (Node r : returns.childrens()) {
  1996. t = gerarVariavel("T");
  1997. rts.add(t);
  1998. code.Add(new Instruction()
  1999. .S("type", "pop_return")
  2000. .S("format", "pop_return")
  2001. .S("p1value", "false")
  2002. .S("p1", t));
  2003. }
  2004. call.addList("returns", rts);
  2005. }
  2006. return call;
  2007. }
  2008. /**
  2009. * Gera inStrução de call
  2010. *
  2011. * @param funcname
  2012. * @param numparam
  2013. * @param idMaster
  2014. * @param variavelRetorno
  2015. * @throws Exception
  2016. */
  2017. protected Instruction __gerarCall(String funcname, String numparam, int idMaster) throws Exception {
  2018. Instruction r = new Instruction();
  2019. r.S("format", "call")
  2020. .S("type", "call")
  2021. .S("funcname", funcname)
  2022. .S("nump", numparam).set("locker", idMaster);
  2023. // if (!variavelRetorno.equals("")) {
  2024. // r.S("dst", variavelRetorno);
  2025. // }
  2026. code.Add(r);
  2027. return r;
  2028. }
  2029. }
  2030. // case "||":
  2031. // and = false;
  2032. // // Não deve inverter operacao no caso de ||
  2033. // branckInvert.push(and);
  2034. //
  2035. // _or(n);
  2036. //
  2037. // Branch(x.get(0));
  2038. // Branch(x.get(1));
  2039. //
  2040. // // Inverte a ultima operacao
  2041. // if (n.parent.eq("value", "||")) {
  2042. // }
  2043. //
  2044. //// if (!loop && branckInvert.size() == 1) {
  2045. //// Instruction last = code.Last();
  2046. //// last.S("op", Complement(last.G("op"))).S("label", n.G("next"));
  2047. //// }
  2048. // if (!x.get(0).Has("and")) {
  2049. // n.remove("and");
  2050. // }
  2051. // branckInvert.pop();
  2052. //
  2053. // break;
  2054. // default:
  2055. //// boolean empty = branckInvert.isEmpty();
  2056. ////
  2057. //// if (empty) {
  2058. //// branckInvert.push(true);
  2059. //// }
  2060. //
  2061. // visit(n);
  2062. // // Resultado do test class ou acesso a um id ou bool
  2063. // if (!n.eq("class", "expr")) {
  2064. // op = "==";
  2065. // p0 = n.G("_return");
  2066. // p1 = "1";
  2067. // } else { //(<, <=, >, >=, ==, !=)
  2068. // p0 = visit(x.get(0)).G("_return");
  2069. // p1 = visit(x.get(1)).G("_return");
  2070. // }
  2071. //
  2072. // Instruction instruction = Branch(op, p0, p1, n.G("next"));
  2073. //// instruction. ;
  2074. //// if (n.Has("false")) {
  2075. // // _goto(n.G("false"));
  2076. // // }
  2077. // // if (empty) {
  2078. // // branckInvert.pop();
  2079. // // }
  2080. // @Override
  2081. // public TacGenInterface AfterCreate(CodeProcessing p) {
  2082. // this.afterCreate.add(p);
  2083. // return this;
  2084. // }
  2085. //
  2086. // public TacGenInterface AfterCreate() throws Exception {
  2087. // for (CodeProcessing x : afterCreate) {
  2088. // x.Exec(code);
  2089. // }
  2090. // return this;
  2091. // }
  2092. // protected Instruction Branch(String op, final String p1, final String p2, String label) throws Exception {
  2093. //
  2094. // Instruction r1 = new Instruction();
  2095. // r1.S("format", "branch")
  2096. // .S("type", "branch")
  2097. // .S("op", op)
  2098. // .S("p1", p1)
  2099. // .S("p2", p2)
  2100. // .S("p1value", "" + Api.IsValue(p1))
  2101. // .S("p2value", "" + Api.IsValue(p2))
  2102. // .S("label", label);
  2103. //
  2104. //// System.out.println("Add branch:" + branckInvert.peek() + branckInvert + ">>" + (!branckInvert.isEmpty() && branckInvert.peek()) + "\n" + r1);
  2105. // code.Add(r1);
  2106. // return r1;
  2107. // }
  2108. // /**
  2109. // * ProceSSa um teSte logico AND
  2110. // *
  2111. // * @param n
  2112. // * @throws Exception
  2113. // */
  2114. // protected void _and(Node n) throws Exception {
  2115. // String attrs = "next,start,end,test,skip.test";
  2116. // Node b1 = n.getFilho(0).copy(attrs, n);
  2117. // Node b2 = n.getFilho(1).copy(attrs, n);
  2118. //
  2119. //// boolean isFor = n.eq("test.type", "for");
  2120. //// System.out.println("_AND{" + isFor + "}:" + n.G(isFor ? "and" : "next"));
  2121. //// String l = n.G(n.eq("test.type", "for") ? "and" : "next");
  2122. // b1.S("true", n.G("next"));
  2123. //// b1.S("false", b.G("false"));
  2124. //// System.out.println("_AND:" + label + "-s" + b1);
  2125. // b2.S("true", n.G("next"));
  2126. //// b2.S("false", b.G("false"));
  2127. //// b1.S("true", gerarLabel());
  2128. //// b1.S("false", b.G("false"));
  2129. ////
  2130. //// b2.S("true", b.G("true"));
  2131. //// b2.S("false", b.G("false"));
  2132. // }
  2133. // /**
  2134. // * ProceSSa um teSte logico OR
  2135. // *
  2136. // * @param n
  2137. // * @throws Exception
  2138. // */
  2139. // protected void _or(Node n) throws Exception {
  2140. //
  2141. // String attrs = "next,start,end,test,skip.test";
  2142. // Node b1 = n.getFilho(0).copy(attrs, n);
  2143. // Node b2 = n.getFilho(1).copy(attrs, n);
  2144. //
  2145. // b1.S("true", n.G("start"));
  2146. // b2.S("true", n.G("start"));
  2147. //
  2148. // }//
  2149. // protected String updateLabel(Node n) {
  2150. // String PushLabel = n.G("_return");
  2151. //// if (!PushLabel.substring(0, 1).equals("_R")) {
  2152. //// }
  2153. //// n.S("_return", PushLabel);
  2154. // return PushLabel;
  2155. // }