--- /dev/null
+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