]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TApply.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / TApply.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 import java.util.List;
8
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;
21
22
23
24 /**
25  * Type application.
26  * @author Hannu Niemistö
27  */
28 public class TApply extends Type {
29     public final Type function;
30     public final Type parameter;
31     
32     public TApply(Type function, Type parameter) {
33         if(NULL_CHECKS) {
34             if(function == null)
35                 throw new NullPointerException();
36             if(parameter == null)
37                 throw new NullPointerException();
38         }
39         this.function = function;
40         this.parameter = parameter;
41     }
42     
43     private TApply create(Type function, Type parameter) {
44         if(function == this.function && parameter == this.parameter)
45             return this;
46         else
47             return new TApply(function, parameter);
48     }
49
50     @Override
51     public TApply replace(TVar var, Type replacement) {
52         return create(
53                 function.replace(var, replacement), 
54                 parameter.replace(var, replacement));
55     }
56
57     @Override
58     public TypeAst toTypeAst(TypeUnparsingContext context) {
59         TMultiApply multiApply = Types.toMultiApply(this);
60         
61         Type function = multiApply.function;
62         List<Type> parameters = multiApply.parameters;
63         
64         TypeAst ast = null;
65         int parameterPos = 0;
66
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));
72                 parameterPos = 2;
73             }
74             else*/ if(function == Types.LIST && parameters.size() >= 1) {
75                 ast = new TListAst(
76                         parameters.get(0).toTypeAst(context));
77                 parameterPos = 1;
78             }
79             else {
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;
90                     }
91                 }                                
92             }
93         }
94         if(ast == null)
95             ast = function.toTypeAst(context);
96         for(;parameterPos < multiApply.parameters.size();++parameterPos)
97             ast = new TApplyAst(
98                     ast, 
99                     parameters.get(parameterPos).toTypeAst(context));
100         return ast;
101     }
102
103     @Override
104     public void updateHashCode(TypeHashCodeContext context) {
105         context.append(TypeHashCodeContext.APPLY);
106         function.updateHashCode(context);
107         parameter.updateHashCode(context);
108     }
109
110     @Override
111     public void collectFreeVars(ArrayList<TVar> vars) {
112         function.collectFreeVars(vars);
113         parameter.collectFreeVars(vars);
114     }
115
116     @Override
117     public void collectMetaVars(ArrayList<TMetaVar> vars) {
118         function.collectMetaVars(vars);
119         parameter.collectMetaVars(vars);
120     }
121     
122     @Override
123     public void collectMetaVars(THashSet<TMetaVar> vars) {
124         function.collectMetaVars(vars);
125         parameter.collectMetaVars(vars);
126     }
127     
128     @Override
129     public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
130         function.collectEffectMetaVars(vars);
131         parameter.collectEffectMetaVars(vars);
132     }
133     
134     @Override
135     public boolean contains(TMetaVar other) {
136         return function.contains(other) || parameter.contains(other);
137     }
138     
139     @Override
140     public Type convertMetaVarsToVars() {
141         Type newFunction = function.convertMetaVarsToVars();
142         Type newParameter = parameter.convertMetaVarsToVars();
143         if(newFunction == function && newParameter == parameter)
144             return this;
145         else
146             return new TApply(newFunction, newParameter);
147     }
148
149     @Override
150     public boolean isGround() {
151         return function.isGround() && parameter.isGround();
152     }
153
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));
158     }
159
160     @Override
161     public boolean containsMetaVars() {
162         return function.containsMetaVars() || parameter.containsMetaVars();
163     }
164
165     @Override
166     public void toName(TypeUnparsingContext context, StringBuilder b) {
167         function.toName(context, b);
168         b.append('_');
169         parameter.toName(context, b);
170     }
171
172     @Override
173     public int getClassId() {
174         return APPLY_ID;
175     }
176
177     @Override
178     public void addPolarity(Polarity polarity) {
179         function.addPolarity(Polarity.BIPOLAR);
180         parameter.addPolarity(Polarity.BIPOLAR);
181     }
182     
183     @Override
184     public Type head() {
185         return function.head();
186     }
187
188     @Override
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)
193             return this;
194         else
195             return new TApply(newFunction, newParameter);
196     }
197 }