]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java
(refs #7375) Replaced collectEffects by CollectEffectsVisitor
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / Expression.java
index a0f28d190bf7340234ae5a052675f572f6275c10..507d335e3479379ce7cd4ae1a66e196493e5c920 100644 (file)
@@ -4,6 +4,7 @@ import java.util.ArrayList;
 
 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
 import org.simantics.scl.compiler.common.precedence.Precedence;
+import org.simantics.scl.compiler.compilation.CompilationContext;
 import org.simantics.scl.compiler.constants.NoRepConstant;
 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
@@ -13,13 +14,14 @@ import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
 import org.simantics.scl.compiler.elaboration.expressions.lhstype.PatternMatchingLhs;
 import org.simantics.scl.compiler.elaboration.expressions.printing.ExpressionToStringVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectEffectsVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectRefsVisitor;
+import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor;
 import org.simantics.scl.compiler.elaboration.query.QAtom;
 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
-import org.simantics.scl.compiler.environment.Environment;
 import org.simantics.scl.compiler.internal.codegen.references.IVal;
 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
 import org.simantics.scl.compiler.internal.elaboration.decomposed.DecomposedExpression;
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;
 import org.simantics.scl.compiler.internal.interpreted.IExpression;
 import org.simantics.scl.compiler.internal.parsing.Symbol;
 import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
@@ -103,23 +105,23 @@ public abstract class Expression extends Symbol implements Typed {
             expression = new ESimpleLet(location, null, expression, new ELiteral(NoRepConstant.PUNIT));
         return expression;
     }
-       
-       /**
-        * Checks the type of the expression against the given type. Adds type
-        * applications and lambdas if needed.
-        */
-       public final Expression checkType(TypingContext context, Type requiredType) {
-           //System.out.println("checkType: " + this + " :: " + requiredType);
-           if(!context.isInPattern()) {
-               requiredType = Types.canonical(requiredType);
-           if(requiredType instanceof TForAll) {
+
+    /**
+     * Checks the type of the expression against the given type. Adds type
+     * applications and lambdas if needed.
+     */
+    public final Expression checkType(TypingContext context, Type requiredType) {
+        //System.out.println("checkType: " + this + " :: " + requiredType);
+        if(!context.isInPattern()) {
+            requiredType = Types.canonical(requiredType);
+            if(requiredType instanceof TForAll) {
                 TForAll forAll = (TForAll)requiredType;
                 TVar var = forAll.var;
                 TVar newVar = Types.var(var.getKind());
                 requiredType = Types.canonical(forAll.type).replace(var, newVar);
                 return new ELambdaType(new TVar[] {newVar}, checkType(context, requiredType));
             }
-           while(requiredType instanceof TFun) {
+            while(requiredType instanceof TFun) {
                 TFun fun = (TFun)requiredType;
                 if(fun.domain instanceof TPred) { // No need to canonicalize
                     ArrayList<Variable> constraints = new ArrayList<Variable>(2);
@@ -143,7 +145,7 @@ public abstract class Expression extends Symbol implements Typed {
                     context.pushEffectUpperBound(location, fun.effect);
                     Expression expr = checkType(context, fun.range);
                     context.popEffectUpperBound();       
-                    
+
                     // Wrap
                     Variable var = new Variable("punit", Types.PUNIT);
                     return new ESimpleLambda(location, var, fun.effect, expr);
@@ -151,15 +153,21 @@ public abstract class Expression extends Symbol implements Typed {
                 else
                     break;
             }
-           }
-           return checkBasicType(context, requiredType); 
-       }
+        }
+        return checkBasicType(context, requiredType); 
+    }
 
-       public abstract void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs);
-       public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
-       public abstract void forVariables(VariableProcedure procedure);
-       
-       public Expression decomposeMatching() {
+    public final void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+        accept(new CollectRefsVisitor(allRefs, refs));
+    }
+
+    public abstract void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars);
+
+    public final void forVariableUses(VariableProcedure procedure) {
+        accept(new ForVariablesUsesVisitor(procedure));
+    }
+
+    public Expression decomposeMatching() {
         return this;
     }
 
@@ -196,7 +204,7 @@ public abstract class Expression extends Symbol implements Typed {
             throw new TypeValidationException(loc);
     }
 
-       public abstract IVal toVal(Environment env, CodeWriter w);
+       public abstract IVal toVal(CompilationContext context, CodeWriter w);
                
        public Expression closure(TVar ... vars) {
            if(vars.length == 0)
@@ -252,11 +260,14 @@ public abstract class Expression extends Symbol implements Typed {
         return expression;
     }
 
+    /**
+     * Used during simplification and in toIExpression
+     */
     public THashSet<Variable> getFreeVariables() {
         THashSet<Variable> result = new THashSet<Variable>();
         collectFreeVariables(result);
         return result;
-    }    
+    }
 
     public static Expression[] concat(Expression[] a, Expression[] b) {
         if(a.length == 0)
@@ -303,14 +314,14 @@ public abstract class Expression extends Symbol implements Typed {
         throw new NotPatternException(this);
     }
     
-    public IVal lambdaToVal(Environment env, CodeWriter w) {
-        DecomposedExpression decomposed = DecomposedExpression.decompose(this);
+    public IVal lambdaToVal(CompilationContext context, CodeWriter w) {
+        DecomposedExpression decomposed = DecomposedExpression.decompose(context.errorLog, this);
         CodeWriter newW = w.createFunction(decomposed.typeParameters, decomposed.effect, decomposed.returnType, decomposed.parameterTypes);
         IVal[] parameters = newW.getParameters();
         IVal functionVal = newW.getFunction().getTarget();
         for(int i=0;i<parameters.length;++i)
             decomposed.parameters[i].setVal(parameters[i]);
-        newW.return_(decomposed.body.toVal(env, newW));
+        newW.return_(decomposed.body.toVal(context, newW));
         return functionVal;
     }
     
@@ -328,8 +339,6 @@ public abstract class Expression extends Symbol implements Typed {
     public Expression applyType(Type type) {
         return new EApplyType(location, this, type);
     }
-    
-    public abstract Expression decorate(ExpressionDecorator decorator);
 
        public boolean isEffectful() {
                return true;
@@ -343,12 +352,10 @@ public abstract class Expression extends Symbol implements Typed {
         return false;
     }
     
-    public abstract void collectEffects(THashSet<Type> effects);
-    
     public Type getEffect() {
-        THashSet<Type> effects = new THashSet<Type>();
-        collectEffects(effects);
-        return Types.union(effects.toArray(new Type[effects.size()]));
+        CollectEffectsVisitor visitor = new CollectEffectsVisitor();
+        accept(visitor);
+        return visitor.getCombinedEffect();
     }
     
     public abstract void accept(ExpressionVisitor visitor);