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