]> gerrit.simantics Code Review - simantics/platform.git/blob
9bec115127b2a0d5a8a32c5edc0f552743eb463a
[simantics/platform.git] /
1 package org.simantics.scl.compiler.elaboration.expressions;\r
2 \r
3 import gnu.trove.map.hash.TObjectIntHashMap;\r
4 import gnu.trove.set.hash.THashSet;\r
5 import gnu.trove.set.hash.TIntHashSet;\r
6 \r
7 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
8 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;\r
9 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;\r
10 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
11 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;\r
12 import org.simantics.scl.compiler.environment.Environment;\r
13 import org.simantics.scl.compiler.errors.Locations;\r
14 import org.simantics.scl.compiler.internal.codegen.continuations.ICont;\r
15 import org.simantics.scl.compiler.internal.codegen.references.IVal;\r
16 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;\r
17 import org.simantics.scl.compiler.internal.elaboration.utils.ExpressionDecorator;\r
18 import org.simantics.scl.compiler.types.Type;\r
19 import org.simantics.scl.compiler.types.Types;\r
20 import org.simantics.scl.compiler.types.exceptions.MatchException;\r
21 \r
22 public class GuardedExpressionGroup extends Expression {\r
23     public GuardedExpression[] expressions;\r
24 \r
25     public GuardedExpressionGroup(GuardedExpression[] expressions) {\r
26         this.expressions = expressions;\r
27     }\r
28 \r
29     @Override\r
30     public void collectRefs(TObjectIntHashMap<Object> allRefs,\r
31             TIntHashSet refs) {\r
32         for(GuardedExpression expression : expressions) {\r
33             for(Expression guard : expression.guards)\r
34                 guard.collectRefs(allRefs, refs);\r
35             expression.value.collectRefs(allRefs, refs);\r
36         }\r
37     }\r
38 \r
39     @Override\r
40     public void collectVars(TObjectIntHashMap<Variable> allVars,\r
41             TIntHashSet vars) {\r
42         for(GuardedExpression expression : expressions) {\r
43             for(Expression guard : expression.guards)\r
44                 guard.collectVars(allVars, vars);\r
45             expression.value.collectVars(allVars, vars);\r
46         }\r
47     }\r
48 \r
49     @Override\r
50     protected void updateType() throws MatchException {\r
51         setType(expressions[0].value.getType());\r
52     }\r
53 \r
54     @Override\r
55     public IVal toVal(Environment env, CodeWriter w) {\r
56         CodeWriter success = w.createBlock(getType());\r
57         IVal result = success.getParameters()[0];\r
58         CodeWriter failure = w.createBlock();\r
59         compile(env, w, success.getContinuation(), failure.getContinuation());\r
60         w.continueAs(success);\r
61         failure.throw_(location, "Matching failure at: " + toString());\r
62         return result;\r
63         //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation.");\r
64     }\r
65 \r
66     @Override\r
67     public void collectFreeVariables(THashSet<Variable> vars) {\r
68         for(GuardedExpression expression : expressions) {\r
69             for(Expression guard : expression.guards)\r
70                 guard.collectFreeVariables(vars);\r
71             expression.value.collectFreeVariables(vars);\r
72         }\r
73     }\r
74 \r
75     @Override\r
76     public Expression simplify(SimplificationContext context) {\r
77         for(GuardedExpression expression : expressions) {\r
78             for(int i=0;i<expression.guards.length;++i)\r
79                 expression.guards[i] = expression.guards[i].simplify(context);\r
80             expression.value = expression.value.simplify(context);\r
81         }\r
82         return this;\r
83     }\r
84 \r
85     @Override\r
86     public Expression resolve(TranslationContext context) {\r
87         for(GuardedExpression expression : expressions) {\r
88             for(int i=0;i<expression.guards.length;++i)\r
89                 expression.guards[i] = expression.guards[i].resolve(context);\r
90             expression.value = expression.value.resolve(context);\r
91         }\r
92         return this;\r
93     }\r
94     \r
95     @Override\r
96     public Expression checkBasicType(TypingContext context, Type requiredType) {\r
97         for(GuardedExpression expression : expressions) {\r
98             for(int i=0;i<expression.guards.length;++i)\r
99                 expression.guards[i] = expression.guards[i].checkType(context, Types.BOOLEAN);\r
100             expression.value = expression.value.checkType(context, requiredType);\r
101         }\r
102         return this;\r
103     }\r
104     \r
105     public void compile(Environment env, CodeWriter firstWriter, ICont success,\r
106             ICont lastFailure) {\r
107         // Create all code blocks\r
108         CodeWriter[] writers = new CodeWriter[expressions.length];                \r
109         ICont[] failures = new ICont[expressions.length];\r
110         writers[0] = firstWriter;\r
111         failures[expressions.length-1] = lastFailure;\r
112         for(int i=1;i<expressions.length;++i) {\r
113             CodeWriter writer = firstWriter.createBlock();\r
114             writers[i] = writer;\r
115             failures[i-1] = writer.getContinuation();\r
116         }\r
117         \r
118         // Compile\r
119         for(int i=0;i<expressions.length;++i) {\r
120             CodeWriter w = writers[i];\r
121             ICont failure = failures[i];\r
122             \r
123             for(Expression guard : expressions[i].guards) {\r
124                 CodeWriter nextW = w.createBlock();\r
125                 w.if_(guard.toVal(env, w), nextW.getContinuation(), failure);\r
126                 w = nextW;\r
127             }\r
128             \r
129             w.jump(success, expressions[i].value.toVal(env, w));\r
130         }\r
131     }\r
132     \r
133     @Override\r
134     public Expression replace(ReplaceContext context) {\r
135         GuardedExpression[] newExpressions = new GuardedExpression[expressions.length];\r
136         for(int i=0;i<expressions.length;++i)\r
137             newExpressions[i] = expressions[i].replace(context);\r
138         return new GuardedExpressionGroup(newExpressions);            \r
139     }\r
140 \r
141     @Override\r
142     public Expression decorate(ExpressionDecorator decorator) {\r
143         for(GuardedExpression expression : expressions)\r
144             expression.decorate(decorator);\r
145         return decorator.decorate(this);\r
146     }\r
147 \r
148     @Override\r
149     public void collectEffects(THashSet<Type> effects) {\r
150         for(GuardedExpression ge : expressions) {\r
151             for(Expression guard : ge.guards)\r
152                 guard.collectEffects(effects);\r
153             ge.value.collectEffects(effects);\r
154         }\r
155     }\r
156     \r
157     @Override\r
158     public void setLocationDeep(long loc) {\r
159         if(location == Locations.NO_LOCATION) {\r
160             location = loc;\r
161             for(GuardedExpression expression : expressions)\r
162                 expression.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         for(GuardedExpression expression : expressions)\r
174             expression.forVariables(procedure);\r
175     }\r
176 \r
177     @Override\r
178     public Expression accept(ExpressionTransformer transformer) {\r
179         return transformer.transform(this);\r
180     }\r
181 }\r