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