BaseTacGen.java 73 KB

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