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.internal.elaboration.utils.ExpressionDecorator;
13 import org.simantics.scl.compiler.types.Type;
14 import org.simantics.scl.compiler.types.Types;
15 import org.simantics.scl.compiler.types.exceptions.MatchException;
16 import org.simantics.scl.compiler.types.exceptions.UnificationException;
17 import org.simantics.scl.compiler.types.kinds.Kinds;
19 import gnu.trove.map.hash.TObjectIntHashMap;
20 import gnu.trove.set.hash.THashSet;
21 import gnu.trove.set.hash.TIntHashSet;
23 public class EBind extends SimplifiableExpression {
24 public Expression pattern;
25 public Expression value;
27 private EVariable monadEvidence;
28 SCLValue bindFunction;
30 Type valueContentType;
33 public EBind(long loc, Expression pattern, Expression value, Expression in) {
35 this.pattern = pattern;
40 public EBind(long loc, Expression pattern, Expression value, Expression in,
41 SCLValue bindFunction) {
43 this.pattern = pattern;
49 public void collectRefs(final TObjectIntHashMap<Object> allRefs, final TIntHashSet refs) {
50 value.collectRefs(allRefs, refs);
51 in.collectRefs(allRefs, refs);
55 public void collectVars(TObjectIntHashMap<Variable> allVars,
57 value.collectVars(allVars, vars);
58 in.collectVars(allVars, vars);
62 protected void updateType() throws MatchException {
63 setType(in.getType());
67 public Expression checkBasicType(TypingContext context, Type requiredType) {
68 monadType = Types.metaVar(Kinds.STAR_TO_STAR);
69 inContentType = Types.metaVar(Kinds.STAR);
70 Type monadContent = Types.apply(monadType, inContentType);
72 Types.unify(requiredType, monadContent);
73 } catch (UnificationException e) {
74 context.typeError(location, requiredType, monadContent);
78 Variable variable = new Variable("monadEvidence");
79 variable.setType(Types.pred(Types.MONAD, monadType));
80 monadEvidence = new EVariable(getLocation(), variable);
81 monadEvidence.setType(variable.getType());
82 context.addConstraintDemand(monadEvidence);
84 pattern = pattern.checkTypeAsPattern(context, Types.metaVar(Kinds.STAR));
85 valueContentType = pattern.getType();
86 value = value.checkType(context, Types.apply(monadType, valueContentType));
87 in = in.checkType(context, requiredType);
88 Type inType = in.getType();
94 public IVal toVal(CompilationContext context, CodeWriter w) {
95 throw new InternalCompilerError("EBind should be eliminated.");
102 public Expression simplify(SimplificationContext context) {
103 value = value.simplify(context);
104 in = in.simplify(context);
105 pattern = pattern.simplify(context);
107 long loc = getLocation();
108 Expression simplified = new EApply(loc,
109 new EConstant(loc, bindFunction, Types.canonical(monadType), Types.canonical(valueContentType), Types.canonical(inContentType)),
112 new ELambda(loc, new Case[] {
113 new Case(new Expression[] { pattern }, in)
115 simplified.setType(getType());
117 return simplified.simplify(context);
121 public void collectFreeVariables(THashSet<Variable> vars) {
122 in.collectFreeVariables(vars);
123 value.collectFreeVariables(vars);
124 pattern.removeFreeVariables(vars);
128 public Expression resolve(TranslationContext context) {
129 value = value.resolve(context);
132 pattern = pattern.resolveAsPattern(context);
133 in = in.resolve(context);
136 bindFunction = context.getBindFunction();
142 public Expression decorate(ExpressionDecorator decorator) {
143 pattern = pattern.decorate(decorator);
144 value = value.decorate(decorator);
145 in = in.decorate(decorator);
146 return decorator.decorate(this);
150 public void collectEffects(THashSet<Type> effects) {
151 pattern.collectEffects(effects);
152 value.collectEffects(effects);
153 in.collectEffects(effects);
157 public void setLocationDeep(long loc) {
158 if(location == Locations.NO_LOCATION) {
160 pattern.setLocationDeep(loc);
161 value.setLocationDeep(loc);
162 in.setLocationDeep(loc);
167 public void accept(ExpressionVisitor visitor) {
172 public void forVariables(VariableProcedure procedure) {
173 pattern.forVariables(procedure);
174 value.forVariables(procedure);
175 if(monadEvidence != null)
176 monadEvidence.forVariables(procedure);
180 public Expression accept(ExpressionTransformer transformer) {
181 return transformer.transform(this);