]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Case.java
54be27b3cc2de0e0d23170ecc0567d8498acf10f
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / Case.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import org.simantics.scl.compiler.elaboration.contexts.ReplaceContext;
4 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
5 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
6 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
7 import org.simantics.scl.compiler.errors.Locations;
8 import org.simantics.scl.compiler.internal.parsing.Symbol;
9 import org.simantics.scl.compiler.types.Type;
10
11 import gnu.trove.map.hash.TObjectIntHashMap;
12 import gnu.trove.set.hash.THashSet;
13 import gnu.trove.set.hash.TIntHashSet;
14
15 public class Case extends Symbol {
16     public Expression[] patterns;
17     public Expression value;
18     
19     long lhs;
20     
21     public Case(Expression[] patterns, Expression value) {
22         this.patterns = patterns;
23         this.value = value;
24     }
25     
26     public Case(Expression pattern, Expression value) {
27         this(new Expression[] {pattern}, value);
28     }
29
30     public void setLhs(long lhs) {
31         this.lhs = lhs;
32     }
33     
34     public long getLhs() {
35         return lhs;
36     }
37
38         public void collectRefs(TObjectIntHashMap<Object> allRefs, TIntHashSet refs) {
39         value.collectRefs(allRefs, refs);
40     }
41
42     public void collectVars(TObjectIntHashMap<Variable> allVars,
43             TIntHashSet vars) {
44         value.collectVars(allVars, vars);
45     }
46
47     public void collectFreeVariables(THashSet<Variable> vars) {
48         value.collectFreeVariables(vars);
49         for(int i=patterns.length-1;i>=0;--i)
50             patterns[i].removeFreeVariables(vars);
51     }
52
53     public void resolve(TranslationContext context) {
54         context.pushFrame();
55         for(int i=0;i<patterns.length;++i)
56             patterns[i] = patterns[i].resolveAsPattern(context);
57         value = value.resolve(context);
58         context.popFrame();
59     }
60
61     public void simplify(SimplificationContext context) {
62         for(int i=0;i<patterns.length;++i)
63             patterns[i] = patterns[i].simplify(context);
64         value = value.simplify(context);
65     }
66
67     public void setLocationDeep(long loc) {
68         if(location == Locations.NO_LOCATION) {
69             location = loc;
70             for(Expression pattern : patterns)
71                 pattern.setLocationDeep(loc);
72             value.setLocationDeep(loc);
73         }
74     }
75
76     public Case replace(ReplaceContext context) {
77         Expression[] newPatterns = new Expression[patterns.length];        
78         for(int i=0;i<patterns.length;++i)
79             newPatterns[i] = patterns[i].replaceInPattern(context);
80         Expression newValue = value.replace(context);
81         Case result = new Case(newPatterns, newValue);
82         result.setLhs(lhs);
83         return result;
84     }
85
86     public Expression[] getPatterns() {
87         return patterns;
88     }
89
90     public void checkType(TypingContext context, Type[] parameterTypes,
91             Type requiredType) {
92         if(patterns.length != parameterTypes.length) {
93             context.getErrorLog().log(location, "This case has different arity ("+patterns.length+
94                     ") than than the first case (+"+parameterTypes.length+"+).");
95             return;
96         }
97         for(int i=0;i<patterns.length;++i)
98             patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);
99         value = value.checkType(context, requiredType);
100     }
101     
102     public void checkIgnoredType(TypingContext context, Type[] parameterTypes) {
103         if(patterns.length != parameterTypes.length) {
104             context.getErrorLog().log(location, "This case has different arity ("+patterns.length+
105                     ") than than the first case (+"+parameterTypes.length+"+).");
106             return;
107         }
108         for(int i=0;i<patterns.length;++i)
109             patterns[i] = patterns[i].checkTypeAsPattern(context, parameterTypes[i]);
110         value = value.checkIgnoredType(context);
111     }
112 }