]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/types/effects/EffectIdMap.java
New SCL syntax <<effects>>
[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> EFFECT_CONS = new ArrayList<TCon>(); 
21     private static TObjectIntHashMap<TCon> EFFECT_CODES = new TObjectIntHashMap<TCon>();
22     
23     private static void add(TCon con, int code) {
24         EFFECT_CODES.put(con, code);
25         EFFECT_CONS.add(con);
26     }
27     
28     static {
29         add(Types.WRITE_GRAPH, 0b11);
30         add(Types.READ_GRAPH,  0b01);
31     }
32     
33     private ArrayList<Type> localCons = new ArrayList<Type>(); 
34     private TObjectIntHashMap<Type> localCodes = new TObjectIntHashMap<Type>();
35     private int freshId = FIRST_FREE_EFFECT_ID;
36     
37     public int toId(Type type, Collection<TMetaVar> metaVars) {
38         type = Types.canonical(type);
39         if(type instanceof TUnion) {
40             int id = 0;
41             for(Type e : ((TUnion)type).effects)
42                 id |= toId(e, metaVars);
43             return id;
44         }
45         else if(EFFECT_CODES.contains(type)) {
46             return EFFECT_CODES.get(type);
47         }
48         else if(type instanceof TMetaVar) {
49             metaVars.add((TMetaVar)type);
50             return 0;
51         }
52         else if(localCodes.contains(type)) {
53             return localCodes.get(type);
54         }
55         else {
56             int id = freshId;
57             localCons.add(type);
58             localCodes.put(type, id);
59             freshId *= 2;
60             return id;
61         }
62     }
63     
64     public Type toType(int id) {
65         if(id == 0)
66             return Types.NO_EFFECTS;
67         ArrayList<Type> components = new ArrayList<Type>();
68         for(TCon con : EFFECT_CONS) {
69             int conId = EFFECT_CODES.get(con);
70             if((id&conId) == conId) {
71                 components.add(con);
72                 id ^= conId;
73             }
74         }
75         for(Type con : localCons) {
76             int conId = localCodes.get(con);
77             if((id&conId) == conId) {
78                 components.add(con);
79                 id ^= conId;
80             }
81         }
82         if(components.size() == 1)
83             return components.get(0);
84         else
85             return Types.union(components);
86     }
87
88 }