package zinara.ast.expression; import zinara.ast.type.Type; import zinara.ast.type.BoolType; import zinara.ast.type.FloatType; import zinara.ast.type.IntType; import zinara.ast.type.ListType; import zinara.ast.type.DictType; import zinara.ast.instructions.Print; import zinara.code_generator.Genx86; import zinara.exceptions.InvalidCodeException; import zinara.exceptions.TypeClashException; import java.io.IOException; public class LValueList extends LValue { private LValue constructor; private Expression index; // requires c.getType() be of List[something] type // requires e be of IntType type public LValueList(LValue c, Expression e) { constructor = c; index = e; } public Type getType() throws TypeClashException { if (type != null) return type; type = ((ListType)constructor.getType().getType()).getInsideType(); return type; } public String toString() { return constructor + "[" + index + "]"; } public void tox86(Genx86 generator) throws IOException,InvalidCodeException{ generator.write("; B-----\n"); try { constructor.register = register; String constructorReg = generator.addrRegName(constructor.register); String valueReg = generator.regName(constructor.register,getType()); //Esto deja la direccion en constructorReg currentDirection(generator); storeValue(generator, valueReg, constructorReg); } catch(TypeClashException e) {} generator.write("; E-----\n"); } private void storeValue(Genx86 generator, String valueReg, String addrReg) throws IOException,InvalidCodeException{ generator.write(generator.mov(valueReg, "[" + addrReg + "]", type.getType() ) ); } public void currentDirection(Genx86 generator) throws InvalidCodeException,IOException{ constructor.register = register; index.register = register + 1; String constructorReg = generator.addrRegName(constructor.register); String indexReg = generator.intRegName(index.register); String errorCheckReg = generator.intRegName(register+2); String listSize = Integer.toString(((ListType)(constructor.type)).len()); //Ver NOTA String offsetReg = generator.addrRegName(index.register); constructor.currentDirection(generator); generator.write(generator.save(index.register)); generator.write(generator.save(register+2)); generator.write(generator.save(register+3)); index.tox86(generator); //Chequeo de errores: indice negativo generator.write(generator.cmp(indexReg,"0")); generator.write(generator.jl("haltNI")); //Chequeo de errores: indice fuera de rango generator.write(generator.movInt(errorCheckReg,listSize)); generator.write(generator.sub(errorCheckReg,indexReg)); generator.write(generator.cmp(errorCheckReg,"0")); generator.write(generator.jle("haltOOB")); generator.write(generator.imul(indexReg, Integer.toString(type.size()))); generator.write(generator.add(constructorReg, offsetReg)); generator.write(generator.restore(register+3)); generator.write(generator.restore(register+2)); generator.write(generator.restore(index.register)); } /*****NOTA*****/ /* Los enteros, para 64bits, son de 32bits, pero las direcciones son de 64bits, no puedes sumar registros de 32 y 64, asi que necesito el nombre del registro de 64bits donde esta guardado en indice*/ public boolean isStaticallyKnown() { // for now, return false; } public Object staticValue() { return null; }; public boolean isConstant() { return constructor.isConstant(); } }