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