]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EPreLet.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreLet.java
new file mode 100755 (executable)
index 0000000..64d5cc3
--- /dev/null
@@ -0,0 +1,97 @@
+package org.simantics.scl.compiler.elaboration.expressions;\r
+\r
+import gnu.trove.map.hash.THashMap;\r
+import gnu.trove.procedure.TObjectObjectProcedure;\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
+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