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