]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/ESimpleLambda.java
Merge "Ensure GetElementClassRequest is not constructed without elementFactory"
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / ESimpleLambda.java
index e1efb30457b25973dd60ee3110930dede5b6bc38..29eff29103dc6a8e2c257c7857b3125c2ccd2982 100755 (executable)
-package org.simantics.scl.compiler.elaboration.expressions;\r
-\r
-import java.util.ArrayList;\r
-\r
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
-import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
-import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
-import org.simantics.scl.compiler.environment.Environment;\r
-import org.simantics.scl.compiler.errors.Locations;\r
-import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
-import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
-import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
-import org.simantics.scl.compiler.internal.interpreted.IExpression;\r
-import org.simantics.scl.compiler.internal.interpreted.ILambda;\r
-import org.simantics.scl.compiler.top.ExpressionInterpretationContext;\r
-import org.simantics.scl.compiler.top.SCLCompilerConfiguration;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.compiler.types.Types;\r
-import org.simantics.scl.compiler.types.exceptions.MatchException;\r
-import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
-import org.simantics.scl.compiler.types.kinds.Kinds;\r
-import org.simantics.scl.compiler.types.util.MultiFunction;\r
-\r
-import gnu.trove.map.hash.TObjectIntHashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ESimpleLambda extends Expression {\r
-    public Variable parameter;\r
-    public Expression value;\r
-    public Type effect = Types.NO_EFFECTS;\r
-    \r
-    public ESimpleLambda(Variable parameter, Expression value) {\r
-        this.parameter = parameter;\r
-        this.value = value;\r
-    }\r
-    \r
-    public ESimpleLambda(Type effect, Variable parameter, Expression value) {\r
-        this.parameter = parameter;\r
-        this.value = value;\r
-        this.effect = effect;\r
-    }\r
-\r
-    public ESimpleLambda(long loc, Variable parameter, Expression value) {\r
-        super(loc);\r
-        this.parameter = parameter;\r
-        this.value = value;\r
-    }\r
-    \r
-    public ESimpleLambda(long loc, Variable parameter, Type effect, Expression value) {\r
-        super(loc);\r
-        this.parameter = parameter;\r
-        this.value = value;\r
-        this.effect = effect;\r
-    }\r
-\r
-       public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {\r
-        value.collectRefs(allRefs, refs);\r
-    }\r
-       \r
-       @Override\r
-       public void collectVars(TObjectIntHashMap<Variable> allVars,\r
-               TIntHashSet vars) {\r
-           value.collectVars(allVars, vars);\r
-       }\r
-\r
-       public Expression decomposeMatching() {\r
-        value = value.decomposeMatching();\r
-        return this;\r
-    }\r
-\r
-       @Override\r
-       protected void updateType() throws MatchException {\r
-           setType(Types.functionE(Types.canonical(parameter.type),\r
-                   effect, value.getType()));\r
-       }\r
-       \r
-       @Override\r
-       public IVal toVal(Environment env, CodeWriter w) {\r
-           return lambdaToVal(env, w);\r
-    }\r
-\r
-    @Override\r
-    public void collectFreeVariables(THashSet<Variable> vars) {\r
-        value.collectFreeVariables(vars);\r
-        vars.remove(parameter);\r
-    }\r
-\r
-    @Override\r
-    public Expression simplify(SimplificationContext context) {\r
-        value = value.simplify(context);\r
-        return this;\r
-    }\r
-\r
-    @Override\r
-    public Expression resolve(TranslationContext context) {\r
-        value = value.resolve(context);\r
-        return this;\r
-    }\r
-\r
-    @Override\r
-    public Expression replace(ReplaceContext context) {\r
-        Variable newParameter = parameter.copy();\r
-        context.varMap.put(parameter, new EVariable(newParameter));\r
-        ESimpleLambda result = new ESimpleLambda(getLocation(),\r
-                newParameter, \r
-                effect.replace(context.tvarMap),\r
-                value.replace(context));\r
-        // not absolutely needed, but maybe good for performance\r
-        context.varMap.remove(parameter); \r
-        return result;\r
-    }\r
-        \r
-    public Type getLocalEffect() {\r
-        if(SCLCompilerConfiguration.DEBUG)\r
-            if(effect == null)\r
-                throw new InternalCompilerError();\r
-        return effect;\r
-    }\r
-    \r
-    public void setEffect(Type effect) {\r
-        if(effect == null)\r
-            throw new InternalCompilerError();\r
-        this.effect = effect;\r
-    }\r
-    \r
-    @Override\r
-    public IExpression toIExpression(ExpressionInterpretationContext context) {\r
-        // Find parameters of the whole function definition\r
-        ArrayList<Variable> parameters = new ArrayList<Variable>(2);\r
-        parameters.add(parameter);\r
-        Expression cur = value;\r
-        while(true) {\r
-            if(cur instanceof ESimpleLambda) {\r
-                ESimpleLambda lambda = (ESimpleLambda)cur;\r
-                parameters.add(lambda.parameter);\r
-                cur = lambda.value;\r
-            }\r
-            else if(cur instanceof ELambdaType) {\r
-                cur = ((ELambdaType)cur).value;\r
-            }\r
-            else\r
-                break;\r
-            \r
-        }\r
-        \r
-        // Free variables;\r
-        ExpressionInterpretationContext innerContext =  context.createNewContext();\r
-        THashSet<Variable> freeVariables = cur.getFreeVariables();\r
-        for(Variable parameter : parameters)\r
-            freeVariables.remove(parameter);\r
-        int i=0;\r
-        int[] inheritedVariableIds = new int[freeVariables.size()];\r
-        for(Variable var : freeVariables) {\r
-            innerContext.push(var);\r
-            inheritedVariableIds[i++] = context.getVariableId(var);\r
-        }\r
-        \r
-        // Parameters\r
-        for(Variable parameter : parameters)\r
-            innerContext.push(parameter);\r
-        \r
-        // Construct lambda\r
-        IExpression body = cur.toIExpression(innerContext); \r
-        return new ILambda(inheritedVariableIds,\r
-                parameters.size(),\r
-                innerContext.getMaxVariableId(),\r
-                body);\r
-    }\r
-    \r
-    public Expression checkBasicType(TypingContext context, Type requiredType) {\r
-        MultiFunction mfun;\r
-        try {\r
-            mfun = Types.unifyFunction(requiredType, 1);\r
-        } catch (UnificationException e) {\r
-            context.getErrorLog().log(location, "Required type is <" + requiredType + "> which is incompatible with lambda.");\r
-            setType(Types.metaVar(Kinds.STAR));\r
-            return this;\r
-        }\r
-        \r
-        effect = mfun.effect;\r
-        context.pushEffectUpperBound(location, mfun.effect);\r
-        parameter.setType(mfun.parameterTypes[0]);\r
-        value = value.checkType(context, mfun.returnType);\r
-        context.popEffectUpperBound();\r
-        return this;\r
-    }\r
-    \r
-    @Override\r
-    public Expression inferType(TypingContext context) {\r
-        effect = Types.metaVar(Kinds.EFFECT);\r
-        context.pushEffectUpperBound(location, effect);\r
-        if(parameter.type == null)\r
-            parameter.setType(Types.metaVar(Kinds.STAR));\r
-        value = value.checkType(context, Types.metaVar(Kinds.STAR));\r
-        context.popEffectUpperBound();\r
-        return this;\r
-    }\r
-\r
-    @Override\r
-    public Expression decorate(ExpressionDecorator decorator) {\r
-        if(decorator.decorateSubstructure(this))\r
-            value = value.decorate(decorator);\r
-        return decorator.decorate(this);\r
-    }\r
-\r
-    @Override\r
-    public boolean isEffectful() {\r
-       return false;\r
-    }\r
-    \r
-    @Override\r
-    public void collectEffects(THashSet<Type> effects) {\r
-    }\r
-    \r
-    @Override\r
-    public void setLocationDeep(long loc) {\r
-        if(location == Locations.NO_LOCATION) {\r
-            location = loc;\r
-            value.setLocationDeep(loc);\r
-        }\r
-    }\r
-    \r
-    @Override\r
-    public void accept(ExpressionVisitor visitor) {\r
-        visitor.visit(this);\r
-    }\r
-    \r
-    public Expression getValue() {\r
-        return value;\r
-    }\r
-    \r
-    public Variable getParameter() {\r
-        return parameter;\r
-    }\r
-\r
-    @Override\r
-    public void forVariables(VariableProcedure procedure) {\r
-        value.forVariables(procedure);\r
-    }\r
-    \r
-    @Override\r
-    public Expression accept(ExpressionTransformer transformer) {\r
-        return transformer.transform(this);\r
-    }\r
-\r
-}\r
+package org.simantics.scl.compiler.elaboration.expressions;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
+import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.errors.Locations;
+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.utils.ExpressionDecorator;
+import org.simantics.scl.compiler.internal.interpreted.IExpression;
+import org.simantics.scl.compiler.internal.interpreted.ILambda;
+import org.simantics.scl.compiler.top.ExpressionInterpretationContext;
+import org.simantics.scl.compiler.top.SCLCompilerConfiguration;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.exceptions.MatchException;
+import org.simantics.scl.compiler.types.exceptions.UnificationException;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.compiler.types.util.MultiFunction;
+
+import gnu.trove.map.hash.TObjectIntHashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class ESimpleLambda extends Expression {
+    public Variable parameter;
+    public Expression value;
+    public Type effect = Types.NO_EFFECTS;
+    
+    public ESimpleLambda(Variable parameter, Expression value) {
+        this.parameter = parameter;
+        this.value = value;
+    }
+    
+    public ESimpleLambda(Type effect, Variable parameter, Expression value) {
+        this.parameter = parameter;
+        this.value = value;
+        this.effect = effect;
+    }
+
+    public ESimpleLambda(long loc, Variable parameter, Expression value) {
+        super(loc);
+        this.parameter = parameter;
+        this.value = value;
+    }
+    
+    public ESimpleLambda(long loc, Variable parameter, Type effect, Expression value) {
+        super(loc);
+        this.parameter = parameter;
+        this.value = value;
+        this.effect = effect;
+    }
+
+       public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
+        value.collectRefs(allRefs, refs);
+    }
+       
+       @Override
+       public void collectVars(TObjectIntHashMap<Variable> allVars,
+               TIntHashSet vars) {
+           value.collectVars(allVars, vars);
+       }
+
+       public Expression decomposeMatching() {
+        value = value.decomposeMatching();
+        return this;
+    }
+
+       @Override
+       protected void updateType() throws MatchException {
+           setType(Types.functionE(Types.canonical(parameter.type),
+                   effect, value.getType()));
+       }
+       
+       @Override
+       public IVal toVal(Environment env, CodeWriter w) {
+           return lambdaToVal(env, w);
+    }
+
+    @Override
+    public void collectFreeVariables(THashSet<Variable> vars) {
+        value.collectFreeVariables(vars);
+        vars.remove(parameter);
+    }
+
+    @Override
+    public Expression simplify(SimplificationContext context) {
+        value = value.simplify(context);
+        return this;
+    }
+
+    @Override
+    public Expression resolve(TranslationContext context) {
+        value = value.resolve(context);
+        return this;
+    }
+
+    @Override
+    public Expression replace(ReplaceContext context) {
+        Variable newParameter = parameter.copy();
+        context.varMap.put(parameter, new EVariable(newParameter));
+        ESimpleLambda result = new ESimpleLambda(getLocation(),
+                newParameter, 
+                effect.replace(context.tvarMap),
+                value.replace(context));
+        // not absolutely needed, but maybe good for performance
+        context.varMap.remove(parameter); 
+        return result;
+    }
+        
+    public Type getLocalEffect() {
+        if(SCLCompilerConfiguration.DEBUG)
+            if(effect == null)
+                throw new InternalCompilerError();
+        return effect;
+    }
+    
+    public void setEffect(Type effect) {
+        if(effect == null)
+            throw new InternalCompilerError();
+        this.effect = effect;
+    }
+    
+    @Override
+    public IExpression toIExpression(ExpressionInterpretationContext context) {
+        // Find parameters of the whole function definition
+        ArrayList<Variable> parameters = new ArrayList<Variable>(2);
+        parameters.add(parameter);
+        Expression cur = value;
+        while(true) {
+            if(cur instanceof ESimpleLambda) {
+                ESimpleLambda lambda = (ESimpleLambda)cur;
+                parameters.add(lambda.parameter);
+                cur = lambda.value;
+            }
+            else if(cur instanceof ELambdaType) {
+                cur = ((ELambdaType)cur).value;
+            }
+            else
+                break;
+            
+        }
+        
+        // Free variables;
+        ExpressionInterpretationContext innerContext =  context.createNewContext();
+        THashSet<Variable> freeVariables = cur.getFreeVariables();
+        for(Variable parameter : parameters)
+            freeVariables.remove(parameter);
+        int i=0;
+        int[] inheritedVariableIds = new int[freeVariables.size()];
+        for(Variable var : freeVariables) {
+            innerContext.push(var);
+            inheritedVariableIds[i++] = context.getVariableId(var);
+        }
+        
+        // Parameters
+        for(Variable parameter : parameters)
+            innerContext.push(parameter);
+        
+        // Construct lambda
+        IExpression body = cur.toIExpression(innerContext); 
+        return new ILambda(inheritedVariableIds,
+                parameters.size(),
+                innerContext.getMaxVariableId(),
+                body);
+    }
+    
+    public Expression checkBasicType(TypingContext context, Type requiredType) {
+        MultiFunction mfun;
+        try {
+            mfun = Types.unifyFunction(requiredType, 1);
+        } catch (UnificationException e) {
+            context.getErrorLog().log(location, "Required type is <" + requiredType + "> which is incompatible with lambda.");
+            setType(Types.metaVar(Kinds.STAR));
+            return this;
+        }
+        
+        effect = mfun.effect;
+        context.pushEffectUpperBound(location, mfun.effect);
+        parameter.setType(mfun.parameterTypes[0]);
+        value = value.checkType(context, mfun.returnType);
+        context.popEffectUpperBound();
+        return this;
+    }
+    
+    @Override
+    public Expression inferType(TypingContext context) {
+        effect = Types.metaVar(Kinds.EFFECT);
+        context.pushEffectUpperBound(location, effect);
+        if(parameter.type == null)
+            parameter.setType(Types.metaVar(Kinds.STAR));
+        value = value.checkType(context, Types.metaVar(Kinds.STAR));
+        context.popEffectUpperBound();
+        return this;
+    }
+
+    @Override
+    public Expression decorate(ExpressionDecorator decorator) {
+        if(decorator.decorateSubstructure(this))
+            value = value.decorate(decorator);
+        return decorator.decorate(this);
+    }
+
+    @Override
+    public boolean isEffectful() {
+       return false;
+    }
+    
+    @Override
+    public void collectEffects(THashSet<Type> effects) {
+    }
+    
+    @Override
+    public void setLocationDeep(long loc) {
+        if(location == Locations.NO_LOCATION) {
+            location = loc;
+            value.setLocationDeep(loc);
+        }
+    }
+    
+    @Override
+    public void accept(ExpressionVisitor visitor) {
+        visitor.visit(this);
+    }
+    
+    public Expression getValue() {
+        return value;
+    }
+    
+    public Variable getParameter() {
+        return parameter;
+    }
+
+    @Override
+    public void forVariables(VariableProcedure procedure) {
+        value.forVariables(procedure);
+    }
+    
+    @Override
+    public Expression accept(ExpressionTransformer transformer) {
+        return transformer.transform(this);
+    }
+    
+    @Override
+    public int getSyntacticFunctionArity() {
+        return 1 + value.getSyntacticFunctionArity();
+    }
+
+}