]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EBlock.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java
new file mode 100755 (executable)
index 0000000..295f3c1
--- /dev/null
@@ -0,0 +1,98 @@
+package org.simantics.scl.compiler.elaboration.expressions;\r
+\r
+import java.util.ArrayList;\r
+import java.util.LinkedList;\r
+import java.util.List;\r
+\r
+import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
+import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;\r
+import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;\r
+import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;\r
+import org.simantics.scl.compiler.elaboration.expressions.block.Statement;\r
+import org.simantics.scl.compiler.errors.Locations;\r
+\r
+public class EBlock extends ASTExpression {\r
+\r
+    LinkedList<Statement> statements = new LinkedList<Statement>();\r
+    boolean monadic;\r
+    \r
+    public EBlock() {\r
+    }\r
+\r
+    public void addStatement(Statement statement) {\r
+        statements.add(statement);\r
+    }\r
+    \r
+    public void setMonadic(boolean monadic) {\r
+        this.monadic = monadic;\r
+    }\r
+    \r
+    public LinkedList<Statement> getStatements() {\r
+        return statements;\r
+    }\r
+\r
+    @Override\r
+    public Expression resolve(TranslationContext context) {\r
+        if(statements.isEmpty())\r
+            throw new InternalCompilerError();\r
+        int i = statements.size()-1;\r
+        Statement last = statements.get(i);\r
+        if(!(last instanceof GuardStatement)) {\r
+            context.getErrorLog().log(last.location, "Block should end with an expression");\r
+            return new EError(location);\r
+        }\r
+\r
+        Expression in = ((GuardStatement)last).value;\r
+        while(--i >= 0) {\r
+            Statement cur = statements.get(i);\r
+            if(cur instanceof RuleStatement) {\r
+                int endId = i+1;\r
+                while(i>0 && statements.get(i-1) instanceof RuleStatement)\r
+                    --i;\r
+                in = extractRules(i, endId, in);\r
+            }\r
+            else if(cur instanceof LetStatement && ((LetStatement)cur).pattern.isFunctionPattern()) {\r
+                int endId = i+1;\r
+                while(i>0 && (cur = statements.get(i-1)) instanceof LetStatement &&\r
+                        ((LetStatement)cur).pattern.isFunctionPattern())\r
+                    --i;\r
+                in = extractLet(i, endId, in);\r
+            }\r
+            else\r
+                in = cur.toExpression(context, monadic, in);\r
+        }\r
+        return in.resolve(context);\r
+    }\r
+\r
+    private Expression extractRules(int begin, int end, Expression in) {\r
+        return new EPreRuleset(statements.subList(begin, end).toArray(new RuleStatement[end-begin]), in);\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    private Expression extractLet(int begin, int end, Expression in) {\r
+        return new EPreLet((List<LetStatement>)(List<?>)statements.subList(begin, end), in);\r
+    }\r
+\r
+    public static Expression create(ArrayList<Expression> statements) {\r
+        EBlock block = new EBlock();\r
+        for(Expression statement : statements)\r
+            block.addStatement(new GuardStatement(statement));\r
+        return block;\r
+    }\r
+\r
+    @Override\r
+    public void setLocationDeep(long loc) {\r
+        if(location == Locations.NO_LOCATION) {\r
+            location = loc;\r
+            for(Statement statement : statements)\r
+                statement.setLocationDeep(loc);\r
+        }\r
+    }\r
+    \r
+    @Override\r
+    public Expression accept(ExpressionTransformer transformer) {\r
+        return transformer.transform(this);\r
+    }\r
+\r
+}\r