X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fcontexts%2FSimplificationContext.java;fp=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Felaboration%2Fcontexts%2FSimplificationContext.java;h=e983e1277e0a93f27ab0964e3083ecf588583531;hb=969bd23cab98a79ca9101af33334000879fb60c5;hp=0000000000000000000000000000000000000000;hpb=866dba5cd5a3929bbeae85991796acb212338a08;p=simantics%2Fplatform.git 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 index 000000000..e983e1277 --- /dev/null +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/contexts/SimplificationContext.java @@ -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 constants = new THashMap(); + THashMap inlinedVariables = new THashMap(); + + 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 getJavaReferenceValidator() { + return (JavaReferenceValidator)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