Code.java 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  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 common;
  7. import API.CodeProcessor;
  8. import Processors.Ocorrence;
  9. import ast.AbstractSyntaxTree;
  10. import java.util.ArrayList;
  11. import java.util.HashMap;
  12. import java.util.LinkedHashMap;
  13. import java.util.LinkedList;
  14. import java.util.Map;
  15. import template.TPLInterface;
  16. import template.TemplateCtx;
  17. /**
  18. * TipoS de SentençaS: – atribuicao : x := y op z ou x := y ou x:= op y – Salto:
  19. * goto L – deSvio_condicional: if x relop y goto L – chamda_procedimento: param
  20. * x and call p,n – retorno: return y – arrayS: x := y[i] ou x[i]:=y
  21. *
  22. * @author Eugenio
  23. */
  24. public class Code {
  25. public static int uniq = 0;
  26. // public HashMap<String, String> vars;
  27. public LinkedHashMap<String, Block> stmts = new LinkedHashMap<>();
  28. public Block current;
  29. protected LinkedList<String> currentBlock = new LinkedList<>();
  30. public AbstractSyntaxTree ast;
  31. public DataFrame Data;
  32. protected boolean limparCodigo = true;
  33. protected TemplateCtx GCtx = new Instruction();
  34. public static HashMap<String, String> reverseName;
  35. public int PosicaoLabel = 0;
  36. public HashMap<String, ArrayList<String>> labels = new HashMap<>();
  37. public HashMap<String, Integer> labelsReferenceCount = new HashMap<>();
  38. protected Integer gline;
  39. protected HashMap<String, String> templates = new HashMap<>();
  40. protected HashMap<String, TPLInterface> _templates = new HashMap<>();
  41. // protected String commentPrefix = "//";
  42. protected String name;
  43. public boolean HasCall = false;
  44. protected TPLInterface TPLManager;
  45. protected int PositionIncrement = 1;
  46. // private ArrayList<CodeProcessing> processing = new ArrayList<>();
  47. public Code Parent;
  48. public Code(String id, AbstractSyntaxTree arvore) {
  49. name = id;
  50. ast = arvore;
  51. Data = new DataFrame(id, null);
  52. }
  53. public boolean HasCall() {
  54. return HasCall;
  55. }
  56. public Code(String id) {
  57. name = id;
  58. // currentBlock = new LinkedList<>();
  59. // stmts = new HashMap<>();
  60. Data = new DataFrame(id, null);
  61. }
  62. public DataFrame GData() {
  63. return Data;
  64. }
  65. public void SetData(DataFrame Data) {
  66. this.Data = Data;
  67. }
  68. public void listBlocks() {
  69. System.out.println("Blocks:" + stmts.keySet());
  70. }
  71. public void setOtimizacao(boolean lc) {
  72. limparCodigo = lc;
  73. }
  74. public boolean OpenBlock(String id) throws Exception {
  75. // if (!bloco.hasChildrens()) {
  76. // return false;
  77. // }
  78. // System.out.println("RegisterBlock:" + id);
  79. currentBlock.push(id);
  80. current = new Block(id, this);
  81. stmts.put(id, current);
  82. CodeProcessor.Trigger(this, this.Name(), "OpenBlock");
  83. // incEndereco = 0;
  84. // ocorrences = new LinkedHashMap<>();
  85. // ocorrencesPerBlocks.put(id, ocorrences);
  86. // dataFrame = new DataFrame(id);
  87. // dataFrames.put(id, dataFrame);
  88. // current = new ArrayList<>();
  89. // stmts.put(id, current);
  90. // pointerCorrente = new Instruction();
  91. // pointers.put(id, pointerCorrente);
  92. // pointerCorrente.S("initAddress", "" + posicaoLabel);
  93. // pointerCorrente.S("bloco", id);
  94. // registerVar("sp", 1, dataFrame.TYPE_STACK);
  95. // storeReturnAddress = false;
  96. // registerVar("ra", 1, dataFrame.TYPE_STACK);
  97. // AfterOpen();
  98. return true;
  99. }
  100. public void CloseBlock() throws Exception {
  101. // AfterClose();
  102. CodeProcessor.Trigger(this, this.Name(), "CloseBlock");
  103. Block().Close();
  104. currentBlock.pop();
  105. Use(currentBlock.peek());
  106. // if (!storeReturnAddress) {
  107. // dataFrame.delete("ra");
  108. // }
  109. // genRepresentation();
  110. // pointerCorrente.S("endAddress", "" + (posicaoLabel - 1));
  111. // pointerCorrente = null;
  112. // current = null;
  113. // ocorrences = null;
  114. // dataFrame = null;
  115. //
  116. }
  117. public void Use(String id) {
  118. // System.out.println("Use '" + id + "'");
  119. if (id == null || id.equals("")) {
  120. return;
  121. }
  122. current = stmts.get(id);
  123. // dataFrame = dataFrames.G(id);
  124. // pointerCorrente = pointers.G(id);
  125. }
  126. public Block Block() {
  127. return current;
  128. }
  129. public String getCodeStream() throws Exception {
  130. // Executa os tratamentos defindos para o codigo;
  131. // Processing();
  132. // Parametro para formatacao dos enderecos
  133. GCtx.Set("_addressLen", (PosicaoLabel + "").length() + "");
  134. // Definicao dos enderecos dos labels
  135. // System.out.println("UpdateLabels:{");
  136. for (Map.Entry<String, ArrayList<String>> x : labels.entrySet()) {
  137. GCtx.Set(x.getKey(), x.getValue().get(0));
  138. GCtx.Set("label." + x.getKey(), x.getValue().get(1));
  139. }
  140. // System.out.println(GCtx);
  141. // System.out.println("}");
  142. StringBuilder s = new StringBuilder();
  143. for (Map.Entry<String, Block> entry : stmts.entrySet()) {
  144. s.append(getCodeStream(entry.getKey()));
  145. }
  146. return s.toString();
  147. }
  148. public String getCodeStream(String bloco) throws Exception {
  149. StringBuilder s = new StringBuilder();
  150. String f;
  151. for (Instruction instruction : stmts.get(bloco).Instructions()) {
  152. f = FormatInstruction(instruction);
  153. if (!f.equals("")) {
  154. s.append(f).append("\n");
  155. }
  156. }
  157. return s.toString();
  158. }
  159. protected String FormatInstruction(Instruction inst) throws Exception {
  160. String format = inst.G("format");
  161. if (format.equals("norender")) {
  162. return "";
  163. }
  164. if (!_templates.containsKey(format)) {
  165. _templates.put(format, TPLManager.New(GetTemplate(format), GCtx));
  166. }
  167. // System.out.println("Format:" + inst);
  168. format = _templates.get(format).Render(inst);
  169. // System.out.println("Format:" + format + "-");
  170. return format;
  171. }
  172. protected String GetTemplate(String template) throws Exception {
  173. // System.out.println("Gettemplate:" + template + templates);
  174. if (!templates.containsKey(template)) {
  175. throw new Exception(String.format("Template '%s' não definido. {%s}", template, templates.keySet()));
  176. }
  177. return templates.get(template);
  178. }
  179. public void RemoveLabelReference(String label) {
  180. if (!labelsReferenceCount.containsKey(label)) {
  181. return;
  182. }
  183. int count = labelsReferenceCount.get(label);
  184. if (count > 0) {
  185. labelsReferenceCount.put(label, count - 1);
  186. }
  187. }
  188. public void AddLabelReference(String label) {
  189. int count = 0;
  190. if (labelsReferenceCount.containsKey(label)) {
  191. count = labelsReferenceCount.get(label);
  192. }
  193. labelsReferenceCount.put(label, count + 1);
  194. }
  195. public Instruction Add(Instruction nr) throws Exception {
  196. boolean add = true;
  197. // Se for um acesso ao label registra. a informação é utilizada para remover labels não referenciadas;
  198. switch (nr.G("type")) {
  199. case "jump":
  200. case "branch":
  201. AddLabelReference(nr.G("label"));
  202. }
  203. Instruction ur = Last();
  204. // int posicaoLocal = LocalPosition();
  205. if (ur != null) {
  206. String label = ur.G("label");
  207. switch (ur.G("format")) {
  208. case "label":
  209. //// nr.S("line", "" + (posicaoLabel--));
  210. //// nr.S("value", label + " " + nr.getText());
  211. //// nr.S("label", label);
  212. //// corrente.remove(ur);
  213. //// RegisterLabelAddress(label);
  214. break;
  215. case "jump":
  216. /**
  217. * Salto para a proxima linha quando o label da nova linha é
  218. * igual ao label do salto anterior. Remove o anterior e não
  219. * adiciona o novo
  220. */
  221. if (nr.G("format").equals("label")
  222. && label.equals(nr.G("label"))) {
  223. current.Remove(ur);
  224. add = false;
  225. }
  226. break;
  227. }
  228. }
  229. if (add) {
  230. switch (nr.G("type")) {
  231. case "call":
  232. current.HasCall = true;
  233. break;
  234. case "label":
  235. // nr.S("label.address", RegisterLabelAddress(nr.G("label")));
  236. break;
  237. }
  238. current.Add(nr);
  239. }
  240. return nr;
  241. }
  242. public Instruction Last() {
  243. if (current == null) {
  244. return null;
  245. }
  246. int size = current.Instructions().size();
  247. if (size == 0) {
  248. return null;
  249. }
  250. return current.Instructions().get(size - 1);
  251. }
  252. public String getCurrentBlockName() {
  253. return Block().getName();
  254. }
  255. public void PrintData() {
  256. System.out.println("DATA FRAME ...................");
  257. System.out.println(Data);
  258. for (Map.Entry<String, Block> entry : stmts.entrySet()) {
  259. System.out.println(entry.getValue().Data());
  260. }
  261. }
  262. public void Print() throws Exception {
  263. System.out.println("INSTRUNCTIONS FRAME ...................");
  264. System.out.println(getCodeStream());
  265. }
  266. public String Format() throws Exception {
  267. return null;
  268. }
  269. protected int LocalPosition() throws Exception {
  270. return 0;
  271. //todo verificar metodo todo
  272. // return posicaoLabel - pointerCorrente.getInt("initAddress");
  273. }
  274. public String RegisterLabelAddress(String label) {
  275. // todo verificar metodo todo
  276. // if (!labels.containsKey(label)) {
  277. // System.out.println("Registerlabel:" + label.replaceAll("\\+_i\\d+", "+" + Block().CurrentAddress));
  278. // System.out.println("label:" + label);
  279. String translated = label.replaceAll("\\+_i\\d+", "+" + Block().CurrentAddress);
  280. ArrayList<String> p = new ArrayList<>();
  281. p.add(Position() + "");
  282. p.add(translated);
  283. // System.out.println("Register label:" + label + "|" + Block().CurrentAddress);
  284. labels.put(label, p);
  285. // }
  286. return translated;
  287. }
  288. public HashMap<String, Ocorrence> getVarOcorrences(String block) throws Exception {
  289. // if (!ocorrencesPerBlocks.containsKey(block)) {
  290. // throw new Exception("Bloco '" + block + "' não definido!");
  291. // }
  292. // ocorrences = ocorrencesPerBlocks.G(block);
  293. //
  294. // ArrayList<Ocorrence> vars = new ArrayList<>();
  295. //
  296. // for (Map.Entry<String, Ocorrence> entry : ocorrences.entrySet()) {
  297. // vars.Add(entry.getValue());
  298. // }
  299. // Collections.sort(vars);
  300. HashMap<String, Ocorrence> varsOrd = new LinkedHashMap<>();
  301. // for (Ocorrence entry : vars) {
  302. // varsOrd.put(entry.var, entry);
  303. // }
  304. return varsOrd;
  305. }
  306. public static void addVarOcorrence(String var, int access) throws Exception {
  307. Ocorrence o;
  308. //todo verificar metodo todo
  309. // var = Utils.clearName(var);
  310. //
  311. // if (!ocorrences.containsKey(var)) {
  312. // o = new Ocorrence(var);
  313. // ocorrences.put(var, o);
  314. // } else {
  315. // o = ocorrences.G(var);
  316. // }
  317. //// } else if (line.equals("+1")) {
  318. // o.Add(posicaoLabel, access);
  319. }
  320. public static String reverseLabel(String var) {
  321. return reverseName.get(var.replaceAll("(\\..*|\\[.*)", ""));
  322. }
  323. boolean has(String R_RA) {
  324. throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  325. }
  326. public HashMap<String, Block> getBlocks() {
  327. return this.stmts;
  328. }
  329. public Code Formats(HashMap<String, String> templates) {
  330. this.templates = templates;
  331. return this;
  332. }
  333. // public Code CommentPrefix(String cp) {
  334. // this.commentPrefix = cp;
  335. // return this;
  336. // }
  337. // public void printOcorrences() {
  338. //// System.out.println("VARIABLES OCORRENCES ...................");
  339. //// for (Map.Entry<String, HashMap<String, Ocorrence>> entry : ocorrenciasGerais.entrySet()) {
  340. // //todo
  341. //// for (Map.Entry<String, HashMap<String, Ocorrence>> o : ocorrencesPerBlocks.entrySet()) {
  342. //// System.out.println("Block: " + o.getKey());
  343. //// for (Map.Entry<String, Ocorrence> x : o.getValue().entrySet()) {
  344. //// System.out.println(x);
  345. //// }
  346. //// }
  347. //// }
  348. // }
  349. public String Name() {
  350. return this.name;
  351. }
  352. public Code Template(TPLInterface template) {
  353. this.TPLManager = template;
  354. return this;
  355. }
  356. public String genLabel() {
  357. return getCurrentBlockName() + "+" + Block().CurrentAddress;
  358. }
  359. public void UpdatePositions() throws Exception {
  360. // Reseta a posicao inicial;
  361. PosicaoLabel = 0;
  362. for (Map.Entry<String, common.Block> x : stmts.entrySet()) {
  363. x.getValue().Update();
  364. }
  365. }
  366. public int Position() {
  367. return PosicaoLabel;
  368. }
  369. public int PositionInc() {
  370. int cur = PosicaoLabel;
  371. PosicaoLabel += PositionIncrement;
  372. return cur;
  373. }
  374. }