1 package org.simantics.scl.compiler.elaboration.expressions;
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.compilation.CompilationContext;
5 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
7 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
8 import org.simantics.scl.compiler.elaboration.modules.SCLValue;
9 import org.simantics.scl.compiler.errors.Locations;
10 import org.simantics.scl.compiler.internal.codegen.references.IVal;
11 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14 import org.simantics.scl.compiler.types.exceptions.MatchException;
15 import org.simantics.scl.compiler.types.exceptions.UnificationException;
16 import org.simantics.scl.compiler.types.kinds.Kinds;
18 public class EBind extends SimplifiableExpression {
19 public Expression pattern;
20 public Expression value;
22 public EVariable monadEvidence;
23 SCLValue bindFunction;
25 Type valueContentType;
28 public EBind(long loc, Expression pattern, Expression value, Expression in) {
30 this.pattern = pattern;
35 public EBind(long loc, Expression pattern, Expression value, Expression in,
36 SCLValue bindFunction) {
38 this.pattern = pattern;
44 protected void updateType() throws MatchException {
45 setType(in.getType());
49 public Expression checkBasicType(TypingContext context, Type requiredType) {
50 monadType = Types.metaVar(Kinds.STAR_TO_STAR);
51 inContentType = Types.metaVar(Kinds.STAR);
52 Type monadContent = Types.apply(monadType, inContentType);
54 Types.unify(requiredType, monadContent);
55 } catch (UnificationException e) {
56 context.typeError(location, requiredType, monadContent);
60 Variable variable = new Variable("monadEvidence");
61 variable.setType(Types.pred(Types.MONAD, monadType));
62 monadEvidence = new EVariable(getLocation(), variable);
63 monadEvidence.setType(variable.getType());
64 context.addConstraintDemand(monadEvidence);
66 pattern = pattern.checkTypeAsPattern(context, Types.metaVar(Kinds.STAR));
67 valueContentType = pattern.getType();
68 value = value.checkType(context, Types.apply(monadType, valueContentType));
69 in = in.checkType(context, requiredType);
70 Type inType = in.getType();
76 public IVal toVal(CompilationContext context, CodeWriter w) {
77 throw new InternalCompilerError("EBind should be eliminated.");
84 public Expression simplify(SimplificationContext context) {
85 value = value.simplify(context);
86 in = in.simplify(context);
87 pattern = pattern.simplify(context);
89 long loc = getLocation();
90 Expression simplified = new EApply(loc,
91 new EConstant(loc, bindFunction, Types.canonical(monadType), Types.canonical(valueContentType), Types.canonical(inContentType)),
94 new ELambda(loc, new Case[] {
95 new Case(new Expression[] { pattern }, in)
97 simplified.setType(getType());
99 return simplified.simplify(context);
103 public Expression resolve(TranslationContext context) {
104 value = value.resolve(context);
107 pattern = pattern.resolveAsPattern(context);
108 in = in.resolve(context);
111 bindFunction = context.getBindFunction();
117 public void setLocationDeep(long loc) {
118 if(location == Locations.NO_LOCATION) {
120 pattern.setLocationDeep(loc);
121 value.setLocationDeep(loc);
122 in.setLocationDeep(loc);
127 public void accept(ExpressionVisitor visitor) {
132 public Expression accept(ExpressionTransformer transformer) {
133 return transformer.transform(this);