]> gerrit.simantics Code Review - simantics/platform.git/blob
295f3c1769f33c567424e80df9839133707e584f
[simantics/platform.git] /
1 package org.simantics.scl.compiler.elaboration.expressions;\r
2 \r
3 import java.util.ArrayList;\r
4 import java.util.LinkedList;\r
5 import java.util.List;\r
6 \r
7 import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;\r
8 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;\r
9 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;\r
10 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;\r
11 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;\r
12 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;\r
13 import org.simantics.scl.compiler.errors.Locations;\r
14 \r
15 public class EBlock extends ASTExpression {\r
16 \r
17     LinkedList<Statement> statements = new LinkedList<Statement>();\r
18     boolean monadic;\r
19     \r
20     public EBlock() {\r
21     }\r
22 \r
23     public void addStatement(Statement statement) {\r
24         statements.add(statement);\r
25     }\r
26     \r
27     public void setMonadic(boolean monadic) {\r
28         this.monadic = monadic;\r
29     }\r
30     \r
31     public LinkedList<Statement> getStatements() {\r
32         return statements;\r
33     }\r
34 \r
35     @Override\r
36     public Expression resolve(TranslationContext context) {\r
37         if(statements.isEmpty())\r
38             throw new InternalCompilerError();\r
39         int i = statements.size()-1;\r
40         Statement last = statements.get(i);\r
41         if(!(last instanceof GuardStatement)) {\r
42             context.getErrorLog().log(last.location, "Block should end with an expression");\r
43             return new EError(location);\r
44         }\r
45 \r
46         Expression in = ((GuardStatement)last).value;\r
47         while(--i >= 0) {\r
48             Statement cur = statements.get(i);\r
49             if(cur instanceof RuleStatement) {\r
50                 int endId = i+1;\r
51                 while(i>0 && statements.get(i-1) instanceof RuleStatement)\r
52                     --i;\r
53                 in = extractRules(i, endId, in);\r
54             }\r
55             else if(cur instanceof LetStatement && ((LetStatement)cur).pattern.isFunctionPattern()) {\r
56                 int endId = i+1;\r
57                 while(i>0 && (cur = statements.get(i-1)) instanceof LetStatement &&\r
58                         ((LetStatement)cur).pattern.isFunctionPattern())\r
59                     --i;\r
60                 in = extractLet(i, endId, in);\r
61             }\r
62             else\r
63                 in = cur.toExpression(context, monadic, in);\r
64         }\r
65         return in.resolve(context);\r
66     }\r
67 \r
68     private Expression extractRules(int begin, int end, Expression in) {\r
69         return new EPreRuleset(statements.subList(begin, end).toArray(new RuleStatement[end-begin]), in);\r
70     }\r
71 \r
72     @SuppressWarnings("unchecked")\r
73     private Expression extractLet(int begin, int end, Expression in) {\r
74         return new EPreLet((List<LetStatement>)(List<?>)statements.subList(begin, end), in);\r
75     }\r
76 \r
77     public static Expression create(ArrayList<Expression> statements) {\r
78         EBlock block = new EBlock();\r
79         for(Expression statement : statements)\r
80             block.addStatement(new GuardStatement(statement));\r
81         return block;\r
82     }\r
83 \r
84     @Override\r
85     public void setLocationDeep(long loc) {\r
86         if(location == Locations.NO_LOCATION) {\r
87             location = loc;\r
88             for(Statement statement : statements)\r
89                 statement.setLocationDeep(loc);\r
90         }\r
91     }\r
92     \r
93     @Override\r
94     public Expression accept(ExpressionTransformer transformer) {\r
95         return transformer.transform(this);\r
96     }\r
97 \r
98 }\r