package zinara.ast.instructions;
import zinara.code_generator.*;
import zinara.ast.expression.Expression;
import zinara.ast.expression.ListExp;
import zinara.ast.expression.Identifier;
import zinara.ast.type.Type;
import zinara.ast.type.ListType;
import zinara.exceptions.InvalidCodeException;
import zinara.exceptions.TypeClashException;
import zinara.symtable.SymTable;
import zinara.symtable.SymValue;
import java.io.IOException;
public class For extends Instruction{
private Expression expr;
public CodeBlock code;
private String i; //Iteration variable name
public For(String i, Expression ex, CodeBlock cb){
this.i = i;
this.code = cb;
this.expr = ex;
}
public String getI(){
return this.i;
}
public CodeBlock getCode(){
return this.code;
}
public Expression getExpression(){
return this.expr;
}
public String toString() {
return "<For " + i + " in " + expr + ": " + code + ">";
}
public void checkNoReturns(){
code.checkNoReturns();
}
public void tox86(Genx86 generator)
throws IOException,InvalidCodeException{
Type listType = ((ListType)expr.type).getInsideType();
SymValue iterVar = code.getSymTable().getSymbol(this.i);
String exprAddr = generator.addrRegName(register); //direccion del la lista
String iteration_var = generator.regName(register+1, listType);
String iteration_var_addr = iterVar.getArea();
iteration_var_addr += iterVar.getOffset();
expr.register = register;
code.register = register+2;
//save
generator.write(generator.save(register+1));
generator.write(generator.save(register+2));
break_label = nextInst;
if (expr instanceof Identifier)
((Identifier)expr).currentDirection(generator);
else if (expr instanceof ListExp)
expr.tox86(generator);
else
throw new InvalidCodeException("For sobre algo que no es lista literal ni identificador tipo lista");
for(int i = 0; i< ((ListType)expr.type).len(); ++i){
continue_label = generator.newLabel();
set_breaks_continues(code,break_label,continue_label);
//Muevo el siguiente valor de la lista un registro
//y de ahi a la direccion de la variable de iteracion
generator.write(generator.mov(iteration_var,"["+exprAddr+"]",listType));
generator.write(generator.mov("["+iteration_var_addr+"]",iteration_var,listType));
//Genero el codigo
code.tox86(generator);
generator.writeLabel(continue_label);
//Muevo exprAddr a apuntar a la siguiente posicion de la lista
generator.write(generator.add(exprAddr,Integer.toString(listType.size())));
}
//restore
generator.write(generator.restore(register+2));
generator.write(generator.restore(register+1));
}
}