]> gerrit.simantics Code Review - simantics/platform.git/blob
5c4a729e2e15fb748a7a17e7793c48d4257e196b
[simantics/platform.git] /
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.elaboration.modules.SCLValue;
9 import org.simantics.scl.compiler.errors.Locations;
10 import org.simantics.scl.compiler.internal.codegen.references.IVal;
11 import org.simantics.scl.compiler.internal.codegen.writer.CodeWriter;
12 import org.simantics.scl.compiler.types.Type;
13 import org.simantics.scl.compiler.types.Types;
14 import org.simantics.scl.compiler.types.exceptions.MatchException;
15 import org.simantics.scl.compiler.types.exceptions.UnificationException;
16 import org.simantics.scl.compiler.types.kinds.Kinds;
17
18 public class EBind extends SimplifiableExpression {
19     public Expression pattern;
20     public Expression value;
21     public Expression in;
22     public EVariable monadEvidence;
23     SCLValue bindFunction;
24     Type monadType;
25     Type valueContentType;
26     Type inContentType;
27     
28     public EBind(long loc, Expression pattern, Expression value, Expression in) {
29         super(loc);
30         this.pattern = pattern;
31         this.value = value;
32         this.in = in;
33     }
34
35     public EBind(long loc, Expression pattern, Expression value, Expression in,
36             SCLValue bindFunction) {
37         super(loc);
38         this.pattern = pattern;
39         this.value = value;
40         this.in = in;
41     }
42     
43     @Override
44     protected void updateType() throws MatchException {
45         setType(in.getType());
46     }
47     
48     @Override
49     public Expression checkBasicType(TypingContext context, Type requiredType) {
50         monadType = Types.metaVar(Kinds.STAR_TO_STAR);
51         inContentType = Types.metaVar(Kinds.STAR);
52         Type monadContent = Types.apply(monadType, inContentType);
53         try {
54             Types.unify(requiredType, monadContent);
55         } catch (UnificationException e) {
56             context.typeError(location, requiredType, monadContent);
57             return this;
58         }
59         
60         Variable variable = new Variable("monadEvidence");
61         variable.setType(Types.pred(Types.MONAD, monadType));
62         monadEvidence = new EVariable(getLocation(), variable);
63         monadEvidence.setType(variable.getType());
64         context.addConstraintDemand(monadEvidence);
65         
66         pattern = pattern.checkTypeAsPattern(context, Types.metaVar(Kinds.STAR));
67         valueContentType = pattern.getType();
68         value = value.checkType(context, Types.apply(monadType, valueContentType));
69         in = in.checkType(context, requiredType);
70         Type inType = in.getType();
71         setType(inType);
72         return this;
73     }
74
75     @Override
76     public IVal toVal(CompilationContext context, CodeWriter w) {
77         throw new InternalCompilerError("EBind should be eliminated.");
78     }
79
80     /**
81      * Splits let 
82      */
83     @Override
84     public Expression simplify(SimplificationContext context) {    
85         value = value.simplify(context);
86         in = in.simplify(context);
87         pattern = pattern.simplify(context);
88         
89         long loc = getLocation();
90         Expression simplified = new EApply(loc,
91                 new EConstant(loc, bindFunction, Types.canonical(monadType), Types.canonical(valueContentType), Types.canonical(inContentType)),
92                 monadEvidence, 
93                 value,
94                 new ELambda(loc, new Case[] {
95                     new Case(new Expression[] { pattern }, in)
96                 }));
97         simplified.setType(getType());
98         
99         return simplified.simplify(context);
100     }
101
102     @Override
103     public Expression resolve(TranslationContext context) {
104         value = value.resolve(context);
105         
106         context.pushFrame();
107         pattern = pattern.resolveAsPattern(context);        
108         in = in.resolve(context);
109         context.popFrame();
110         
111         bindFunction = context.getBindFunction();
112         
113         return this; 
114     }
115     
116     @Override
117     public void setLocationDeep(long loc) {
118         if(location == Locations.NO_LOCATION) {
119             location = loc;
120             pattern.setLocationDeep(loc);
121             value.setLocationDeep(loc);
122             in.setLocationDeep(loc);
123         }
124     }
125     
126     @Override
127     public void accept(ExpressionVisitor visitor) {
128         visitor.visit(this);
129     }
130     
131     @Override
132     public Expression accept(ExpressionTransformer transformer) {
133         return transformer.transform(this);
134     }
135
136 }