]> gerrit.simantics Code Review - simantics/platform.git/blob
434f2da6e13ff7b8249d6373aa7595c87eb7aca6
[simantics/platform.git] /
1 package org.simantics.scl.compiler.elaboration.java;
2
3
4 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.apply;
5 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.constant;
6 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.string;
7 import static org.simantics.scl.compiler.elaboration.expressions.Expressions.var;
8
9 import org.cojen.classfile.TypeDesc;
10 import org.simantics.scl.compiler.constants.generic.CallJava;
11 import org.simantics.scl.compiler.constants.generic.MethodRef.ObjectMethodRef;
12 import org.simantics.scl.compiler.constants.generic.MethodRef.StaticMethodRef;
13 import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
14 import org.simantics.scl.compiler.constants.generic.StackItem;
15 import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
16 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
17 import org.simantics.scl.compiler.elaboration.expressions.EApply;
18 import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
19 import org.simantics.scl.compiler.elaboration.expressions.EVariable;
20 import org.simantics.scl.compiler.elaboration.expressions.Expression;
21 import org.simantics.scl.compiler.elaboration.expressions.Variable;
22 import org.simantics.scl.compiler.elaboration.query.QAtom;
23 import org.simantics.scl.compiler.elaboration.query.QConjunction;
24 import org.simantics.scl.compiler.elaboration.query.Query;
25 import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
26 import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
27 import org.simantics.scl.compiler.elaboration.relations.AbstractRelation;
28 import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
29 import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
30 import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
31 import org.simantics.scl.compiler.internal.codegen.utils.Constants;
32 import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
33 import org.simantics.scl.compiler.module.ConcreteModule;
34 import org.simantics.scl.compiler.types.TCon;
35 import org.simantics.scl.compiler.types.TVar;
36 import org.simantics.scl.compiler.types.Type;
37 import org.simantics.scl.compiler.types.Types;
38 import org.simantics.scl.compiler.types.kinds.Kinds;
39 import org.simantics.scl.runtime.minigraph.Minigraph;
40
41 public class MinigraphModule extends ConcreteModule {
42     public static final String MODULE = "Minigraph"; 
43    // public static final TCon RESOURCE = Types.con(MODULE, "Resource");
44     public static final TCon RESOURCE = Types.INTEGER;
45     public static final TCon GRAPH = Types.con(MODULE, "Graph");
46     
47     private static final String THREAD_LOCAL_VARIABLE_NAME = "graph";
48     private static final TypeDesc MINIGRAPH = TypeDesc.forClass(Minigraph.class);
49     
50     private static final CallJava CLAIM_METHOD = new CallJava(
51             TVar.EMPTY_ARRAY,
52             GRAPH,
53             Types.tupleConstructor(0),
54             new Type[] { RESOURCE, RESOURCE, RESOURCE },
55             new StackItem[] {
56                 new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
57                 new ParameterStackItem(0, RESOURCE),
58                 new ParameterStackItem(1, RESOURCE),
59                 new ParameterStackItem(2, RESOURCE),
60             },
61             new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "claim", TypeDesc.VOID, new TypeDesc[] {
62                 TypeDesc.INT, TypeDesc.INT, TypeDesc.INT 
63             }),
64             null
65             );
66     
67     private static final CallJava HAS_STATEMENT_METHOD = new CallJava(
68             TVar.EMPTY_ARRAY,
69             GRAPH,
70             Types.BOOLEAN,
71             new Type[] { RESOURCE, RESOURCE, RESOURCE },
72             new StackItem[] {
73                 new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
74                 new ParameterStackItem(0, RESOURCE),
75                 new ParameterStackItem(1, RESOURCE),
76                 new ParameterStackItem(2, RESOURCE),
77             },
78             new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "hasStatement", TypeDesc.BOOLEAN, new TypeDesc[] {
79                 TypeDesc.INT, TypeDesc.INT, TypeDesc.INT 
80             }),
81             null
82             );
83     
84     private static final CallJava GET_OBJECTS_METHOD = new CallJava(
85             TVar.EMPTY_ARRAY,
86             GRAPH,
87             Types.vector(RESOURCE),
88             new Type[] { RESOURCE, RESOURCE },
89             new StackItem[] {
90                 new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
91                 new ParameterStackItem(0, RESOURCE),
92                 new ParameterStackItem(1, RESOURCE),
93             },
94             new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getObjects", TypeDesc.INT.toArrayType(), new TypeDesc[] {
95                 TypeDesc.INT, TypeDesc.INT
96             }),
97             null
98             );
99     
100     private static final CallJava BLANK_METHOD = new CallJava(
101             TVar.EMPTY_ARRAY,
102             GRAPH,
103             RESOURCE,
104             new Type[] { Types.UNIT },
105             new StackItem[] {
106                 new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH)
107             },
108             new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "blank", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY),
109             null
110             );
111     
112     private static final CallJava GET_SUBJECTS_METHOD = new CallJava(
113             TVar.EMPTY_ARRAY,
114             GRAPH,
115             Types.vector(RESOURCE),
116             new Type[] { RESOURCE, RESOURCE },
117             new StackItem[] {
118                 new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
119                 new ParameterStackItem(0, RESOURCE),
120                 new ParameterStackItem(1, RESOURCE),
121             },
122             new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getSubjects", TypeDesc.INT.toArrayType(), new TypeDesc[] {
123                 TypeDesc.INT, TypeDesc.INT
124             }),
125             null
126             );
127     
128     private static final CallJava RESOURCE_METHOD = new CallJava(
129             TVar.EMPTY_ARRAY,
130             GRAPH,
131             RESOURCE,
132             new Type[] { Types.STRING },
133             new StackItem[] {
134                 new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
135                 new ParameterStackItem(0, Types.STRING),
136             },
137             new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getResource", TypeDesc.INT, new TypeDesc[] {
138                 TypeDesc.STRING
139             }),
140             null
141             );
142     
143     private static final CallJava GET_URI_METHOD = new CallJava(
144             TVar.EMPTY_ARRAY,
145             GRAPH,
146             Types.STRING,
147             new Type[] { RESOURCE },
148             new StackItem[] {
149                 new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
150                 new ParameterStackItem(0, RESOURCE),
151             },
152             new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getUri", TypeDesc.STRING, new TypeDesc[] {
153                 TypeDesc.INT
154             }),
155             null
156             );
157     
158     private static final TVar A = Types.var(Kinds.STAR);
159     private static final TVar E = Types.var(Kinds.EFFECT);
160     private static final Type F = Types.functionE(Types.PUNIT, Types.union(new Type[] {GRAPH, E}), A);
161     private static final CallJava WITH_GRAPH_METHOD = new CallJava(
162             new TVar[] { A, E },
163             Types.union(new Type[] {Types.PROC, E}),
164             A,
165             new Type[] { F },
166             new StackItem[] {
167                 new ParameterStackItem(0, F),
168             },
169             new StaticMethodRef(MethodBuilderBase.getClassName(MINIGRAPH), "withGraph", TypeDesc.OBJECT, new TypeDesc[] {
170                 Constants.FUNCTION
171             }),
172             null
173             );
174     
175     public static final MinigraphModule INSTANCE = new MinigraphModule();
176     
177     private MinigraphModule() {
178         super(MODULE);
179         //addTypeConstructor("Resource", new StandardTypeConstructor(RESOURCE, Kinds.STAR, TypeDesc.INT));
180         EffectConstructor effect = new EffectConstructor(Types.con(MODULE, "Graph"));
181         effect.addThreadLocalVariable(new ThreadLocalVariable(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH));
182         addEffectConstructor("Graph", effect);
183         addValue("resource", RESOURCE_METHOD);
184         addValue("blank", BLANK_METHOD);
185         addValue("withGraph", WITH_GRAPH_METHOD);
186         addValue("uriOf", GET_URI_METHOD);
187         addRelation("Statement", new AbstractRelation() {
188             
189             @Override
190             public TVar[] getTypeVariables() {
191                 return TVar.EMPTY_ARRAY;
192             }
193             
194             @Override
195             public double getSelectivity(int boundVariabes) {
196                 switch(boundVariabes) {
197                 case BBF: return 10.0;
198                 case FBB: return 10.0;
199                 case BBB: return 0.95;
200                 default: return Double.POSITIVE_INFINITY;
201                 }
202             }
203             
204             @Override
205             public int getRequiredVariablesMask() {
206                 return FBF;
207             }
208             
209             @Override
210             public Type[] getParameterTypes() {
211                 return new Type[] { RESOURCE, RESOURCE, RESOURCE };
212             }            
213             
214             @Override
215             public Expression generateEnforce(long location, EnforcingContext context,
216                     Type[] typeParameters,
217                     Variable[] parameters) {
218                 return new EApply(new ELiteral(CLAIM_METHOD),
219                         new Expression[] {
220                         new EVariable(parameters[0]),
221                         new EVariable(parameters[1]),
222                         new EVariable(parameters[2])
223                 });
224             }
225             
226             @Override
227             public void generate(long location,
228                     QueryCompilationContext context,
229                     Type[] typeParameters, Variable[] parameters, int boundVariables) {
230                 switch(boundVariables) {
231                 case BBF:
232                     context.iterateVector(parameters[2],
233                         new EApply(new ELiteral(GET_OBJECTS_METHOD),
234                                 new Expression[] {
235                                 new EVariable(parameters[0]),
236                                 new EVariable(parameters[1]),
237                         }));
238                     break;
239                 case FBB:
240                     context.iterateVector(parameters[0],
241                         new EApply(new ELiteral(GET_SUBJECTS_METHOD),
242                                 new Expression[] {
243                                 new EVariable(parameters[2]),
244                                 new EVariable(parameters[1]),
245                         }));
246                     break;
247                 case BBB: 
248                     context.condition(
249                         new EApply(new ELiteral(HAS_STATEMENT_METHOD),
250                                 new Expression[] {
251                                 new EVariable(parameters[0]),
252                                 new EVariable(parameters[1]),
253                                 new EVariable(parameters[2])
254                         }));
255                     break;
256                 default: throw new IllegalArgumentException();
257                 }
258             }
259             
260             @Override
261             public String toString() {
262                 return "Statement";
263             }
264         });
265         addEntityType("Resource", new SCLEntityType() {
266             @Override
267             public Query generateQuery(TranslationContext context, Variable base,
268                     AttributeBinding[] attributeBindings) {
269                 Query[] queries = new Query[attributeBindings.length];
270                 for(int i=0;i<attributeBindings.length;++i) {
271                     AttributeBinding binding = attributeBindings[i];
272                     queries[i] = new QAtom(getRelation("Statement"),
273                             var(base),
274                             apply(constant(getValue("resource")), string(((ResourceAttribute)binding.attribute).name)),
275                             var(binding.variable));
276                 }
277                 return new QConjunction(queries);
278             }
279
280             @Override
281             public Attribute getAttribute(String name) {
282                 return new ResourceAttribute(name);
283             }
284         });
285         setParentClassLoader(getClass().getClassLoader());
286     }
287     
288     private static class ResourceAttribute implements SCLEntityType.Attribute {
289         String name;
290
291         public ResourceAttribute(String name) {
292             this.name = name;
293         }
294     }
295 }