]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java
035a2cadca6a02413575095ccd83112662961117
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EPreLet.java
1 package org.simantics.scl.compiler.elaboration.expressions;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
7 import org.simantics.scl.compiler.elaboration.errors.NotPatternException;
8 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
9 import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs;
10 import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType;
11 import org.simantics.scl.compiler.errors.Locations;
12
13 import gnu.trove.map.hash.THashMap;
14 import gnu.trove.procedure.TObjectObjectProcedure;
15
16 public class EPreLet extends ASTExpression {
17
18     List<LetStatement> assignments;
19     Expression in;
20     
21     public EPreLet(List<LetStatement> assignments, Expression in) {
22         this.assignments = assignments;
23         this.in = in;
24     }
25     
26     @Override
27     public Expression resolve(final TranslationContext context) {
28         context.pushFrame();
29         THashMap<String, ArrayList<LetStatement>> functionDefinitions =
30                 new THashMap<String, ArrayList<LetStatement>>();
31         ArrayList<LetStatement> otherDefinitions = new ArrayList<LetStatement>();
32         final THashMap<String, Variable> localVars = new THashMap<String, Variable>();
33         try {
34             for(LetStatement assign : assignments) {
35                 LhsType lhsType = assign.pattern.getLhsType();
36                 if(!(assign.pattern instanceof EVar) && lhsType instanceof FunctionDefinitionLhs) {
37                     String name = ((FunctionDefinitionLhs)lhsType).functionName;
38                     ArrayList<LetStatement> group = functionDefinitions.get(name);
39                     if(group == null) {
40                         group = new ArrayList<LetStatement>(2);
41                         functionDefinitions.put(name, group);
42                     }
43                     group.add(assign);
44                     localVars.put(name, context.newVariable(name));
45                 }
46                 else {
47                     otherDefinitions.add(assign);
48                     assign.pattern = assign.pattern.resolveAsPattern(context);
49                 }
50             }
51         } catch (NotPatternException e) {
52             context.getErrorLog().log(e.getExpression().location, "Not a pattern.");
53             return new EError();
54         }
55         
56         final ArrayList<Assignment> as = new ArrayList<Assignment>(functionDefinitions.size() + otherDefinitions.size());
57         functionDefinitions.forEachEntry(new TObjectObjectProcedure<String, ArrayList<LetStatement>>() {
58             @Override
59             public boolean execute(String name, ArrayList<LetStatement> cases) {
60                 as.add(new Assignment(
61                         new EVariable(cases.size()==1 ? cases.get(0).pattern.location : location, localVars.get(name)), 
62                         context.translateCases(cases)));
63                 return true;
64             }
65         });
66         for(LetStatement stat : otherDefinitions)
67             as.add(new Assignment(
68                     stat.pattern /* already resolved above */, 
69                     stat.value.resolve(context)));
70         Expression inExpr = in.resolve(context);
71         context.popFrame();
72         
73         ELet result = new ELet(location, as.toArray(new Assignment[as.size()]), inExpr);
74         /*System.out.println("-----------------------------------------");
75         System.out.println(this);
76         System.out.println("-----------------------------------------");
77         System.out.println(result);
78         System.out.println("-----------------------------------------");*/
79         return result;
80     }
81
82     @Override
83     public void setLocationDeep(long loc) {
84         if(location == Locations.NO_LOCATION) {
85             location = loc;
86             for(LetStatement assignment : assignments)
87                 assignment.setLocationDeep(loc);
88             in.setLocationDeep(loc);
89         }
90     }
91     
92     @Override
93     public Expression accept(ExpressionTransformer transformer) {
94         return transformer.transform(this);
95     }
96     
97     @Override
98     public int getSyntacticFunctionArity() {
99         return in.getSyntacticFunctionArity();
100     }
101     
102     @Override
103     public void accept(ExpressionVisitor visitor) {
104         visitor.visit(this);
105     }
106 }