1 package org.simantics.scl.compiler.elaboration.expressions;
\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
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
22 public class GuardedExpressionGroup extends Expression {
\r
23 public GuardedExpression[] expressions;
\r
25 public GuardedExpressionGroup(GuardedExpression[] expressions) {
\r
26 this.expressions = expressions;
\r
30 public void collectRefs(TObjectIntHashMap<Object> allRefs,
\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
40 public void collectVars(TObjectIntHashMap<Variable> allVars,
\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
50 protected void updateType() throws MatchException {
\r
51 setType(expressions[0].value.getType());
\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
63 //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation.");
\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
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
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
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
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
119 for(int i=0;i<expressions.length;++i) {
\r
120 CodeWriter w = writers[i];
\r
121 ICont failure = failures[i];
\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
129 w.jump(success, expressions[i].value.toVal(env, w));
\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
142 public Expression decorate(ExpressionDecorator decorator) {
\r
143 for(GuardedExpression expression : expressions)
\r
144 expression.decorate(decorator);
\r
145 return decorator.decorate(this);
\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
158 public void setLocationDeep(long loc) {
\r
159 if(location == Locations.NO_LOCATION) {
\r
161 for(GuardedExpression expression : expressions)
\r
162 expression.setLocationDeep(loc);
\r
167 public void accept(ExpressionVisitor visitor) {
\r
168 visitor.visit(this);
\r
172 public void forVariables(VariableProcedure procedure) {
\r
173 for(GuardedExpression expression : expressions)
\r
174 expression.forVariables(procedure);
\r
178 public Expression accept(ExpressionTransformer transformer) {
\r
179 return transformer.transform(this);
\r