]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - 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
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TApply.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TApply.java
new file mode 100644 (file)
index 0000000..ced9692
--- /dev/null
@@ -0,0 +1,197 @@
+package org.simantics.scl.compiler.types;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.internal.types.TypeHashCodeContext;
+import org.simantics.scl.compiler.internal.types.ast.TApplyAst;
+import org.simantics.scl.compiler.internal.types.ast.TListAst;
+import org.simantics.scl.compiler.internal.types.ast.TTupleAst;
+import org.simantics.scl.compiler.internal.types.ast.TypeAst;
+import org.simantics.scl.compiler.types.exceptions.KindUnificationException;
+import org.simantics.scl.compiler.types.kinds.Kind;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.Polarity;
+import org.simantics.scl.compiler.types.util.TMultiApply;
+import org.simantics.scl.compiler.types.util.TypeUnparsingContext;
+
+
+
+/**
+ * Type application.
+ * @author Hannu Niemistö
+ */
+public class TApply extends Type {
+    public final Type function;
+    public final Type parameter;
+    
+    public TApply(Type function, Type parameter) {
+        if(NULL_CHECKS) {
+            if(function == null)
+                throw new NullPointerException();
+            if(parameter == null)
+                throw new NullPointerException();
+        }
+        this.function = function;
+        this.parameter = parameter;
+    }
+    
+    private TApply create(Type function, Type parameter) {
+        if(function == this.function && parameter == this.parameter)
+            return this;
+        else
+            return new TApply(function, parameter);
+    }
+
+    @Override
+    public TApply replace(TVar var, Type replacement) {
+        return create(
+                function.replace(var, replacement), 
+                parameter.replace(var, replacement));
+    }
+
+    @Override
+    public TypeAst toTypeAst(TypeUnparsingContext context) {
+        TMultiApply multiApply = Types.toMultiApply(this);
+        
+        Type function = multiApply.function;
+        List<Type> parameters = multiApply.parameters;
+        
+        TypeAst ast = null;
+        int parameterPos = 0;
+
+        if(function instanceof TCon) {
+            /*if(function == Types.ARROW && parameters.size() >= 2) {
+                ast = new TFunctionAst(
+                        parameters.get(0).toTypeAst(context), 
+                        parameters.get(1).toTypeAst(context));
+                parameterPos = 2;
+            }
+            else*/ if(function == Types.LIST && parameters.size() >= 1) {
+                ast = new TListAst(
+                        parameters.get(0).toTypeAst(context));
+                parameterPos = 1;
+            }
+            else {
+                TCon con = (TCon)function;
+                if(con.module == Types.BUILTIN && con.name.charAt(0)=='(') {
+                    int tupleLength = con.name.length()-2;
+                    if(tupleLength>0) ++tupleLength;
+                    if(parameters.size() >= tupleLength) {
+                        TypeAst[] components = new TypeAst[tupleLength];
+                        for(int i=0;i<tupleLength;++i)
+                            components[i] = parameters.get(i).toTypeAst(context);
+                        ast = new TTupleAst(components);
+                        parameterPos = tupleLength;
+                    }
+                }                                
+            }
+        }
+        if(ast == null)
+            ast = function.toTypeAst(context);
+        for(;parameterPos < multiApply.parameters.size();++parameterPos)
+            ast = new TApplyAst(
+                    ast, 
+                    parameters.get(parameterPos).toTypeAst(context));
+        return ast;
+    }
+
+    @Override
+    public void updateHashCode(TypeHashCodeContext context) {
+        context.append(TypeHashCodeContext.APPLY);
+        function.updateHashCode(context);
+        parameter.updateHashCode(context);
+    }
+
+    @Override
+    public void collectFreeVars(ArrayList<TVar> vars) {
+        function.collectFreeVars(vars);
+        parameter.collectFreeVars(vars);
+    }
+
+    @Override
+    public void collectMetaVars(ArrayList<TMetaVar> vars) {
+        function.collectMetaVars(vars);
+        parameter.collectMetaVars(vars);
+    }
+    
+    @Override
+    public void collectMetaVars(THashSet<TMetaVar> vars) {
+        function.collectMetaVars(vars);
+        parameter.collectMetaVars(vars);
+    }
+    
+    @Override
+    public void collectEffectMetaVars(ArrayList<TMetaVar> vars) {
+        function.collectEffectMetaVars(vars);
+        parameter.collectEffectMetaVars(vars);
+    }
+    
+    @Override
+    public boolean contains(TMetaVar other) {
+        return function.contains(other) || parameter.contains(other);
+    }
+    
+    @Override
+    public Type convertMetaVarsToVars() {
+        Type newFunction = function.convertMetaVarsToVars();
+        Type newParameter = parameter.convertMetaVarsToVars();
+        if(newFunction == function && newParameter == parameter)
+            return this;
+        else
+            return new TApply(newFunction, newParameter);
+    }
+
+    @Override
+    public boolean isGround() {
+        return function.isGround() && parameter.isGround();
+    }
+
+       public void checkKind(Environment context, Kind requiredKind) throws KindUnificationException {
+        Kind functionKind = function.inferKind(context);
+        Kind parameterKind = parameter.inferKind(context);
+        Kinds.unify(functionKind, Kinds.arrow(parameterKind, requiredKind));
+    }
+
+    @Override
+    public boolean containsMetaVars() {
+        return function.containsMetaVars() || parameter.containsMetaVars();
+    }
+
+    @Override
+    public void toName(TypeUnparsingContext context, StringBuilder b) {
+        function.toName(context, b);
+        b.append('_');
+        parameter.toName(context, b);
+    }
+
+    @Override
+    public int getClassId() {
+        return APPLY_ID;
+    }
+
+    @Override
+    public void addPolarity(Polarity polarity) {
+        function.addPolarity(Polarity.BIPOLAR);
+        parameter.addPolarity(Polarity.BIPOLAR);
+    }
+    
+    @Override
+    public Type head() {
+        return function.head();
+    }
+
+    @Override
+    public Type copySkeleton(THashMap<TMetaVar, TMetaVar> metaVarMap) {
+        Type newFunction = function.copySkeleton(metaVarMap);
+        Type newParameter = parameter.copySkeleton(metaVarMap);
+        if(newFunction == function && newParameter == parameter)
+            return this;
+        else
+            return new TApply(newFunction, newParameter);
+    }
+}