IRGenerator.java 83 KB

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