]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/GuardedExpressionGroup.java
90e13d7507f1d858b48c56485a84b90bcd3c8125
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / GuardedExpressionGroup.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import org.simantics.scl.compiler.compilation.CompilationContext;
4 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
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.errors.Locations;
9 import org.simantics.scl.compiler.internal.codegen.continuations.ICont;
10 import org.simantics.scl.compiler.internal.codegen.references.IVal;
11 import org.simantics.scl.compiler.internal.codegen.ssa.exits.Throw;
12 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
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
17 import gnu.trove.map.hash.TObjectIntHashMap;
18 import gnu.trove.set.hash.TIntHashSet;
19
20 public class GuardedExpressionGroup extends Expression {
21     public GuardedExpression[] expressions;
22
23     public GuardedExpressionGroup(GuardedExpression[] expressions) {
24         this.expressions = expressions;
25     }
26
27     @Override
28     public void collectVars(TObjectIntHashMap<Variable> allVars,
29             TIntHashSet vars) {
30         for(GuardedExpression expression : expressions) {
31             for(Expression guard : expression.guards)
32                 guard.collectVars(allVars, vars);
33             expression.value.collectVars(allVars, vars);
34         }
35     }
36
37     @Override
38     protected void updateType() throws MatchException {
39         setType(expressions[0].value.getType());
40     }
41
42     @Override
43     public IVal toVal(CompilationContext context, CodeWriter w) {
44         CodeWriter success = w.createBlock(getType());
45         IVal result = success.getParameters()[0];
46         CodeWriter failure = w.createBlock();
47         compile(context, w, success.getContinuation(), failure.getContinuation());
48         w.continueAs(success);
49         failure.throw_(location, Throw.MatchingException, "Matching failure at: " + toString());
50         return result;
51         //throw new InternalCompilerError("GuardedExpressionGroup should be handled in match compilation.");
52     }
53
54     @Override
55     public Expression simplify(SimplificationContext context) {
56         for(GuardedExpression expression : expressions) {
57             for(int i=0;i<expression.guards.length;++i)
58                 expression.guards[i] = expression.guards[i].simplify(context);
59             expression.value = expression.value.simplify(context);
60         }
61         return this;
62     }
63
64     @Override
65     public Expression resolve(TranslationContext context) {
66         for(GuardedExpression expression : expressions) {
67             for(int i=0;i<expression.guards.length;++i)
68                 expression.guards[i] = expression.guards[i].resolve(context);
69             expression.value = expression.value.resolve(context);
70         }
71         return this;
72     }
73     
74     @Override
75     public Expression checkBasicType(TypingContext context, Type requiredType) {
76         for(GuardedExpression expression : expressions) {
77             for(int i=0;i<expression.guards.length;++i)
78                 expression.guards[i] = expression.guards[i].checkType(context, Types.BOOLEAN);
79             expression.value = expression.value.checkType(context, requiredType);
80         }
81         return this;
82     }
83     
84     public void compile(CompilationContext context, CodeWriter firstWriter, ICont success,
85             ICont lastFailure) {
86         // Create all code blocks
87         CodeWriter[] writers = new CodeWriter[expressions.length];                
88         ICont[] failures = new ICont[expressions.length];
89         writers[0] = firstWriter;
90         failures[expressions.length-1] = lastFailure;
91         for(int i=1;i<expressions.length;++i) {
92             CodeWriter writer = firstWriter.createBlock();
93             writers[i] = writer;
94             failures[i-1] = writer.getContinuation();
95         }
96         
97         // Compile
98         for(int i=0;i<expressions.length;++i) {
99             CodeWriter w = writers[i];
100             ICont failure = failures[i];
101             
102             for(Expression guard : expressions[i].guards) {
103                 CodeWriter nextW = w.createBlock();
104                 w.if_(guard.toVal(context, w), nextW.getContinuation(), failure);
105                 w = nextW;
106             }
107             
108             w.jump(success, expressions[i].value.toVal(context, w));
109         }
110     }
111     
112     @Override
113     public Expression replace(ReplaceContext context) {
114         GuardedExpression[] newExpressions = new GuardedExpression[expressions.length];
115         for(int i=0;i<expressions.length;++i)
116             newExpressions[i] = expressions[i].replace(context);
117         return new GuardedExpressionGroup(newExpressions);            
118     }
119     
120     @Override
121     public void setLocationDeep(long loc) {
122         if(location == Locations.NO_LOCATION) {
123             location = loc;
124             for(GuardedExpression expression : expressions)
125                 expression.setLocationDeep(loc);
126         }
127     }
128     
129     @Override
130     public void accept(ExpressionVisitor visitor) {
131         visitor.visit(this);
132     }
133
134     @Override
135     public Expression accept(ExpressionTransformer transformer) {
136         return transformer.transform(this);
137     }
138     
139     @Override
140     public int getSyntacticFunctionArity() {
141         return expressions[0].value.getSyntacticFunctionArity();
142     }
143 }