package org.simantics.scl.compiler.elaboration.expressions; import org.simantics.scl.compiler.common.exceptions.InternalCompilerError; import org.simantics.scl.compiler.compilation.CompilationContext; 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.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.interpreted.IExpression; import org.simantics.scl.compiler.top.ExpressionInterpretationContext; import org.simantics.scl.compiler.types.Type; import org.simantics.scl.compiler.types.Types; import org.simantics.scl.compiler.types.exceptions.MatchException; public class EApplyType extends Expression { public Expression expression; Type parameter; public EApplyType(Expression expression, Type parameter) { this.expression = expression; this.parameter = parameter; } public static Expression create(Expression expression, Type ... parameters) { for(Type parameter : parameters) expression = new EApplyType(expression, parameter); return expression; } public EApplyType(long loc, Expression expression, Type parameter) { super(loc); if(parameter == null) throw new NullPointerException(); this.expression = expression; this.parameter = parameter; } public Expression getExpression() { return expression; } public Type getParameter() { return parameter; } @Override protected void updateType() throws MatchException { setType(Types.instantiate(expression.getType(), parameter)); } @Override public IVal toVal(CompilationContext context, CodeWriter w) { IVal val = expression.toVal(context, w); return val.createSpecialization(parameter); } @Override public Expression simplify(SimplificationContext context) { expression = expression.simplify(context); if(expression instanceof EConstant) { ((EConstant)expression).addTypeParameters(parameter); return expression; } return this; } @Override public Expression resolve(TranslationContext context) { expression = expression.resolve(context); return this; } @Override public Expression replace(ReplaceContext context) { return new EApplyType(expression.replace(context), parameter.replace(context.tvarMap)); } @Override public IExpression toIExpression(ExpressionInterpretationContext target) { return expression.toIExpression(target); } @Override public Expression inferType(TypingContext context) { throw new InternalCompilerError("Should not type check " + getClass().getSimpleName() + "."); } @Override public boolean isEffectful() { return expression.isEffectful(); } @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { location = loc; expression.setLocationDeep(loc); } } @Override public void accept(ExpressionVisitor visitor) { visitor.visit(this); } @Override public Expression accept(ExpressionTransformer transformer) { return transformer.transform(this); } }