1 package org.simantics.scl.compiler.internal.parsing.types;
3 import java.util.Arrays;
5 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
6 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
7 import org.simantics.scl.compiler.elaboration.modules.TypeDescriptor;
8 import org.simantics.scl.compiler.environment.AmbiguousNameException;
9 import org.simantics.scl.compiler.environment.Environments;
10 import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
11 import org.simantics.scl.compiler.types.Type;
12 import org.simantics.scl.compiler.types.Types;
13 import org.simantics.scl.compiler.types.kinds.Kind;
14 import org.simantics.scl.compiler.types.kinds.Kinds;
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.set.hash.TIntHashSet;
20 public class TApplyAst extends TypeAst {
21 public final TypeAst function;
22 public final TypeAst[] parameters;
24 public TApplyAst(TypeAst function, TypeAst[] parameters) {
25 this.function = function;
26 this.parameters = parameters;
30 public void toString(StringBuilder b) {
31 function.toString(b, 2);
32 for(TypeAst parameter : parameters) {
34 parameter.toString(b, 1);
39 public Type toType(TypeTranslationContext context, Kind expectedKind) {
40 if(function instanceof TVarAst) {
41 String name = ((TVarAst)function).name;
42 TypeAlias alias = null;
44 TypeDescriptor tdesc = Environments.getTypeDescriptor(context.getEnvironment(), name);
45 if(tdesc instanceof TypeAlias)
46 alias = (TypeAlias)tdesc;
47 } catch (AmbiguousNameException e) {
48 context.getErrorLog().log(location, e.getMessage());
49 return Types.metaVar(Kinds.STAR);
52 int arity = alias.getArity();
53 if(parameters.length < arity) {
54 context.getErrorLog().log(location, "Wrong number of parameters are given to the type alias. Expected " +
55 arity + " parameters, got " + parameters.length + " parameters.");
56 return Types.metaVar(Kinds.metaVar());
58 Type[] parameterTypes = new Type[arity];
59 for(int i=0;i<arity;++i)
60 parameterTypes[i] = parameters[i].toType(context, Kinds.metaVar());
61 Type result = alias.body.replace(alias.parameters, parameterTypes);
62 for(int i=arity;i<parameters.length;++i)
63 result = Types.apply(result, parameters[i].toType(context, Kinds.metaVar()));
68 Kind[] parameterKinds = new Kind[parameters.length];
69 Kind functionKind = expectedKind;
70 for(int i=parameters.length-1;i>=0;--i) {
71 Kind kind = Kinds.metaVar();
72 parameterKinds[i] = kind;
73 functionKind = Kinds.arrow(kind, functionKind);
75 Type functionType = function.toType(context, functionKind);
76 Type[] parameterTypes = new Type[parameters.length];
77 for(int i=0;i<parameters.length;++i) {
78 parameterTypes[i] = parameters[i].toType(context, parameterKinds[i]);
80 return Types.apply(functionType, parameterTypes);
84 public Type toType(TypeElaborationContext context) {
85 Type functionType = function.toType(context);
86 Type[] parameterTypes = new Type[parameters.length];
87 for(int i=0;i<parameters.length;++i)
88 parameterTypes[i] = parameters[i].toType(context);
89 return Types.apply(functionType, parameterTypes);
93 public int getPrecedence() {
97 public static TApplyAst apply(TypeAst f, TypeAst p) {
98 if(f instanceof TApplyAst) {
99 TApplyAst fApply = (TApplyAst)f;
100 TypeAst[] parameters = Arrays.copyOf(fApply.parameters,
101 fApply.parameters.length+1);
102 parameters[fApply.parameters.length] = p;
103 return new TApplyAst(fApply.function, parameters);
106 return new TApplyAst(f, new TypeAst[] {p});
110 public void collectReferences(TObjectIntHashMap<String> typeNameMap,
112 function.collectReferences(typeNameMap, set);
113 for(TypeAst parameter : parameters)
114 parameter.collectReferences(typeNameMap, set);