package org.simantics.scl.compiler.elaboration.contexts; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.common.names.Name; import org.simantics.scl.compiler.common.names.Names; import org.simantics.scl.compiler.compilation.CompilationContext; 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; import gnu.trove.list.array.TLongArrayList; import gnu.trove.map.hash.THashMap; public class SimplificationContext implements EnvironmentalContext { CompilationContext compilationContext; Environment environment; ErrorLog errorLog; THashMap constants = new THashMap(); THashMap inlinedVariables = new THashMap(); TLongArrayList locatableStack = new TLongArrayList(); long locatable; JavaTypeTranslator javaTypeTranslator; JavaReferenceValidator validator; public SimplificationContext(CompilationContext compilationContext, JavaReferenceValidator validator) { this.compilationContext = compilationContext; this.environment = compilationContext.environment; this.errorLog = compilationContext.errorLog; this.javaTypeTranslator = compilationContext.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(Names.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(Names.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