]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/types/TFunctionAst.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / parsing / types / TFunctionAst.java
1 package org.simantics.scl.compiler.internal.parsing.types;\r
2 \r
3 import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;\r
4 import org.simantics.scl.compiler.internal.types.TypeElaborationContext;\r
5 import org.simantics.scl.compiler.types.Type;\r
6 import org.simantics.scl.compiler.types.Types;\r
7 import org.simantics.scl.compiler.types.kinds.Kind;\r
8 import org.simantics.scl.compiler.types.kinds.Kinds;\r
9 \r
10 import gnu.trove.map.hash.TObjectIntHashMap;\r
11 import gnu.trove.set.hash.TIntHashSet;\r
12 \r
13 \r
14 \r
15 public class TFunctionAst extends TypeAst {\r
16     public final TypeAst domain;\r
17     public final TypeAst range;\r
18     \r
19     public TFunctionAst(TypeAst domain, TypeAst range) {\r
20         this.domain = domain;\r
21         this.range = range;\r
22     }\r
23     \r
24     @Override\r
25     public void toString(StringBuilder b) {\r
26         domain.toString(b, 2);\r
27         b.append(" -> ");\r
28         range.toString(b, 3);\r
29     }\r
30 \r
31     @Override\r
32     public Type toType(TypeTranslationContext context, Kind expectedKind) {\r
33         context.unify(location, Kinds.STAR, expectedKind);\r
34         if(range instanceof TEffectAst) {\r
35             TEffectAst effectAst = (TEffectAst)range;\r
36             return Types.functionE(\r
37                     domain.toType(context, Kinds.STAR),\r
38                     toEffect(context, effectAst.effects),\r
39                     effectAst.type.toType(context, Kinds.STAR));\r
40         }\r
41         else\r
42             return Types.function(domain.toType(context, Kinds.STAR), range.toType(context, Kinds.STAR));\r
43     }\r
44     \r
45     @Override\r
46     public Type toType(TypeElaborationContext context) {\r
47         if(range instanceof TEffectAst) {\r
48             TEffectAst effectAst = (TEffectAst)range;\r
49             return Types.functionE(\r
50                     domain.toType(context),\r
51                     toEffect(context, effectAst.effects),\r
52                     effectAst.type.toType(context));\r
53         }\r
54         else\r
55             return Types.function(domain.toType(context), range.toType(context));\r
56     }\r
57     \r
58     static Type toEffect(TypeTranslationContext context, TypeAst[] effects) {\r
59         if(effects.length == 0)\r
60             return Types.NO_EFFECTS;\r
61         if(effects.length == 1)\r
62             return effects[0].toEffect(context);\r
63         Type[] types = new Type[effects.length];\r
64         for(int i=0;i<effects.length;++i)\r
65             types[i] = effects[i].toEffect(context);\r
66         return Types.union(types);\r
67     }\r
68     \r
69     static Type toEffect(TypeElaborationContext context, TypeAst[] effects) {\r
70         if(effects.length == 0)\r
71             return Types.NO_EFFECTS;\r
72         if(effects.length == 1)\r
73             return effects[0].toEffect(context);\r
74         Type[] types = new Type[effects.length];\r
75         for(int i=0;i<effects.length;++i)\r
76             types[i] = effects[i].toEffect(context);\r
77         return Types.union(types);\r
78     }\r
79     \r
80     @Override\r
81     public int getPrecedence() {\r
82         return 2;\r
83     }\r
84 \r
85     @Override\r
86     public void collectReferences(TObjectIntHashMap<String> typeNameMap,\r
87             TIntHashSet set) {\r
88         domain.collectReferences(typeNameMap, set);\r
89         range.collectReferences(typeNameMap, set);\r
90     }\r
91 }\r