1 package org.simantics.scl.compiler.elaboration.query.pre;
3 import java.util.Arrays;
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.EVar;
8 import org.simantics.scl.compiler.elaboration.expressions.Expression;
9 import org.simantics.scl.compiler.elaboration.expressions.QueryTransformer;
10 import org.simantics.scl.compiler.elaboration.java.CheckRelation;
11 import org.simantics.scl.compiler.elaboration.query.QAtom;
12 import org.simantics.scl.compiler.elaboration.query.QMapping;
13 import org.simantics.scl.compiler.elaboration.query.Query;
14 import org.simantics.scl.compiler.elaboration.relations.SCLRelation;
15 import org.simantics.scl.compiler.elaboration.relations.TransitiveClosureRelation;
16 import org.simantics.scl.compiler.elaboration.rules.MappingRelation;
17 import org.simantics.scl.compiler.environment.AmbiguousNameException;
18 import org.simantics.scl.compiler.environment.Environments;
19 import org.simantics.scl.compiler.errors.Locations;
21 public class QPreGuard extends PreQuery {
22 public Expression guard;
24 public QPreGuard(Expression guard) {
29 private static Query resolveAsQuery(TranslationContext context, Expression function,
30 Expression[] parameters) {
31 if(function instanceof EVar) {
32 String relationName = ((EVar)function).name;
33 if(relationName.equals("tc") && parameters.length > 0) {
34 Query query_ = resolveAsQuery(context, parameters[0],
35 Arrays.copyOfRange(parameters, 1, parameters.length));
38 if(!(query_ instanceof QAtom)) {
39 context.getErrorLog().log(query_.location, "Cannot form a transitive relation.");
42 QAtom query = (QAtom)query_;
43 query.relation = new TransitiveClosureRelation(query.relation);
47 MappingRelation mappingRelation;
49 mappingRelation = Environments.getMappingRelation(
50 context.getEnvironment(), relationName);
51 } catch (AmbiguousNameException e) {
52 context.getErrorLog().log(function.location, e.getMessage());
55 if(mappingRelation != null) {
56 if(parameters.length != 2)
57 context.getErrorLog().log(function.location,
58 "An arity of mapping relation should always be 2.");
59 for(int i=0;i<parameters.length;++i)
60 parameters[i] = parameters[i].resolve(context);
61 return new QMapping(mappingRelation, parameters);
64 SCLRelation relation = context.resolveRelation(function.getLocation(), relationName);
65 if(relation != null) {
66 for(int i=0;i<parameters.length;++i)
67 parameters[i] = parameters[i].resolve(context);
68 return new QAtom(relation, parameters);
74 private static Query resolveAsQuery(TranslationContext context, Expression expression) {
75 if(expression instanceof EApply) {
76 EApply apply = (EApply)expression;
77 Query query = resolveAsQuery(context, apply.getFunction(), apply.getParameters());
81 return new QAtom(CheckRelation.INSTANCE,
82 new Expression[] { expression.resolve(context) });
86 public Query resolve(TranslationContext context) {
87 PreQuery oldPreQuery = context.currentPreQuery;
88 context.currentPreQuery = this;
89 Query query = resolveAsQuery(context, guard);
90 context.currentPreQuery = oldPreQuery;
91 query.location = location;
92 return withSideQueries(query);
96 public void setLocationDeep(long loc) {
97 if(location == Locations.NO_LOCATION) {
99 guard.setLocationDeep(loc);
104 public Query accept(QueryTransformer transformer) {
105 return transformer.transform(this);