Code.java 13 KB

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