]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EViewPattern.java
f2a017edda95d9aa15581b8bf22658e84b32558e
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EViewPattern.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
4 import org.simantics.scl.compiler.compilation.CompilationContext;
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.references.IVal;
10 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
11 import org.simantics.scl.compiler.types.Types;
12 import org.simantics.scl.compiler.types.exceptions.MatchException;
13 import org.simantics.scl.compiler.types.util.MultiFunction;
14
15 import gnu.trove.map.hash.TObjectIntHashMap;
16 import gnu.trove.set.hash.TIntHashSet;
17
18 public class EViewPattern extends Expression {
19     public Expression expression;
20     public Expression pattern;
21     
22     public EViewPattern(Expression expression, Expression pattern) {
23         this.expression = expression;
24         this.pattern = pattern;
25     }
26
27     @Override
28     public void collectVars(TObjectIntHashMap<Variable> allVars, TIntHashSet vars) {
29         expression.collectVars(allVars, vars);
30         pattern.collectVars(allVars, vars);
31     }
32     
33     @Override
34     public Expression inferType(TypingContext context) {
35         context.setInPattern(false);
36         expression = expression.inferType(context);
37         context.setInPattern(true);
38         MultiFunction mfun;
39         try {
40             mfun = Types.matchFunction(expression.getType(), 1);
41         } catch (MatchException e) {
42             context.getErrorLog().log(expression.location, "Expected a function as a transformation expression.");
43             return new EError(location);
44         }
45         setType(mfun.parameterTypes[0]);
46         pattern.checkType(context, mfun.returnType);
47         return this;
48     }
49
50     @Override
51     protected void updateType() throws MatchException {
52         MultiFunction mfun = Types.matchFunction(expression.getType(), 1);
53         setType(mfun.parameterTypes[0]);
54     }
55
56     @Override
57     public IVal toVal(CompilationContext context, CodeWriter w) {
58         throw new InternalCompilerError(location, "EViewPattern.toVal should not be invoked.");
59     }
60
61     @Override
62     public Expression resolve(TranslationContext context) {
63         context.getErrorLog().log("View pattern cannot occur only in patterns. Maybe you are missing '\\' in front of a lambda experssion?");
64         return new EError(location);
65     }
66
67     @Override
68     public Expression resolveAsPattern(TranslationContext context) {
69         expression = expression.resolve(context);
70         pattern = pattern.resolveAsPattern(context);
71         return this;
72     }
73     
74     @Override
75     public void setLocationDeep(long loc) {
76         if(location == Locations.NO_LOCATION) {
77             location = loc; 
78             expression.setLocationDeep(loc);
79             pattern.setLocationDeep(loc);
80         }
81     }
82
83     @Override
84     public void accept(ExpressionVisitor visitor) {
85         visitor.visit(this);
86     }
87
88     @Override
89     public Expression accept(ExpressionTransformer transformer) {
90         return transformer.transform(this);
91     }
92     
93     @Override
94     public Expression simplify(SimplificationContext context) {
95         expression = expression.simplify(context);
96         pattern = pattern.simplify(context);
97         return this;
98     }
99
100 }