]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java
Refactoring CHR handling code
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / expressions / EBlock.java
index c5f30417eed13983d839b211a1a8cf1f88aacc25..c911474eba8b39c41004b10cff3d7b824b73a8a4 100644 (file)
@@ -1,16 +1,18 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 
-import org.simantics.scl.compiler.common.exceptions.InternalCompilerError;
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRQueryTranslationMode;
 import org.simantics.scl.compiler.elaboration.chr.translation.CHRTranslation;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.block.BlockType;
 import org.simantics.scl.compiler.elaboration.expressions.block.CHRStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.ConstraintStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.GuardStatement;
+import org.simantics.scl.compiler.elaboration.expressions.block.IncludeStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.LetStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.RuleStatement;
 import org.simantics.scl.compiler.elaboration.expressions.block.Statement;
@@ -19,28 +21,39 @@ import org.simantics.scl.compiler.errors.Locations;
 
 public class EBlock extends ASTExpression {
 
-    LinkedList<Statement> statements = new LinkedList<Statement>();
-    boolean monadic;
+    public ArrayList<Statement> statements = new ArrayList<Statement>();
+    BlockType blockType = BlockType.Normal;
     
     public EBlock() {
+        this.blockType = blockType;
+    }
+    
+    public void setBlockType(BlockType blockType) {
+        this.blockType = blockType;
     }
 
     public void addStatement(Statement statement) {
         statements.add(statement);
     }
     
-    public void setMonadic(boolean monadic) {
-        this.monadic = monadic;
+    public ArrayList<Statement> getStatements() {
+        return statements;
+    }
+    
+    public Statement getFirst() {
+        return statements.get(0);
     }
     
-    public LinkedList<Statement> getStatements() {
-        return statements;
+    public Statement getLast() {
+        return statements.get(statements.size()-1);
     }
 
     @Override
     public Expression resolve(TranslationContext context) {
-        if(statements.isEmpty())
-            throw new InternalCompilerError();
+        if(statements.isEmpty()) {
+            context.getErrorLog().log(location, "Block should not be empty.");
+            return new EError(location);
+        }
         int i = statements.size()-1;
         Statement last = statements.get(i);
         if(!(last instanceof GuardStatement)) {
@@ -53,7 +66,7 @@ public class EBlock extends ASTExpression {
             Statement cur = statements.get(i);
             StatementGroup group = cur.getStatementGroup();
             if(group == null)
-                in = cur.toExpression(context, monadic, in);
+                in = cur.toExpression(context, blockType, in);
             else {
                 int endId = i+1;
                 while(i>0 && statements.get(i-1).getStatementGroup() == group)
@@ -65,10 +78,14 @@ public class EBlock extends ASTExpression {
                 case Rule:
                     in = extractRules(i, endId, in);
                     break;
-                case CHR:
-                    in = extractCHRRules(context, i, endId, in);
+                case CHR: {
+                    CHRRuleset ruleset = extractCHRRules(context, i, endId);
+                    long location = Locations.combine(ruleset.location, in.location);
+                    in = new ECHRRuleset(ruleset, in);
+                    in.location = location;
                     break;
                 }
+                }
             }
         }
         return in.resolve(context);
@@ -78,21 +95,31 @@ public class EBlock extends ASTExpression {
         return new EPreRuleset(statements.subList(begin, end).toArray(new RuleStatement[end-begin]), in);
     }
     
-    private Expression extractCHRRules(TranslationContext context, int begin, int end, Expression in) {
+    private CHRRuleset extractCHRRules(TranslationContext context, int begin, int end) {
         CHRRuleset ruleset = new CHRRuleset();
         ruleset.location = Locations.combine(statements.get(begin).location, statements.get(end-1).location);
         for(int i=begin;i<end;++i) {
             Statement statement = statements.get(i);
-            if(statement instanceof CHRStatement)
-                ruleset.rules.add(CHRTranslation.convertCHRStatement(context, (CHRStatement)statement));
+            if(statement instanceof CHRStatement) {
+                CHRStatement chrStatement = (CHRStatement)statement;
+                ruleset.addRule(new CHRRule(chrStatement.location,
+                        chrStatement.head.translate(context, CHRQueryTranslationMode.RULE_HEAD),
+                        chrStatement.body.translate(context, CHRQueryTranslationMode.RULE_BODY)));
+            }
             else if(statement instanceof ConstraintStatement)
-                ruleset.constraints.add(CHRTranslation.convertConstraintStatement(context, (ConstraintStatement)statement));
+                ruleset.addConstraint(CHRTranslation.convertConstraintStatement(context, (ConstraintStatement)statement));
+            else if(statement instanceof IncludeStatement)
+                ruleset.includes.add((IncludeStatement)statement);
             else
-                throw new InternalCompilerError("Invalid CHR statement.");
+                context.getErrorLog().log(statement.location, "Invalid CHR statement.");
         }
-        return new ECHRRuleset(ruleset, in);
+        return ruleset;
     }
 
+    public CHRRuleset extractCHRRules(TranslationContext context) {
+        return extractCHRRules(context, 0, statements.size());
+    }
+    
     @SuppressWarnings("unchecked")
     private Expression extractLet(int begin, int end, Expression in) {
         return new EPreLet((List<LetStatement>)(List<?>)statements.subList(begin, end), in);
@@ -121,9 +148,9 @@ public class EBlock extends ASTExpression {
 
     @Override
     public int getSyntacticFunctionArity() {
-        if(monadic)
+        if(blockType != BlockType.Normal)
             return 0;
-        Statement lastStatement = statements.getLast();
+        Statement lastStatement = statements.get(statements.size()-1);
         if(!(lastStatement instanceof GuardStatement))
             return 0;
         return ((GuardStatement)lastStatement).value.getSyntacticFunctionArity();