BaseTacGen.java 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  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.LinkedList;
  18. import java.util.Map;
  19. import java.util.Stack;
  20. import java.util.regex.Pattern;
  21. // a0 a1
  22. // sync recebe mandando
  23. // exec recebe mandando
  24. // synexec recebe mandando
  25. /**
  26. *
  27. * @author Eugenio
  28. */
  29. public final class BaseTacGen implements TacGenInterface {
  30. protected boolean inicializado = false;
  31. protected int incLabel = 0;
  32. protected int tmpVarCount = 1;
  33. protected AbstractSyntaxTree ast;
  34. protected Code code;
  35. protected Node calEndAtt;
  36. protected Node compileParams;
  37. protected String label;
  38. protected String calEndVar;
  39. protected String calEndSize;
  40. protected String calEndTipo;
  41. protected Stack<Node> master = new Stack<>();
  42. protected ArrayList<String> line = new ArrayList<>();
  43. protected LinkedList<Boolean> branckInvert = new LinkedList<>();
  44. protected HashMap<String, String> arrayAcesso = new HashMap<>();
  45. protected HashMap<String, String> varGenMap = new HashMap<>();
  46. protected HashMap<String, String> funcGenMap = new HashMap<>();
  47. protected HashMap<String, Integer> systemCalls = new HashMap<>();
  48. protected ArrayList<String> currentMatrixvalues = new ArrayList<>();
  49. protected HashMap<String, ArrayList<String>> matrixValues = new HashMap<>();
  50. // protected ArrayList<CodeProcessing> afterCreate = new ArrayList<CodeProcessing>();
  51. protected HashMap<String, String> Complements = new HashMap<String, String>() {
  52. {
  53. put("!=", "==");
  54. put("==", "!=");
  55. put("<", ">=");
  56. put("<=", ">");
  57. put(">", "<=");
  58. put(">=", "<");
  59. }
  60. };
  61. public static Pattern AddressOperator = Pattern.compile("(\\&|\\*)");
  62. protected boolean enableOtimization = true;
  63. protected HashMap<String, String> ArrayShiftMap = new HashMap<>();
  64. public BaseTacGen() {
  65. }
  66. public BaseTacGen(AbstractSyntaxTree ast) {
  67. Ast(ast);
  68. }
  69. // @Override
  70. // public TacGenInterface AfterCreate(CodeProcessing p) {
  71. // this.afterCreate.add(p);
  72. // return this;
  73. // }
  74. //
  75. // public TacGenInterface AfterCreate() throws Exception {
  76. // for (CodeProcessing x : afterCreate) {
  77. // x.Exec(code);
  78. // }
  79. // return this;
  80. // }
  81. public void Ast(AbstractSyntaxTree ast) {
  82. this.ast = ast;
  83. code = new Code("TAC", ast);
  84. // code.AfterClose("otimization.1", new CodeOtimizadorProcessor(enableOtimization));
  85. compileParams = ast.BuildParams();
  86. code.Template(new template.Template())
  87. .Formats(new HashMap<String, String>() {
  88. {
  89. String base = "{[PAD(global.position,_addressLen,' ')]':'}{[T(1)]}{[PAD(block.position,_addressLen,' ')]':'}{[T(2)]}";
  90. String end = "{[T(2)]}{' T< '[type]' >'}";
  91. put("label", "{[PAD(global.position,_addressLen,' ')]':'}{[T(2)]}{'<'[label]'>'}':'");
  92. put("assign", base + "{[dst]}' := '{[p1]}{' '[op]' '}{[p2]}{' --'[comment]}" + end);
  93. put("pointer_assignment", base + "{[dst.pointer]}{[dst]' := '}{[op]}{[p1]}{' --'[comment]}" + end);
  94. put("unary", base + " {[dst]} ' := '{[op]' '}{[p1]} {' --'[comment]}" + end);
  95. put("copy", base + " {[dst]} ' := '{[p1]} {' --'[comment]}" + end);
  96. put("jump", base + " 'goto ' {'<'[label]'>'} {' --'[comment]}" + end);
  97. put("branch", base + " 'if '{[p1]} {' '[op]' '} {[p2]} ' goto ' {'<'[label]'>'} {' --'[comment]}" + end);
  98. put("call", base + " {[dst]' := '} 'call <' {[funcname]} '>, ' {[nump]} {' --'[comment]}" + end);
  99. put("return", base + " 'return ' {[p1]} {' --'[comment]}" + end);
  100. put("push_param", base + " 'push_param '{[p1]} {' --'[comment]}" + end);
  101. put("push_return", base + " 'push_return '{[p1]} {' --'[comment]}" + end);
  102. put("pop_param", base + " 'pop_param '{[p1]} {' --'[comment]}" + end);
  103. put("pop_return", base + " 'pop_return '{[p1]} {' --'[comment]}" + end);
  104. }
  105. });
  106. }
  107. @Override
  108. public Code Create(AbstractSyntaxTree ast, HashMap<String, String> settings) throws Exception {
  109. Ast(ast);
  110. // setOtimizacao(settings.G("clearCode").equals("true"));
  111. Code code = run();
  112. // Executa todos os tratametos definidos apos geracao do codigo
  113. // AfterCreate();
  114. printVarMap();
  115. // code.PrintData();
  116. code.Print();
  117. code.printOcorrences();
  118. return code;
  119. }
  120. protected Node visit(Node n) throws Exception {
  121. if (null == n || n.eq("visited", "true")) {
  122. return n;
  123. }
  124. n.S("visited", "true");
  125. // System.out.println("Visit:" + n.Class());
  126. switch (n.Class()) {
  127. case "dec.const":
  128. gerarConstante(n);
  129. break;
  130. case "if.stmt":
  131. IfStmts(n);
  132. break;
  133. case "selector":
  134. Selector(n);
  135. break;
  136. case "dec.var":
  137. // Log.PrintInfo("TAC", new Instruction().S("msg", "DECVAR." + n));
  138. if (n.find("exprs") != null) {
  139. n.S("class", "dec.var.short")
  140. .S("value", "dec.var.short");
  141. genAssign(n);
  142. break;
  143. }
  144. case "def.assign":
  145. genAssign(n);
  146. break;
  147. case "call":
  148. genCall(n);
  149. break;
  150. case "ID":
  151. genID(n);
  152. break;
  153. case "incdec":
  154. IncDecStmt(n);
  155. break;
  156. case "for.stmt":
  157. genFor(n);
  158. break;
  159. case "expr":
  160. _visitExpr(n);
  161. break;
  162. case "unary":
  163. unaryStmt(n);
  164. break;
  165. case "switch.stmt":
  166. switchStmt(n);
  167. break;
  168. case "test":
  169. test(n);
  170. break;
  171. case "return":
  172. visitChildrensFirst(n);
  173. break;
  174. default:
  175. visitRootFirst(n);
  176. break;
  177. }
  178. return n;
  179. }
  180. protected void genID(Node n) throws Exception {
  181. // System.out.println("GenId:" + n);
  182. Node var = Variaveis.Get(n.getText());
  183. n.S("_return", gerarVariavel(var));
  184. }
  185. protected void test(Node n) throws Exception {
  186. Node x = null;
  187. ArrayList<Node> chils = n.childrens();
  188. int size = chils.size();
  189. for (int i = 0; i < size; i++) {
  190. x = chils.get(i);
  191. visit(x);
  192. }
  193. n.copy("_return", x);
  194. }
  195. protected void IncDecStmt(Node n) throws Exception {
  196. Instruction operacao = new Instruction();
  197. String dst = gerarVariavel(n.findByClass("selector"));
  198. operacao.S("type", "assign")
  199. .S("format", "assign")
  200. .S("cat", "exp")
  201. .S("_return", "exp")
  202. .S("dst", dst)
  203. .S("p1", dst)
  204. .S("p2", "1")
  205. .S("p1value", "" + Api.IsValue(dst))
  206. .S("p2value", "true")
  207. .S("op", n.findByClass("operator").eq("value", "++") ? "+" : "-");
  208. code.Add(operacao);
  209. }
  210. protected void Selector(Node n) throws Exception {
  211. String tmp;
  212. String shift = null;
  213. n.S("copymode", "copy");
  214. switch (n.G("subclass")) {
  215. case "operand":
  216. if (n.eq("classType", "value")) {
  217. // n.S("value", Api.Value(n.getText()));
  218. n.S("_return", Api.Value(n.getText()));
  219. } else {
  220. String v = gerarVariavel(n);
  221. if (n.eq("pointer", "*") && n.eq("access", "read")) {
  222. String t = gerarVariavel("T");
  223. Copy(t, v, false);
  224. v = t;
  225. }
  226. n.S("_return", v);
  227. }
  228. // System.out.println("Seletor operand:" + n);
  229. break;
  230. case "index":
  231. // shift = n.childrens().G(0).getInt("value");
  232. // shift = n.childrens().G(0).getInt("value");
  233. shift = ArrayShift(n);
  234. case "selector":
  235. if (shift == null) {
  236. shift = "" + Variaveis.Shift(n.getText());
  237. }
  238. tmp = gerarVariavel(n) + "[" + shift + "]";
  239. if (!n.eq("access", "write")) {
  240. String t = gerarVariavel("T");
  241. Copy(t, tmp, false);
  242. tmp = t;
  243. }
  244. n.S("_return", tmp);
  245. break;
  246. case "arguments":
  247. break;
  248. }
  249. }
  250. protected String ArrayShift(Node n) throws Exception {
  251. // Cria a chave para a ocorrencia de um acesso ao array, evitando recalcular o endereco
  252. String key = n.getText();
  253. for (Node node : n.childrens()) {
  254. key += "_" + node.getText();
  255. }
  256. if (!ArrayShiftMap.containsKey(key)) {
  257. // String shift;
  258. Node var = Variaveis.Get(n.getText());
  259. // System.out.println("INDEX shift:" + n.childrens());
  260. for (int i = 0, j = 1; j < var.childrens().size(); j++) {
  261. n.childrens().get(i++).S("collNumber", var.childrens().get(j).getText());
  262. }
  263. String ret = CalcArrayAddress(n.childrens(), Tipos.Size(var.G("type")));
  264. // Se o offset for calculado em um inteiro atribui o mesmo como shift
  265. // if (Utils.isNumber(ret)) {
  266. // shift = ret;
  267. // } else {
  268. //// Se for um endereci faz a soma com o offset da varivel
  269. //// __exp("+", ret, gerarVariavel(n), ret);
  270. // shift = ret;
  271. // }
  272. ArrayShiftMap.put(key, ret);
  273. }
  274. return ArrayShiftMap.get(key);
  275. }
  276. protected String CalcArrayAddress(ArrayList<Node> childrens, int Size) throws Exception {
  277. String offset = CalcArrayAddress(childrens, Size, 0);
  278. if (Utils.isNumber(offset)) {
  279. return "" + Integer.parseInt(offset) * Size;
  280. } else {
  281. String ret = gerarVariavel("T");
  282. __exp("*", offset, "" + Size, ret).S("comment", "Element count * size(Element)");
  283. return ret;
  284. }
  285. }
  286. protected String CalcArrayAddress(ArrayList<Node> childrens, int Size, int index) throws Exception {
  287. int nindex = index + 1;
  288. Node ind = childrens.remove(0);
  289. if (childrens.size() >= 1) {
  290. String ret = CalcArrayAddress(childrens, Size, nindex);
  291. int collNumber = ind.getInt("collNumber");
  292. if (Utils.isNumber(ret) && ind.isNumber("value")) {
  293. System.out.println("CalcArray:" + ind.getInt("value") + ":" + collNumber + ":" + Integer.parseInt(ret));
  294. return "" + ((ind.getInt("value") * collNumber) + Integer.parseInt(ret));
  295. } else {
  296. String retl = gerarVariavel("T");
  297. __exp("*", gerarVariavel(ind), "" + collNumber, retl)
  298. .S("comment", "lines shift");
  299. __exp("+", retl, ret, retl)
  300. .S("comment", "colls shift");
  301. return retl;
  302. }
  303. } else {
  304. if (Utils.isNumber(ind.getText())) {
  305. return ind.getText();
  306. } else {
  307. return gerarVariavel(ind);
  308. }
  309. }
  310. }
  311. /**
  312. * ProceSSa um node:<br>
  313. * Ordem:<br>
  314. * ->Primeiro filhoS;<br>
  315. * ->No principal;<br>
  316. *
  317. * @param n
  318. * @throws Exception
  319. */
  320. protected void visitChildrensFirst(Node n) throws Exception {
  321. // System.out.println("Visit:" + n.getText());
  322. for (Node n1 : n.childrens()) {
  323. // System.out.println("Visit:" + n1.getText());
  324. visit(n1);
  325. }
  326. // System.out.println("Process:" + n.getText());
  327. processarNode(n);
  328. }
  329. /**
  330. * ProceSSa um node:<br>
  331. * Ordem:<br>
  332. * ->Primeiro filho;<br>
  333. * ->No principal;<br>
  334. * ->Segundo filho;<br>
  335. *
  336. * @param n
  337. * @throws Exception
  338. */
  339. protected void visitNoMeio(Node n) throws Exception {
  340. visit(n.getFilho(0));
  341. processarNode(n);
  342. visit(n.getFilho(1));
  343. }
  344. /**
  345. * ProceSSa um node:<br>
  346. * Ordem:<br>
  347. * ->No princial;<br>
  348. * ->DepoiS oS filhoS
  349. *
  350. * @param n
  351. * @throws Exception
  352. */
  353. protected void visitRootFirst(Node n) throws Exception {
  354. processarNode(n);
  355. for (Node n1 : n.childrens()) {
  356. visit(n1);
  357. }
  358. }
  359. /**
  360. * Aloca endereço no inicio da memoria para conStanteS ApenaS tipoS<br>
  361. * [inteiro, booleano e char]
  362. *
  363. * @param n
  364. * @throws Exception
  365. */
  366. protected void gerarConstante(Node n) throws Exception {
  367. gerarVariavel(n);
  368. // getLabel("C", n);
  369. // if (n.closest("block", "class") != null) {
  370. // code.registerVar(n.G("_return"), 1, DataFrame.TYPE_VAR);
  371. // }
  372. }
  373. /**
  374. * Executa a extração fo block principal
  375. *
  376. * @throws Exception
  377. */
  378. public void main() throws Exception {
  379. Node main = ast.getMain();
  380. // main.S("_return", Threads.getId("main"));
  381. Node stmts = main.find("stmts");
  382. if (code.OpenBlock("main")) {
  383. PushLabel("main", "block");
  384. visit(stmts);
  385. PushLabel("main-end", "block");
  386. code.CloseBlock();
  387. }
  388. }
  389. public Code run() throws Exception {
  390. if (!inicializado) {
  391. inicializado = true;
  392. main();
  393. }
  394. code.UpdatePositions();
  395. return code;
  396. }
  397. /**
  398. * ProceSSa If (ElSe'S)*
  399. *
  400. * @param n
  401. * @throws Exception
  402. */
  403. protected void IfStmts(Node n) throws Exception {
  404. String end = gerarLabel();
  405. if (n.childrens().size() > 1) { //(If)+ (else)?
  406. n.S("end", end);
  407. }
  408. for (Node stmt : n.childrens()) {
  409. switch (stmt.Class()) {
  410. case "if.case.stmt":
  411. IfCaseStmt(n, stmt);
  412. break;
  413. // Else case
  414. case "stmts":
  415. String next = gerarLabel();
  416. n.S("next", next);
  417. visit(stmt.S("next", next));
  418. // Cria um PushLabel final
  419. PushLabel(n.G("end"), "branch");
  420. // PushLabel(end);
  421. break;
  422. }
  423. }
  424. }
  425. /**
  426. * ProceSSa If, eSSe metodo deve Ser chamado pelo metodo IfStmtS
  427. *
  428. * @param n
  429. * @param _if
  430. * @throws Exception
  431. */
  432. protected void IfCaseStmt(Node n, Node _if) throws Exception {
  433. Node test = _if.first().first();
  434. Node stmts = _if.find("stmts");
  435. String next = gerarLabel();
  436. n.S("next", next);
  437. // test.S("false", next);
  438. // test.S("true", gerarLabel());
  439. test.S("and", next);
  440. test.S("next", next);
  441. test.S("or", gerarLabel());
  442. // test.S("false", next);
  443. stmts.S("next", next);
  444. // System.out.println("Open Branch:" + test.G("id"));
  445. Branch(test);
  446. // System.out.println("IF TESTE:" + test);
  447. if (test.Has("or")) {
  448. PushLabel(test.G("or"), "branch");
  449. }
  450. visit(stmts);
  451. if (n.Has("end")) {
  452. _goto(n.G("end"));
  453. }
  454. PushLabel(test.G("next"), "branch");
  455. }
  456. /**
  457. * Executa tratamento de um no eSpecifico, Selecionado pelo atributo claSS
  458. *
  459. * @param n
  460. * @throws Exception
  461. */
  462. protected void processarNode(Node n) throws Exception {
  463. switch (n.Class()) {
  464. case "return":
  465. genReturn(n);
  466. break;
  467. case "ctrl.stmt":
  468. ctrlStmt(n);
  469. break;
  470. case "label.stmt":
  471. PushLabel(n.getText(), "user");
  472. break;
  473. }
  474. }
  475. protected void _visitExpr(Node n) throws Exception {
  476. // System.out.println("VisitExpr:" + n);
  477. visit(n.childrens().get(0));
  478. visit(n.childrens().get(1));
  479. switch (n.G("subclass")) {
  480. case "arith":// ( + | - | * | / ) integer
  481. genExpArith(n);
  482. break;
  483. }
  484. }
  485. protected void Branch(Node n) throws Exception {
  486. // Se for um test class
  487. // if (n.eq("class", "test")) {
  488. // visit(n);
  489. // Branch(n.last().copy("true,false,and,or,next", n));
  490. // return;
  491. // }
  492. String op = n.getText(), p0, p1;
  493. boolean and = true;
  494. ArrayList<Node> x = n.childrens();
  495. // branckInvert.push(and);
  496. switch (op) {
  497. case "&&":
  498. // Deve inverter operacao
  499. branckInvert.push(and);
  500. _and(n);
  501. Branch(x.get(0));
  502. Branch(x.get(1));
  503. n.remove("or");
  504. branckInvert.pop();
  505. break;
  506. case "||":
  507. and = false;
  508. // Não deve inverter operacao
  509. branckInvert.push(and);
  510. _or(n);
  511. Branch(x.get(0));
  512. Branch(x.get(1));
  513. // Inverte a ultima operacao
  514. if (branckInvert.size() == 1) {
  515. Instruction last = code.Last();
  516. last.S("op", Complement(last.G("op"))).S("label", n.G("next"));
  517. }
  518. branckInvert.pop();
  519. break;
  520. default:
  521. boolean empty = branckInvert.isEmpty();
  522. if (empty) {
  523. branckInvert.push(and);
  524. }
  525. visit(n);
  526. // Resultado do test class ou acesso a um id ou bool
  527. if (!n.eq("class", "expr")) {
  528. op = "==";
  529. p0 = n.G("_return");
  530. p1 = "1";
  531. } else { //(<, <=, >, >=, ==, !=)
  532. p0 = visit(x.get(0)).G("_return");
  533. p1 = visit(x.get(1)).G("_return");
  534. }
  535. Branch(op, p0, p1, n.G("next"));
  536. if (n.Has("false")) {
  537. _goto(n.G("false"));
  538. }
  539. if (empty) {
  540. branckInvert.pop();
  541. }
  542. }
  543. if (and) {
  544. n.remove("or");
  545. }
  546. // branckInvert.pop();
  547. }
  548. protected void Branch(String op, final String p1, final String p2, String label) throws Exception {
  549. // System.out.println("Add branch:" + branckInvert.peek() + branckInvert);
  550. Instruction r1 = new Instruction();
  551. r1.S("format", "branch")
  552. .S("type", "branch")
  553. .S("op", (!branckInvert.isEmpty() && branckInvert.peek()) ? Complement(op) : op)
  554. .S("p1", p1)
  555. .S("p2", p2)
  556. .S("p1value", "" + Api.IsValue(p1))
  557. .S("p2value", "" + Api.IsValue(p2))
  558. .S("label", label);
  559. code.Add(r1);
  560. }
  561. protected String Complement(String op) {
  562. return Complements.get(op);
  563. }
  564. /**
  565. * ProceSSa um teSte logico AND
  566. *
  567. * @param n
  568. * @throws Exception
  569. */
  570. protected void _and(Node n) throws Exception {
  571. Node b1 = n.getFilho(0).copy("next,or,and", n);
  572. Node b2 = n.getFilho(1).copy("next,or,and", n);
  573. System.out.println("_AND:" + n);
  574. b1.S("true", n.G("next"));
  575. // b1.S("false", b.G("false"));
  576. b2.S("true", n.G("next"));
  577. // b2.S("false", b.G("false"));
  578. // b1.S("true", gerarLabel());
  579. // b1.S("false", b.G("false"));
  580. //
  581. // b2.S("true", b.G("true"));
  582. // b2.S("false", b.G("false"));
  583. }
  584. /**
  585. * ProceSSa um teSte logico OR
  586. *
  587. * @param n
  588. * @throws Exception
  589. */
  590. protected void _or(Node n) throws Exception {
  591. Node b1 = n.getFilho(0).copy("next,or,and", n);
  592. Node b2 = n.getFilho(1).copy("next,or,and", n);
  593. // System.out.println("Or:" + n + ":" + n.G("or"));
  594. b1.S("next", n.G("or"));
  595. b2.S("next", n.G("or"));
  596. // n.S("true", gerarLabel());
  597. // b1.S("false", gerarLabel());
  598. // Invert op
  599. // b2.S("false", b.G("true"));
  600. // b2.S("true", b.G("true"));
  601. // b2.S("false", b.G("false"));
  602. }
  603. /**
  604. * Cria uma linha de Salto para PuShLabel eSpecificado no parametro.
  605. *
  606. * @param label
  607. * @throws Exception
  608. */
  609. protected void _goto(String label) throws Exception {
  610. Instruction r = new Instruction();
  611. r.S("label", label)
  612. .S("type", "jump")
  613. .S("format", "jump")
  614. .set("locker", getIdMaster());
  615. code.Add(r);
  616. }
  617. /*Inicio das avaliacoes booleanas*/
  618. /**
  619. * Gera um linha de inStrução de retorno no block de codigo
  620. *
  621. * @param n
  622. * @throws Exception
  623. */
  624. protected void genReturn(Node n) throws Exception {
  625. Instruction nreg;
  626. ArrayList<Node> returns = n.find("exprs").childrens();
  627. for (Node ret : returns) {
  628. // System.out.println("Return p:" + ret);
  629. nreg = new Instruction()
  630. .S("type", "push_return")
  631. .S("format", "push_return")
  632. .S("p1value", "" + Api.IsValue(ret.getText()))
  633. .S("p1", ret.G("_return"));
  634. nreg.set("locker", getIdMaster());
  635. code.Add(nreg);
  636. }
  637. code.Add(new Instruction()
  638. .S("type", "return")
  639. .S("format", "return")
  640. .set("p1", returns.size())
  641. .S("p1value", "true")
  642. .set("locker", getIdMaster()));
  643. }
  644. //
  645. // protected String updateLabel(Node n) {
  646. // String PushLabel = n.G("_return");
  647. //// if (!PushLabel.substring(0, 1).equals("_R")) {
  648. //// }
  649. //// n.S("_return", PushLabel);
  650. // return PushLabel;
  651. // }
  652. /**
  653. * Gera todoS oS SaltoS de um loop for
  654. *
  655. * @param n
  656. * @throws Exception
  657. */
  658. protected void genFor(Node n) throws Exception {
  659. setMaster(n);
  660. String start = gerarLabel(), next = gerarLabel();
  661. n.S("next", next);
  662. n.S("start", start);
  663. Node stmt = n.find("stmts");
  664. stmt.S("next", start);
  665. /*Inicializacoes e atribuicoes*/
  666. visit(n.find("initialization"));
  667. // Label que marca o inicio do for
  668. PushLabel(start, "branch");
  669. Node test = n.find("test").first();
  670. // if (test.hasChildrens())
  671. // test.S("true", gerarLabel());
  672. // test.S("false", n.G("next"));
  673. // test.S("true", next);
  674. // test.S("false", n.G("next"));
  675. test.S("and", next);
  676. test.S("next", next);
  677. test.S("or", gerarLabel());
  678. Branch(test);
  679. if (test.Has("or")) {
  680. PushLabel(test.G("or"), "branch");
  681. }
  682. // PushLabel(test.G("true"), "branch");
  683. /*Executa o bloco do for*/
  684. visit(stmt);
  685. /*Executa os incrementos*/
  686. visit(n.find("increment"));
  687. /*Salta para inicio do laço*/
  688. _goto(start);
  689. /*Marca o endereço final para sair do laço*/
  690. PushLabel(test.G("next"), "branch");
  691. setNullMaster();
  692. }
  693. protected void genExpArith(Node n) throws Exception {
  694. Node op1 = n.childrens.get(0);
  695. Node op2 = n.childrens.get(1);
  696. String _op = n.getText();
  697. //
  698. //
  699. // // se os dois valores são
  700. // if (op1.eq("type", "value") && op2.eq("type", "value")) {
  701. //
  702. // n.S("_return", resolveExpr(_op, op1.G("value"), op2.G("value")));
  703. // }
  704. // if (op1.isNumber("value") && op2.isNumber("value")) {
  705. //
  706. // } else {
  707. // Inverte a ordem dos operandos se o segundo for seletor e o primeiro for valor
  708. if (op1.isNumber("value") && !op2.isNumber("value")) {
  709. Node aux = op1;
  710. op1 = op2;
  711. op2 = aux;
  712. }
  713. // System.out.println("GerarArit" + op1 + "-" + op2);
  714. String _p1 = op1.G("_return");
  715. String _p2 = op2.G("_return");
  716. String _return = gerarVariavel("T");
  717. n.S("_return", _return);
  718. Instruction instruction = __exp(_op, _p1, _p2, _return);
  719. if (instruction.eq("type", "copy")) {
  720. n.S("_p1", instruction.G("p1"));
  721. n.S("value", instruction.G("p1"));
  722. } else {
  723. n.S("_op", _op);
  724. n.S("_p1", _p1);
  725. n.S("_p2", _p2);
  726. }
  727. }
  728. /**
  729. * Para cima verificado <==>
  730. */
  731. protected void genArray(Node n) {
  732. if (n.eq("raiz", "t")) {
  733. currentMatrixvalues = new ArrayList<String>();
  734. matrixValues.put(n.G("id"), currentMatrixvalues);
  735. for (Node c : n.childrens()) {
  736. genArray(c);
  737. }
  738. } else if (n.eq("terminal", "t")) {
  739. currentMatrixvalues.add(n.getText());
  740. } else {
  741. for (Node c : n.childrens()) {
  742. genArray(c);
  743. }
  744. }
  745. }
  746. protected ArrayList<String> initValues(Node n) {
  747. ArrayList<String> values = new ArrayList<>();
  748. switch (n.G("class")) {
  749. case "_array":
  750. values = matrixValues.get(n.G("id"));
  751. break;
  752. /*valores e constantes*/
  753. default:
  754. String _return = n.G("_return");
  755. if (_return.matches("^_.*")) {
  756. _return = "0";
  757. }
  758. values.add(_return);
  759. }
  760. return values;
  761. }
  762. /**
  763. * Gera a chamada para o metodo de deSalocacao de memoria
  764. *
  765. * @param n
  766. * @throws Exception
  767. */
  768. protected void genDelete(Node n) throws Exception {
  769. for (Node address : n.childrens()) {
  770. visit(address);
  771. __genParam(address.G("_return"));
  772. __gerarCall(Functions.FREE, "1", getIdMaster());
  773. }
  774. }
  775. /**
  776. * Gera a Switch caSe
  777. *
  778. * @param n
  779. */
  780. protected void switchStmt(Node n) throws Exception {
  781. /*Label que sera consultado pelo break para sair do case*/
  782. String end = gerarLabel();
  783. String dst = null, next = null;
  784. Node test = n.find("test");
  785. n.S("next", end);
  786. // Verifica se existe entrada para selecao
  787. if (test.childrens().size() > 0) {
  788. test = test.first();
  789. visit(test);
  790. dst = test.G("_return");
  791. }
  792. ArrayList<Node> cases = n.findAll("def.case", "class", 1);
  793. int id = 0, count = cases.size() - 1;
  794. for (Node _case : cases) {
  795. if (next != null) {
  796. _case.S("start", next);
  797. }
  798. _case.S("_input", dst);
  799. _case.S("end", end);
  800. genCase(_case, id == count);
  801. next = _case.G("next");
  802. id++;
  803. }
  804. /*Marca o endereço final para sair do switch*/
  805. PushLabel(end, "branch");
  806. }
  807. protected Node NodeBoolExpr(String op, Node e1, Node e2) {
  808. return new Node(op)
  809. .S("type", "bool")
  810. .S("class", "expr")
  811. .S("subclass", "bool")
  812. .addFilho(e1)
  813. .addFilho(e2);
  814. }
  815. protected ArrayList<Node> ExprsEq(Node n, Node input) throws Exception {
  816. ArrayList<Node> list = new ArrayList<>();
  817. switch (n.Class()) {
  818. case "exprs":
  819. for (Node e : n.childrens()) {
  820. list.add(NodeBoolExpr("==", input, e));
  821. }
  822. break;
  823. default:
  824. list.add(NodeBoolExpr("==", input, n));
  825. }
  826. return list;
  827. }
  828. /**
  829. * Gera oS caSeS de um Switch
  830. *
  831. * @param n
  832. */
  833. protected void genCase(Node n, boolean last) throws Exception {
  834. String start = n.Has("start") ? n.G("start") : gerarLabel();
  835. String next = gerarLabel(), end;
  836. // System.out.println("GenCase:" + start + ":" + next);
  837. ArrayList<Node> itens = n.childrens();
  838. Node stmts = n.find("stmts");
  839. Node or;
  840. if (itens.size() >= 2) { // Tem teste
  841. String input = n.G("_input");
  842. Node test = n.first();
  843. ArrayList<Node> exprs;
  844. if (input != null) {
  845. exprs = ExprsEq(test, new Node(input).S("_return", input));
  846. } else {
  847. exprs = test.childrens();
  848. }
  849. /*Seleciona o endereco de saida se é no proximo case ou no fim do switch*/
  850. if (stmts.last().eq("value", "fallthrough")) {
  851. end = gerarLabel();
  852. n.S("next", end);
  853. } else {
  854. end = n.G("end");
  855. }
  856. // Atualiza o PushLabel de sucesso das exprs
  857. for (Node expr : exprs) {
  858. expr.S("true", !last ? next : end);
  859. // expr.S("false", next);
  860. // expr.S("false", start);
  861. }
  862. Branch(OR(exprs).S("next", next));
  863. /*Se nenhum dos casos for compativel salta para o proximo*/
  864. // _goto(!last ? next : end);
  865. /*Marca o PushLabel inicial do caso*/
  866. PushLabel(start, "branch");
  867. /*Visita o bloco do case*/
  868. visit(stmts);
  869. if (!last) {
  870. /*Salta para o proximo case ou para o fim do switchcase*/
  871. _goto(end);
  872. /*Label do inicio do proximo case*/
  873. PushLabel(next, "branch");
  874. }
  875. } else { // Default statiment
  876. visit(stmts);
  877. }
  878. }
  879. protected Node OR(ArrayList<Node> n) throws Exception {
  880. switch (n.size()) {
  881. case 0:
  882. return null;
  883. case 1:
  884. return n.get(0);
  885. default:
  886. Node x = n.get(0);
  887. n.remove(x);
  888. return NodeBoolExpr("||", x, OR(n)).copy("true,false", x);
  889. }
  890. }
  891. protected int qtdByIndex(Node n) throws Exception {
  892. Node indexes = n.find("indexes");
  893. if (indexes == null) {
  894. return 1;
  895. } else {
  896. int sum = 0;
  897. for (Node index : indexes.childrens()) {
  898. sum += index.getInt("_return");
  899. }
  900. return sum;
  901. }
  902. }
  903. /**
  904. * Gera inStrução de atribuicao
  905. *
  906. * @param n
  907. * @throws Exception
  908. */
  909. protected void genAssign(Node n) throws Exception {
  910. ArrayList<String> localAttribs = new ArrayList<>(),
  911. // copymode = new ArrayList<>(),
  912. // operators = new ArrayList<>(),
  913. returns;
  914. ArrayList<Boolean> copyaddress = new ArrayList<>();
  915. String p1, declare = "" + n.getText().equals("dec.var.short");
  916. Node dsts = n.childrens().get(0);
  917. if (n.in("value", new String[]{"dec.var.short", "def.assign"})) {
  918. for (Node attrib : n.childrens().get(1).childrens()) {
  919. visit(attrib);
  920. // System.out.println("n:" + n);
  921. // System.out.println("genAssign:" + attrib.G("class") + ":" + attrib.G("value"));
  922. if (attrib.eq("class", "call")) {
  923. returns = attrib.getList("returns");
  924. if (returns != null) {
  925. for (String _return : returns) {
  926. localAttribs.add(_return);
  927. copyaddress.add(attrib.eq("subclass", "address"));
  928. }
  929. }
  930. } else if (attrib.eq("class", "index")) {
  931. System.out.println("Attr <- :" + attrib);
  932. } else if (attrib.eq("class", "literal")) {
  933. // System.out.println("literal<- :" + attrib);
  934. switch (attrib.G("subclass")) {
  935. case "array":
  936. for (Node element : attrib.find("exprs").childrens()) {
  937. visit(element);
  938. copyaddress.add(element.eq("subclass", "address"));
  939. localAttribs.add(element.G("_return"));
  940. }
  941. break;
  942. }
  943. } else {
  944. // System.out.println("Assign:" + attrib);
  945. copyaddress.add(attrib.eq("subclass", "address"));
  946. localAttribs.add(attrib.G("_return"));
  947. }
  948. }
  949. }
  950. // System.out.println("Copy::" + localAttribs);
  951. // System.out.println("Lista de atribuicoes locais:\n" + dsts + "\n>>\n" + n);
  952. // System.out.println("Lista de atribuicoes locais:\n" + dsts + "\n>>\n" + localAttribs);
  953. // Executa a copia dos valores
  954. for (int dstPosition = 0, i = 0; i < localAttribs.size(); dstPosition++) {
  955. Node d = dsts.childrens().get(dstPosition);
  956. d.S("declare", declare);
  957. visit(d);
  958. // System.out.println("D:" + d.childrens());
  959. if (d.eq("class", "unary") && d.eq("dst.pointer", "*")) {
  960. p1 = localAttribs.get(i);
  961. code.Add(new Instruction()
  962. .S("format", "pointer_assignment")
  963. .S("type", "pointer_assignment")
  964. .S("dst", d.childrens().get(1).G("_return"))
  965. .S("p1", p1)
  966. .S("p1value", "" + Api.IsValue(p1))
  967. .S("dst.pointer", "*")
  968. .set("locker", getIdMaster()));
  969. i++;
  970. // Salva o valor em memoria
  971. } else if (d.eq("array", "true")) {
  972. for (int j = 0; j < d.getInt("array_size"); j++, i++) {
  973. // System.out.println("ARRAY:" + d.G("_return") + "[" + j + "]" + " -- " + localAttribs.get(i));
  974. Copy(d.G("_return") + "[" + j + "]", localAttribs.get(i), copyaddress.get(i));
  975. }
  976. } else {
  977. // Copia valor para endereco
  978. // System.out.println("Attrib:" + d.G("_return") + "<" + localAttribs.get(i));
  979. Copy(d.G("_return"), localAttribs.get(i), copyaddress.get(i));
  980. i++;
  981. }
  982. }
  983. }
  984. protected void __genParam(String param) throws Exception {
  985. Instruction r = new Instruction();
  986. r.S("format", "push_param")
  987. .S("type", "push_param")
  988. .S("p1", param)
  989. .S("p1value", "" + Api.IsValue(param))
  990. .set("locker", getIdMaster());
  991. code.Add(r);
  992. }
  993. protected void genFunction(String id, Node func) throws Exception {
  994. if (!funcGenMap.containsKey(id)) {
  995. funcGenMap.put(id, "true");
  996. Node block = func.find("stmts");
  997. code.OpenBlock(id);
  998. /*Cria a PushLabel inicial da funcao*/
  999. PushLabel(id, "block");
  1000. /*Declara as variaveis de parametro*/
  1001. genPopParams(func);
  1002. /*Declara as variaveis de retorno caso sejam nomeadas*/
  1003. // visit(func.find("def::return"));
  1004. // System.out.println(Variaveis.printScope(func.G("scope")));
  1005. /*Processa o bloco de instrucoes*/
  1006. visit(block);
  1007. /*Cria a PushLabel final da funcao*/
  1008. PushLabel(id + "-end", "block");
  1009. code.CloseBlock();
  1010. }
  1011. }
  1012. protected void genCall(Node n) throws Exception {
  1013. int argsNum = 0;
  1014. // Se for metodo carrega o contexto no primeiro parametro
  1015. // System.out.println("GenCall:" + n);
  1016. if (!n.eq("ctx", "")) {
  1017. Node var = Variaveis.Get(n.G("ctx"));
  1018. // System.out.println("");
  1019. // __genParam("&" + gerarVariavel(var));
  1020. // code.Add(new Instruction()
  1021. // .S("", PushLabel));
  1022. // gerarVariavel(var)
  1023. __genParam(gerarVariavel(var));
  1024. argsNum++;
  1025. }
  1026. // Gera os argumentos
  1027. Node args = n.find("arguments").find("exprs");
  1028. if (args != null) {
  1029. for (Node param : args.childrens()) {
  1030. // Processa o argumento para obter o _return
  1031. visit(param);
  1032. // Cria a instrução de parametro
  1033. __genParam(param.G("_return"));
  1034. }
  1035. argsNum += args.getChildrenCount();
  1036. }
  1037. // System.out.println("GenCall:" + n.getText());
  1038. Node def = Functions.Get(n.getText());
  1039. genFunction(n.getText(), def);
  1040. // Cria a instrução de chamada
  1041. Instruction r = __gerarCall(n.getText(), "" + argsNum, getIdMaster(), def.find("dec.return"));
  1042. // System.out.println("CALL -> " + r.getList("returns"));
  1043. n.addList("returns", r.getList("returns"));
  1044. }
  1045. protected String UnaryResolve(String op, String value) throws Exception {
  1046. switch (op) {
  1047. case "-":
  1048. return "-" + value;
  1049. case "!":
  1050. return "" + (value.equalsIgnoreCase("false") || value.equals("0") ? "1" : "0");
  1051. }
  1052. throw new Exception(String.format("Invalid [%s]%s ", op, value));
  1053. }
  1054. /*Fim dos laços*/
  1055. /*Inicio das operacoes aritimeticas*/
  1056. /**
  1057. * Unary pode Ser uma expreSSão do tipo <br>
  1058. * (&|*)addreSS - operacao de ponteiroS <br>
  1059. * (-) addreSS|value - negação aritimetica <br>
  1060. * (!) addreSS|value - negação booleana
  1061. *
  1062. * @param n
  1063. * @throws Exception
  1064. */
  1065. protected void unaryStmt(Node n) throws Exception {
  1066. String op = n.childrens().get(0).getText().trim();
  1067. Node value = n.childrens().get(1);
  1068. visit(value);
  1069. String _ret,
  1070. _val = value.G("_return");
  1071. // Se for escrita verifica se é escrita no ponteir ou no lugar referenciado
  1072. if (Api.IsValue(_val)) {
  1073. _ret = UnaryResolve(op, _val);
  1074. // } else {
  1075. } else if (n.eq("access", "write")) {
  1076. _ret = "ERR";
  1077. n.S("dst.pointer", op);
  1078. } else {
  1079. // System.out.println("N:[" + n.G("id") + "]");
  1080. _ret = gerarVariavel("T");
  1081. // System.out.println("Unary:" + n.childrens().G(1));
  1082. String type;
  1083. if (AddressOperator.matcher(op).matches()) {
  1084. type = "pointer_assignment";
  1085. } else {
  1086. type = "unary";
  1087. }
  1088. Instruction r = new Instruction()
  1089. .S("type", type)
  1090. .S("format", type)
  1091. .S("dst", _ret)
  1092. .S("p1", _val)
  1093. .S("op", op)
  1094. .S("copymode", "unary")
  1095. .S("p1value", "" + Api.IsValue(_val))
  1096. .set("locker", getIdMaster());
  1097. code.Add(r);
  1098. // System.out.println("N:" + n);
  1099. // throw new Exception("Unary Stmt not defined");
  1100. }
  1101. n.S("_return", _ret);
  1102. // System.out.println("UnaryStmt:[" + _val + ":" + op + "]" + n);
  1103. }
  1104. protected Integer _ExprResolve(String op, String p1, String p2) throws Exception {
  1105. int p1v = Integer.parseInt(p1),
  1106. p2v = Integer.parseInt(p2);
  1107. switch (op) {
  1108. case "+":
  1109. return p1v + p2v;
  1110. case "-":
  1111. return p1v - p2v;
  1112. case "*":
  1113. return p1v * p2v;
  1114. case "/":
  1115. return p1v / p2v;
  1116. case "%":
  1117. return p1v % p2v;
  1118. }
  1119. return null;
  1120. }
  1121. protected Instruction __exp(String op, String p1, String p2, String ret) throws Exception {
  1122. boolean p1value = Api.IsValue(p1),
  1123. p2value = Api.IsValue(p2);
  1124. Instruction r = new Instruction();
  1125. if (p1value && p2value) {
  1126. r.S("type", "copy")
  1127. .S("format", "copy")
  1128. .S("p1value", "true")
  1129. .S("p1", "" + _ExprResolve(op, p1, p2));
  1130. } else {
  1131. r.S("type", "assign")
  1132. .S("format", "assign")
  1133. .S("cat", "exp")
  1134. .S("p1", p1)
  1135. .S("p2", p2)
  1136. .S("copymode", "assign")
  1137. .S("p1value", "" + p1value)
  1138. .S("p2value", "" + p2value);
  1139. // System.out.println("__EXP:"+p1value+":"+p2value);
  1140. }
  1141. r.S("dst", ret)
  1142. .S("op", op)
  1143. .set("locker", getIdMaster());
  1144. // System.out.println("EXP:"+r);
  1145. return code.Add(r);
  1146. }
  1147. /**
  1148. * Gera Salto para inStruçõeS de continue e break;
  1149. *
  1150. * @param n
  1151. * @throws Exception
  1152. */
  1153. protected void ctrlStmt(Node n) throws Exception {
  1154. Node container = n.closest("for.stmt,switch.stmt", "class");
  1155. switch (n.getText()) {
  1156. case "continue":
  1157. _goto(container.G("start"));
  1158. break;
  1159. case "break":
  1160. _goto(container.G("next"));
  1161. break;
  1162. case "goto":
  1163. _goto(n.G("label"));
  1164. break;
  1165. }
  1166. }
  1167. /**
  1168. * Executa a extração do codigo baSeado na aSt, e retorna um objeto
  1169. * CodigoTreSEnderecoS contendo oS blockS em Formato de treS endereçoS.
  1170. *
  1171. * @return
  1172. * @throws Exception
  1173. */
  1174. public Code getCodigoDeTresEnderecos() throws Exception {
  1175. return run();
  1176. }
  1177. /**
  1178. * Ativa ou deSativa a otimizacao
  1179. *
  1180. * @param lc
  1181. */
  1182. public void setOtimizacao(boolean lc) {
  1183. code.setOtimizacao(lc);
  1184. }
  1185. protected void setMaster(Node n) {
  1186. master.push(n);
  1187. }
  1188. protected Node getMaster() {
  1189. return master.peek();
  1190. }
  1191. protected void setNullMaster() {
  1192. master.pop();
  1193. }
  1194. protected int getIdMaster() throws Exception {
  1195. if (master.empty()) {
  1196. return 0;
  1197. }
  1198. return master.peek().getInt("id");
  1199. }
  1200. /**
  1201. * Adiciona aS declaraçõeS bem como carregaoS parametroS e referenciaS
  1202. *
  1203. * @param n
  1204. * @throws Exception
  1205. */
  1206. protected void genPopParams(Node func) throws Exception {
  1207. int reg = 0;
  1208. String destino, atribuido;
  1209. /**
  1210. * Se for method declara e atribui o endereco a variavel
  1211. */
  1212. Node receive = func.find("receive.type");
  1213. if (receive != null) {
  1214. // atribuido = "_A" + (reg++);
  1215. // destino = clearPointer(atribuido, gerarVariavel(receive.childrens().G(0)));
  1216. destino = gerarVariavel(receive.childrens().get(0));
  1217. // copy_pointer?
  1218. Copy(Api.clearID(destino), __popParam().G("_return"), false);
  1219. }
  1220. for (Node argument : func.find("arguments").childrens()) {
  1221. for (Node arg : argument.find("ids").childrens()) {
  1222. /**
  1223. * Gera uma instrução de copia do registrador a{i},i = [0-4],
  1224. * para o endereço de memoria dos parametros
  1225. */
  1226. // atribuido = "_Ra" + (reg++);
  1227. // atribuido = "_A" + (reg++);
  1228. // System.out.println("PopArg:" + arg);
  1229. // destino = clearPointer(atribuido, gerarVariavel(arg));
  1230. // copy_pointer?
  1231. Copy(Api.clearID(gerarVariavel(arg)), __popParam().G("_return"), false);
  1232. }
  1233. }
  1234. }
  1235. protected Instruction __popParam() throws Exception {
  1236. String varname = gerarVariavel("T");
  1237. Instruction r = new Instruction()
  1238. .S("type", "pop_param")
  1239. .S("format", "pop_param")
  1240. .S("p1", varname)
  1241. .S("p1value", "false")
  1242. .S("_return", varname);
  1243. r.set("locker", getIdMaster());
  1244. code.Add(r);
  1245. return r;
  1246. }
  1247. // protected void inicializarVariaveis() throws Exception {
  1248. //// System.out.println("INICIALIZAR VARIAVEIS:");
  1249. //
  1250. // for (Node container : ast.getRoot().childrens()) {
  1251. // for (Node constant : container.findAll("dec::const,dec::var", "class", 1)) {
  1252. // visit(constant);
  1253. // }
  1254. // }
  1255. // }
  1256. protected void Copy(String dst, String src, boolean address) throws Exception {
  1257. // System.out.println("TAC:Copy:" + dst + "=" + src);
  1258. String type, format, arrayPattern = ".*\\[.*\\]";
  1259. Instruction r = new Instruction();
  1260. if (dst.matches(arrayPattern) || src.matches(arrayPattern)) {
  1261. type = "indexed_assign";
  1262. format = "copy";
  1263. if (Variaveis.isArray(src)) {
  1264. r.S("src_indexed", "true");
  1265. r.S("p1.indice", Api.getIndice(src));
  1266. }
  1267. if (Variaveis.isArray(dst)) {
  1268. r.S("dst_indexed", "true");
  1269. r.S("dst.indice", Api.getIndice(dst));
  1270. } else {
  1271. r.S("dst_indexed", "false");
  1272. }
  1273. if (Variaveis.isArray(src)) {
  1274. r.S("indice", Api.getIndice(src));
  1275. }
  1276. } else {
  1277. type = format = "copy";
  1278. }
  1279. // Identifica que o valor copiado é um endereco ou valor
  1280. if (address) {
  1281. r.S("src.address", "true");
  1282. }
  1283. r.S("format", format)
  1284. .S("type", type)
  1285. .S("dst", dst)
  1286. .S("p1", src)
  1287. .S("p1value", Api.IsValue(src) + "")
  1288. .set("locker", getIdMaster());
  1289. code.Add(r);
  1290. }
  1291. /**
  1292. * Gera um PuShLabel unico
  1293. *
  1294. * @param n
  1295. * @return
  1296. */
  1297. protected String gerarLabel(Node n) {
  1298. // return code.genLabel();
  1299. return code.getCurrentBlockName() + "+_i" + (incLabel++);
  1300. }
  1301. protected String gerarLabel() {
  1302. // return code.genLabel();
  1303. return code.getCurrentBlockName() + "+_i" + (incLabel++);
  1304. }
  1305. /**
  1306. * Cria uma linha de PuShLabel no block de codigo corrente
  1307. *
  1308. * @param label String
  1309. * @throws Exception
  1310. */
  1311. protected Instruction PushLabel(String label, String type) throws Exception {
  1312. Instruction r = new Instruction()
  1313. .S("label", label)
  1314. .S("type", "label")
  1315. .S("label_type", type)
  1316. .S("format", "label")
  1317. .set("locker", getIdMaster());
  1318. return code.Add(r);
  1319. }
  1320. /**
  1321. * Gera um nome de variavel unico,
  1322. *
  1323. * @param pre prefixo da variavel
  1324. * @param n
  1325. * @return
  1326. */
  1327. protected String gerarVariavel(String pre) {
  1328. return "_" + pre + (tmpVarCount++);
  1329. }
  1330. protected String gerarVariavel(Node n) throws Exception {
  1331. String id = n.getText();
  1332. if (!varGenMap.containsKey(id)) {
  1333. varGenMap.put(id, gerarVariavelSet(id, n));
  1334. }
  1335. return varGenMap.get(id);
  1336. }
  1337. protected String gerarVariavelSet(String id, Node n) throws Exception {
  1338. Node var = Variaveis.Get(id);
  1339. String varname, alias, vn;
  1340. if (var.eq("constant", "true")) {
  1341. varname = id;
  1342. } else {
  1343. varname = var.getText();
  1344. }
  1345. // System.out.printf("GerarVariavelSet{%s\n,%s\n,%s\n}\n", id, varname, var);
  1346. // if (var.eq("constant", "true")) {
  1347. // System.out.printf("GerarVariavelSet{%s\n,%s\n,%s\n}\n", id, varname, var);
  1348. // }
  1349. if (varGenMap.containsKey(varname)) {
  1350. alias = varGenMap.get(varname);
  1351. // System.out.printf("GerarVariavelSet[MAPPED]{%s,%s}\n", varname, alias);
  1352. } else {
  1353. String prefix;
  1354. // System.out.println("GerarVariavelSet\n" + varname + "\n" + id + "\n" + var);
  1355. if (var.eq("class", "dec.const")) {
  1356. prefix = "C";
  1357. } else if (var.eq("global", "true")) {
  1358. prefix = "G";
  1359. } else {
  1360. prefix = "V";
  1361. }
  1362. // System.out.println("DecVar:" + var);
  1363. // alias = var.G("pointer") + gerarVariavel(prefix);
  1364. alias = gerarVariavel(prefix);
  1365. n.S("alias", alias);
  1366. n.copy("pointer", var);
  1367. varGenMap.put(varname, alias);
  1368. // vn = var.G("scope");
  1369. int size = Tipos.Size(var.G("type")), b = 1;
  1370. // System.out.println("gerarVariave[" + prefix + "|" + id + "]:" + var);
  1371. // Se for um array considera os filhos como index
  1372. if (!var.eq("constant", "true") && var.childrens().size() > 0) {
  1373. for (Node node : var.childrens()) {
  1374. b *= node.getInt("value");
  1375. }
  1376. }
  1377. size *= b;
  1378. var.set("size", size);
  1379. DataFrame data;
  1380. if (prefix.equals("G")) {
  1381. data = code.GData();
  1382. } else {
  1383. data = code.Block().Data();
  1384. }
  1385. data.Add(alias, var);
  1386. }
  1387. return alias;
  1388. }
  1389. /**
  1390. * Imprime o codigo de treS endereçoS
  1391. *
  1392. * @return
  1393. */
  1394. @Override
  1395. public String toString() {
  1396. return printVarMap() + code.toString();
  1397. }
  1398. public String printVarMap() {
  1399. StringBuilder s = new StringBuilder();
  1400. for (Map.Entry<String, String> e : varGenMap.entrySet()) {
  1401. s.append(e.getKey() + " : " + e.getValue() + "\n");
  1402. }
  1403. System.out.println("Var Map:\n" + s.toString());
  1404. return varGenMap.toString();
  1405. }
  1406. /**
  1407. * Executa a extração da aSt para codigo de treS endereçoS
  1408. *
  1409. * @throws Exception
  1410. */
  1411. public void extrair() throws Exception {
  1412. if (!inicializado) {
  1413. inicializado = true;
  1414. }
  1415. // inicializarVariaveis();
  1416. // extrairTraps();
  1417. // extrairThreads();
  1418. // extractFunctions();
  1419. // extracMethods();
  1420. main();
  1421. }
  1422. protected Instruction __gerarCall(String funcname, String numparam, int idMaster, Node returns) throws Exception {
  1423. Instruction call = __gerarCall(funcname, numparam, idMaster);
  1424. // Atribuição dos enderecos de retorn
  1425. if (returns != null) {
  1426. ArrayList<String> rts = new ArrayList<>();
  1427. String t;
  1428. for (Node r : returns.childrens()) {
  1429. t = gerarVariavel("T");
  1430. rts.add(t);
  1431. code.Add(new Instruction()
  1432. .S("type", "pop_return")
  1433. .S("format", "pop_return")
  1434. .S("p1value", "false")
  1435. .S("p1", t));
  1436. }
  1437. call.addList("returns", rts);
  1438. }
  1439. return call;
  1440. }
  1441. /**
  1442. * Gera inStrução de call
  1443. *
  1444. * @param funcname
  1445. * @param numparam
  1446. * @param idMaster
  1447. * @param variavelRetorno
  1448. * @throws Exception
  1449. */
  1450. protected Instruction __gerarCall(String funcname, String numparam, int idMaster) throws Exception {
  1451. Instruction r = new Instruction();
  1452. r.S("format", "call")
  1453. .S("type", "call")
  1454. .S("funcname", funcname)
  1455. .S("nump", numparam).set("locker", idMaster);
  1456. // if (!variavelRetorno.equals("")) {
  1457. // r.S("dst", variavelRetorno);
  1458. // }
  1459. code.Add(r);
  1460. return r;
  1461. }
  1462. }