(refs #7377) Refactoring CHR query parsing
authorHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 21 Jul 2017 11:06:25 +0000 (14:06 +0300)
committerHannu Niemistö <hannu.niemisto@semantum.fi>
Fri, 21 Jul 2017 12:13:58 +0000 (15:13 +0300)
Change-Id: Ia0e2e4589180505c02fabeb5b1dd2267825e3255

21 files changed:
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/CHRRule.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java [new file with mode: 0644]
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/translation/CHRTranslation.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EBlock.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/EPreCHRSelect.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/Expression.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionTransformer.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/StandardExpressionVisitor.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/expressions/block/CHRStatement.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCL.grammar
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParserImpl.java
bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/parser/generator/table/ParseTableBuilder.java
tests/org.simantics.scl.compiler.tests/src/org/simantics/scl/compiler/tests/scl/CHR3.scl

index f714497c4212c76c1ccef6e217a06c40f2d71a39..c668005d7f1f6b07ea714d3101ef944d28957d45 100644 (file)
@@ -45,6 +45,10 @@ public class CHRRule extends Symbol {
         this.body = body;
         this.existentialVariables = existentialVariables;
     }
+    
+    public CHRRule(long location, CHRQuery head, CHRQuery body) {
+        this(location, head, body, null);
+    }
 
     public void resolve(TranslationContext context) {
         context.pushExistentialFrame();
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstAtom.java
new file mode 100644 (file)
index 0000000..031d8ed
--- /dev/null
@@ -0,0 +1,143 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.simantics.scl.compiler.common.names.Name;
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
+import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.EBinary;
+import org.simantics.scl.compiler.elaboration.expressions.EConstant;
+import org.simantics.scl.compiler.elaboration.expressions.ERecord;
+import org.simantics.scl.compiler.elaboration.expressions.EVar;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.records.FieldAssignment;
+import org.simantics.scl.compiler.environment.AmbiguousNameException;
+import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.errors.Locations;
+import org.simantics.scl.compiler.types.Types;
+
+public class CHRAstAtom extends CHRAstQuery {
+    public Expression expression;
+    public boolean remove;
+
+    public CHRAstAtom(Expression expression, boolean remove) {
+        this.expression = expression;
+        this.remove = remove;
+    }
+    
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+    
+    public static CHRAstQuery atom(Expression expression) {
+        boolean remove = false;
+        if(expression instanceof EVar) {
+            EVar var = (EVar)expression;
+            if(var.name.equals("True")) {
+                CHRAstConjunction query = new CHRAstConjunction(Collections.emptyList());
+                query.location = expression.location;
+                return query;
+            }
+        }
+        else if(expression instanceof EBinary) {
+            EBinary binary = (EBinary)expression;
+            if(binary.negation != null && binary.rights.isEmpty()) {
+                remove = true;
+                expression = binary.left;
+            }
+            // If query is marked for removal, it must be an atom
+        }
+        else if(expression instanceof EApply) {
+            EApply apply = (EApply)expression;
+            if(apply.function instanceof EVar && ((EVar)apply.function).name.equals("not")) {
+                Expression subExpression;
+                if(apply.parameters.length == 1)
+                    subExpression = apply.parameters[0];
+                else
+                    subExpression = new EApply(
+                            Locations.combine(apply.parameters[0].location, apply.parameters[apply.parameters.length-1].location),
+                            apply.parameters[0],
+                            Arrays.copyOfRange(apply.parameters, 1, apply.parameters.length));
+                CHRAstNegation query = new CHRAstNegation(atom(subExpression));
+                query.location = expression.location;
+                return query;
+            }
+            else if(apply.function instanceof EConstant) {
+                Name valueName = ((EConstant)apply.function).getValue().getName();
+                if(valueName.module.equals(Types.BUILTIN) && valueName.name.startsWith("(")) {
+                    CHRAstQuery[] conjuncts = new CHRAstQuery[apply.parameters.length];
+                    for(int i=0;i<conjuncts.length;++i)
+                        conjuncts[i] = atom(apply.parameters[i]);
+                    CHRAstQuery query = CHRAstConjunction.conjunction(conjuncts);
+                    query.location = expression.location;
+                    return query;
+                }
+            }
+        }
+        CHRAstAtom query = new CHRAstAtom(expression, remove);
+        query.location = expression.location;
+        return query;
+    }
+
+    @Override
+    protected void translate(TranslationContext context, boolean isHead, ArrayList<CHRLiteral> literals) {
+        literals.add(
+            isConstraint(context, expression) ?
+            convertConstraint(remove, expression) :
+            convertExpression(isHead, expression));
+    }
+    
+    private static boolean isConstraint(TranslationContext context, Expression expression) {
+        if(expression instanceof EApply)
+            expression = ((EApply)expression).function;
+        else if(expression instanceof ERecord)
+            expression = ((ERecord)expression).constructor;
+        if(!(expression instanceof EVar))
+            return false;
+        String name = ((EVar)expression).name;
+        if(TranslationContext.isConstructorName(name))
+            return true;
+        try {
+            return Environments.getRelation(context.getEnvironment(), name) != null;
+        } catch (AmbiguousNameException e) {
+            return true;
+        }
+    }
+    
+    private static CHRLiteral convertExpression(boolean isHead, Expression expression) {
+        if(isHead)
+            return new CHRLiteral(expression.location, SpecialCHRRelation.CHECK, new Expression[] {expression}, false, false);
+        else
+            return new CHRLiteral(expression.location, SpecialCHRRelation.EXECUTE, new Expression[] {expression}, false, false);
+    }
+
+    private static CHRLiteral convertConstraint(boolean remove, Expression expression) {
+        long location = expression.location;
+        Expression[] parameters;
+        FieldAssignment[] fields = null;
+        if(expression instanceof EApply) {
+            EApply apply = (EApply)expression;
+            parameters = apply.parameters;
+            expression = apply.function;
+        }
+        else if(expression instanceof ERecord) {
+            ERecord record = (ERecord)expression;
+            parameters = null;
+            fields = record.fields;
+            expression = record.constructor;
+        }
+        else // if(expression instanceof EVar)
+            parameters = Expression.EMPTY_ARRAY;
+        EVar var = (EVar)expression; // this should succeed because of isConstraint test
+        CHRLiteral literal = new CHRLiteral(location, new UnresolvedCHRRelation(var.location, var.name),
+                parameters, remove, false);
+        literal.fields = fields;
+        return literal;
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstBinds.java
new file mode 100644 (file)
index 0000000..aa78f4e
--- /dev/null
@@ -0,0 +1,29 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+
+public class CHRAstBinds extends CHRAstQuery {
+    public Expression left;
+    public Expression right;
+    
+    public CHRAstBinds(Expression left, Expression right) {
+        this.left = left;
+        this.right = right;
+    }
+    
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+    
+    @Override
+    protected void translate(TranslationContext context, boolean isHead, ArrayList<CHRLiteral> literals) {
+        literals.add(new CHRLiteral(location, SpecialCHRRelation.MEMBER,
+                new Expression[] { left, right }, false, false));
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstConjunction.java
new file mode 100644 (file)
index 0000000..48f8ae7
--- /dev/null
@@ -0,0 +1,40 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+
+public class CHRAstConjunction extends CHRAstQuery {
+    public List<CHRAstQuery> conjuncts;
+
+    public CHRAstConjunction(List<CHRAstQuery> conjuncts) {
+        this.conjuncts = conjuncts;
+    }
+    
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+    
+    public static CHRAstQuery conjunction(CHRAstQuery[] conjuncts) {
+        ArrayList<CHRAstQuery> result = new ArrayList<CHRAstQuery>(conjuncts.length);
+        for(CHRAstQuery conjunct : conjuncts) {
+            if(conjunct instanceof CHRAstConjunction)
+                result.addAll(((CHRAstConjunction)conjunct).conjuncts);
+            else
+                result.add(conjunct);
+        }
+        if(result.size() == 1)
+            return result.get(0);
+        else
+            return new CHRAstConjunction(result);
+    }
+
+    @Override
+    protected void translate(TranslationContext context, boolean isHead, ArrayList<CHRLiteral> literals) {
+        for(CHRAstQuery conjunct : conjuncts)
+            conjunct.translate(context, isHead, literals);
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstEquals.java
new file mode 100644 (file)
index 0000000..d282893
--- /dev/null
@@ -0,0 +1,29 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+
+public class CHRAstEquals extends CHRAstQuery {
+    public Expression left;
+    public Expression right;
+    
+    public CHRAstEquals(Expression left, Expression right) {
+        this.left = left;
+        this.right = right;
+    }
+    
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    @Override
+    protected void translate(TranslationContext context, boolean isHead, ArrayList<CHRLiteral> literals) {
+        literals.add(new CHRLiteral(location, SpecialCHRRelation.EQUALS,
+                new Expression[] { left, right }, false, false));
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstNegation.java
new file mode 100644 (file)
index 0000000..b97f1e7
--- /dev/null
@@ -0,0 +1,24 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+
+public class CHRAstNegation extends CHRAstQuery {
+    public CHRAstQuery subquery;
+    
+    public CHRAstNegation(CHRAstQuery subquery) {
+        this.subquery = subquery;
+    }
+
+    @Override
+    public void accept(CHRAstQueryVisitor visitor) {
+        visitor.visit(this);
+    }
+
+    @Override
+    protected void translate(TranslationContext context, boolean isHead, ArrayList<CHRLiteral> literals) {
+        context.getCompilationContext().errorLog.log(location, "CHR negation is not yet supported.");
+    }
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQuery.java
new file mode 100644 (file)
index 0000000..bd708e6
--- /dev/null
@@ -0,0 +1,28 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+import java.util.ArrayList;
+
+import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
+import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.internal.parsing.Symbol;
+
+public abstract class CHRAstQuery extends Symbol {
+    public CHRQuery translateAsHead(TranslationContext context) {
+        return translate(context, true);
+    }
+    
+    public CHRQuery translateAsBody(TranslationContext context) {
+        return translate(context, false);
+    }
+
+    private CHRQuery translate(TranslationContext context, boolean isHead) {
+        ArrayList<CHRLiteral> literals = new ArrayList<CHRLiteral>(); 
+        translate(context, isHead, literals);
+        return new CHRQuery(literals.toArray(new CHRLiteral[literals.size()]));
+    }
+
+    protected abstract void translate(TranslationContext context, boolean isHead, ArrayList<CHRLiteral> literals);
+
+    public abstract void accept(CHRAstQueryVisitor visitor);
+}
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/chr/ast/CHRAstQueryVisitor.java
new file mode 100644 (file)
index 0000000..3c7b425
--- /dev/null
@@ -0,0 +1,9 @@
+package org.simantics.scl.compiler.elaboration.chr.ast;
+
+public interface CHRAstQueryVisitor {
+    void visit(CHRAstAtom query);
+    void visit(CHRAstBinds query);
+    void visit(CHRAstConjunction query);
+    void visit(CHRAstEquals query);
+    void visit(CHRAstNegation query);
+}
index d4f21a7265178bfe2b629066b423349066cd917f..260927b74c6c3659e12997035a80cfd5c5fb167a 100644 (file)
@@ -5,7 +5,6 @@ import java.util.Arrays;
 
 import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
-import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.relations.CHRConstraint;
 import org.simantics.scl.compiler.elaboration.chr.relations.SpecialCHRRelation;
 import org.simantics.scl.compiler.elaboration.chr.relations.UnresolvedCHRRelation;
@@ -15,7 +14,6 @@ import org.simantics.scl.compiler.elaboration.expressions.EBinary;
 import org.simantics.scl.compiler.elaboration.expressions.ERecord;
 import org.simantics.scl.compiler.elaboration.expressions.EVar;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-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.list.ListAssignment;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
@@ -140,12 +138,12 @@ public class CHRTranslation {
         return new CHRQuery(query.toArray(new CHRLiteral[query.size()]));
     }
     
-    public static CHRRule convertCHRStatement(TranslationContext context, CHRStatement statement) {
+    /*public static CHRRule convertCHRStatement(TranslationContext context, CHRStatement statement) {
         return new CHRRule(statement.location,
                 convertCHRQuery(context, true, statement.head),
                 convertCHRQuery(context, false, statement.body),
                 null);
-    }
+    }*/
 
     public static CHRConstraint convertConstraintStatement(TranslationContext context, ConstraintStatement statement) {
         CHRConstraint constraint = new CHRConstraint(statement.location, statement.name.text, TypeAst.toTypes(context, statement.parameterTypes));
index 2c70bd90742ef6562d8c9f141bd705838264dc82..e184b1397938e5604e91e90edaefd3699839c88d 100644 (file)
@@ -3,6 +3,7 @@ package org.simantics.scl.compiler.elaboration.expressions;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
 import org.simantics.scl.compiler.elaboration.chr.translation.CHRTranslation;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
@@ -92,8 +93,10 @@ public class EBlock extends ASTExpression {
         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.addRule(CHRTranslation.convertCHRStatement(context, (CHRStatement)statement));
+            if(statement instanceof CHRStatement) {
+                CHRStatement chrStatement = (CHRStatement)statement;
+                ruleset.addRule(new CHRRule(chrStatement.location, chrStatement.head.translateAsHead(context), chrStatement.body.translateAsBody(context)));
+            }
             else if(statement instanceof ConstraintStatement)
                 ruleset.constraints.add(CHRTranslation.convertConstraintStatement(context, (ConstraintStatement)statement));
             else if(statement instanceof IncludeStatement)
index 80943f7d8704620edc20ef88fc928e11af447b44..371ffbf72355abd44aec505cf387a89666640d5c 100644 (file)
@@ -1,22 +1,19 @@
 package org.simantics.scl.compiler.elaboration.expressions;
 
-import org.simantics.scl.compiler.elaboration.chr.translation.CHRTranslation;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
-import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
 
 public class EPreCHRSelect extends ASTExpression {
-    ListQualifier[] query;
+    CHRAstQuery query;
     Expression expression;
     
-    public EPreCHRSelect(ListQualifier[] query, Expression expression) {
+    public EPreCHRSelect(CHRAstQuery query, Expression expression) {
         this.query = query;
         this.expression = expression;
     }
 
     @Override
     public Expression resolve(TranslationContext context) {
-        return new ECHRSelect(expression, CHRTranslation.convertCHRQuery(context, true, query)).resolve(context);
+        return new ECHRSelect(expression, query.translateAsHead(context)).resolve(context);
     }
-
-
 }
index 0d48c4a153492e47307e7521831fc1dc0f7cc1db..d3e226cf490b5e70a1aae97fd2d654e7ff448adc 100644 (file)
@@ -258,7 +258,7 @@ public abstract class Expression extends Symbol implements Typed {
         THashSet<Variable> result = new THashSet<Variable>();
         collectFreeVariables(result);
         return result;
-    }    
+    }
 
     public static Expression[] concat(Expression[] a, Expression[] b) {
         if(a.length == 0)
index 948f7c645380b03ace647558546579ef09ceba68..c489422a54ccd71fef05b073c77381d4c0622de7 100644 (file)
@@ -4,6 +4,13 @@ import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
 import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstNegation;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQueryVisitor;
 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
 import org.simantics.scl.compiler.elaboration.equation.Equation;
@@ -41,7 +48,7 @@ import org.simantics.scl.compiler.elaboration.query.pre.QPreGuard;
 
 public class StandardExpressionTransformer implements
 ExpressionTransformer, QueryTransformer, ListQualifierTransformer, StatementVisitor,
-EquationVisitor {
+EquationVisitor, CHRAstQueryVisitor {
 
     @Override
     public Expression transform(EAmbiguous expression) {
@@ -532,10 +539,36 @@ EquationVisitor {
 
     @Override
     public void visit(CHRStatement statement) {
-        for(int i=0;i<statement.body.length;++i)
-            statement.body[i] = statement.body[i].accept(this);
-        for(int i=0;i<statement.head.length;++i)
-            statement.head[i] = statement.head[i].accept(this);
+        statement.head.accept(this);
+        statement.body.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstAtom query) {
+        query.expression = query.expression.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstBinds query) {
+        query.left = query.left.accept(this);
+        query.right = query.right.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstConjunction query) {
+        for(CHRAstQuery conjunct : query.conjuncts)
+            conjunct.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstEquals query) {
+        query.left = query.left.accept(this);
+        query.right = query.right.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstNegation query) {
+        query.subquery.accept(this);
     }
 
 }
index 83bbd34d1bfe29356cf14811828fa1bfec7f9270..d75080095d1c45a455e7eb08d20ea58eca96be2b 100644 (file)
@@ -4,6 +4,13 @@ import org.simantics.scl.compiler.elaboration.chr.CHRLiteral;
 import org.simantics.scl.compiler.elaboration.chr.CHRQuery;
 import org.simantics.scl.compiler.elaboration.chr.CHRRule;
 import org.simantics.scl.compiler.elaboration.chr.CHRRuleset;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstNegation;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQueryVisitor;
 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
 import org.simantics.scl.compiler.elaboration.equation.Equation;
@@ -24,7 +31,6 @@ import org.simantics.scl.compiler.elaboration.expressions.block.StatementVisitor
 import org.simantics.scl.compiler.elaboration.expressions.list.ListAssignment;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListGenerator;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListGuard;
-import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifierVisitor;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListSeq;
 import org.simantics.scl.compiler.elaboration.expressions.list.ListThen;
@@ -43,7 +49,7 @@ import org.simantics.scl.compiler.elaboration.query.QueryVisitor;
 
 public class StandardExpressionVisitor implements 
 ExpressionVisitor, QueryVisitor, FieldAccessorVisitor, ListQualifierVisitor,
-EquationVisitor, StatementVisitor {
+EquationVisitor, StatementVisitor, CHRAstQueryVisitor {
 
     @Override
     public void visit(EApply expression) {
@@ -457,9 +463,35 @@ EquationVisitor, StatementVisitor {
     
     @Override
     public void visit(CHRStatement statement) {
-        for(ListQualifier q : statement.body)
-            q.accept(this);
-        for(ListQualifier q : statement.head)
-            q.accept(this);
+        statement.body.accept(this);
+        statement.head.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstAtom query) {
+        query.expression.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstBinds query) {
+        query.left.accept(this);
+        query.right.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstConjunction query) {
+        for(CHRAstQuery conjunct : query.conjuncts)
+            conjunct.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstEquals query) {
+        query.left.accept(this);
+        query.right.accept(this);
+    }
+
+    @Override
+    public void visit(CHRAstNegation query) {
+        query.subquery.accept(this);
     }
 }
index d58f9c360e79c072eeb2723b8216466913a4c8b5..0c41b513a6c502a13a4eb62d631c8f46a544fa6d 100644 (file)
@@ -1,17 +1,17 @@
 package org.simantics.scl.compiler.elaboration.expressions.block;
 
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
 import org.simantics.scl.compiler.elaboration.contexts.EnvironmentalContext;
 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
 import org.simantics.scl.compiler.elaboration.expressions.Expression;
-import org.simantics.scl.compiler.elaboration.expressions.list.ListQualifier;
 import org.simantics.scl.compiler.errors.Locations;
 
 public class CHRStatement extends Statement {
 
-    public ListQualifier[] head;
-    public ListQualifier[] body;
+    public CHRAstQuery head;
+    public CHRAstQuery body;
 
-    public CHRStatement(ListQualifier[] head, ListQualifier[] body) {
+    public CHRStatement(CHRAstQuery head, CHRAstQuery body) {
         this.head = head;
         this.body = body;
     }
@@ -23,13 +23,8 @@ public class CHRStatement extends Statement {
 
     @Override
     public void setLocationDeep(long loc) {
-        if(location == Locations.NO_LOCATION) {
+        if(location == Locations.NO_LOCATION)
             location = loc;
-            for(ListQualifier lq : head)
-                lq.setLocationDeep(loc);
-            for(ListQualifier lq : body)
-                lq.setLocationDeep(loc);
-        }
     }
 
     @Override
index ea3df9722456cec4163ee9694498ea7b5e7716fb..b7bb1924c680efc17326fc39fedd3b6d04bb17bd 100644 (file)
@@ -206,12 +206,19 @@ statement
     | INCLUDE ID aexp                                        # LocalInclude
     ;
 
+verboseChrQuery
+    = LBRACE chrQuery (SEMICOLON chrQuery)* RBRACE           # VerboseCHRConjunction
+    ;
+    
+
 chrQuery 
-    = listQualifier (COMMA listQualifier)*                   # CHRQuery
+    = chrQueryPart (COMMA chrQueryPart)*                     # CHRConjunction
     ;
 
-verboseChrQuery
-    = LBRACE listQualifier (SEMICOLON listQualifier)* RBRACE # VerboseCHRQuery
+chrQueryPart
+    = exp                                                    # CHRAtom
+    | exp EQUALS exp                                         # CHREquals
+    | exp BINDS exp                                          # CHRBinds
     ;
 
 listQualifier
index e0aca1bb3fa476ebb227a69b0c51acd92110bac1..3d4d5096294402e60dcbbc6bf75b0fa3a5e7ab78 100644 (file)
Binary files a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat and b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/parser/SCLParser.dat differ
index 612b118ad3d7a3053b11a72d12e52e8fda90bdf5..3e857b7f1bc8192ef7dc0fe55c80fcdc78f66ab5 100644 (file)
@@ -13,18 +13,18 @@ public abstract class SCLParser {
     public static final boolean TRACE = false;
 
     private static final int INITIAL_CAPACITY = 16;
-    private static final int STATE_COUNT = 357;
+    private static final int STATE_COUNT = 362;
     private static final int TERMINAL_COUNT = 85;
-    private static final int NONTERMINAL_COUNT = 51;
-    private static final int PRODUCT_COUNT = 135;
+    private static final int NONTERMINAL_COUNT = 52;
+    private static final int PRODUCT_COUNT = 138;
     
     private static final int[] ACTION_ROW_ID = new int[STATE_COUNT];
     private static final int[] ACTION_COLUMN_ID = new int[TERMINAL_COUNT];
-    private static final short[] ACTION_TABLE = new short[6765];
-    private static final int[] ERROR_TABLE = new int[949];
+    private static final short[] ACTION_TABLE = new short[6832];
+    private static final int[] ERROR_TABLE = new int[962];
     private static final int[] GOTO_ROW_ID = new int[STATE_COUNT];
     private static final int[] GOTO_COLUMN_ID = new int[NONTERMINAL_COUNT];
-    private static final short[] GOTO_TABLE = new short[1647];
+    private static final short[] GOTO_TABLE = new short[1953];
     private static final int[] PRODUCT_LHS = new int[PRODUCT_COUNT];
 
     private static final short STATE_MASK = (short)0x0fff;
@@ -162,6 +162,7 @@ public abstract class SCLParser {
         "symbolWithoutMinus",
         "listQualifier",
         "chrQuery",
+        "chrQueryPart",
         "caseRhs",
         "guardedExpArrow",
         "equation",
@@ -395,19 +396,19 @@ public abstract class SCLParser {
         return parse(0);
     }
     public Object parseCommands() {
-        return parse(341);
+        return parse(346);
     }
     public Object parseImport() {
-        return parse(349);
+        return parse(354);
     }
     public Object parseType() {
-        return parse(351);
+        return parse(356);
     }
     public Object parseExp() {
-        return parse(353);
+        return parse(358);
     }
     public Object parseEquationBlock() {
-        return parse(355);
+        return parse(360);
     }
 
 
@@ -629,7 +630,7 @@ public abstract class SCLParser {
         case 106:
             return reduceQueryBlock();
         case 107:
-            return reduceVerboseCHRQuery();
+            return reduceVerboseCHRConjunction();
         case 108:
             return reduceStringLiteral();
         case 109:
@@ -651,26 +652,32 @@ public abstract class SCLParser {
         case 117:
             return reduceThenQualifier();
         case 118:
-            return reduceCHRQuery();
+            return reduceCHRConjunction();
         case 119:
-            return reduceSimpleCaseRhs();
+            return reduceCHRAtom();
         case 120:
-            return reduceGuardedCaseRhs();
+            return reduceCHREquals();
         case 121:
-            return reduceGuardedExpArrow();
+            return reduceCHRBinds();
         case 122:
-            return reduceGuardEquation();
+            return reduceSimpleCaseRhs();
         case 123:
-            return reduceBasicEquation();
+            return reduceGuardedCaseRhs();
         case 124:
-            return reduceEffect();
+            return reduceGuardedExpArrow();
         case 125:
-            return reduceJustEtype();
+            return reduceGuardEquation();
         case 126:
-            return reduceForAll();
+            return reduceBasicEquation();
         case 127:
-            return reduceApplyType();
+            return reduceEffect();
         case 128:
+            return reduceJustEtype();
+        case 129:
+            return reduceForAll();
+        case 130:
+            return reduceApplyType();
+        case 131:
             return reduceDummy();
 
         default:
@@ -1116,9 +1123,9 @@ public abstract class SCLParser {
      */
     protected abstract Object reduceQueryBlock();
     /**
-     * verboseChrQuery ::= LBRACE listQualifier (SEMICOLON listQualifier)&#42; RBRACE
+     * verboseChrQuery ::= LBRACE chrQuery (SEMICOLON chrQuery)&#42; RBRACE
      */
-    protected abstract Object reduceVerboseCHRQuery();
+    protected abstract Object reduceVerboseCHRConjunction();
     /**
      * stringLiteral ::= BEGIN_STRING (SUSPEND_STRING exp CONTINUE_STRING)&#42; END_STRING
      */
@@ -1140,9 +1147,21 @@ public abstract class SCLParser {
      */
     protected abstract Object reduceThenQualifier();
     /**
-     * chrQuery ::= (listQualifier COMMA)&#42; listQualifier
+     * chrQuery ::= (chrQueryPart COMMA)&#42; chrQueryPart
+     */
+    protected abstract Object reduceCHRConjunction();
+    /**
+     * chrQueryPart ::= exp
+     */
+    protected abstract Object reduceCHRAtom();
+    /**
+     * chrQueryPart ::= exp EQUALS exp
+     */
+    protected abstract Object reduceCHREquals();
+    /**
+     * chrQueryPart ::= exp BINDS exp
      */
-    protected abstract Object reduceCHRQuery();
+    protected abstract Object reduceCHRBinds();
     /**
      * caseRhs ::= ARROW exp (WHERE statements)?
      */
index dd614f964630aa8b7de8846a1de65616923f57b9..bda298bd661afd593eb59fc5766f9a6b72ba46da 100644 (file)
@@ -11,6 +11,11 @@ import org.simantics.scl.compiler.common.precedence.Precedence;
 import org.simantics.scl.compiler.compilation.CompilationContext;
 import org.simantics.scl.compiler.constants.CharacterConstant;
 import org.simantics.scl.compiler.constants.StringConstant;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstAtom;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstBinds;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstConjunction;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstEquals;
+import org.simantics.scl.compiler.elaboration.chr.ast.CHRAstQuery;
 import org.simantics.scl.compiler.elaboration.equation.EqBasic;
 import org.simantics.scl.compiler.elaboration.equation.EqGuard;
 import org.simantics.scl.compiler.elaboration.equation.Equation;
@@ -1247,25 +1252,12 @@ public class SCLParserImpl extends SCLParser {
         return new EViewPattern((Expression)get(1), (Expression)get(3));
     }
 
-    @Override
-    protected Object reduceCHRStatement() {
-        return new CHRStatement((ListQualifier[])get(0), (ListQualifier[])get(2));
-    }
-
     @Override
     protected Object reduceConstraintStatement() {
         ConstructorAst constructor = (ConstructorAst)get(1);
         return new ConstraintStatement(constructor.name, constructor.parameters, constructor.fieldNames, constructor.annotations);
     }
 
-    @Override
-    protected Object reduceCHRQuery() {
-        ListQualifier[] query = new ListQualifier[(length()+1)/2];
-        for(int i=0;i<query.length;++i)
-            query[i] = (ListQualifier)get(i*2);
-        return query;
-    }
-
     /*
     @Override
     protected Object reduceWhen() {
@@ -1273,19 +1265,6 @@ public class SCLParserImpl extends SCLParser {
                 new QConjunction((Query[])get(1)),
                 (Expression)get(3));
     }*/
-    
-    @Override
-    protected Object reduceVerboseCHRQuery() {
-        ListQualifier[] query = new ListQualifier[(length()-1)/2];
-        for(int i=0;i<query.length;++i)
-            query[i] = (ListQualifier)get(i*2+1);
-        return query;
-    }
-    
-    @Override
-    protected Object reduceVerboseCHRStatement() {
-        return new CHRStatement((ListQualifier[])get(1), (ListQualifier[])get(3));
-    }
 
     @Override
     protected Object reduceDummy() {
@@ -1316,7 +1295,48 @@ public class SCLParserImpl extends SCLParser {
 
     @Override
     protected Object reduceCHRSelect() {
-        return new EPreCHRSelect((ListQualifier[])get(3), (Expression)get(1));
+        return new EPreCHRSelect((CHRAstQuery)get(3), (Expression)get(1));
+    }
+
+    @Override
+    protected Object reduceCHRAtom() {
+        return CHRAstAtom.atom((Expression)get(0));
+    }
+
+    @Override
+    protected Object reduceCHREquals() {
+        return new CHRAstEquals((Expression)get(0), (Expression)get(2));
+    }
+
+    @Override
+    protected Object reduceCHRBinds() {
+        return new CHRAstBinds((Expression)get(0), (Expression)get(2));
+    }
+
+    @Override
+    protected Object reduceCHRConjunction() {
+        CHRAstQuery[] conjuncts = new CHRAstQuery[(length()+1)/2];
+        for(int i=0;i<conjuncts.length;++i)
+            conjuncts[i] = (CHRAstQuery)get(i*2);
+        return CHRAstConjunction.conjunction(conjuncts);
+    }
+    
+    @Override
+    protected Object reduceVerboseCHRConjunction() {
+        CHRAstQuery[] conjuncts = new CHRAstQuery[(length()-1)/2];
+        for(int i=0;i<conjuncts.length;++i)
+            conjuncts[i] = (CHRAstQuery)get(i*2+1);
+        return CHRAstConjunction.conjunction(conjuncts);
+    }
+    
+    @Override
+    protected Object reduceVerboseCHRStatement() {
+        return new CHRStatement((CHRAstQuery)get(1), (CHRAstQuery)get(3));
+    }
+
+    @Override
+    protected Object reduceCHRStatement() {
+        return new CHRStatement((CHRAstQuery)get(0), (CHRAstQuery)get(2));
     }
 
 }
index da837fb60e59947395c9872fddc27b45a4eee3cc..fdb01e58d37ce2f1cf37a49dee5fd82eee3531e2 100644 (file)
@@ -126,7 +126,7 @@ public class ParseTableBuilder {
                     }
                 }
                 stackOpMap.put(a, stackOp);
-                System.out.println(newState + " " + grammar.getName(a) + " " + stackOp);
+                //System.out.println(newState + " " + grammar.getName(a) + " " + stackOp);
                 
                 if(stackOverflow) {
                     System.err.println("Stack overflow when following " + grammar.getName(a) + " at");
@@ -396,7 +396,7 @@ public class ParseTableBuilder {
         
         //builder.visualize();
         
-        builder.printParseTable();
+        //builder.printParseTable();
         return builder.getParseTable();
     }
 
index 1d8451439ee92b8b9d6cb680ffd92cbb67fa9ca2..98c3a4338aa639a517366f15532096f3490321d5 100644 (file)
@@ -6,5 +6,4 @@ main = ()
     A ?x, not A (?x+1) => A (?x-1)
     True => A 0
 --
-0
-()
\ No newline at end of file
+6:11-6:23: CHR negation is not yet supported.
\ No newline at end of file