package Portugol.Language.Criar; import Portugol.Language.Analisador.Keyword; import Portugol.Language.Analisador.Simbolo; import Portugol.Language.Analisador.SymbolArray; import Portugol.Language.Utilitario.IteratorCodeLine; import Portugol.Language.Utilitario.IteratorCodeParams; import Portugol.Language.Utilitario.LanguageException; import Portugol.Language.Utilitario.TrataDefLiteral; import Portugol.Language.Utilitario.Values; import java.util.Vector; public class ExpandDefinirSimbol { public static String VERSION = "Versão:2.0 \t(c)Augusto Bilabila e David Silva Barrera"; private static int SIMPLES = 0; private static int ARRAY = 1; //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- //------------ ---------------------------- //------------ V A R I A V E I S ---------------------------- //------------ --------------------------- //------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------- public static NodeInstruction ExpandVariable(NodeInstruction node, int level, Vector memory) throws LanguageException { int tipoVar = SIMPLES; // tipo simples ou array boolean isConst, isRegist; // para constante node.SetLevel(level); String alter, type, name, value = "", memValue = ""; String CONSTANTE = Keyword.GetTextKey(Keyword.CONSTANTE); String VARIAVEL = Keyword.GetTextKey(Keyword.VARIAVEL); //lugar para onde aponta node NodeInstruction originalNextNode = node.GetNext(); //David: this new object is created to keep a copy of the original node, in case of //an expantion action changes the original text, it will be used to show message errors to the user. //Separating the internal list's node and the "user written" (and almost not processed) node NodeInstruction CopyOriginalNode = new NodeInstruction(node); // uma instrucao pode desgenerar em muitos nos // com a definicao de varias variaveis ao mesmo tempo NodeInstruction prevNode = null; String instruction = node.GetText(); IteratorCodeLine tok = new IteratorCodeLine(instruction); alter = tok.current().toUpperCase(); tok.next(); //verificar se is constante ou variavel if (alter.equalsIgnoreCase(CONSTANTE)) { isConst = true; type = tok.current().toUpperCase(); tok.next(); } else if (alter.equals(VARIAVEL)) { isConst = false; type = tok.current().toUpperCase(); tok.next(); } else { isConst = false; type = alter; alter = VARIAVEL; } if (Simbolo.getType(type) == Simbolo.DESCONHECIDO) { throw new LanguageException( node.GetCharNum(), node.GetText(), type + " NÃO É UM TIPO DE SIMBOLO VÁLIDO ", " VERIFIQUE O TIPO DA CONSTANTE OU VARIÁVEL"); } //----definicao de variaveis e valores -------------------- //--------------------------------------------------------- // as variaveis estao separadas por virgulas //-------------------------------------------------------- String vars = tok.getUnprocessedString().trim(); if (vars.length() == 0) { throw new LanguageException( node.GetCharNum(), node.GetText(), " NÃO EXISTE NOME DO SÍMBOLO", " INSIRA UM NOME PARA O SÍMBOLO "); } TrataDefLiteral defLiteral = new TrataDefLiteral(type); defLiteral.tratar(vars); vars = defLiteral.getLiteral(); // iterador por virgulas IteratorCodeParams params = new IteratorCodeParams(vars); while (params.hasMoreElements()) { // definir as variaveis //David: Agora se utiliza CopyOriginalNode, it was "node" before, but once it chances starts to show //the new value and not the original one in the user code //This object is used just in error codes, to uses it's attributes for message text creation NodeInstruction newNode = null; try { newNode = DefineSymbol(alter, type, params.current(), CopyOriginalNode, memory); params.getNext(); } catch (Exception e) { if (e instanceof LanguageException) { if (((LanguageException) e).line > 0 && !((LanguageException) e).codeLine.isEmpty()) { throw e; } throw new LanguageException( node.GetCharNum(), node.GetText(), ((LanguageException) e).error, ((LanguageException) e).solution); } else { throw new LanguageException( node.GetCharNum(), node.GetText(), "O SIMBOLO NÃO PODE SER DEFINIDO", " VERIFIQUE A EXPRESSÃO"); } } //----------------- ligar os diversos nodos -------------------- if (prevNode == null) { node.SetText(newNode.GetText()); prevNode = node; } else { newNode.SetPositionY(prevNode.GetPositionY() + 1); prevNode.SetNext(newNode); prevNode = newNode; } } //------------------------------------------------------- //fazer a ligacao com o no da intrucao seguinte prevNode.SetNext(originalNextNode); //retornar o ultimo return prevNode; //------------------------------------------------------------------------------ } private static NodeInstruction DefineSymbol(String alter, String type, String code, NodeInstruction node, Vector memory) throws LanguageException { String value; String name; int pos_atr = code.indexOf(Keyword.ATRIBUI); if (pos_atr == -1) { // nao tem valores name = code.trim(); //se for constante tem de ser inicializada por isso provoca excepcao if (alter.equalsIgnoreCase(Keyword.GetTextKey(Keyword.CONSTANTE))) { throw new LanguageException( node.GetCharNum(), node.GetText(), "<" + name + "> É UMA CONSTANTE E DEVE SER INICIALIZADA", " INSIRA UM VALOR PARA O SÍMBOLO <" + name + ">"); } value = Values.getDefault(type); } else { name = code.substring(0, pos_atr).trim(); value = code.substring(pos_atr + Keyword.ATRIBUI.length()).trim(); } if (SymbolArray.isArray(name)) { return ExpandDefinirArray.Define(alter, type, name, value, node, memory); } else { return ExpandDefinirVariavel.Define(alter, type, name, value, node, memory); } } //--------------------------------------------------------------------------------------------------- public static void main(String args[]) { System.out.println("EXPAND SIMBOL"); Vector memory = new Vector(); try { NodeInstruction node = new NodeInstruction("literal a,b,c", 0, 0); ExpandVariable(node, 0, memory); } catch (Exception e) { System.out.println(e.toString()); } } }