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