]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / types / effects / EffectIdMap.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java
new file mode 100644 (file)
index 0000000..149e139
--- /dev/null
@@ -0,0 +1,90 @@
+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);
+    }
+
+}