1 package org.simantics.scl.compiler.internal.parsing.declarations;
3 import java.util.ArrayList;
5 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
6 import org.simantics.scl.compiler.elaboration.expressions.EApply;
7 import org.simantics.scl.compiler.elaboration.expressions.EIntegerLiteral;
8 import org.simantics.scl.compiler.elaboration.expressions.ERealLiteral;
9 import org.simantics.scl.compiler.elaboration.expressions.EVar;
10 import org.simantics.scl.compiler.elaboration.expressions.Expression;
11 import org.simantics.scl.compiler.elaboration.expressions.Variable;
12 import org.simantics.scl.compiler.elaboration.query.QConjunction;
13 import org.simantics.scl.compiler.elaboration.query.Query;
14 import org.simantics.scl.compiler.elaboration.relations.ConcreteRelation;
16 public class DRelationAst extends DeclarationAst {
17 public final Expression lhs;
18 public final Object[] queries;
19 public DDocumentationAst documentation;
21 public DRelationAst(Expression lhs, Object[] queries) {
23 this.queries = queries;
27 public void toString(int indentation, StringBuilder b) {
28 for(int i=0;i<indentation;++i) b.append(" ");
31 for(Object query : queries) {
33 for(int i=0;i<=indentation;++i) b.append(" ");
34 System.out.println(query);
38 public void toString(StringBuilder b) {
42 public void setLocationDeep(long der) {
43 lhs.setLocationDeep(der);
44 for(Object query : queries)
45 if(query instanceof Query)
46 ((Query)query).setLocationDeep(der);
49 public void translateTo(TranslationContext context,
50 ConcreteRelation relation) {
53 EApply apply = (EApply)lhs;
54 Expression[] applyParameters = apply.getParameters();
55 relation.parameters = new Variable[applyParameters.length];
56 for(int i=0;i<applyParameters.length;++i) {
57 EVar var = (EVar)applyParameters[i];
58 Variable variable = context.newVariable(var.name);
59 relation.parameters[i] = variable;
63 ArrayList<Query> ql = new ArrayList<Query>();
64 DAnnotationAst annotation = null;
65 for(Object statement : queries) {
66 if(statement instanceof DAnnotationAst) {
68 translateSection(context, annotation, ql, relation);
71 annotation = (DAnnotationAst)statement;
74 ql.add((Query)statement);
77 translateSection(context, annotation, ql, relation);
80 private void translateSection(TranslationContext context, DAnnotationAst annotation, ArrayList<Query> queries, ConcreteRelation relation) {
81 Query query = queries.size() == 1 ? queries.get(0) : new QConjunction(queries);
82 String sectionName = annotation.id.text.substring(1);
83 if(sectionName.equals("enforce")) {
84 relation.enforceSection = query.resolve(context);
85 if(annotation.parameters.length > 0) {
86 relation.phase = Integer.parseInt(((EIntegerLiteral)annotation.parameters[0]).getValue());
92 for(int i=0;i<sectionName.length();++i) {
93 char c = sectionName.charAt(i);
97 context.getErrorLog().log(annotation.location, "Invalid section name '" + sectionName + "'.");
101 if(relation.getSection(pattern) != null)
102 context.getErrorLog().log(annotation.location, "Query section is redundant because the previous sections cover it.");
103 double selectivity = 10.0;
104 if(annotation.parameters.length > 0) {
105 Expression selExp = annotation.parameters[0];
106 if(selExp instanceof ERealLiteral)
107 selectivity = Double.parseDouble(((ERealLiteral)selExp).getValue());
109 selectivity = Integer.parseInt(((EIntegerLiteral)selExp).getValue());
111 context.pushExistentialFrame();
112 Query resolvedQuery = query.resolve(context);
113 Variable[] existentials = context.popExistentialFrame();
114 relation.addSection(pattern, selectivity, existentials, resolvedQuery);