package zinara.ast.expression;
import zinara.code_generator.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Stack;
import java.io.IOException;
import zinara.ast.type.Type;
import zinara.ast.type.DictType;
import zinara.exceptions.InvalidDictionaryException;
import zinara.exceptions.InvalidCodeException;
import zinara.exceptions.TypeClashException;
public class DictExp extends Expression {
public HashMap value; // hashmap of string:expr
public DictExp(HashMap v) { value = v; }
public DictExp() { value = new HashMap(); }
public Type getType() throws TypeClashException {
if (type != null) return type;
HashMap typemap = new HashMap();
Iterator it = value.keySet().iterator();
String ckey;
while(it.hasNext()) {
ckey = (String)it.next();
if (typemap.put(ckey, (Type)((Expression)value.get(ckey)).getType()) != null)
throw new TypeClashException("La clave " + ckey + " se repite en el diccionario " + this);
}
type = new DictType(typemap);
return type;
}
// DictType(null) = {} which doesn't exist;
public String toString() {
String ret = "{";
Iterator it = value.keySet().iterator();
String ckey;
while (it.hasNext()) {
ckey = (String)it.next();
ret += ckey + ": " + (Expression)value.get(ckey) + ", ";
}
return ret.substring(0, ret.length()-2) + "}";
}
public void tox86(Genx86 generator)
throws IOException, InvalidCodeException{
Expression expr;
String reg;
String regAddr = generator.addrRegName(register);
Iterator it = value.keySet().iterator();
Stack st = new Stack();
while(it.hasNext()) {
st.push(it.next());
}
while(! st.empty()) {
//Se genera el valor
expr = (Expression)value.get((String)st.pop());
expr.register = register;
reg = generator.regName(register, expr.type);
if (expr instanceof BooleanExp){
String ret = generator.newLabel();
boolValue(generator,expr,ret,reg);
generator.writeLabel(ret);
}
else
expr.tox86(generator);
//Se pushea en la pila
if (!(expr instanceof ListExp)&&
!(expr instanceof DictExp)&&
!(expr instanceof TupleExp)&&
!(expr instanceof StringExp))
generator.write(generator.push(reg, expr.type.size()));
}
//Por ultimo, devuelvo la direccion donde comienza el diccionario
generator.write(generator.mov(regAddr,generator.stack_pointer()));
}
public boolean isStaticallyKnown() {
boolean isk = true;
Expression v;
Iterator it = value.entrySet().iterator();
while (it.hasNext()) {
v = (Expression)it.next();
isk = isk && v.isStaticallyKnown();
}
return isk;
}
public Object staticValue() {
HashMap result = new HashMap();
Iterator it = value.keySet().iterator();
String ckey;
while(it.hasNext()) {
ckey = (String)it.next();
result.put(ckey, ((Expression)value.get(ckey)).staticValue());
}
return result;
}
}