package tirateima.controlador;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import tirateima.gui.variaveis.Function;
import tirateima.gui.variaveis.Variavel;
import tirateima.parser.TiraTeimaParserConstants;
/**
* Armazena uma declaração de função a ser executada pelo Tira-Teima.
* Extende a classe comando, portanto pode ser executada.
*
* @author Luciano Santos
*/
public class FunctionDeclaration extends Command
implements TiraTeimaParserConstants {
private String name;
/** Lista de variáveis passadas por parâmetro */
private List<VarDefinition> param;
private Type type;
/** Lista de variáveis locais */
private List<VarDefinition> local_vars;
public FunctionDeclaration(
String name,
List<VarDefinition> param,
Type type,
List<VarDefinition> local_vars) {
this.name = name;
this.param = param;
this.type = type;
this.local_vars = local_vars;
}
/**
* Executa declaração de função.
*
* Recebe o gerador de estados e adiciona a declaração no mapa de funções declaradas.
* @param Gerador g
*/
public void execute(Controlador c)
throws TiraTeimaLanguageException {
/** Declara a função colocando-a na lista de declarações do gerador. */
c.declared_functions.put(name, this);
}
@Override
public void revert(Controlador c) throws TiraTeimaLanguageException,
ExecutionException {
// TODO Auto-generated method stub
}
/**
* Cria uma nova função, com os parâmetros passados por valor.
*
* @param g
* @param args
* @return
* @throws TiraTeimaLanguageException
*/
public Function newFunction(Controlador c, List<Object> args)
throws TiraTeimaLanguageException {
/** Testa se foram passadas todas as variáveis */
if (args.size() != param.size())
gerarErro("Número de parâmetros inválido!");
List<Variavel> params = new ArrayList<Variavel>();
ListIterator<Object> i = args.listIterator();
int cont = 1;
Variavel vaux;
/** Para cada nova definição de variável passada por parâmetro */
for (VarDefinition v : param) {
/** Cria uma nova variável */
vaux = newVar(c, v);
try {
vaux.setValor(i.next());
} catch (ClassCastException e) {
gerarErro("Argumento " + cont + " passado à função " + name
+ " incompatível.");
}
params.add(vaux);
cont++;
}
List<Variavel> vars = new ArrayList<Variavel>();
/** Para cada nova definição de variável local */
for (VarDefinition v : local_vars) {
/** Cria uma nova variável */
vars.add(newVar(c, v));
}
/** Retona uma nova função */
return new Function(name, type, params, vars);
}
}