123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670 |
- /*
- * 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 common.Instruction;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- /**
- *
- * @author Eugenio
- */
- public class Variables {
- public static Integer indexCount = 0;
- public static HashMap<String, Node> vars;
- public static HashMap<String, Instruction> scopes;
- public static String UNDEFINED = "undefined";
- public static String currentKey;
- public static Pattern BASEVEXPR = Pattern.compile("(\\w+(\\.@\\w+)*\\.\\w+)");
- public static String CLEARBASEVAR = "(\\w+)(\\.@\\w+)*(\\.)";
- public static String SCOPE_LEVE = "(\\.@\\w+)((\\.\\w)*)";
- public static String VARNAME = "(\\.\\w*)+";
- public static void _init() {
- vars = new HashMap<>();
- scopes = new HashMap<>();
- }
- public static void Add(String id, Node var) throws Exception {
- // System.out.println("AddVar:" + id + "\n" + var);
- if (vars.containsKey(id)) {
- String[] parts = id.split("\\.");
- throw new Exception("'" + parts[parts.length - 1] + "' previamente declarado em na linha " + vars.get(id).Get("line", ""));
- // throw new Exception("'" + id + "' previamente declarado em na linha " + vars.Get(id).Get("line", ""));
- }
- var.Set("public", Base.IsPublic(var.Get("name")) ? "true" : "false");
- // System.out.println("Add var:" + var.Get("name"));
- vars.put(id, var);
- }
- public static boolean Defined(String id) {
- return Defined(id, true);
- }
- public static boolean Defined(String id, boolean clear) {
- if (clear) {
- id = BaseVar(id);
- }
- // System.out.println("Defined:"+id+":"+vars.containsKey(id));
- return vars.containsKey(id);
- }
- public static String BaseVar(String id) {
- Matcher match = BASEVEXPR.matcher(id);
- while (match.find()) {
- return match.group(1);
- }
- return id;
- }
- public static String TypeOf(String varname) throws Exception {
- Node var = Get(varname);
- Node tmp, t;
- String type = "undefined";
- if (var != null) {
- // System.out.println("TypeOf:\n" + varname + "\n" + var + "\n" + var.contem("scope", "."));
- String path;
- if (var.contem("scope", ".")) {
- path = varname.replace(var.Get("fullname"), "");
- } else {
- ArrayList<String> parts = new ArrayList<>();
- for (String s : var.Get("fullname").split("\\.")) {
- parts.add(s);
- }
- parts.add(1, "(\\.@\\w+)+\\.");
- // System.out.println("PARTS:" + Utils.Join(parts, ""));
- path = varname.replaceFirst(Utils.Join(parts, ""), "");
- }
- // System.out.println("path:" + var.Get("fullname") + "---" + path);
- // Sem path
- if (path.length() > 0) {
- ArrayList<String> parts = new ArrayList<>(Arrays.asList(path.split("\\.")));
- parts.remove(0); // Remove a primaira parte que é uma string vazia
- String typed = var.Get("type"), attr;
- t = Types.Get(typed);
- while (parts.size() > 0) {
- if (Types.Primitive(typed)) {
- return typed;
- }
- if (t == null) {
- throw new Exception(String.format("Tipo '%s' não definido", typed));
- }
- attr = parts.remove(0);
- tmp = t.find(attr);
- if (tmp == null) {
- throw new Exception(String.format("Tipo '%s' não possui o atributo '%s'", typed, attr));
- }
- typed = tmp.find("type").Get("type");
- t = Types.Get(typed);
- }
- // System.out.println("Type:" + t + type);
- type = t.Get("type");
- } else {
- type = var.Get("type");
- }
- }
- // System.out.println("Type of:" + varname + ":" + type);
- return type;
- }
- public static Node Get(String id) {
- // System.out.println("Get VAR:" + id);
- String x = id;
- id = BaseVar(id);
- // System.out.println("Get:" + id + "=" + x);
- if (Defined(id, false)) {
- // System.out.println("Var defined:" + id);
- return vars.get(id);
- }
- List<String> items = Arrays.asList(id.split("\\."));
- // Minima representacao de uma variavel sendo o pacote e o id
- if (items.size() <= 2) {
- return null;
- }
- List<String> parts = items.subList(0, items.size() - 2);
- parts = new ArrayList<>(parts);
- parts.add(items.get(items.size() - 1));
- // System.out.println("Get ID:" + Utils.Join(parts, "."));
- return Get(Utils.Join(parts, "."));
- }
- /**
- * Metodos antigos
- */
- /**
- * Adiciona uma variavel em um eScopo
- *
- * @param name
- * @param type
- * @param scope
- * @param array
- */
- public static void add(String name, String type, String scope, Node n) {
- String key = name + ":" + scope;
- vars.put(key, n);
- if (!scopes.containsKey(scope)) {
- scopes.put(scope, new Instruction());
- }
- scopes.get(scope).Set(name, type);
- }
- public static String type(String id, String scope) {
- if (exist(id, scope)) {
- return vars.get(currentKey).Get("type");
- }
- return UNDEFINED;
- }
- /**
- * Retorna true Se uma variavel é aceSSivel de um determinado eScopo.
- *
- * @param name
- * @param scope
- * @return
- */
- public static boolean accessible(String name, String scope) {
- return type(name, scope) != UNDEFINED;
- }
- /**
- * Verifica Se uma variavel foi declarada em um determinado eScopo
- *
- * @param name
- * @param scope
- * @return
- */
- public static boolean exist(String name, String scope) {
- String key = name + ":" + scope;
- if (vars.containsKey(key)) {
- currentKey = key;
- return true;
- }
- String[] path = scope.split(",", 2);
- if (path.length == 2) {
- return exist(name, path[1]);
- }
- key = name + ":" + path[0];
- if (vars.containsKey(key)) {
- currentKey = key;
- return true;
- }
- return false;
- }
- /**
- * Verifica Se uma variavel foi declarada por meio do no da AST
- *
- * @param nome
- * @param escopo
- * @return
- */
- public static boolean exist(Node var) {
- return exist(var.getText(), var.Get("scope"));
- }
- public static Node get(Node n) {
- return exist(n) ? vars.get(currentKey) : null;
- }
- public static Node get(String name, String scope) {
- return exist(name, scope) ? vars.get(currentKey) : null;
- }
- public static String printScope(String scope) {
- if (!scopes.containsKey(scope)) {
- return "Scope " + scope + " não definido!";
- }
- return "Scope{" + scope + "}\n" + scopes.get(scope);
- }
- /**
- *
- * DAQUI PRA CIMA O RESTO APAGA
- *
- *
- */
- /**
- * Verifica Se uma dada variavel é um array
- *
- * @param varname
- * @return
- */
- public static boolean isArray(String varname) {
- return (varname.lastIndexOf("[") >= 0);
- }
- public static String clearName(String nome) {
- return nome.split("\\[")[0].replace("&", "");
- }
- // /**
- // * Retorna uma variavel em um dado escopo do programa
- // *
- // * @param nome nome da variavel
- // * @param escopo escopo da variavel (onde foi declarada)
- // * @return Node | null
- // * @throws Exception
- // */
- // public static Node var(String nome, String escopo) {
- // existe(nome, escopo);
- // return varsNodes.Get(index.Get(baseName(nome) + ":" + escopo));
- //
- // }
- //
- // /**
- // * Adiciona uma variavel em um dado escopo do programa
- // *
- // * @param nome nome da variavel
- // * @param escopo escopo da variavel (onde foi declarada)
- // * @param var no com todos os dados da variavel
- // * @throws Exception
- // */
- // public static void var(String nome, String escopo, Node var) {
- // existe(nome, escopo);
- // varsNodes.put(index.Get(baseName(nome) + ":" + escopo), var);
- // }
- //
- // public static String tipo(Node variavel) {
- // return tipo(variavel.Get("value"), variavel.Get("escopo"));
- // }
- // public static String tipo(String nome, String escopo) {
- // nome = baseName(nome);
- // try {
- // existe(nome, escopo);
- // return types.Get(index.Get(nome + ":" + escopo));
- // } catch (Exception e) {
- // return _tipo(nome, escopo);
- // }
- // }
- // protected static String _tipo(String nome, String escopo) {
- // nome = baseName(nome);
- // try {
- // String[] escopos = escopo.split(",", 2);
- // if (escopos.length == 2) {
- // return tipo(nome, escopos[1]);
- // }
- // existe(nome, escopos[0]);
- // return types.Get(index.Get(nome + ":" + escopos[0]));
- // } catch (Exception e) {
- // return null;
- // }
- // }
- // /**
- // * Retorna uma variavel do escopo, caso não a encontre vai buscar no escopo
- // * pai. Se chegar ao no root e não encontrar a variavel, será retornado o
- // * valor null.
- // *
- // * @param nome
- // * @param escopo
- // * @return
- // */
- // public static Node find(Node variavel) {
- // if (variavel == null) {
- // return null;
- // }
- // return find(variavel.getText(), variavel.Get("escopo"));
- // }
- //
- // /**
- // * Retorna uma variavel do escopo, caso não a encontre vai buscar no escopo
- // * pai. Se chegar ao no root e não encontrar a variavel, será retornado o
- // * valor null.
- // *
- // * @param nome
- // * @param escopo
- // * @return
- // */
- // public static Node find(String nome, String escopo) {
- // nome = baseName(nome);
- // return existe(nome, escopo)
- // ? varsNodes.Get(index.Get(nome + ":" + escopo))
- // : _find(nome, escopo);
- // }
- // /**
- // * Auxiliar do metodo find
- // *
- // * @param nome
- // * @param escopo
- // * @return
- // */
- // protected static Node _find(String nome, String escopo) {
- // nome = baseName(nome);
- // String[] escopos = escopo.split(",", 2);
- // if (escopos.length == 2) {
- // return find(nome, escopos[1]);
- // }
- // return existe(nome, escopos[0])
- // ? varsNodes.Get(index.Get(nome + ":" + escopos[0]))
- // : null;
- // }
- // /**
- // * Retorna o escopo onde a variavel foi declarada.
- // *
- // * @param nome
- // * @param escopo
- // * @return
- // */
- // public static String declaracao(String nome, String escopo) {
- // nome = baseName(nome);
- // try {
- // existe(nome, escopo);
- // return escopo;
- // } catch (Exception e) {
- // return _declaracao(nome, escopo);
- // }
- // }
- //
- // /**
- // * Auxiliar do metodo declaracao.
- // *
- // * @param nome
- // * @param escopo
- // * @return
- // */
- // protected static String _declaracao(String nome, String escopo) {
- // nome = baseName(nome);
- // try {
- // String[] escopos = escopo.split(",", 2);
- // if (escopos.length == 2) {
- // return declaracao(nome, escopos[1]);
- // }
- // existe(nome, escopos[0]);
- // return escopos[0];
- // } catch (Exception e) {
- // return null;
- // }
- // }
- // public static void var(int cod, Node var) {
- // varsNodes.put(cod, var);
- // }
- public static String baseName(String text) {
- return clearName(text).split("\\.")[0];
- }
- public static void print() {
- String str = "Variaveis\n";
- for (Map.Entry<String, Node> entry : vars.entrySet()) {
- String varKey = entry.getKey();
- Node value = entry.getValue();
- str += "\n" + value;
- }
- System.out.println(str);
- }
- // /**
- // * Testa ocorrencia de uma variavel, verifica se a mesma existe e se o tipo
- // * corresponde com o esperado.
- // *
- // * @param current
- // * @param tipoEsperado
- // */
- // public static boolean teste(Node current, String tipoEsperado) {
- // /*Verifica se existe declaracao da variavel*/
- // String varpath = current.getText();
- // existe(varpath, current.Get("escopo"));
- //
- //// if (Types.structAcesso(varpath)) {
- //// Types.validarAtribuicao(current);
- //// }
- // Node var = find(varpath, current.Get("escopo"));
- // if (!var.Get("tipo").equals(tipoEsperado)) {
- // return false;
- // }
- // return true;
- //
- // }
- // static String getFullName(Node param) {
- // System.out.println("\n\nFULL:" + param);
- // String indices = "";
- // Node indicesNodes = param.encontre("indices");
- // if (null != indicesNodes) {
- // for (Node ind : indicesNodes.filhos()) {
- // indices += "[" + ind.getText() + "]";
- // }
- // }
- // return param.getText() + indices;
- // }
- // protected static void verificarIndices(ArrayList<Node> acessoIndices) {
- // for (Node indice : acessoIndices) {
- // if (!indice.IsNumber("value")) {
- // AnalizadorSemantico.testExist(indice);
- // }
- // }
- // }
- // public static void acessoMatrixIsValid(Node var) throws Exception {
- // String tipoParent = var.parent.Get("tipo");
- // String atributo = ivannosysUtils.clearName(var.getText());
- // int limit, acesso, i = 0;
- //
- // Node indices = var.encontre("indices");
- //
- // /*Caso não seja acessado nenhum indice da matrix return*/
- // if (null == indices) {
- // return;
- // }
- //
- // ArrayList<Node> acessoIndices = indices.filhos();
- //
- // verificarIndices(acessoIndices);
- //
- // /*Se for declaração apenas verifica se indices são corretos*/
- // if (var.igual("class", "dec::var")) {
- // return;
- // }
- // /*Se for acesso de uma variavel e possuir indices verificar se os mesmos estao dentro dos limites*/
- // ArrayList<String> decIndices;
- // boolean isAtributo = var.igual("class", "atributo");
- // decIndices = isAtributo
- // ? Types.getIndices(var) : Variables.getIndices(var);
- // limit = decIndices.size();
- // acesso = acessoIndices.size();
- //
- //// if (acesso < limit) {
- //// throw new Exception(Api.getFormatedPosition(var) + " Matriz acesso invalido. "
- //// + "Quantidade de indices inferior ao da matriz");
- //// } else
- //// System.out.println("VAR:" + var.getText() + ",limit:" + limit + ", acesso:" + acesso);
- // if (acesso > limit) {
- // throw new Exception(Api.getFormatedPosition(var) + " Matriz acesso invalido. "
- // + "Quantidade {" + acesso + "} de indices superior ao da matriz {" + limit + "} ");
- // }
- // if (decIndices.size() != 0) {
- // return;
- // }
- //
- // for (Node indice : acessoIndices) {
- // if (indice.IsNumber("value")) {
- // limit = Integer.parseInt(decIndices.Get(i));
- // acesso = indice.GetInt("value");
- // if (acesso >= limit || acesso < 0) {
- // throw new Exception("Acesso indevido a um array, limite {"
- // + (limit - 1) + "} enquanto a tentativa foi {"
- // + acesso + "} na posição {" + i + "}");
- //
- // }
- // }
- // i++;
- // }
- //
- // Node attr = var.encontreByClass("atributo");
- // if (null == attr) {
- // return;
- // }
- // if (!temAtributo(tipoParent, atributo)) {
- // throw new Exception(" Acessando atributo [" + atributo + "] não definido no tipo[" + tipoParent + "]");
- // }
- //
- // acessoMatrixIsValid(attr);
- //
- // }
- //
- // public static ArrayList<String> getIndices(Node var) {
- // Node declaracao = find(var);
- // ArrayList<String> indices = new ArrayList<>();
- // for (Node n : declaracao.encontre("indices").filhos()) {
- // indices.add(n.getText());
- // }
- // return indices;
- // }
- //
- // public static boolean isMagica(String nome) {
- // return nome.matches("__.*__(\\[.*\\])*");
- // }
- // /**
- // * Verfica se todos os indices do acesso são numericos
- // *
- // * @param var
- // * @return
- // */
- // public static boolean todosIndicesNumericos(Node var) {
- // Node indices = var.encontre("indices");
- // if (null != indices) {
- // for (Node n : indices.filhos()) {
- // if (!n.IsNumber("value")) {
- // return false;
- // }
- // }
- // }
- // Node atributo = var.encontreByClass("atributo");
- // return (null != atributo) ? todosIndicesNumericos(atributo) : true;
- // }
- //
- // public static int tamanhoVetor(Node n) throws Exception {
- // Node indices = n.encontre("indices");
- // int size = 1;
- // if (null != indices) {
- // for (Node indice : indices.filhos()) {
- // size *= indice.GetInt("value");
- // }
- // }
- // return size;
- // }
- public static void List() {
- StringBuilder s = new StringBuilder();
- Node v;
- String index, constant, Public;
- for (String var : vars.keySet()) {
- index = "";
- constant = "";
- v = vars.get(var);
- if (v.eq("constant", "true")) {
- constant = "constant";
- }
- Public = v.eq("public", "true") ? "public" : "private";
- for (Node i : v.childrens()) {
- index += "[" + i.getText() + "]";
- }
- s.append("\t" + var + ": " + index + v.Get("type") + " [" + Public + " " + constant + "]\n");
- }
- System.out.println("Vars:\n" + s.toString());
- }
- public static String Type(String id) {
- Node var = Get(id);
- if (var == null) {
- return "undefined";
- }
- return var.Get("type");
- }
- public static int Shift(String id) throws Exception {
- Node var = Get(id);
- if (var == null) {
- return 0;
- }
- // System.out.println("Var Shift:" + id);
- String[] varparts = var.getText().split("\\.");
- String varname = varparts[varparts.length - 1];
- String[] idparts = id.split(varname + "\\.?");
- if (idparts.length == 2) {
- ArrayList<String> path = new ArrayList<>(Arrays.asList(idparts[1].split("\\.")));
- // System.out.println("shift:" + var.Get("type") + "-" + path);
- return Types.Shift(var.Get("type"), path);
- }
- // Não é acesso a um atributo
- return 0;
- }
- }
- // Node attrib = getAtributo(tipoParent, atributo);
- // if (attrib.igual("matrix", "false")) {
- // throw new Exception("Atributo [" + atributo + "] não é matrix");
- // return;
- // }
- //
- // int i = 0, limit, limitCall, acesso;
- // ArrayList<Node> tipoIndices = new ArrayList<>();
- //
- // String atributo = ivannosysUtils.clearName(var.getText());
- // boolean eDeclaracao = var.igual("class", "dec::var");
- // if (!eDeclaracao) {
- //
- // if (!temAtributo(tipoParent, atributo)) {
- // throw new Exception(" Acessando atributo [" + atributo + "] não definido no tipo[" + tipoParent + "]");
- // }
- //
- // Node attrib = getAtributo(tipoParent, atributo);
- //
- // if (attrib.igual("matrix", "false")) {
- // if (!acessoIndices.isEmpty()) {
- // throw new Exception("Atributo [" + atributo + "] não é matrix");
- // }
- // return;
- // }
- // tipoIndices = attrib.encontre("indices").getChildrens();
- // }
- //
- // for (Node indice : acessoIndices) {
- // if (!indice.eNumerico("value")) {
- // AnalizadorSemantico.testExist(indice);
- // continue;
- // } else if (!eDeclaracao) {
- // limit = tipoIndices.Get(i).GetInt("value");
- // acesso = indice.GetInt("value");
- // if (acesso >= limit || acesso < 0) {
- // throw new Exception("Acesso indevido a um array, limite {"
- // + (limit - 1) + "} enquanto a tentativa foi {"
- // + acesso + "} na posição {" + i + "}");
- //
- // }
- // }
- // i++;
- // }
|