]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/types/TApplyAst.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / parsing / types / TApplyAst.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/types/TApplyAst.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/types/TApplyAst.java
new file mode 100644 (file)
index 0000000..c1b2d43
--- /dev/null
@@ -0,0 +1,110 @@
+package org.simantics.scl.compiler.internal.parsing.types;
+
+import java.util.Arrays;
+
+import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
+import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
+import org.simantics.scl.compiler.environment.AmbiguousNameException;
+import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kind;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.TIntHashSet;
+
+
+public class TApplyAst extends TypeAst {
+    public final TypeAst function;
+    public final TypeAst[] parameters;
+    
+    public TApplyAst(TypeAst function, TypeAst[] parameters) {
+        this.function = function;
+        this.parameters = parameters;
+    }
+
+    @Override
+    public void toString(StringBuilder b) {
+        function.toString(b, 2);
+        for(TypeAst parameter : parameters) {
+            b.append(' ');
+            parameter.toString(b, 1);
+        }
+    }
+
+    @Override
+    public Type toType(TypeTranslationContext context, Kind expectedKind) {
+        if(function instanceof TVarAst) {
+            String name = ((TVarAst)function).name;
+            TypeAlias alias;
+            try {
+                alias = Environments.getTypeAlias(context.getEnvironment(), name);
+            } catch (AmbiguousNameException e) {
+                context.getErrorLog().log(location, e.getMessage());
+                return Types.metaVar(Kinds.STAR);
+            }
+            if(alias != null) {
+                if(parameters.length != alias.getArity()) {
+                    context.getErrorLog().log(location, "Wrong number of parameters are given to the type alias. Expected " +
+                            alias.getArity() + " parameters, got " + parameters.length + " parameters.");
+                    return Types.metaVar(Kinds.metaVar());
+                }
+                Type[] parameterTypes = new Type[parameters.length];
+                for(int i=0;i<parameters.length;++i)
+                    parameterTypes[i] = parameters[i].toType(context, Kinds.metaVar());
+                return alias.body.replace(alias.parameters, parameterTypes);
+            }
+        }
+        
+        Kind[] parameterKinds = new Kind[parameters.length];
+        Kind functionKind = expectedKind;
+        for(int i=parameters.length-1;i>=0;--i) {
+            Kind kind = Kinds.metaVar();
+            parameterKinds[i] = kind;
+            functionKind = Kinds.arrow(kind, functionKind);
+        }        
+        Type functionType = function.toType(context, functionKind);
+        Type[] parameterTypes = new Type[parameters.length];
+        for(int i=0;i<parameters.length;++i) {
+            parameterTypes[i] = parameters[i].toType(context, parameterKinds[i]);
+        }
+        return Types.apply(functionType, parameterTypes);
+    }
+
+    @Override
+    public Type toType(TypeElaborationContext context) {
+        Type functionType = function.toType(context);
+        Type[] parameterTypes = new Type[parameters.length];
+        for(int i=0;i<parameters.length;++i)
+            parameterTypes[i] = parameters[i].toType(context);
+        return Types.apply(functionType, parameterTypes);
+    }
+    
+    @Override
+    public int getPrecedence() {
+        return 1;
+    }
+
+    public static TApplyAst apply(TypeAst f, TypeAst p) {
+        if(f instanceof TApplyAst) {
+            TApplyAst fApply = (TApplyAst)f; 
+            TypeAst[] parameters = Arrays.copyOf(fApply.parameters,
+                    fApply.parameters.length+1);
+            parameters[fApply.parameters.length] = p;
+            return new TApplyAst(fApply.function, parameters);
+        }
+        else
+            return new TApplyAst(f, new TypeAst[] {p});
+    }
+
+    @Override
+    public void collectReferences(TObjectIntHashMap<String> typeNameMap,
+            TIntHashSet set) {
+        function.collectReferences(typeNameMap, set);
+        for(TypeAst parameter : parameters)
+            parameter.collectReferences(typeNameMap, set);
+    }
+
+}