package Portugol.Language.Criar;
import Portugol.Language.Analisador.Expressao;
import Portugol.Language.Analisador.Keyword;
import Portugol.Language.Analisador.ParteDeExpresion;
import Portugol.Language.Analisador.Simbolo;
import Portugol.Language.Analisador.Variavel;
import Portugol.Language.Utilitario.LanguageException;
import java.util.Vector;
import javax.swing.JOptionPane;
public class ExpandSe {
public static String VERSION = "Versão:2.0 \t(c)Augusto Bilabila e David Silva Barrera";
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
//------------ ----------------------------
//------------ I N S T R U C A O S E ----------------------------
//------------ ---------------------------
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
/**
* expande o ciclo
* @param begin nodo de inicip
* @param level nivel
* @param memory vector de memoria
* @throws Portugol.Language.Utils.LanguageException erro
*/
public static void ExpandIF(NodeInstruction begin , int level , Vector memory)
throws LanguageException{
//string das instrucoes
String SE = Keyword.GetTextKey( Keyword.SE);
String ENTAO = Keyword.GetTextKey( Keyword.ENTAO );
String exp = Normalize(begin.GetText());//David: Normalizado para reconocer então con acento
int endExp = exp.indexOf(ENTAO);
if(endExp < 0)
throw new LanguageException(
begin.GetCharNum(), begin.GetText(),
"SE sem ENTAO" ,
"Coloque o ENTAO no final da instrução");
// SE ocupa dois caracteres
String condicao = begin.GetText().substring(SE.length(),endExp).trim(); int cont=0,pos=0;
//David: problemas con el operador <>. ajusté el codigo para que fuera mas estricto en la
//verificación.
if(condicao.indexOf('<')!=-1 && condicao.indexOf('>') != -1){
pos = condicao.indexOf('>');
String partCond2 = condicao.substring(pos+1);
for(int i=0; i<=pos;i++){
if((condicao.charAt(i)=='<')){
cont++;
break;
}
}
for(int i=0; i<=pos;i++){
if(condicao.charAt(i)=='>'){
cont++;
break;
}
}
//coloca =/= caso o utilizador colocar <>
if(cont==2 && (condicao.indexOf('<') == condicao.indexOf('>') - 1 || condicao.indexOf('<') == condicao.indexOf('>') - 2)){//Se é umo de cada tipo, continuos con espacio o no por medio
condicao = condicao.substring(0, condicao.indexOf('<'));
condicao = ((condicao+"=/=")+partCond2).trim();
}
}
//David: solo cambie desde arriba, desde el otro comentario
// se nao for uma variavel logica
ParteDeExpresion var = Variavel.getVariable(condicao, memory);
if( (var == null || ((Simbolo) var).getType() != Simbolo.LOGICO ) &&
// uma expressao logica
Expressao.TypeExpression(condicao,memory)!= Simbolo.LOGICO)
throw new LanguageException(
begin.GetCharNum(), begin.GetText(),
"\"" + condicao + "\" Não é uma condição válida" ,
"Verifique se a condição está bem escrita");
begin.SetLevel(level);
// retirar o SE e o ENTAO i faca apenas a condicao
begin.SetText(condicao);
// defenir o tipo
begin.SetType(Keyword.SE);
NodeInstruction tmp = begin.GetNext();
//David: Fixed some errors about IF or ELSE without instructions
//ate el fin del metodo tudo trocado
NodeInstruction endIF= tmp ; // nodo onde termina o if
NodeInstruction endELSE= tmp ; // nodo onde termina o if
// incrementar o nivel
boolean firstOfSpaceTRUE_Assigned = false; //trabajando en espacio true
boolean firstOfSpaceFALSE_Assigned = false; //trabajando en espacio false
boolean In_Space_TRUE = true; //si ya se asigno el primero al espacio true o false (para ambos)
//ligar o ponteiro do verdadeiro
//-----------------------------------------------------
//ponteiro para o final do if verdade
//endIF = tmp;
boolean encerrar = false;
do{
if(tmp.GetType()== Keyword.FIMSE){
//fimse, ya terminó SE
endIF = tmp;
begin.SetNext(endIF); //ligacao directa do se ao fimse
tmp = tmp.GetNext();
endIF.SetNext(tmp);
endIF.SetLevel(level);
endIF.SetType(Keyword.CONECTOR);
if (firstOfSpaceTRUE_Assigned == false)
begin.SetIfTrue(endIF); //no há comando para TRUE
if (firstOfSpaceFALSE_Assigned == false)
begin.SetIfFalse(endIF); //no há comando para FALSE
if (In_Space_TRUE == false) //if cambió para SENAO ajustar su conector
{
endELSE.SetNext(endIF);
endELSE.SetLevel(level);
endELSE.SetType(Keyword.CONECTOR);
}
encerrar = true;
}
else
if(tmp.GetType()== Keyword.SENAO){
//comienza el SENAO
In_Space_TRUE = false;//se cambia al espacio SENAO
endELSE = tmp;
tmp = tmp.GetNext();
}
else
{
if (In_Space_TRUE == true)
{
if (firstOfSpaceTRUE_Assigned == false){
begin.SetIfTrue(tmp);
firstOfSpaceTRUE_Assigned = true;
}
}
else
{
if (firstOfSpaceFALSE_Assigned == false){
begin.SetIfFalse(tmp);
firstOfSpaceFALSE_Assigned = true;
}
}
tmp.SetLevel(level+1);
tmp = tmp.GetNext();
}
} while( !encerrar );
cont=0;
}
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
/**
* texto do ciclo
* @param begin nodo de inicio
* @return texto do ciclo
*/
public static String toString(NodeInstruction begin){
StringBuffer str = new StringBuffer();
str.append(begin.toString()+"\n");
NodeInstruction tmp = begin.GetIfTrue();
NodeInstruction end = begin.GetNext();
while( tmp != end ){
str.append(Intermediario.GetCode(tmp));
tmp = tmp.GetNext();
}
str.append("\n");
tmp = begin.GetIfFalse();
while(tmp != end){
str.append(Intermediario.GetCode(tmp));
tmp = tmp.GetNext();
}
str.append(end.toString()+ "\n");
return str.toString();
}
//-------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------
public static void CalculatePositions( NodeInstruction begin ,double Y, double X ){
double PY , PX ;
PX = 0.5/(begin.level + 1.0);
begin.SetPositionY(Y);
begin.SetPositionX(X);
NodeInstruction tmp = begin.GetIfTrue();
//fazer o if
PY = Y+1;
NodeInstruction end = begin.GetNext();
while(tmp != end){
// FluxogramVisual.ProcessNodePosition(tmp, PY , X + PX);
PY = tmp.GetPositionY() + 1;
tmp = tmp.GetNext();
}
// posicao Y do conector
end.SetPositionY(PY);
// fazer o else
tmp = begin.GetIfFalse();
PY = Y+1;
while(tmp != end){
// FluxogramVisual.ProcessNodePosition(tmp,PY , X - PX);
PY = tmp.GetPositionY() + 1;
tmp = tmp.GetNext();
}
//conector ( calcular o maximo dos ys do if e do else
if( end.GetPositionY() < PY)
end.SetPositionY(PY);
//posicao X do conector
end.SetPositionX(X);
}
//David: Agregado para permitir que se identifique ENTÃO con acento
static private String from = "ãõáéíóúàèìòùâêîôûÁÉÍÓÚÀÈÌÒÙÃÕÂÊÎÔÛçÇ";
static private String to = "AOAEIOUAEIOUAEIOUAEIOUAEIOUAOAEIOUCC";
public static String Normalize(String str){
StringBuffer tmp = new StringBuffer();
int index;
for(int i=0; i< str.length();i++ ){
index = from.indexOf(str.charAt(i));
if( index == -1 )
tmp.append(str.charAt(i));
else
tmp.append(to.charAt(index));
}
return tmp.toString().trim().toUpperCase();
}
}