package org.simantics.scl.compiler.elaboration.expressions; import java.util.ArrayList; import java.util.List; import org.simantics.scl.compiler.elaboration.contexts.TranslationContext; import org.simantics.scl.compiler.elaboration.errors.NotPatternException; import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement; import org.simantics.scl.compiler.elaboration.expressions.lhstype.FunctionDefinitionLhs; import org.simantics.scl.compiler.elaboration.expressions.lhstype.LhsType; import org.simantics.scl.compiler.errors.Locations; import gnu.trove.map.hash.THashMap; import gnu.trove.procedure.TObjectObjectProcedure; public class EPreLet extends ASTExpression { List assignments; Expression in; public EPreLet(List assignments, Expression in) { this.assignments = assignments; this.in = in; } @Override public Expression resolve(final TranslationContext context) { context.pushFrame(); THashMap> functionDefinitions = new THashMap>(); ArrayList otherDefinitions = new ArrayList(); final THashMap localVars = new THashMap(); try { for(LetStatement assign : assignments) { LhsType lhsType = assign.pattern.getLhsType(); if(!(assign.pattern instanceof EVar) && lhsType instanceof FunctionDefinitionLhs) { String name = ((FunctionDefinitionLhs)lhsType).functionName; ArrayList group = functionDefinitions.get(name); if(group == null) { group = new ArrayList(2); functionDefinitions.put(name, group); } group.add(assign); localVars.put(name, context.newVariable(name)); } else { otherDefinitions.add(assign); assign.pattern = assign.pattern.resolveAsPattern(context); } } } catch (NotPatternException e) { context.getErrorLog().log(e.getExpression().location, "Not a pattern."); return new EError(); } final ArrayList as = new ArrayList(functionDefinitions.size() + otherDefinitions.size()); functionDefinitions.forEachEntry(new TObjectObjectProcedure>() { @Override public boolean execute(String name, ArrayList cases) { as.add(new Assignment( new EVariable(cases.size()==1 ? cases.get(0).pattern.location : location, localVars.get(name)), context.translateCases(cases))); return true; } }); for(LetStatement stat : otherDefinitions) as.add(new Assignment( stat.pattern /* already resolved above */, stat.value.resolve(context))); Expression inExpr = in.resolve(context); context.popFrame(); ELet result = new ELet(location, as.toArray(new Assignment[as.size()]), inExpr); /*System.out.println("-----------------------------------------"); System.out.println(this); System.out.println("-----------------------------------------"); System.out.println(result); System.out.println("-----------------------------------------");*/ return result; } @Override public void setLocationDeep(long loc) { if(location == Locations.NO_LOCATION) { location = loc; for(LetStatement assignment : assignments) assignment.setLocationDeep(loc); in.setLocationDeep(loc); } } @Override public Expression accept(ExpressionTransformer transformer) { return transformer.transform(this); } }