--- /dev/null
+package org.simantics.scl.compiler.internal.parsing.types;\r
+\r
+import org.simantics.scl.compiler.elaboration.contexts.TypeTranslationContext;\r
+import org.simantics.scl.compiler.internal.types.TypeElaborationContext;\r
+import org.simantics.scl.compiler.types.Type;\r
+import org.simantics.scl.compiler.types.Types;\r
+import org.simantics.scl.compiler.types.kinds.Kind;\r
+import org.simantics.scl.compiler.types.kinds.Kinds;\r
+\r
+import gnu.trove.map.hash.TObjectIntHashMap;\r
+import gnu.trove.set.hash.TIntHashSet;\r
+\r
+\r
+\r
+public class TFunctionAst extends TypeAst {\r
+ public final TypeAst domain;\r
+ public final TypeAst range;\r
+ \r
+ public TFunctionAst(TypeAst domain, TypeAst range) {\r
+ this.domain = domain;\r
+ this.range = range;\r
+ }\r
+ \r
+ @Override\r
+ public void toString(StringBuilder b) {\r
+ domain.toString(b, 2);\r
+ b.append(" -> ");\r
+ range.toString(b, 3);\r
+ }\r
+\r
+ @Override\r
+ public Type toType(TypeTranslationContext context, Kind expectedKind) {\r
+ context.unify(location, Kinds.STAR, expectedKind);\r
+ if(range instanceof TEffectAst) {\r
+ TEffectAst effectAst = (TEffectAst)range;\r
+ return Types.functionE(\r
+ domain.toType(context, Kinds.STAR),\r
+ toEffect(context, effectAst.effects),\r
+ effectAst.type.toType(context, Kinds.STAR));\r
+ }\r
+ else\r
+ return Types.function(domain.toType(context, Kinds.STAR), range.toType(context, Kinds.STAR));\r
+ }\r
+ \r
+ @Override\r
+ public Type toType(TypeElaborationContext context) {\r
+ if(range instanceof TEffectAst) {\r
+ TEffectAst effectAst = (TEffectAst)range;\r
+ return Types.functionE(\r
+ domain.toType(context),\r
+ toEffect(context, effectAst.effects),\r
+ effectAst.type.toType(context));\r
+ }\r
+ else\r
+ return Types.function(domain.toType(context), range.toType(context));\r
+ }\r
+ \r
+ static Type toEffect(TypeTranslationContext context, TypeAst[] effects) {\r
+ if(effects.length == 0)\r
+ return Types.NO_EFFECTS;\r
+ if(effects.length == 1)\r
+ return effects[0].toEffect(context);\r
+ Type[] types = new Type[effects.length];\r
+ for(int i=0;i<effects.length;++i)\r
+ types[i] = effects[i].toEffect(context);\r
+ return Types.union(types);\r
+ }\r
+ \r
+ static Type toEffect(TypeElaborationContext context, TypeAst[] effects) {\r
+ if(effects.length == 0)\r
+ return Types.NO_EFFECTS;\r
+ if(effects.length == 1)\r
+ return effects[0].toEffect(context);\r
+ Type[] types = new Type[effects.length];\r
+ for(int i=0;i<effects.length;++i)\r
+ types[i] = effects[i].toEffect(context);\r
+ return Types.union(types);\r
+ }\r
+ \r
+ @Override\r
+ public int getPrecedence() {\r
+ return 2;\r
+ }\r
+\r
+ @Override\r
+ public void collectReferences(TObjectIntHashMap<String> typeNameMap,\r
+ TIntHashSet set) {\r
+ domain.collectReferences(typeNameMap, set);\r
+ range.collectReferences(typeNameMap, set);\r
+ }\r
+}\r