package zinara.ast.instructions;
import zinara.ast.expression.Expression;
import zinara.ast.expression.BooleanExp;
import zinara.ast.expression.Identifier;
import zinara.ast.expression.ListExp;
import zinara.ast.expression.LValue;
import zinara.ast.expression.StringExp;
import zinara.ast.type.*;
import zinara.code_generator.Genx86;
import zinara.exceptions.TypeClashException;
import zinara.exceptions.InvalidCodeException;
import java.io.IOException;
public class SingleAssignation extends Assignation {
private LValue lvalue;
private Expression expr;
public boolean isSingle(){
return true;
}
public SingleAssignation(LValue lv, Expression ex){
this.lvalue = lv;
this.expr = ex;
}
public LValue getLValue() {
return this.lvalue;
}
public Expression getExpression(){
return this.expr;
}
public String toString() {
return "<" + lvalue + " = " + expr + ">";
}
public void tox86(Genx86 generator)
throws IOException,InvalidCodeException{
String exprReg;
String lvalueReg;
expr.register = register;
lvalue.register = register + 1;
if (lvalue.type.equals(new BoolType())) {
booleanAssignationToX86(generator);
return;
}
//Se genera la expresion
expr.tox86(generator);
exprReg = generator.regName(expr.register,expr.type);
lvalueReg = generator.addrRegName(lvalue.register);
generator.save(lvalue.register);
//Se calcula la direccion de lvalue
lvalue.currentDirection(generator);
//Se guarda el valor de la exp en el lvalue
storeValue(generator, lvalue.type, expr,
lvalueReg, exprReg,
register+2);
if ((expr.type.getType() instanceof ListType)&&
(expr instanceof ListExp)) {
//Si era una lista literal se genero en la pila.
//Hay que desempilarla
generator.write(generator.add(generator.stack_pointer(),
Integer.toString(lvalue.type.getType().size())));
}
generator.restore(lvalue.register);
}
// This one can be improved =S
public void booleanAssignationToX86(Genx86 generator)
throws IOException,InvalidCodeException{
String lvalueReg;
BooleanExp bExpr = (BooleanExp)expr;
// if (expr instanceof LValue)
// ((LValue)bExpr).setAsBool(true);
bExpr.yesLabel = generator.newLabel();
bExpr.noLabel = generator.newLabel();
//En caso de que bExpr necesite computarse
bExpr.register = register;
String bExprReg = generator.regName(bExpr.register,bExpr.type);
bExpr.tox86(generator);
if (!(bExpr instanceof BooleanExp)){
generator.add(bExprReg,"0");
generator.jz(bExpr.noLabel);
}
lvalue.register = register;
lvalueReg = generator.addrRegName(lvalue.register);
generator.writeLabel(bExpr.yesLabel);
lvalue.currentDirection(generator);
generator.write(generator.movBool("[" + lvalueReg + "]", "1"));
generator.write(generator.jump(nextInst));
generator.writeLabel(bExpr.noLabel);
lvalue.currentDirection(generator);
generator.write(generator.movBool("[" + lvalueReg + "]", "0"));
}
private void storeValue(Genx86 generator, Type t, Expression expr,
String lvalueReg, String exprReg,
int free_register)
throws IOException,InvalidCodeException{
if (t.getType() instanceof StringType){
generator.save(free_register);
String auxReg = generator.charRegName(free_register);
int stringLen = ((StringExp)expr).value.length();
for (int i = 0; i < stringLen; ++i) {
generator.write(generator.movChar(auxReg,"["+exprReg+"]"));
generator.write(generator.movChar("["+lvalueReg+"]",auxReg));
generator.write(generator.add(lvalueReg,"1"));
generator.write(generator.add(exprReg,"1"));
}
generator.restore(free_register);
}
else if ((t.getType() instanceof ListType)||
(t.getType() instanceof TupleType)||
(t.getType() instanceof DictType)){
generator.save(free_register);
String auxReg = generator.charRegName(free_register);
int listSize = t.getType().size();
for (int i = 0; i < listSize; i++) {
generator.write(generator.movChar(auxReg,"["+exprReg+"]"));
generator.write(generator.movChar("["+lvalueReg+"]",auxReg));
generator.write(generator.add(lvalueReg,"1"));
generator.write(generator.add(exprReg,"1"));
}
generator.restore(free_register);
}
else
generator.write(generator.mov("[" + lvalueReg + "]",
exprReg, t.getType()));
}
}