Code.java 13 KB

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