1 package org.simantics.scl.compiler.elaboration.expressions;
\r
3 import gnu.trove.map.hash.THashMap;
\r
4 import gnu.trove.procedure.TObjectObjectProcedure;
\r
6 import java.util.ArrayList;
\r
7 import java.util.List;
\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
16 public class EPreLet extends ASTExpression {
\r
18 List<LetStatement> assignments;
\r
21 public EPreLet(List<LetStatement> assignments, Expression in) {
\r
22 this.assignments = assignments;
\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
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
40 group = new ArrayList<LetStatement>(2);
\r
41 functionDefinitions.put(name, group);
\r
44 localVars.put(name, context.newVariable(name));
\r
47 otherDefinitions.add(assign);
\r
48 assign.pattern = assign.pattern.resolveAsPattern(context);
\r
51 } catch (NotPatternException e) {
\r
52 context.getErrorLog().log(e.getExpression().location, "Not a pattern.");
\r
53 return new EError();
\r
56 final ArrayList<Assignment> as = new ArrayList<Assignment>(functionDefinitions.size() + otherDefinitions.size());
\r
57 functionDefinitions.forEachEntry(new TObjectObjectProcedure<String, ArrayList<LetStatement>>() {
\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
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
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
83 public void setLocationDeep(long loc) {
\r
84 if(location == Locations.NO_LOCATION) {
\r
86 for(LetStatement assignment : assignments)
\r
87 assignment.setLocationDeep(loc);
\r
88 in.setLocationDeep(loc);
\r
93 public Expression accept(ExpressionTransformer transformer) {
\r
94 return transformer.transform(this);
\r