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