]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / contexts / SimplificationContext.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java
new file mode 100755 (executable)
index 0000000..e983e12
--- /dev/null
@@ -0,0 +1,274 @@
+package org.simantics.scl.compiler.elaboration.contexts;
+
+import gnu.trove.list.array.TLongArrayList;
+import gnu.trove.map.hash.THashMap;
+
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.constants.Constant;
+import org.simantics.scl.compiler.elaboration.expressions.Case;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;
+import org.simantics.scl.compiler.elaboration.expressions.EError;
+import org.simantics.scl.compiler.elaboration.expressions.EIf;
+import org.simantics.scl.compiler.elaboration.expressions.ELambda;
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
+import org.simantics.scl.compiler.elaboration.expressions.EMatch;
+import org.simantics.scl.compiler.elaboration.expressions.ESimpleLambda;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.java.Builtins;
+import org.simantics.scl.compiler.elaboration.modules.SCLValue;
+import org.simantics.scl.compiler.environment.Environment;
+import org.simantics.scl.compiler.errors.ErrorLog;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.internal.codegen.types.JavaReferenceValidator;
+import org.simantics.scl.compiler.internal.codegen.types.JavaTypeTranslator;
+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.util.MultiFunction;
+
+public class SimplificationContext implements EnvironmentalContext {
+    Environment environment;
+    ErrorLog errorLog;
+    
+    public static final Name MAP_LIST = Name.create("Prelude", "mapList");
+    public static final Name GUARD_LIST = Name.create("Prelude", "guardList");
+    public static final Name CONCAT_MAP = Name.create("Prelude", "concatMap");
+    public static final Name EMPTY_LIST = Name.create("Prelude", "emptyList");
+    public static final Name SINGLETON_LIST = Name.create("Prelude", "singletonList");    
+    public static final Name APPEND_LIST = Name.create("Prelude", "appendList");
+    public static final Name ADD_LIST = Name.create("Prelude", "addList");
+    public static final Name FROM_INTEGER = Name.create("Prelude", "fromInteger");
+    public static final Name FROM_DOUBLE = Name.create("Prelude", "fromDouble");
+    
+    THashMap<Name, SCLValue> constants = new THashMap<Name, SCLValue>();
+    THashMap<Variable, Expression> inlinedVariables = new THashMap<Variable, Expression>();
+    
+    TLongArrayList locatableStack = new TLongArrayList();
+    long locatable;
+    JavaTypeTranslator javaTypeTranslator;
+    JavaReferenceValidator<?, ?, ?, ?> validator;
+    
+    public SimplificationContext(Environment environment, ErrorLog errorLog, 
+            JavaTypeTranslator javaTypeTranslator, JavaReferenceValidator<?, ?, ?, ?> validator) {
+        this.environment = environment;
+        this.errorLog = errorLog;
+        this.javaTypeTranslator = javaTypeTranslator;
+        this.validator = validator;         
+    }
+    
+    public Environment getEnvironment() {
+        return environment;
+    }
+    
+    public ErrorLog getErrorLog() {
+        return errorLog;
+    }
+    
+    public void pushLocation(long loc) {
+        locatableStack.add(locatable);
+        locatable = loc;
+    }
+    
+    public void popLocation() {
+        locatable = locatableStack.removeAt(locatableStack.size()-1);
+    }
+    
+    public SCLValue getValue(Name name) {
+        if(constants.containsKey(name))
+            return constants.get(name);
+        SCLValue value = environment.getValue(name);
+        if(value == null)
+            errorLog.log(locatable, "Couldn't find " + name + ".");
+        constants.put(name, value);
+        return value;
+    }
+    
+    public Expression getConstant(Name name, Type ... typeParameters) {
+        SCLValue value = getValue(name);
+        if(value == null)
+            return new EError(locatable);
+        return new EConstant(value, typeParameters);
+    }
+    
+    public Expression apply(Expression f, Expression ... ps) {
+        Expression result = f;
+        Type type = f.getType();
+        for(Expression p : ps) {
+            result = new EApply(locatable, result, p);
+            MultiFunction mfun;
+            try {
+                mfun = Types.matchFunction(type, 1);
+            } catch (MatchException e) {
+                throw new InternalCompilerError(e);
+            }
+            type = mfun.returnType;
+            result.setType(type);
+        }
+        return result;
+    }
+    
+    public Expression tuple(Expression ... cs) {
+        if(cs.length == 1)
+            return cs[0];
+        Type[] typeParameters = new Type[cs.length];
+        for(int i=0;i<cs.length;++i)
+            typeParameters[i] = cs[i].getType();
+        Expression result = new EConstant(locatable, Builtins.TUPLE_CONSTRUCTORS[cs.length], typeParameters);
+        for(Expression c : cs)
+            result = new EApply(locatable, result, c);
+        result.setType(Types.tuple(Types.getTypes(cs)));
+        return result;
+    }
+
+    public Expression var(Variable var) {
+        EVariable result =  new EVariable(locatable, var);
+        result.setType(var.getType());
+        return result;
+    }
+    
+    public Expression simpleLambda(Variable var, Expression val) {
+        ESimpleLambda result = new ESimpleLambda(var, val);
+        result.setType(Types.function(var.getType(), val.getType()));
+        return result;
+    }
+    
+    public Expression lambda(Expression pat, Expression val) {
+        return new ELambda(locatable,  pat, val);
+    }
+    
+    public Expression lambda(Case ... cases) {
+        return new ELambda(locatable, cases);
+    }
+    
+    /*
+    public Expression constant(SCLValue value) {
+        Expression result = new EConstant(loc, value);
+        result.setType(value.getType());
+        return result;
+    }
+    
+    public Expression constant(SCLValue value, Type ... typeParameters) {
+        Expression result = constant(value);
+        for(Type typeParameter : typeParameters)
+            result = new EApplyType(loc, result, typeParameter);
+        result.setType(Types.instantiate(value.getType(), typeParameters));
+        return result;
+    }
+    */
+    
+    public Expression if_(Expression condition, Expression then_, Expression else_) {
+        return new EIf(locatable, condition, then_, else_);
+    }
+    
+    public Expression mapList(Expression f, Expression l) {
+        try {
+            MultiFunction mfun = Types.matchFunction(f.getType(), 1);
+            return apply(getConstant(MAP_LIST, new Type[] {mfun.parameterTypes[0], mfun.returnType}), f, l);
+        } catch (MatchException e) {
+            throw new InternalCompilerError(e);
+        }
+    }
+    
+    public Expression guardList(Expression cond) {
+        return apply(getConstant(GUARD_LIST), cond);
+    }
+
+    public Expression concatMap(Expression f, Expression l) {
+        try {
+            MultiFunction mfun = Types.matchFunction(f.getType(), 1);
+            return apply(getConstant(CONCAT_MAP, new Type[] {
+                    mfun.parameterTypes[0], mfun.effect,
+                    Types.matchApply(Types.LIST, mfun.returnType)}
+            ), f, l);
+        } catch (MatchException e) {
+            throw new InternalCompilerError(e);
+        }
+    }
+    
+    public Expression emptyList(Type type) {
+        return getConstant(EMPTY_LIST, type);
+    }
+    
+    public Expression singletonList(Expression e) {
+        return apply(getConstant(SINGLETON_LIST, e.getType()), e);
+    }
+
+    public Expression match(Expression scrutinee, Expression pattern, Expression value) {
+        Case case_ = new Case(pattern, value);
+        return new EMatch(scrutinee, new Case[] { case_ });        
+    }
+    
+    public Expression match(Expression scrutinee, Case ... cases) {
+        return new EMatch(scrutinee, cases);
+    }
+
+    public Expression literal(Constant constant) {
+        return new ELiteral(constant);
+    }
+    
+    @SuppressWarnings({ "unchecked" })
+    public JavaReferenceValidator<Object,Object,Object,Object> getJavaReferenceValidator() {
+        return (JavaReferenceValidator<Object,Object,Object,Object>)validator;
+    }
+    
+    public JavaTypeTranslator getJavaTypeTranslator() {
+        return javaTypeTranslator;
+    }
+
+    /**
+     * Variable added to the context will be inlined to the
+     * given expression in subsequent simplifications. It is assumed
+     * that the value is already simplified.
+     */
+    public void addInlinedVariable(Variable variable, Expression value) {
+        inlinedVariables.put(variable, value);        
+    }
+
+    public Expression getInlinedValue(Variable variable) {
+        return inlinedVariables.get(variable);
+    }
+
+    public EVariable blank() {
+        return new EVariable(new Variable("_"));
+    }
+
+    public Expression conditionalExecution(Expression condition, Expression continuation) {
+        return new EIf(condition, continuation, new EConstant(Builtins.TUPLE_CONSTRUCTORS[0]));
+    }
+    
+    public Expression iteratedExecution(Expression list, Variable variable, Expression continuation) {
+        return new EApply(
+                Locations.NO_LOCATION,
+                Types.PROC,
+                getConstant(Name.create("Prelude", "iterList"), variable.getType(), Types.PROC, Types.tupleConstructor(0)),
+                new Expression[] {
+                    new ESimpleLambda(Types.PROC, variable, continuation), 
+                    list
+                }
+                );
+    }
+
+    public Expression iteratedVectorExecution(EApply vector, Variable variable,
+            Expression continuation) {
+        return new EApply(
+                Locations.NO_LOCATION,
+                Types.PROC,
+                getConstant(Name.create("Vector", "iterVector"), variable.getType(), Types.PROC, Types.tupleConstructor(0)),
+                new Expression[] {
+                    new ESimpleLambda(Types.PROC, variable, continuation), 
+                    vector
+                }
+                );
+    }
+
+    public Expression[] vars(Variable[] parameters) {
+        Expression[] result = new Expression[parameters.length];
+        for(int i=0;i<parameters.length;++i)
+            result[i] = new EVariable(parameters[i]);
+        return result;
+    }
+}
\ No newline at end of file