/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package common; import API.Types; import API.Utils; import ast.Node; import java.util.LinkedHashMap; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * * @author Eugenio */ public class DataLayout { protected String ID; protected LinkedHashMap values = new LinkedHashMap<>(); // address guarda o endereço de cada variavel protected LinkedHashMap entrys = new LinkedHashMap<>(); protected LinkedHashMap addressMap = new LinkedHashMap<>(); // Quantidade minima de bytes que protected Integer minWordSize = 1, // 8 bits // Quantidade maximo de bytes que corresponde a uma palavra maxWordSize = 4; // 32 bits protected boolean initialized = false; protected Pattern normalId = Pattern.compile("(?[\\w_]+)(\\[(?\\w+)\\])?"); //Endereço base do conjunto public Long BaseAddress = 0L; // public int offsetctrl = 0; // protected DataLayout global = null; // Guarda a quantidade de palavras do frame // É atualizado sempre que o mapeamento dos endereços sofre alteração. protected Long FrameSize = 0L; protected Long FP = 0L; public DataLayout(String ID) { this.ID = ID; } public void SetInitialized(boolean init) { initialized = init; } public Long Size() { return FrameSize; } @Override public String toString() { StringBuilder s = new StringBuilder("Data Frame <" + ID + ">:" + Size() + "\n"); DataEntry value; for (Map.Entry x : entrys.entrySet()) { value = x.getValue(); s.append(x.getKey()) .append(": ") .append(value.toString()) .append("\n"); } return s.toString(); } protected String baseName(String id) { Matcher m = normalId.matcher(id); if (m.find()) { id = m.group("id"); } return id; } protected String normalize(String id) { String shift = "0", index; Matcher m = normalId.matcher(id); if (m.find()) { id = m.group("id"); index = m.group("index"); if (Utils.IsNumber(index)) { shift = index; } } if (!id.contains(".")) { id += "." + shift; } // System.out.println("Normalize:" + id + "::" + or); return id; } public void Replace(String dst, String ori) { String rest; LinkedHashMap add = new LinkedHashMap<>(); for (Map.Entry x : this.values.entrySet()) { rest = x.getKey().replace(dst, ""); if (rest.equals("") || rest.substring(0, 1).equals(".")) { add.put(ori + rest, x.getValue()); } else { add.put(x.getKey(), x.getValue()); } } this.values = add; } void Remove(String dst) throws Exception { String alias; DataEntry de; Boolean updateFP = false; Long diff = 0L; for (Map.Entry entry : entrys.entrySet()) { alias = entry.getKey(); de = entry.getValue(); if (alias.equals(dst)) { diff = de.getSize(); FrameSize -= diff; entrys.remove(de); updateFP = true; } if (updateFP) { de.SetAddress(de.getAddress() - diff); } } FP -= diff; System.out.println("Remove:" + dst + "\n" + values); } // Pra baixo OK public Long Shift(String id) throws Exception { Long shift = 0L; Matcher m = normalId.matcher(id); if (m.find()) { String index = m.group("index"); if (Utils.IsNumber(index)) { shift = Long.parseLong(index); } } return shift; } public Offset Offset(String id) throws Exception { String var = baseName(id); Long offset = 0L, shift = Shift(id); // if (id.contains("_G") && global != null) { // return global.Offset(id); // } try { offset = entrys.get(var).getAddress(); // System.out.println("Offset from " + var); // System.out.println("Offset:" + id + ":\n" + offset); } catch (Exception e) { // System.out.println("address(" + id + ")[" + frameSize + "].:" + address + values); // System.out.println("ERROR:" + e.getMessage()); throw new Exception(String.format("Invalid offset %s in context %s.", var, ID)); } return new Offset(offset, shift); } public DataEntry Add(String alias, String type, Integer numElements) throws Exception { if (entrys.containsKey(alias)) { throw new Exception("A variavel '%s' previamente definida no frame."); } Long size = AllocSizeOf(type) * numElements; DataEntry de = new DataEntry(size); de.SetAddress(FP); // Atualiza o frame pointer FP += size; FrameSize += size; entrys.put(alias, de); return de; } protected Long AllocSizeOf(String type) throws Exception { // Se o tipo for um ponteiro retorna o tamanho maximo de uma palavra em bytes if (type.contains("*")) { return maxWordSize.longValue(); } Integer size = Types.Size(type), i = maxWordSize; while (i < size) { i += maxWordSize; } return i.longValue(); } public boolean contains(String id) { return entrys.get(id) != null; } } // System.out.println("Value:" + value); // s.append(x.getKey()) // .append(": ") // .append(value.Get("ID")) // .append("\tsize:") // .append(value.Get("size")) // .append("\tvalue:") // .append(value.Get("default.value")) // .append("\n"); // break; // protected LinkedList values = new LinkedList<>();//Map< String, String> Copy = new TreeMap<>(); // protected HashMap size = new LinkedHashMap<>(); // protected HashMap type = new LinkedHashMap<>(); // protected HashMap _offset_ = new LinkedHashMap<>(); // protected static AbstractSyntaxTree ast; // public static int TYPE_ARGUMENT = 0; // public static int TYPE_VAR = 1; // public static int TYPE_RETURN = 2; // public static int TYPE_STACK = 3; // // /** // * Formata oS haSh para a impreSSão no metoglobalo toString // * // * @param hash // * @return // */ // protected String hashToString(HashMap hash) { // String r = ""; // for (Map.Entry entry : hash.entrySet()) { // String ID = entry.getKey(); // Node value = entry.getValue(); //// int type = this.type.Get(ID); // r += "{" + ID + ":" + value + "},"; // } // return r; // } // public DataLayout copy(DataLayout data) { // String k; // for (Map.Entry x : data.values().entrySet()) { // System.out.println("Copy:" + x.getKey() + "-" + x.getValue()); // k = x.getKey(); // values.put(k, x.getValue()); // address.put(k, data.address.get(x)); // } // frameSize = data.frameSize; // return this; // } // // public void Set(String vname, Node copy) throws Exception { // values.put( // vname, // copy // ); // address.put(vname, frameSize); // frameSize += copy.getInt("size"); // } // public DataLayout Add(String alias, Node var, int elements) throws Exception { // // System.out.println("Add global to frame:" + var); //// int vSize = 1; //// int size = var.getInt("size"), vSize = 1; //// boolean isArray = var.eq("array", "true"); //// if (isArray) { //// vSize = Tipos.Size(var.Get("type")); //// } // ArrayList defaults = var.getList("default.values"); // // Integer defSize = defaults.size(); // String vname; // Node copy; // for (int i = 0; i < elements; i++) { // vname = alias + "." + i; // copy = var.copy().Set("default.value", (i < defSize ? defaults.get(i) : "0")); // Set(vname, copy); //// values.put( //// vname, //// Copy //// ); //// //// address.put(vname, frameSize); //// frameSize += Copy.getInt("size"); // } // // return this; // } // // public LinkedHashMap values() { // return values; // } // // public boolean has(String id) { // return values.containsKey(id); //// for (Map.Entry x : values.entrySet()) { //// if (x.getKey().equals(id)) { //// return true; //// } //// } //// return false; // } // public static void setAbstractSyntaxTree(AbstractSyntaxTree ast) { // DataLayout.ast = ast; // }