public Typing(Type[] inputs, List<Entry> stmts, int numSlots) { this.stmts = new ArrayList<Entry>(stmts); this.cache = new HashMap<String, Type[]>(); this.environments = new Type[stmts.size()][]; this.environments[0] = Arrays.copyOf(inputs, numSlots); this.numSlots = numSlots; }
private void determineTypesUpto(int end) { Type[] environment = environments[0]; for (int i = position; i < end; ++i) { Code code = stmts.get(i).code; if (code instanceof Code.Label) { Code.Label label = (Code.Label) code; Type[] nEnv = cache.get(label.label); environment = join(environment, nEnv); } else if (code instanceof Code.AbstractAssignable) { Code.AbstractAssignable c = (Code.AbstractAssignable) code; environment = Arrays.copyOf(environment, environment.length); environment[c.target] = c.assignedType(); } else if (code instanceof Code.Goto) { Code.Goto gto = (Code.Goto) code; cache.put(gto.target, environment); environment = null; } else if (code instanceof Code.If) { Code.If gto = (Code.If) code; cache.put(gto.target, environment); } else if (code instanceof Code.IfIs) { Code.IfIs gto = (Code.IfIs) code; Type[] trueEnv = Arrays.copyOf(environment, environment.length); trueEnv[gto.operand] = Type.intersect(trueEnv[gto.operand], gto.rightOperand); cache.put(gto.target, trueEnv); environment[gto.operand] = Type.intersect(trueEnv[gto.operand], Type.Negation(gto.rightOperand)); } else if (code instanceof Code.Switch) { Code.Switch sw = (Code.Switch) code; for (Pair<Constant, String> c : sw.branches) { cache.put(c.second(), environment); } cache.put(sw.defaultTarget, environment); } else if (code instanceof Code.ForAll) { // FIXME: what this need to do is update the type for the // index variable, and then invalidate it afterwards. throw new RuntimeException("need to implement for-all loop!"); } else if (code instanceof Code.Return || code instanceof Code.Throw) { environment = null; } environments[i] = environment; } }