package zinara.ast.expression; import zinara.ast.type.*; import zinara.ast.type.TupleType; import zinara.code_generator.Genx86; import zinara.exceptions.KeyErrorException; import zinara.exceptions.TypeClashException; import zinara.exceptions.InvalidCodeException; import java.io.IOException; public class LValueTuple extends LValue { private LValue constructor; private int index; // requires c.getType() be of Tuple type public LValueTuple(LValue c, int i) throws KeyErrorException, TypeClashException { // check if i is between the bounds of the type if (i < 0 || i >= ((TupleType)(c.getType().getType())).len()) throw new KeyErrorException("El indice " + i + " es mayor al tamano de la tupla (" + ((TupleType)c.getType()).len() + ")"); constructor = c; index = i; } public Type getType() throws TypeClashException { if (type != null) return type; type = ((TupleType)(constructor.getType().getType())).get(index); return type; } public String toString() { return constructor + "[" + index + "]"; } public void tox86(Genx86 generator) throws IOException,InvalidCodeException{ generator.write("; B-----\n"); constructor.register = register; String constructorReg = generator.addrRegName(constructor.register); String valueReg = generator.regName(constructor.register,type); //Deja la direccion en constructorReg currentDirection(generator); storeValue(generator, valueReg, constructorReg); 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; String constructorReg = generator.addrRegName(constructor.register); constructor.currentDirection(generator); generator.write(generator.add(constructorReg, Integer.toString(calculateOffsetForIndex()))); } public int calculateOffsetForIndex() { int offset = 0; try { Type t, constructorType = ((TupleType)(constructor.getType().getType())); for (int i = 0; i < index; i++) offset += ((Type)((TupleType)constructorType).get(i)).size(); } catch (TypeClashException e) { System.err.println("TypeClashException in LValueTuple.java:87 this should not happen"); } return offset; } public boolean isStaticallyKnown() { return false; } public Object staticValue() { return null; }; public boolean isConstant() { return constructor.isConstant(); } }