/*? * 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 API; import ast.Node; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Set; /** * * @author Eugenio */ public class Types { // public static AbstractSyntaxTree ast; public static HashMap _types = new HashMap<>(); // Tamanho em bytes de cada tipo public static HashMap _sizes = new HashMap<>(); public static HashMap primitiveTypes = new HashMap<>(); public static HashMap> _propList = new HashMap<>(); public static HashMap _offsetList = new HashMap<>(); public static HashMap getSizes() { return _sizes; } public static void _init() throws Exception { HashMap types = new HashMap() { { //Numeric types // uint8 the set of all unsigned 8-bit integers (0 to 255) // uint16 the set of all unsigned 16-bit integers (0 to 65535) // uint32 the set of all unsigned 32-bit integers (0 to 4294967295) // uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615) // int8 the set of all signed 8-bit integers (-128 to 127) // int16 the set of all signed 16-bit integers (-32768 to 32767) // int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) // int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) // float32 the set of all IEEE-754 32-bit floating-point numbers // float64 the set of all IEEE-754 64-bit floating-point numbers // complex64 the set of all complex numbers with float32 real and imaginary parts // complex128 the set of all complex numbers with float64 real and imaginary parts // byte alias for uint8 // rune alias for int32 put("byte", 1); put("uint8", 1); put("uint16", 2); put("uint32", 4); put("uint64", 8); put("int8", 1); put("int16", 2); put("int32", 4); put("int64", 8); put("float32", 4); put("float64", 8); put("complex64", 8); put("complex128", 16); put("bool", 1); put("char", 1); } }; String type; for (Map.Entry entry : types.entrySet()) { type = entry.getKey(); Add(type, new Node(type) .Set("size", entry.getValue()) .Set("file", "std") .Set("scope", "") .Set("primitive", "true") .Set("block", "true") // Diz que não deve editar o tipo .Set("class", "type") .Set("public", "true") ); } } // Deve ser chamada no fim da leitura do listner para atuaizar os tamanhos dos tipos public static void Update() throws Exception { Node def; for (Map.Entry entry : _types.entrySet()) { Node type = entry.getValue(); if (type.eq("block", "true")) { continue; } // Completa a definicao da struct importando os atributos herdados for (Node t : type.findAll("type", "class", 1)) { def = Get(t.Get("type")); for (Node attr : def.findAll("attr", "class")) { attr.Set("path", def.getText()); type.addFilho(attr); } } UpdateSize(type); } } protected static void UpdateSize(Node type) throws Exception { // Atualiza o tamanho to tipo int size = 0; for (Node attr : type.findAll("attr", "class")) { size += Size(attr.childrens().get(0).Get("type")); } _sizes.put(type.getText(), size); } /** * Adiciona um tipo a linguagem * * @param id * @param type * @throws java.lang.Exception */ public static void Add(String id, Node type) throws Exception { if (_types.containsKey(id)) { throw new Exception(String.format("Tipo '%s' previamente definido na linha %s", id, _types.get(id).Get("line", ""))); } if (!type.Has("public")) { type.Set("public", Base.IsPublic(id) ? "true" : "false"); } type.Set("type", id) .Set("value", id); if (type.Has("size")) { _sizes.put(id, type.getInt("size")); } _types.put(id, type); // Adiciona ao controle de tipos primitivos if (type.eq("primitive", "true")) { getPrimitiveTypes().put(type.Get("value"), 1); } } /** * Retorna verdadeiro Se o tipo exiStir * * @param type * @return true Se o tipo exiSte * @throws Exception caSo tipo não exiSta */ public static Node Get(String id) throws Exception { if (!_types.containsKey(id)) { throw new Exception(String.format("Tipo '%s' não definido.", id)); } return _types.get(id); } public static boolean Defined(String id) { return _types.containsKey(id); } public static void List() { System.out.println("Types:\n\t" + _sizes); } public static int Size(String type) throws Exception { if (!_sizes.containsKey(type)) { Node t = Get(type); UpdateSize(t); } // System.out.println("Size of <" + type + ">" + _sizes.); return _sizes.get(type); } public static int Shift(String type, ArrayList path) throws Exception { return Shift(type, path.get(path.size() - 1)); } public static int Shift(String type, String attrib) throws Exception { Node T = Get(type); String attrType; int shift = 0; // System.out.println("Shift header:" + type + ":" + attrib + ":" + T); // System.out.println("Shift:{"); for (Node attr : T.findAll("attr", "class", 1)) { attrType = attr.childrens().get(0).Get("type"); // System.out.println("Shift:" + attr.getText() + "[" + attrib + "]"); if (!attr.getText().equals(attrib)) { shift += Size(attrType); //incrementar e buscar no proximo continue; } break; } // System.out.println("}"); return shift; } public static HashMap getPrimitiveTypes() { return primitiveTypes; } public static boolean Primitive(String type) { return primitiveTypes.containsKey(type); } public static String[] getPrimitiveTypesList() { Set set = primitiveTypes.keySet(); String[] ret = new String[set.size()]; int i = 0; for (String s : set) { ret[i++] = s; } return ret; } }