]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java
migrated to svn revision 33108
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / types / effects / EffectIdMap.java
1 package org.simantics.scl.compiler.internal.types.effects;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5
6 import org.simantics.scl.compiler.types.TCon;
7 import org.simantics.scl.compiler.types.TMetaVar;
8 import org.simantics.scl.compiler.types.TUnion;
9 import org.simantics.scl.compiler.types.Type;
10 import org.simantics.scl.compiler.types.Types;
11
12 import gnu.trove.map.hash.TObjectIntHashMap;
13
14 public class EffectIdMap {
15
16     public static final int MIN = 0;
17     public static final int MAX = 0xffffffff;
18     private static final int FIRST_FREE_EFFECT_ID = 16;
19     
20     private static ArrayList<TCon> effectCons = new ArrayList<TCon>(); 
21     private static TObjectIntHashMap<TCon> effectCodes = new TObjectIntHashMap<TCon>();
22     
23     private static void add(String module, String name, int code) {
24         TCon con = Types.con(module, name);
25         effectCodes.put(con, code);
26         effectCons.add(con);
27     }
28     
29     static {
30         add("Simantics/DB", "WriteGraph", 12);
31         add("Simantics/DB", "ReadGraph",  4);
32         add(Types.BUILTIN, "Proc",       1);
33     }
34     
35     private ArrayList<Type> localCons = new ArrayList<Type>(); 
36     private TObjectIntHashMap<Type> localCodes = new TObjectIntHashMap<Type>();
37     private int freshId = FIRST_FREE_EFFECT_ID;
38     
39     public int toId(Type type, Collection<TMetaVar> metaVars) {
40         type = Types.canonical(type);
41         if(type instanceof TUnion) {
42             int id = 0;
43             for(Type e : ((TUnion)type).effects)
44                 id |= toId(e, metaVars);
45             return id;
46         }
47         else if(effectCodes.contains(type)) {
48             return effectCodes.get(type);
49         }
50         else if(type instanceof TMetaVar) {
51             metaVars.add((TMetaVar)type);
52             return 0;
53         }
54         else if(localCodes.contains(type)) {
55             return localCodes.get(type);
56         }
57         else {
58             int id = freshId;
59             localCons.add(type);
60             localCodes.put(type, id);
61             freshId *= 2;
62             return id;
63         }
64     }
65     
66     public Type toType(int id) {
67         if(id == 0)
68             return Types.NO_EFFECTS;
69         ArrayList<Type> components = new ArrayList<Type>();
70         for(TCon con : effectCons) {
71             int conId = effectCodes.get(con);
72             if((id&conId) == conId) {
73                 components.add(con);
74                 id ^= conId;
75             }
76         }
77         for(Type con : localCons) {
78             int conId = localCodes.get(con);
79             if((id&conId) == conId) {
80                 components.add(con);
81                 id ^= conId;
82             }
83         }
84         if(components.size() == 1)
85             return components.get(0);
86         else
87             return Types.union(components);
88     }
89
90 }