1 package org.simantics.scl.compiler.types;
3 import gnu.trove.map.hash.THashMap;
4 import gnu.trove.set.hash.THashSet;
6 import java.util.ArrayList;
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;
20 public class TFun extends Type {
21 public final Type domain;
22 public final Type effect;
23 public final Type range;
25 TFun(Type domain, Type effect, Type range) {
27 throw new NullPointerException();
29 throw new NullPointerException();
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();*/
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)
52 return new TFun(newDomain, newEffect, newRange);
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)
68 return new TEffectAst(Types.NO_EFFECTS, rangeAst);*/
71 return new TFunctionAst(domainAst, rangeAst);
75 public void toName(TypeUnparsingContext context, StringBuilder b) {
77 domain.toName(context, b);
79 effect.toName(context, b);
81 range.toName(context, b);
85 public void updateHashCode(TypeHashCodeContext context) {
86 context.append(TypeHashCodeContext.FUN);
87 domain.updateHashCode(context);
88 effect.updateHashCode(context);
89 range.updateHashCode(context);
93 public void collectFreeVars(ArrayList<TVar> vars) {
94 domain.collectFreeVars(vars);
95 effect.collectFreeVars(vars);
96 range.collectFreeVars(vars);
100 public void collectMetaVars(ArrayList<TMetaVar> vars) {
101 domain.collectMetaVars(vars);
102 effect.collectMetaVars(vars);
103 range.collectMetaVars(vars);
107 public void collectMetaVars(THashSet<TMetaVar> vars) {
108 domain.collectMetaVars(vars);
109 effect.collectMetaVars(vars);
110 range.collectMetaVars(vars);
114 public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
115 domain.collectEffectMetaVars(vars);
116 effect.collectMetaVars(vars);
117 range.collectEffectMetaVars(vars);
121 public boolean isGround() {
122 return domain.isGround() && effect.isGround() && range.isGround();
126 public boolean containsMetaVars() {
127 return domain.containsMetaVars()
128 || effect.containsMetaVars()
129 || range.containsMetaVars();
133 public boolean contains(TMetaVar other) {
134 return domain.contains(other)
135 || effect.contains(other)
136 || range.contains(other);
140 public int getClassId() {
145 public Kind inferKind(Environment context)
146 throws KindUnificationException {
147 domain.checkKind(context, Kinds.STAR);
148 range.checkKind(context, Kinds.STAR);
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)
160 return new TFun(newDomain, newEffect, newRange);
164 public boolean isMinimal() {
165 return Types.canonical(effect) == Types.NO_EFFECTS &&
166 range.isMinimal() && domain.isMaximal();
169 public boolean isMaximal() {
174 public void addPolarity(Polarity polarity) {
175 domain.addPolarity(polarity.flip());
176 effect.addPolarity(polarity);
177 range.addPolarity(polarity);
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);