areaDeInstrucoes.append("}\n}");
break;
}
case 3: //write
{
Classe pop = pilhaDeTipos.pop();
switch (pop) {
case INTEIRO:
areaDeInstrucoes
.append("call void [mscorlib]System.Console::Write(int32)\n");
break;
case REAL:
areaDeInstrucoes
.append("call void [mscorlib]System.Console::Write(float32)\n");
break;
case LITERAL:
areaDeInstrucoes
.append("call void [mscorlib]System.Console::Write(string)\n");
break;
case LOGICO:
areaDeInstrucoes
.append("call void [mscorlib]System.Console::Write(bool)\n");
break;
case DATA:
areaDeInstrucoes.append("stloc $long\n");
areaDeInstrucoes.append("ldloca $date\n");
areaDeInstrucoes.append("ldloca $date\n");
areaDeInstrucoes.append("ldloc $long\n");
areaDeInstrucoes.append("call instance void [mscorlib]System.DateTime::.ctor(int64)\n");
areaDeInstrucoes.append("ldstr \"dd/MM/yyyy\"\n");
areaDeInstrucoes.append("call instance string [mscorlib]System.DateTime::ToString(string)\n");
areaDeInstrucoes.append("call void [mscorlib]System.Console::Write(string)\n");
break;
case HORA:
//chama o metodo estatico FromMilliseconds, que jogar� o objeto resultante na pilha
areaDeInstrucoes.append("call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromMilliseconds(float64)\n");
//guarda o objeto em $time
areaDeInstrucoes.append("stloc $time\n");
areaDeInstrucoes.append("ldloca $time\n");
areaDeInstrucoes.append("call instance string [mscorlib]System.TimeSpan::ToString()\n");
areaDeInstrucoes.append("call void [mscorlib]System.Console::Write(string)\n");
break;
// case SIMBOLO_ESPECIAL: n�o tem como ser s�mbolo especial, pois daria erro sint�tico
// case IDENTIFICADOR: n�o tem como ser identificador, pois a a��o sem�ntica #24,
// que � do identificador, empilhar� o tipo do identificador em quest�o
}
break;
}
case 4: //or '|'
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == LOGICO && pop2 == LOGICO) {
pilhaDeTipos.push(LOGICO);
instrucao.append("or\n");
} else {
throw new SemanticError(String.format("tipos inv�lidos para operador or '|' (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
break;
}
case 5: //and '&'
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == LOGICO && pop2 == LOGICO) {
pilhaDeTipos.push(LOGICO);
instrucao.append("and\n");
} else {
throw new SemanticError(String.format("tipos inv�lidos para operador and '&' (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
break;
}
case 6: //true
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
pilhaDeTipos.push(LOGICO);
instrucao.append("ldc.i4.1\n");
break;
}
case 7: //false
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
pilhaDeTipos.push(LOGICO);
instrucao.append("ldc.i4.0\n");
break;
}
case 8: //nega��o '!'
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
if (pop1 == LOGICO) {
pilhaDeTipos.push(LOGICO);
instrucao.append("ldc.i4.0\n");
instrucao.append("ceq\n");
} else {
throw new SemanticError(String.format("tipo inv�lido para operador not '!' (%s)",pop1.getDescricao()), token.getLine());
}
pilhaDeTipos.push(LOGICO);
break;
}
case 9: //reconhecimento operador relacional
{
this.operadorRelacional = OperadorRelacional.getOperadorRealcionalBySimbolo(token.getLexeme());
break;
}
case 10: //opera��o relacional
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == INTEIRO && pop2 == INTEIRO) {
} else if (pop1 == REAL && pop2 == INTEIRO) {
instrucao.append("stloc $float\n");
instrucao.append("conv.r4\n");
instrucao.append("ldloc $float\n");
} else if (pop1 == INTEIRO && pop2 == REAL) {
instrucao.append("conv.r4\n");
} else if (pop1 == REAL && pop2 == REAL) {
} else if (pop1 == DATA && pop2 == DATA) {
} else if (pop1 == HORA && pop2 == HORA) {
} else if (pop1 == LITERAL && pop2 == LITERAL) {
switch(operadorRelacional) {
case IGUAL:
instrucao.append("call bool [mscorlib]System.String::Equals(string,string)\n");
break;
case DIFERENTE:
instrucao.append("call bool [mscorlib]System.String::Equals(string,string)\n");
instrucao.append("ldc.i4.0\n");
instrucao.append("ceq\n");
break;
case MENOR:
instrucao.append("call int32 [mscorlib]System.String::Compare(string,string)\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("clt\n");
break;
case MENOR_OU_IGUAL:
instrucao.append("call int32 [mscorlib]System.String::Compare(string,string)\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("cgt\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("ceq\n");
break;
case MAIOR:
instrucao.append("call int32 [mscorlib]System.String::Compare(string,string)\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("cgt\n");
break;
case MAIOR_OU_IGUAL:
instrucao.append("call int32 [mscorlib]System.String::Compare(string,string)\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("clt\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("ceq\n");
break;
}
pilhaDeTipos.push(LOGICO);
break;
} else {
throw new SemanticError(String.format("tipos inv�lidos para opera��o relacional (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
switch(operadorRelacional) {
case IGUAL:
instrucao.append("ceq\n");
break;
case DIFERENTE:
instrucao.append("ceq\n");
instrucao.append("ldc.i4.0\n");
instrucao.append("ceq\n");
break;
case MENOR:
instrucao.append("clt\n");
break;
case MENOR_OU_IGUAL:
instrucao.append("cgt\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("ceq\n");
break;
case MAIOR:
instrucao.append("cgt\n");
break;
case MAIOR_OU_IGUAL:
instrucao.append("clt\n");
instrucao.append("ldc.i4 0\n");
instrucao.append("ceq\n");
break;
}
pilhaDeTipos.push(LOGICO);
break;
}
case 11: //soma
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == INTEIRO && pop2 == INTEIRO) {
pilhaDeTipos.push(INTEIRO);
} else if (pop1 == REAL && pop2 == INTEIRO) {
pilhaDeTipos.push(REAL);
instrucao.append("stloc $float\n");
instrucao.append("conv.r4\n");
instrucao.append("ldloc $float\n");
} else if (pop1 == INTEIRO && pop2 == REAL) {
pilhaDeTipos.push(REAL);
instrucao.append("conv.r4\n");
} else if (pop1 == REAL && pop2 == REAL) {
pilhaDeTipos.push(REAL);
} else if (pop1 == DATA && pop2 == DATA) {
pilhaDeTipos.push(DATA);
} else if (pop1 == HORA && pop2 == HORA) {
pilhaDeTipos.push(HORA);
} else {
throw new SemanticError(String.format("tipos inv�lidos para soma (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
instrucao.append("add\n");
break;
}
case 12: //subtracao
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == INTEIRO && pop2 == INTEIRO) {
pilhaDeTipos.push(INTEIRO);
} else if (pop1 == REAL && pop2 == INTEIRO) {
pilhaDeTipos.push(REAL);
instrucao.append("stloc $float\n");
instrucao.append("conv.r4\n");
instrucao.append("ldloc $float\n");
} else if (pop1 == INTEIRO && pop2 == REAL) {
pilhaDeTipos.push(REAL);
instrucao.append("conv.r4\n");
} else if (pop1 == REAL && pop2 == REAL) {
pilhaDeTipos.push(REAL);
} else if (pop1 == DATA && pop2 == DATA) {
pilhaDeTipos.push(DATA);
} else if (pop1 == HORA && pop2 == HORA) {
pilhaDeTipos.push(HORA);
} else {
throw new SemanticError(String.format("tipos inv�lidos para subtra��o (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
instrucao.append("sub\n");
break;
}
case 13: //multiplicacao
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == INTEIRO && pop2 == INTEIRO) {
pilhaDeTipos.push(INTEIRO);
} else if (pop1 == REAL && pop2 == INTEIRO) {
pilhaDeTipos.push(REAL);
instrucao.append("stloc $float\n");
instrucao.append("conv.r4\n");
instrucao.append("ldloc $float\n");
} else if (pop1 == INTEIRO && pop2 == REAL) {
pilhaDeTipos.push(REAL);
instrucao.append("conv.r4\n");
} else if (pop1 == REAL && pop2 == REAL) {
pilhaDeTipos.push(REAL);
} else {
throw new SemanticError(String.format("tipos inv�lidos para multiplica��o (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
instrucao.append("mul\n");
break;
}
case 14: //divisao
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == INTEIRO && pop2 == INTEIRO) {
instrucao.append("conv.r4\n");
instrucao.append("stloc $float\n");
instrucao.append("conv.r4\n");
instrucao.append("ldloc $float\n");
} else if (pop1 == REAL && pop2 == INTEIRO) {
instrucao.append("stloc $float\n");
instrucao.append("conv.r4\n");
instrucao.append("ldloc $float\n");
} else if (pop1 == INTEIRO && pop2 == REAL) {
instrucao.append("conv.r4\n");
} else if (pop1 == REAL && pop2 == REAL) {
} else {
throw new SemanticError(String.format("tipos inv�lidos para divis�o (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
pilhaDeTipos.push(REAL);
instrucao.append("div\n");
break;
}
case 15: //quociente divis�o inteira
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == INTEIRO && pop2 == INTEIRO) {
pilhaDeTipos.push(INTEIRO);
instrucao.append("div\n");
} else {
throw new SemanticError(String.format("tipos inv�lidos para divis�o inteira (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
break;
}
case 16: //resto de divis�o inteira
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
Classe pop2 = pilhaDeTipos.pop();
if (pop1 == INTEIRO && pop2 == INTEIRO) {
pilhaDeTipos.push(INTEIRO);
instrucao.append("rem\n");
} else {
throw new SemanticError(String.format("tipos inv�lidos para resto de divis�o inteira (%s e %s)",pop2.getDescricao(),pop1.getDescricao()), token.getLine());
}
break;
}
case 17: //constante_inteira
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
instrucao.append("ldc.i4 " + token.getLexeme() + "\n");
pilhaDeTipos.push(INTEIRO);
break;
}
case 18: //constante_real
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
instrucao.append("ldc.r4 " + token.getLexeme().replace(',', '.') + "\n");
pilhaDeTipos.push(REAL);
break;
}
case 19: //constante_data
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
String strData = token.getLexeme();
GregorianCalendar gc = new GregorianCalendar();
gc.setTime(new SimpleDateFormat(strData.length() > 8 ? "dd/MM/yyyy" : "dd/MM/yy").parse(strData));
//empilha os parametros do construtor
instrucao.append("ldloca $date\n");
instrucao.append("ldc.i4 " + gc.get(GregorianCalendar.YEAR) + "\n");
instrucao.append("ldc.i4 " + (gc.get(GregorianCalendar.MONTH)+1) + "\n");
instrucao.append("ldc.i4 " + gc.get(GregorianCalendar.DAY_OF_MONTH) + "\n");
//chama o construtor do date time (year,month,day)
instrucao.append("call instance void [mscorlib]System.DateTime::.ctor(int32, int32, int32)\n");
instrucao.append("ldloca $date\n");
instrucao.append("call instance int64 [mscorlib]System.DateTime::get_Ticks()\n");
pilhaDeTipos.push(DATA);
break;
}
case 20: //constante_hora
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
String[] strHora = token.getLexeme().split(":");
int hora = Integer.valueOf(strHora[0]);
int minuto = Integer.valueOf(strHora[1]);
int segundo = strHora.length > 2 ? Integer.valueOf(strHora[2]) : 0;
//empilha os parametros do construtor
instrucao.append("ldloca $time\n");
instrucao.append("ldc.i4 " + hora + "\n");
instrucao.append("ldc.i4 " + minuto + "\n");
instrucao.append("ldc.i4 " + segundo + "\n");
//chama o construtor do timespan (hora,minuto,segundo)
instrucao.append("call instance void [mscorlib]System.TimeSpan::.ctor(int32, int32, int32)\n");
instrucao.append("ldloca $time\n");
//joga os millisegundos do timespan na pilha
instrucao.append("call instance float64 [mscorlib]System.TimeSpan::get_TotalMilliseconds()\n");
pilhaDeTipos.push(HORA);
break;
}
case 21: //constante_literal
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
instrucao.append("ldstr " + token.getLexeme() + "\n");
pilhaDeTipos.push(LITERAL);
break;
}
case 22: //numero negativo
{
StringBuilder instrucao = isVariaveisDeclaradas ? areaDeInstrucoes : valorInicializacao;
Classe pop1 = pilhaDeTipos.pop();
if(pop1 == INTEIRO) {
instrucao.append("ldc.i4 -1\n");
pilhaDeTipos.push(INTEIRO);
} else if(pop1 == REAL) {
instrucao.append("ldc.r4 -1\n");
pilhaDeTipos.push(REAL);
} else {
throw new SemanticError(String.format("tipo inv�lido para n�mero negativo (%s)",pop1.getDescricao()), token.getLine());
}
instrucao.append("mul\n");
break;
}
case 23: // declara��o e atribui��o dos identificadores
{
if(isVariaveisDeclaradas) {
// ta no meio do c�digo
if(!tabelaDeSimbolos.containsKey(token.getLexeme())) {
throw new SemanticError(String.format("identificador (%s) n�o declarado", token.getLexeme()), token.getLine());
}
listaDeIdentificadores.add(token.getLexeme());
} else {
// ta na declara��o ainda
/*Verifica se deve limpar a lista (esta flag � alterada na action #25).
Esta flag foi criada pois a action #26 tamb�m utiliza a listaDeIdentificadores, por�m ela n�o poderia
ser a responsavel por limpar a lista, visto que a action #26 � opcional*/
if(isLimparListaDeIdentificadores) {
listaDeIdentificadores.clear();
}
if(token.getLexeme().equals(nomeModulo)) {
throw new SemanticError(String.format("identificador (%s) n�o pode ter o mesmo nome do identificador do programa", token.getLexeme()), token.getLine());
}
if(tabelaDeSimbolos.containsKey(token.getLexeme()) || listaDeIdentificadores.contains(token.getLexeme())) {
throw new SemanticError(String.format("identificador (%s) j� declarado", token.getLexeme()), token.getLine());
}
listaDeIdentificadores.add(token.getLexeme());
}
break;
}
case 24: //identificador
{
if(!isVariaveisDeclaradas) {
throw new SemanticError(String.format("identificador (%s) n�o pode ser utilizado na inicializa��o de vari�veis", token.getLexeme()), token.getLine());
}
if(!tabelaDeSimbolos.containsKey(token.getLexeme())) {
throw new SemanticError(String.format("identificador (%s) n�o declarado", token.getLexeme()), token.getLine());
}
Classe classe = tabelaDeSimbolos.get(token.getLexeme());
pilhaDeTipos.push(classe);
areaDeInstrucoes.append(String.format("ldloc %s\n",token.getLexeme()));
break;
}
case 25: // definindo o tipo para o(s) identificador(es)
{
for(String id : listaDeIdentificadores) {
tabelaDeSimbolos.put(id, Classe.getClasseByDescricao(token.getLexeme()));
}
//defnie que a listaDeIdentificadores pode ser limpa, pois os identificadores j� foram inseridos na tabela de simbolos
isLimparListaDeIdentificadores = true;
break;
}
case 26: // definindo o os valores de inicializa��o para o(s) identificador(es)
{
Classe classe = tabelaDeSimbolos.get(listaDeIdentificadores.get(0));
Classe pop1 = pilhaDeTipos.pop();
if(classe != pop1) {
throw new SemanticError(String.format("tipo do identificador diferente do tipo de express�o (%s e %s)", classe.getDescricao(), pop1.getDescricao()), token.getLine());
}
for(String id : listaDeIdentificadores) {
tabelaDeInicializacao.put(id, valorInicializacao.toString());
}
//limpa o valorInicializacao para as proximas inicializacoes
valorInicializacao = new StringBuilder();
break;
}
case 27: { //exit
if(loopGeradorID.getIDAtual() == null) {
throw new SemanticError("o comando exit n�o pode ser utilizado fora de um contexto loop", token.getLine());
}
areaDeInstrucoes.append(String.format("br endloop%d\n",loopGeradorID.getIDAtual()));
break;
}
case 28: { //operador atribuicao
operadorAtrib = OperadorAtribuicao.getOperadorAtribuicaoBySimbolo(token.getLexeme());
break;
}
case 29: {//opera��o de atribui��o
Classe pop1 = pilhaDeTipos.pop();
String identificador = listaDeIdentificadores.get(0);
Classe classe = tabelaDeSimbolos.get(identificador);
if(classe != pop1 && (classe != REAL || pop1 != INTEIRO)) {
throw new SemanticError(String.format("tipos incompat�veis (%s e %s)", classe.getDescricao(), pop1.getDescricao()), token.getLine());
}
switch (operadorAtrib) {
case RECEBE:
{
if(classe == REAL && pop1 == INTEIRO) {
areaDeInstrucoes.append("conv.r4\n");
}
break;
}
case SOMARECEBE:
{
areaDeInstrucoes.append(String.format("ldloc %s\n", identificador));
if (classe == INTEIRO && pop1 == INTEIRO) {
} else if (classe == REAL && pop1 == INTEIRO) {
areaDeInstrucoes.append("stloc $float\n");
areaDeInstrucoes.append("conv.r4\n");
areaDeInstrucoes.append("ldloc $float\n");
} else if (classe == REAL && pop1 == REAL) {
} else if (classe == DATA && pop1 == DATA) {
} else if (classe == HORA && pop1 == HORA) {
} else {
throw new SemanticError(String.format("tipos inv�lidos para soma (%s e %s)",pop1.getDescricao(),classe.getDescricao()), token.getLine());
}
areaDeInstrucoes.append("add\n");
break;
}
case SUBTRAIRECEBE:
{
if (classe == INTEIRO && pop1 == INTEIRO) {
areaDeInstrucoes.append("stloc $int\n");
areaDeInstrucoes.append(String.format("ldloc %s\n", identificador));
areaDeInstrucoes.append("ldloc $int\n");
} else if (classe == REAL && pop1 == INTEIRO) {
areaDeInstrucoes.append("conv.r4\n");
areaDeInstrucoes.append("stloc $float\n");
areaDeInstrucoes.append(String.format("ldloc %s\n", identificador));
areaDeInstrucoes.append("ldloc $float\n");
} else if (classe == REAL && pop1 == REAL) {
areaDeInstrucoes.append("stloc $float\n");
areaDeInstrucoes.append(String.format("ldloc %s\n", identificador));
areaDeInstrucoes.append("ldloc $float\n");
} else if (classe == DATA && pop1 == DATA) {
//guarda os millisegundos na variavel auxiliar
areaDeInstrucoes.append("stloc $long\n");
//coloca na pilha o valor em millisegundos do identificador
areaDeInstrucoes.append(String.format("ldloc %s\n", identificador));
//devolve os millisegundos da variavel que ira subtrair
areaDeInstrucoes.append("ldloc $long\n");
} else if (classe == HORA && pop1 == HORA) {
//transforma de millisegundos em objeto TimeSpan
areaDeInstrucoes.append("call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromMilliseconds(float64)\n");
//guarda na variavel auxiliar
areaDeInstrucoes.append("stloc $time\n");
//coloca na pilha o valor em millisegundos do identificador
areaDeInstrucoes.append(String.format("ldloc %s\n", identificador));
//coloca na pilha o valor em millisegundos da variavel auxiliar
areaDeInstrucoes.append("ldloca $time\n");
areaDeInstrucoes.append("call instance float64 [mscorlib]System.TimeSpan::get_TotalMilliseconds()\n");
} else {
throw new SemanticError(String.format("tipos inv�lidos para subtra��o (%s e %s)",pop1.getDescricao(),classe.getDescricao()), token.getLine());
}
areaDeInstrucoes.append("sub\n");
break;
}
}
areaDeInstrucoes.append(String.format("stloc %s\n",identificador));
listaDeIdentificadores.clear();
break;
}
case 30: //comando read
{
for(String identificador: listaDeIdentificadores) {
Classe classe = tabelaDeSimbolos.get(identificador);
areaDeInstrucoes.append("call string [mscorlib]System.Console::ReadLine()\n");
switch(classe) {
case LITERAL:
{
break;
}
case INTEIRO:
{
areaDeInstrucoes.append("call int32 [mscorlib]System.Int32::Parse(string)\n");
break;
}
case REAL:
{
areaDeInstrucoes.append("call float32 [mscorlib]System.Single::Parse(string)\n");
break;
}
default:
{
throw new SemanticError(String.format("tipo (%s) do identificador (%s) inv�lido para leitura",classe.getDescricao(), identificador), token.getLine());
}
}
areaDeInstrucoes.append(String.format("stloc %s\n",identificador));
}
listaDeIdentificadores.clear();
break;
}
case 31: //if
{
ifGeradorID.gerarNovoID();
Classe pop1 = pilhaDeTipos.pop();
if(pop1 != LOGICO) {
throw new SemanticError(String.format("express�o usada em sele��o possui tipo (%s) diferente de boolean",pop1.getDescricao()), token.getLine());
}
//adiciona o goto para um label que ainda n�o se sabe se ser� o 'endif' ou o 'else'
areaDeInstrucoes.append(String.format("brfalse %s\n",strLabel));
break;
}
case 32: //endif
{
//caso ele encontre o strLabel, quer dizer que n�o existe else no if, portanto deve alterar o strLabel para 'endif'
int i = areaDeInstrucoes.lastIndexOf(strLabel);
if(i > 0) {
areaDeInstrucoes.replace(i, i+strLabel.length(), String.format("endif%d",ifGeradorID.getIDAtual()));
}
//adiciona o label 'endif'
areaDeInstrucoes.append(String.format("endif%d:\n",ifGeradorID.getIDAtual()));
ifGeradorID.retirarID();
break;
}
case 33: //else
{
//se o if possui um else, altera o strLabel para 'else'
int i = areaDeInstrucoes.lastIndexOf(strLabel);
areaDeInstrucoes.replace(i, i+strLabel.length(), String.format("else%d",ifGeradorID.getIDAtual()));
//adiciona um goto endif, pois caso a sele��o seja true, ele nao deve executar o else
areaDeInstrucoes.append(String.format("br endif%d\n",ifGeradorID.getIDAtual()));
//adiciona o label else
areaDeInstrucoes.append(String.format("else%d:\n",ifGeradorID.getIDAtual()));
break;
}
case 34: //loop
{
loopGeradorID.gerarNovoID();
areaDeInstrucoes.append(String.format("loop%d:\n",loopGeradorID.getIDAtual()));
break;
}
case 35: //endloop
{
areaDeInstrucoes.append(String.format("br loop%d\n",loopGeradorID.getIDAtual()));
areaDeInstrucoes.append(String.format("endloop%d:\n",loopGeradorID.getIDAtual()));
loopGeradorID.retirarID();
break;
}
case 36: // nome do m�dulo
{
this.nomeModulo = token.getLexeme();
areaDeInstrucoes.append(".class public " + token.getLexeme()
+ "{\n");
areaDeInstrucoes.append(".method static public void principal()\n");
areaDeInstrucoes.append("{ .entrypoint\n");
areaDeInstrucoes.append(".locals init (\n");
areaDeInstrucoes.append("valuetype [mscorlib]System.DateTime $date\n");
areaDeInstrucoes.append(",valuetype [mscorlib]System.TimeSpan $time\n");
areaDeInstrucoes.append(",float32 $float\n");
areaDeInstrucoes.append(",int32 $int\n");
areaDeInstrucoes.append(",int64 $long\n");
break;
}
case 37: // declara��o das vari�veis, fechamento do locals e inicializa��o de vari�veis
{
//limpa a listaDeIdentificadores, pois a ultima lista de vari�veis da declara��o ainda estar� na listaDeIdentificadores
listaDeIdentificadores.clear();
//declara��o das vari�veis
for(String id : tabelaDeSimbolos.keySet()) {
Classe classe = tabelaDeSimbolos.get(id);
switch (classe) {
case INTEIRO:
areaDeInstrucoes.append(String.format(",int32 %s\n",id));
break;
case LITERAL: