]> gerrit.simantics Code Review - simantics/platform.git/blob
c1b2d43723e744f780983627d7d1f3480db55897
[simantics/platform.git] /
1 package org.simantics.scl.compiler.internal.parsing.types;
2
3 import java.util.Arrays;
4
5 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;
6 import org.simantics.scl.compiler.elaboration.modules.TypeAlias;
7 import org.simantics.scl.compiler.environment.AmbiguousNameException;
8 import org.simantics.scl.compiler.environment.Environments;
9 import org.simantics.scl.compiler.internal.types.TypeElaborationContext;
10 import org.simantics.scl.compiler.types.Type;
11 import org.simantics.scl.compiler.types.Types;
12 import org.simantics.scl.compiler.types.kinds.Kind;
13 import org.simantics.scl.compiler.types.kinds.Kinds;
14
15 import gnu.trove.map.hash.TObjectIntHashMap;
16 import gnu.trove.set.hash.TIntHashSet;
17
18
19 public class TApplyAst extends TypeAst {
20     public final TypeAst function;
21     public final TypeAst[] parameters;
22     
23     public TApplyAst(TypeAst function, TypeAst[] parameters) {
24         this.function = function;
25         this.parameters = parameters;
26     }
27
28     @Override
29     public void toString(StringBuilder b) {
30         function.toString(b, 2);
31         for(TypeAst parameter : parameters) {
32             b.append(' ');
33             parameter.toString(b, 1);
34         }
35     }
36
37     @Override
38     public Type toType(TypeTranslationContext context, Kind expectedKind) {
39         if(function instanceof TVarAst) {
40             String name = ((TVarAst)function).name;
41             TypeAlias alias;
42             try {
43                 alias = Environments.getTypeAlias(context.getEnvironment(), name);
44             } catch (AmbiguousNameException e) {
45                 context.getErrorLog().log(location, e.getMessage());
46                 return Types.metaVar(Kinds.STAR);
47             }
48             if(alias != null) {
49                 if(parameters.length != alias.getArity()) {
50                     context.getErrorLog().log(location, "Wrong number of parameters are given to the type alias. Expected " +
51                             alias.getArity() + " parameters, got " + parameters.length + " parameters.");
52                     return Types.metaVar(Kinds.metaVar());
53                 }
54                 Type[] parameterTypes = new Type[parameters.length];
55                 for(int i=0;i<parameters.length;++i)
56                     parameterTypes[i] = parameters[i].toType(context, Kinds.metaVar());
57                 return alias.body.replace(alias.parameters, parameterTypes);
58             }
59         }
60         
61         Kind[] parameterKinds = new Kind[parameters.length];
62         Kind functionKind = expectedKind;
63         for(int i=parameters.length-1;i>=0;--i) {
64             Kind kind = Kinds.metaVar();
65             parameterKinds[i] = kind;
66             functionKind = Kinds.arrow(kind, functionKind);
67         }        
68         Type functionType = function.toType(context, functionKind);
69         Type[] parameterTypes = new Type[parameters.length];
70         for(int i=0;i<parameters.length;++i) {
71             parameterTypes[i] = parameters[i].toType(context, parameterKinds[i]);
72         }
73         return Types.apply(functionType, parameterTypes);
74     }
75
76     @Override
77     public Type toType(TypeElaborationContext context) {
78         Type functionType = function.toType(context);
79         Type[] parameterTypes = new Type[parameters.length];
80         for(int i=0;i<parameters.length;++i)
81             parameterTypes[i] = parameters[i].toType(context);
82         return Types.apply(functionType, parameterTypes);
83     }
84     
85     @Override
86     public int getPrecedence() {
87         return 1;
88     }
89
90     public static TApplyAst apply(TypeAst f, TypeAst p) {
91         if(f instanceof TApplyAst) {
92             TApplyAst fApply = (TApplyAst)f; 
93             TypeAst[] parameters = Arrays.copyOf(fApply.parameters,
94                     fApply.parameters.length+1);
95             parameters[fApply.parameters.length] = p;
96             return new TApplyAst(fApply.function, parameters);
97         }
98         else
99             return new TApplyAst(f, new TypeAst[] {p});
100     }
101
102     @Override
103     public void collectReferences(TObjectIntHashMap<String> typeNameMap,
104             TIntHashSet set) {
105         function.collectReferences(typeNameMap, set);
106         for(TypeAst parameter : parameters)
107             parameter.collectReferences(typeNameMap, set);
108     }
109
110 }