IRGenerator.java 82 KB

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