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