Code.java 13 KB

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