]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/parsing/declarations/DRelationAst.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / internal / parsing / declarations / DRelationAst.java
1 package org.simantics.scl.compiler.internal.parsing.declarations;
2
3 import java.util.ArrayList;
4
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;
15
16 public class DRelationAst extends DeclarationAst {
17     public final Expression lhs;
18     public final Object[] queries;
19     public DDocumentationAst documentation;
20     
21     public DRelationAst(Expression lhs, Object[] queries) {
22         this.lhs = lhs;
23         this.queries = queries;
24     }
25     
26     @Override
27     public void toString(int indentation, StringBuilder b) {
28         for(int i=0;i<indentation;++i) b.append("    ");
29         b.append(lhs);
30         b.append(" :-");
31         for(Object query : queries) {
32             b.append('\n');
33             for(int i=0;i<=indentation;++i) b.append("    ");
34             System.out.println(query);
35         }
36     }
37
38     public void toString(StringBuilder b) {
39         toString(0, b);
40     }
41
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);
47     }
48
49     public void translateTo(TranslationContext context,
50             ConcreteRelation relation) {
51         
52         // Parameters
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;
60         }
61         
62         // Sections
63         ArrayList<Query> ql = new ArrayList<Query>();
64         DAnnotationAst annotation = null;
65         for(Object statement : queries) {
66             if(statement instanceof DAnnotationAst) {
67                 if(!ql.isEmpty()) {
68                     translateSection(context, annotation, ql, relation);
69                     ql.clear();
70                 }
71                 annotation = (DAnnotationAst)statement;
72             }
73             else
74                 ql.add((Query)statement);
75         }
76         if(!ql.isEmpty())
77             translateSection(context, annotation, ql, relation);
78     }
79
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());
87             }
88             return;
89         }
90         
91         int pattern = 0;
92         for(int i=0;i<sectionName.length();++i) {
93             char c = sectionName.charAt(i);
94             if(c == 'b')
95                 pattern |= 1 << i;
96             else if(c != 'f') {
97                 context.getErrorLog().log(annotation.location, "Invalid section name '" + sectionName + "'.");
98                 return;
99             }   
100         }
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());
108             else
109                 selectivity = Integer.parseInt(((EIntegerLiteral)selExp).getValue());
110         }
111         context.pushExistentialFrame();
112         Query resolvedQuery = query.resolve(context);
113         Variable[] existentials = context.popExistentialFrame(); 
114         relation.addSection(pattern, selectivity, existentials, resolvedQuery);
115     }
116 }