IRGenerator.java 82 KB

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