X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Ftypes%2FTFun.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Ftypes%2FTFun.java;h=917526dd0bd4494bfa3e4dc73f295f2a0cc3befd;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java new file mode 100644 index 000000000..917526dd0 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java @@ -0,0 +1,192 @@ +package org.simantics.scl.compiler.types; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.set.hash.THashSet; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.environment.Environment; +import org.simantics.scl.compiler.internal.types.TypeHashCodeContext; +import org.simantics.scl.compiler.internal.types.ast.TEffectAst; +import org.simantics.scl.compiler.internal.types.ast.TFunctionAst; +import org.simantics.scl.compiler.internal.types.ast.TPredAst; +import org.simantics.scl.compiler.internal.types.ast.TypeAst; +import org.simantics.scl.compiler.types.exceptions.KindUnificationException; +import org.simantics.scl.compiler.types.kinds.Kind; +import org.simantics.scl.compiler.types.kinds.Kinds; +import org.simantics.scl.compiler.types.util.Polarity; +import org.simantics.scl.compiler.types.util.TypeUnparsingContext; + +public class TFun extends Type { + public final Type domain; + public final Type effect; + public final Type range; + + TFun(Type domain, Type effect, Type range) { + if(domain == null) + throw new NullPointerException(); + if(effect == null) + throw new NullPointerException(); + if(range == null) + throw new NullPointerException(); + /*domain = Types.weakCanonical(domain); + range = Types.weakCanonical(range); + if(domain instanceof TUnion) + throw new RuntimeException(); + if(range instanceof TUnion) + throw new RuntimeException();*/ + + this.domain = domain; + this.effect = effect; + this.range = range; + } + + @Override + public Type replace(TVar var, Type replacement) { + Type newDomain = domain.replace(var, replacement); + Type newEffect = effect.replace(var, replacement); + Type newRange = range.replace(var, replacement); + if(newDomain == domain && newEffect == effect && newRange == range) + return this; + else + return new TFun(newDomain, newEffect, newRange); + } + + @Override + public TypeAst toTypeAst(TypeUnparsingContext context) { + TypeAst domainAst = domain.toTypeAst(context); + TypeAst rangeAst = range.toTypeAst(context); + if(Types.canonical(effect) != Types.NO_EFFECTS) + rangeAst = new TEffectAst(effect.toTypeAst(context), rangeAst); + Type dom = Types.canonical(domain); + if(dom instanceof TPred) + return new TPredAst(domainAst, rangeAst); + else if(dom == Types.PUNIT) { + //if(rangeAst instanceof TEffectAst) + return rangeAst; + /*else + return new TEffectAst(Types.NO_EFFECTS, rangeAst);*/ + } + else + return new TFunctionAst(domainAst, rangeAst); + } + + @Override + public void toName(TypeUnparsingContext context, StringBuilder b) { + b.append("FUNC_"); + domain.toName(context, b); + b.append('_'); + effect.toName(context, b); + b.append('_'); + range.toName(context, b); + } + + @Override + public void updateHashCode(TypeHashCodeContext context) { + context.append(TypeHashCodeContext.FUN); + domain.updateHashCode(context); + effect.updateHashCode(context); + range.updateHashCode(context); + } + + @Override + public void collectFreeVars(ArrayList vars) { + domain.collectFreeVars(vars); + effect.collectFreeVars(vars); + range.collectFreeVars(vars); + } + + @Override + public void collectMetaVars(ArrayList vars) { + domain.collectMetaVars(vars); + effect.collectMetaVars(vars); + range.collectMetaVars(vars); + } + + @Override + public void collectMetaVars(THashSet vars) { + domain.collectMetaVars(vars); + effect.collectMetaVars(vars); + range.collectMetaVars(vars); + } + + @Override + public void collectEffectMetaVars(ArrayList vars) { + domain.collectEffectMetaVars(vars); + effect.collectMetaVars(vars); + range.collectEffectMetaVars(vars); + } + + @Override + public boolean isGround() { + return domain.isGround() && effect.isGround() && range.isGround(); + } + + @Override + public boolean containsMetaVars() { + return domain.containsMetaVars() + || effect.containsMetaVars() + || range.containsMetaVars(); + } + + @Override + public boolean contains(TMetaVar other) { + return domain.contains(other) + || effect.contains(other) + || range.contains(other); + } + + @Override + public int getClassId() { + return FUN_ID; + } + + @Override + public Kind inferKind(Environment context) + throws KindUnificationException { + domain.checkKind(context, Kinds.STAR); + range.checkKind(context, Kinds.STAR); + return Kinds.STAR; + } + + @Override + public Type convertMetaVarsToVars() { + Type newDomain = domain.convertMetaVarsToVars(); + Type newEffect = effect.convertMetaVarsToVars(); + Type newRange = range.convertMetaVarsToVars(); + if(newDomain == domain && newEffect == effect && newRange == range) + return this; + else + return new TFun(newDomain, newEffect, newRange); + } + + @Override + public boolean isMinimal() { + return Types.canonical(effect) == Types.NO_EFFECTS && + range.isMinimal() && domain.isMaximal(); + } + + public boolean isMaximal() { + return false; + } + + @Override + public void addPolarity(Polarity polarity) { + domain.addPolarity(polarity.flip()); + effect.addPolarity(polarity); + range.addPolarity(polarity); + } + + @Override + public Type head() { + return Types.ARROW; + } + + @Override + public Type copySkeleton(THashMap metaVarMap) { + Type newDomain = domain.copySkeleton(metaVarMap); + Type newEffect = Types.NO_EFFECTS; + Type newRange = range.copySkeleton(metaVarMap); + return new TFun(newDomain, newEffect, newRange); + } +}