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;
9 import org.simantics.scl.compiler.environment.Environment;
10 import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
11 import org.simantics.scl.compiler.internal.types.ast.TApplyAst;
12 import org.simantics.scl.compiler.internal.types.ast.TListAst;
13 import org.simantics.scl.compiler.internal.types.ast.TTupleAst;
14 import org.simantics.scl.compiler.internal.types.ast.TypeAst;
15 import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
16 import org.simantics.scl.compiler.types.kinds.Kind;
17 import org.simantics.scl.compiler.types.kinds.Kinds;
18 import org.simantics.scl.compiler.types.util.Polarity;
19 import org.simantics.scl.compiler.types.util.TMultiApply;
20 import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
26 * @author Hannu Niemistö
28 public class TApply extends Type {
29 public final Type function;
30 public final Type parameter;
32 public TApply(Type function, Type parameter) {
35 throw new NullPointerException();
37 throw new NullPointerException();
39 this.function = function;
40 this.parameter = parameter;
43 private TApply create(Type function, Type parameter) {
44 if(function == this.function && parameter == this.parameter)
47 return new TApply(function, parameter);
51 public TApply replace(TVar var, Type replacement) {
53 function.replace(var, replacement),
54 parameter.replace(var, replacement));
58 public TypeAst toTypeAst(TypeUnparsingContext context) {
59 TMultiApply multiApply = Types.toMultiApply(this);
61 Type function = multiApply.function;
62 List<Type> parameters = multiApply.parameters;
67 if(function instanceof TCon) {
68 /*if(function == Types.ARROW && parameters.size() >= 2) {
69 ast = new TFunctionAst(
70 parameters.get(0).toTypeAst(context),
71 parameters.get(1).toTypeAst(context));
74 else*/ if(function == Types.LIST && parameters.size() >= 1) {
76 parameters.get(0).toTypeAst(context));
80 TCon con = (TCon)function;
81 if(con.module == Types.BUILTIN && con.name.charAt(0)=='(') {
82 int tupleLength = con.name.length()-2;
83 if(tupleLength>0) ++tupleLength;
84 if(parameters.size() >= tupleLength) {
85 TypeAst[] components = new TypeAst[tupleLength];
86 for(int i=0;i<tupleLength;++i)
87 components[i] = parameters.get(i).toTypeAst(context);
88 ast = new TTupleAst(components);
89 parameterPos = tupleLength;
95 ast = function.toTypeAst(context);
96 for(;parameterPos < multiApply.parameters.size();++parameterPos)
99 parameters.get(parameterPos).toTypeAst(context));
104 public void updateHashCode(TypeHashCodeContext context) {
105 context.append(TypeHashCodeContext.APPLY);
106 function.updateHashCode(context);
107 parameter.updateHashCode(context);
111 public void collectFreeVars(ArrayList<TVar> vars) {
112 function.collectFreeVars(vars);
113 parameter.collectFreeVars(vars);
117 public void collectMetaVars(ArrayList<TMetaVar> vars) {
118 function.collectMetaVars(vars);
119 parameter.collectMetaVars(vars);
123 public void collectMetaVars(THashSet<TMetaVar> vars) {
124 function.collectMetaVars(vars);
125 parameter.collectMetaVars(vars);
129 public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
130 function.collectEffectMetaVars(vars);
131 parameter.collectEffectMetaVars(vars);
135 public boolean contains(TMetaVar other) {
136 return function.contains(other) || parameter.contains(other);
140 public Type convertMetaVarsToVars() {
141 Type newFunction = function.convertMetaVarsToVars();
142 Type newParameter = parameter.convertMetaVarsToVars();
143 if(newFunction == function && newParameter == parameter)
146 return new TApply(newFunction, newParameter);
150 public boolean isGround() {
151 return function.isGround() && parameter.isGround();
154 public void checkKind(Environment context, Kind requiredKind) throws KindUnificationException {
155 Kind functionKind = function.inferKind(context);
156 Kind parameterKind = parameter.inferKind(context);
157 Kinds.unify(functionKind, Kinds.arrow(parameterKind, requiredKind));
161 public boolean containsMetaVars() {
162 return function.containsMetaVars() || parameter.containsMetaVars();
166 public void toName(TypeUnparsingContext context, StringBuilder b) {
167 function.toName(context, b);
169 parameter.toName(context, b);
173 public int getClassId() {
178 public void addPolarity(Polarity polarity) {
179 function.addPolarity(Polarity.BIPOLAR);
180 parameter.addPolarity(Polarity.BIPOLAR);
185 return function.head();
189 public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
190 Type newFunction = function.copySkeleton(metaVarMap);
191 Type newParameter = parameter.copySkeleton(metaVarMap);
192 if(newFunction == function && newParameter == parameter)
195 return new TApply(newFunction, newParameter);