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