--- /dev/null
+package org.simantics.scl.compiler.internal.types.effects;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TMetaVar;
+import org.simantics.scl.compiler.types.TUnion;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+
+public class EffectIdMap {
+
+ public static final int MIN = 0;
+ public static final int MAX = 0xffffffff;
+ private static final int FIRST_FREE_EFFECT_ID = 16;
+
+ private static ArrayList<TCon> effectCons = new ArrayList<TCon>();
+ private static TObjectIntHashMap<TCon> effectCodes = new TObjectIntHashMap<TCon>();
+
+ private static void add(String module, String name, int code) {
+ TCon con = Types.con(module, name);
+ effectCodes.put(con, code);
+ effectCons.add(con);
+ }
+
+ static {
+ add("Simantics/DB", "WriteGraph", 12);
+ add("Simantics/DB", "ReadGraph", 4);
+ add(Types.BUILTIN, "Proc", 1);
+ }
+
+ private ArrayList<Type> localCons = new ArrayList<Type>();
+ private TObjectIntHashMap<Type> localCodes = new TObjectIntHashMap<Type>();
+ private int freshId = FIRST_FREE_EFFECT_ID;
+
+ public int toId(Type type, Collection<TMetaVar> metaVars) {
+ type = Types.canonical(type);
+ if(type instanceof TUnion) {
+ int id = 0;
+ for(Type e : ((TUnion)type).effects)
+ id |= toId(e, metaVars);
+ return id;
+ }
+ else if(effectCodes.contains(type)) {
+ return effectCodes.get(type);
+ }
+ else if(type instanceof TMetaVar) {
+ metaVars.add((TMetaVar)type);
+ return 0;
+ }
+ else if(localCodes.contains(type)) {
+ return localCodes.get(type);
+ }
+ else {
+ int id = freshId;
+ localCons.add(type);
+ localCodes.put(type, id);
+ freshId *= 2;
+ return id;
+ }
+ }
+
+ public Type toType(int id) {
+ if(id == 0)
+ return Types.NO_EFFECTS;
+ ArrayList<Type> components = new ArrayList<Type>();
+ for(TCon con : effectCons) {
+ int conId = effectCodes.get(con);
+ if((id&conId) == conId) {
+ components.add(con);
+ id ^= conId;
+ }
+ }
+ for(Type con : localCons) {
+ int conId = localCodes.get(con);
+ if((id&conId) == conId) {
+ components.add(con);
+ id ^= conId;
+ }
+ }
+ if(components.size() == 1)
+ return components.get(0);
+ else
+ return Types.union(components);
+ }
+
+}