]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBind.java
Merge remote-tracking branch 'origin/svn'
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EBind.java
1 package org.simantics.scl.compiler.elaboration.expressions;\r
2 \r
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
4 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
5 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
6 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
7 import org.simantics.scl.compiler.elaboration.modules.SCLValue;\r
8 import org.simantics.scl.compiler.environment.Environment;\r
9 import org.simantics.scl.compiler.errors.Locations;\r
10 import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
11 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
12 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
13 import org.simantics.scl.compiler.types.Type;\r
14 import org.simantics.scl.compiler.types.Types;\r
15 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
16 import org.simantics.scl.compiler.types.exceptions.UnificationException;\r
17 import org.simantics.scl.compiler.types.kinds.Kinds;\r
18 \r
19 import gnu.trove.map.hash.TObjectIntHashMap;\r
20 import gnu.trove.set.hash.THashSet;\r
21 import gnu.trove.set.hash.TIntHashSet;\r
22 \r
23 public class EBind extends SimplifiableExpression {\r
24     public Expression pattern;\r
25     public Expression value;\r
26     public Expression in;\r
27     private EVariable monadEvidence;\r
28     SCLValue bindFunction;\r
29     Type monadType;\r
30     Type valueContentType;\r
31     Type inContentType;\r
32     \r
33     public EBind(long loc, Expression pattern, Expression value, Expression in) {\r
34         super(loc);\r
35         this.pattern = pattern;\r
36         this.value = value;\r
37         this.in = in;\r
38     }\r
39 \r
40     public EBind(long loc, Expression pattern, Expression value, Expression in,\r
41             SCLValue bindFunction) {\r
42         super(loc);\r
43         this.pattern = pattern;\r
44         this.value = value;\r
45         this.in = in;\r
46     }\r
47 \r
48     @Override\r
49     public void collectRefs(final TObjectIntHashMap<Object> allRefs, final TIntHashSet refs) {\r
50         value.collectRefs(allRefs, refs);\r
51         in.collectRefs(allRefs, refs);\r
52     }\r
53     \r
54     @Override\r
55     public void collectVars(TObjectIntHashMap<Variable> allVars,\r
56             TIntHashSet vars) {\r
57         value.collectVars(allVars, vars);\r
58         in.collectVars(allVars, vars);\r
59     }\r
60     \r
61     @Override\r
62     protected void updateType() throws MatchException {\r
63         setType(in.getType());\r
64     }\r
65     \r
66     @Override\r
67     public Expression checkBasicType(TypingContext context, Type requiredType) {\r
68         monadType = Types.metaVar(Kinds.STAR_TO_STAR);\r
69         inContentType = Types.metaVar(Kinds.STAR);\r
70         Type monadContent = Types.apply(monadType, inContentType);\r
71         try {\r
72             Types.unify(requiredType, monadContent);\r
73         } catch (UnificationException e) {\r
74             context.typeError(location, requiredType, monadContent);\r
75             return this;\r
76         }\r
77         \r
78         Variable variable = new Variable("monadEvidence");\r
79         variable.setType(Types.pred(Types.MONAD, monadType));\r
80         monadEvidence = new EVariable(getLocation(), variable);\r
81         monadEvidence.setType(variable.getType());\r
82         context.addConstraintDemand(monadEvidence);\r
83         \r
84         pattern = pattern.checkTypeAsPattern(context, Types.metaVar(Kinds.STAR));\r
85         valueContentType = pattern.getType();\r
86         value = value.checkType(context, Types.apply(monadType, valueContentType));\r
87         in = in.checkType(context, requiredType);\r
88         Type inType = in.getType();\r
89         setType(inType);\r
90         return this;\r
91     }\r
92 \r
93     @Override\r
94     public IVal toVal(Environment env, CodeWriter w) {\r
95         throw new InternalCompilerError("EBind should be eliminated.");\r
96     }\r
97 \r
98     /**\r
99      * Splits let \r
100      */\r
101     @Override\r
102     public Expression simplify(SimplificationContext context) {    \r
103         value = value.simplify(context);\r
104         in = in.simplify(context);\r
105         pattern = pattern.simplify(context);\r
106         \r
107         long loc = getLocation();\r
108         Expression simplified = new EApply(loc,\r
109                 new EConstant(loc, bindFunction, Types.canonical(monadType), Types.canonical(valueContentType), Types.canonical(inContentType)),\r
110                 monadEvidence, \r
111                 value,\r
112                 new ELambda(loc, new Case[] {\r
113                     new Case(new Expression[] { pattern }, in)\r
114                 }));\r
115         simplified.setType(getType());\r
116         \r
117         return simplified.simplify(context);\r
118     }\r
119 \r
120     @Override\r
121     public void collectFreeVariables(THashSet<Variable> vars) {\r
122         in.collectFreeVariables(vars);\r
123         value.collectFreeVariables(vars);\r
124         pattern.removeFreeVariables(vars);\r
125     }\r
126 \r
127     @Override\r
128     public Expression resolve(TranslationContext context) {\r
129         value = value.resolve(context);\r
130         \r
131         context.pushFrame();\r
132         pattern = pattern.resolveAsPattern(context);        \r
133         in = in.resolve(context);\r
134         context.popFrame();\r
135         \r
136         bindFunction = context.getBindFunction();\r
137         \r
138         return this; \r
139     }\r
140     \r
141     @Override\r
142     public Expression decorate(ExpressionDecorator decorator) {\r
143         pattern = pattern.decorate(decorator);\r
144         value = value.decorate(decorator);\r
145         in = in.decorate(decorator);\r
146         return decorator.decorate(this);\r
147     }\r
148 \r
149     @Override\r
150     public void collectEffects(THashSet<Type> effects) {\r
151         pattern.collectEffects(effects);\r
152         value.collectEffects(effects);\r
153         in.collectEffects(effects);\r
154     }\r
155     \r
156     @Override\r
157     public void setLocationDeep(long loc) {\r
158         if(location == Locations.NO_LOCATION) {\r
159             location = loc;\r
160             pattern.setLocationDeep(loc);\r
161             value.setLocationDeep(loc);\r
162             in.setLocationDeep(loc);\r
163         }\r
164     }\r
165     \r
166     @Override\r
167     public void accept(ExpressionVisitor visitor) {\r
168         visitor.visit(this);\r
169     }\r
170 \r
171     @Override\r
172     public void forVariables(VariableProcedure procedure) {\r
173         pattern.forVariables(procedure);\r
174         value.forVariables(procedure);\r
175         if(monadEvidence != null)\r
176             monadEvidence.forVariables(procedure);\r
177     }\r
178     \r
179     @Override\r
180     public Expression accept(ExpressionTransformer transformer) {\r
181         return transformer.transform(this);\r
182     }\r
183 \r
184 }\r