IRGenerator.java 86 KB

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