X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fexpressions%2FExpression.java;h=427acbd19b9dbbdd082df33f7c8ca97b0792d3ed;hp=8adf33936524d266115b25a0b706052b30e6ea9c;hb=666ee533a3cfa9f59e79215a269f8342227cdbda;hpb=593a8f75d9dbc363234002dc500c346afbeba040 diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java old mode 100755 new mode 100644 index 8adf33936..427acbd19 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java @@ -1,11 +1,12 @@ package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; +import java.util.Set; 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.EnvironmentalContext; import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext; import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; @@ -14,13 +15,17 @@ 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.CollectFreeVariablesVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectRefsVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.CollectVarsVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.ForVariablesUsesVisitor; +import org.simantics.scl.compiler.elaboration.expressions.visitors.StandardExpressionVisitor; 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; @@ -35,7 +40,6 @@ import org.simantics.scl.compiler.types.kinds.Kinds; import org.simantics.scl.compiler.types.util.Typed; import gnu.trove.map.hash.TObjectIntHashMap; -import gnu.trove.set.hash.THashSet; import gnu.trove.set.hash.TIntHashSet; public abstract class Expression extends Symbol implements Typed { @@ -84,13 +88,14 @@ public abstract class Expression extends Symbol implements Typed { return context.subsume(inferType(context), requiredType); } - protected Expression applyPUnit(EnvironmentalContext context) { + protected Expression applyPUnit(TypingContext context) { Type type = Types.canonical(getType()); if(type instanceof TFun) { TFun fun = (TFun)type; if(fun.getCanonicalDomain() == Types.PUNIT) { EApply result = new EApply(location, this, new ELiteral(NoRepConstant.PUNIT)); result.effect = fun.getCanonicalEffect(); + context.declareEffect(this.location, result.effect); return result; } } @@ -103,23 +108,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 constraints = new ArrayList(2); @@ -143,7 +148,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 +156,23 @@ public abstract class Expression extends Symbol implements Typed { else break; } - } - return checkBasicType(context, requiredType); - } + } + return checkBasicType(context, requiredType); + } - public abstract void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs); - public abstract void collectVars(TObjectIntHashMap allVars, TIntHashSet vars); - public abstract void forVariables(VariableProcedure procedure); - - public Expression decomposeMatching() { + public final void collectRefs(TObjectIntHashMap allRefs, TIntHashSet refs) { + accept(new CollectRefsVisitor(allRefs, refs)); + } + + public final void collectVars(TObjectIntHashMap allVars, TIntHashSet vars) { + accept(new CollectVarsVisitor(allVars, vars)); + } + + public final void forVariableUses(VariableProcedure procedure) { + accept(new ForVariablesUsesVisitor(procedure)); + } + + public Expression decomposeMatching() { return this; } @@ -196,7 +209,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) @@ -204,8 +217,6 @@ public abstract class Expression extends Symbol implements Typed { return new ELambdaType(vars, this); } - public abstract void collectFreeVariables(THashSet vars); - public Expression simplify(SimplificationContext context) { System.out.println("#############################"); System.out.println(this); @@ -238,10 +249,6 @@ public abstract class Expression extends Symbol implements Typed { context.getErrorLog().log(location, "Pattern was expected here."); return new EError(); } - - public void removeFreeVariables(THashSet vars) { - throw new InternalCompilerError(getClass().getSimpleName() + " is not a pattern."); - } public Expression checkTypeAsPattern(TypingContext context, Type requiredType) { if(context.isInPattern()) @@ -252,11 +259,14 @@ public abstract class Expression extends Symbol implements Typed { return expression; } - public THashSet getFreeVariables() { - THashSet result = new THashSet(); - collectFreeVariables(result); - return result; - } + /** + * Used during simplification and in toIExpression + */ + public Set getFreeVariables() { + CollectFreeVariablesVisitor visitor = new CollectFreeVariablesVisitor(); + accept(visitor); + return visitor.getFreeVariables(); + } public static Expression[] concat(Expression[] a, Expression[] b) { if(a.length == 0) @@ -303,14 +313,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 effects); - public Type getEffect() { - THashSet effects = new THashSet(); - 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);