]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/types/TFun.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / types / TFun.java
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 (file)
index 0000000..917526d
--- /dev/null
@@ -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<TVar> vars) {
+        domain.collectFreeVars(vars);
+        effect.collectFreeVars(vars);
+        range.collectFreeVars(vars);
+    }
+    
+    @Override
+    public void collectMetaVars(ArrayList<TMetaVar> vars) {
+        domain.collectMetaVars(vars);
+        effect.collectMetaVars(vars);
+        range.collectMetaVars(vars);
+    }
+    
+    @Override
+    public void collectMetaVars(THashSet<TMetaVar> vars) {
+        domain.collectMetaVars(vars);
+        effect.collectMetaVars(vars);
+        range.collectMetaVars(vars);
+    }
+    
+    @Override
+    public void collectEffectMetaVars(ArrayList<TMetaVar> 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<TMetaVar, TMetaVar> metaVarMap) {
+        Type newDomain = domain.copySkeleton(metaVarMap);
+        Type newEffect = Types.NO_EFFECTS;
+        Type newRange = range.copySkeleton(metaVarMap);
+        return new TFun(newDomain, newEffect, newRange);
+    }
+}