]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java
Added missing parts from SVN org.simantics.root project.
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / TFun.java
1 package org.simantics.scl.compiler.types;
2
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.set.hash.THashSet;
5
6 import java.util.ArrayList;
7
8 import org.simantics.scl.compiler.environment.Environment;
9 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
10 import org.simantics.scl.compiler.internal.types.ast.TEffectAst;
11 import org.simantics.scl.compiler.internal.types.ast.TFunctionAst;
12 import org.simantics.scl.compiler.internal.types.ast.TPredAst;
13 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
14 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
15 import org.simantics.scl.compiler.types.kinds.Kind;
16 import org.simantics.scl.compiler.types.kinds.Kinds;
17 import org.simantics.scl.compiler.types.util.Polarity;
18 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
19
20 public class TFun extends Type {
21     public final Type domain;
22     public final Type effect;
23     public final Type range;
24     
25     TFun(Type domain, Type effect, Type range) {
26         if(domain == null)
27             throw new NullPointerException();
28         if(effect == null)
29             throw new NullPointerException();
30         if(range == null)
31             throw new NullPointerException();
32         /*domain = Types.weakCanonical(domain);
33         range = Types.weakCanonical(range);
34         if(domain instanceof TUnion)
35             throw new RuntimeException();
36         if(range instanceof TUnion)
37             throw new RuntimeException();*/
38         
39         this.domain = domain;
40         this.effect = effect;
41         this.range = range;
42     }
43
44     @Override
45     public Type replace(TVar var, Type replacement) {
46         Type newDomain = domain.replace(var, replacement);
47         Type newEffect = effect.replace(var, replacement);
48         Type newRange = range.replace(var, replacement);
49         if(newDomain == domain && newEffect == effect && newRange == range)
50             return this;
51         else
52             return new TFun(newDomain, newEffect, newRange);
53     }
54     
55     @Override
56     public TypeAst toTypeAst(TypeUnparsingContext context) {
57         TypeAst domainAst = domain.toTypeAst(context);
58         TypeAst rangeAst = range.toTypeAst(context);
59         if(Types.canonical(effect) != Types.NO_EFFECTS)
60             rangeAst = new TEffectAst(effect.toTypeAst(context), rangeAst);
61         Type dom = Types.canonical(domain);
62         if(dom instanceof TPred)
63             return new TPredAst(domainAst, rangeAst);
64         else if(dom == Types.PUNIT) {
65             //if(rangeAst instanceof TEffectAst)
66                 return rangeAst;
67             /*else
68                 return new TEffectAst(Types.NO_EFFECTS, rangeAst);*/
69         }
70         else
71             return new TFunctionAst(domainAst, rangeAst);
72     }
73     
74     @Override
75     public void toName(TypeUnparsingContext context, StringBuilder b) {
76         b.append("FUNC_");
77         domain.toName(context, b);
78         b.append('_');
79         effect.toName(context, b);
80         b.append('_');
81         range.toName(context, b);
82     }
83     
84     @Override
85     public void updateHashCode(TypeHashCodeContext context) {
86         context.append(TypeHashCodeContext.FUN);
87         domain.updateHashCode(context);
88         effect.updateHashCode(context);
89         range.updateHashCode(context);
90     }
91     
92     @Override
93     public void collectFreeVars(ArrayList<TVar> vars) {
94         domain.collectFreeVars(vars);
95         effect.collectFreeVars(vars);
96         range.collectFreeVars(vars);
97     }
98     
99     @Override
100     public void collectMetaVars(ArrayList<TMetaVar> vars) {
101         domain.collectMetaVars(vars);
102         effect.collectMetaVars(vars);
103         range.collectMetaVars(vars);
104     }
105     
106     @Override
107     public void collectMetaVars(THashSet<TMetaVar> vars) {
108         domain.collectMetaVars(vars);
109         effect.collectMetaVars(vars);
110         range.collectMetaVars(vars);
111     }
112     
113     @Override
114     public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
115         domain.collectEffectMetaVars(vars);
116         effect.collectMetaVars(vars);
117         range.collectEffectMetaVars(vars);
118     }
119     
120     @Override
121     public boolean isGround() {
122         return domain.isGround() && effect.isGround() && range.isGround();
123     }
124     
125     @Override
126     public boolean containsMetaVars() {
127         return domain.containsMetaVars() 
128                 || effect.containsMetaVars() 
129                 || range.containsMetaVars();
130     }
131     
132     @Override
133     public boolean contains(TMetaVar other) {
134         return domain.contains(other) 
135                 || effect.contains(other)
136                 || range.contains(other);
137     }
138     
139     @Override
140     public int getClassId() {
141         return FUN_ID;
142     }
143     
144     @Override
145     public Kind inferKind(Environment context)
146             throws KindUnificationException {
147         domain.checkKind(context, Kinds.STAR);
148         range.checkKind(context, Kinds.STAR);
149         return Kinds.STAR;
150     }
151
152     @Override
153     public Type convertMetaVarsToVars() {
154         Type newDomain = domain.convertMetaVarsToVars();
155         Type newEffect = effect.convertMetaVarsToVars();
156         Type newRange = range.convertMetaVarsToVars();
157         if(newDomain == domain && newEffect == effect && newRange == range)
158             return this;
159         else
160             return new TFun(newDomain, newEffect, newRange);
161     }
162     
163     @Override
164     public boolean isMinimal() {
165         return Types.canonical(effect) == Types.NO_EFFECTS &&
166                 range.isMinimal() && domain.isMaximal();
167     }
168     
169     public boolean isMaximal() {
170         return false;
171     }
172
173     @Override
174     public void addPolarity(Polarity polarity) {
175         domain.addPolarity(polarity.flip());
176         effect.addPolarity(polarity);
177         range.addPolarity(polarity);
178     }
179
180     @Override
181     public Type head() {
182         return Types.ARROW;
183     }
184
185     @Override
186     public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
187         Type newDomain = domain.copySkeleton(metaVarMap);
188         Type newEffect = Types.NO_EFFECTS;
189         Type newRange = range.copySkeleton(metaVarMap);
190         return new TFun(newDomain, newEffect, newRange);
191     }
192 }