--- /dev/null
+package org.simantics.scl.compiler.elaboration.java;
+
+
+import static org.simantics.scl.compiler.elaboration.expressions.Expressions.*;
+
+import org.cojen.classfile.TypeDesc;
+import org.simantics.scl.compiler.constants.generic.CallJava;
+import org.simantics.scl.compiler.constants.generic.MethodRef.ObjectMethodRef;
+import org.simantics.scl.compiler.constants.generic.MethodRef.StaticMethodRef;
+import org.simantics.scl.compiler.constants.generic.ParameterStackItem;
+import org.simantics.scl.compiler.constants.generic.StackItem;
+import org.simantics.scl.compiler.constants.generic.ThreadLocalStackItem;
+import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
+import org.simantics.scl.compiler.elaboration.expressions.EApply;
+import org.simantics.scl.compiler.elaboration.expressions.ELiteral;
+import org.simantics.scl.compiler.elaboration.expressions.EVariable;
+import org.simantics.scl.compiler.elaboration.expressions.Expression;
+import org.simantics.scl.compiler.elaboration.expressions.Variable;
+import org.simantics.scl.compiler.elaboration.query.QAtom;
+import org.simantics.scl.compiler.elaboration.query.QConjunction;
+import org.simantics.scl.compiler.elaboration.query.Query;
+import org.simantics.scl.compiler.elaboration.query.compilation.EnforcingContext;
+import org.simantics.scl.compiler.elaboration.query.compilation.QueryCompilationContext;
+import org.simantics.scl.compiler.elaboration.relations.AbstractRelation;
+import org.simantics.scl.compiler.elaboration.relations.SCLEntityType;
+import org.simantics.scl.compiler.internal.codegen.effects.EffectConstructor;
+import org.simantics.scl.compiler.internal.codegen.effects.ThreadLocalVariable;
+import org.simantics.scl.compiler.internal.codegen.utils.Constants;
+import org.simantics.scl.compiler.internal.codegen.utils.MethodBuilderBase;
+import org.simantics.scl.compiler.module.ConcreteModule;
+import org.simantics.scl.compiler.types.TCon;
+import org.simantics.scl.compiler.types.TVar;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.compiler.types.Types;
+import org.simantics.scl.compiler.types.kinds.Kinds;
+import org.simantics.scl.runtime.minigraph.Minigraph;
+
+public class MinigraphModule extends ConcreteModule {
+ public static final String MODULE = "Minigraph";
+ // public static final TCon RESOURCE = Types.con(MODULE, "Resource");
+ public static final TCon RESOURCE = Types.INTEGER;
+ public static final TCon GRAPH = Types.con(MODULE, "Graph");
+
+ private static final String THREAD_LOCAL_VARIABLE_NAME = "graph";
+ private static final TypeDesc MINIGRAPH = TypeDesc.forClass(Minigraph.class);
+
+ private static final CallJava CLAIM_METHOD = new CallJava(
+ TVar.EMPTY_ARRAY,
+ GRAPH,
+ Types.tupleConstructor(0),
+ new Type[] { RESOURCE, RESOURCE, RESOURCE },
+ new StackItem[] {
+ new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
+ new ParameterStackItem(0, RESOURCE),
+ new ParameterStackItem(1, RESOURCE),
+ new ParameterStackItem(2, RESOURCE),
+ },
+ new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "claim", TypeDesc.VOID, new TypeDesc[] {
+ TypeDesc.INT, TypeDesc.INT, TypeDesc.INT
+ }),
+ null
+ );
+
+ private static final CallJava HAS_STATEMENT_METHOD = new CallJava(
+ TVar.EMPTY_ARRAY,
+ GRAPH,
+ Types.BOOLEAN,
+ new Type[] { RESOURCE, RESOURCE, RESOURCE },
+ new StackItem[] {
+ new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
+ new ParameterStackItem(0, RESOURCE),
+ new ParameterStackItem(1, RESOURCE),
+ new ParameterStackItem(2, RESOURCE),
+ },
+ new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "hasStatement", TypeDesc.BOOLEAN, new TypeDesc[] {
+ TypeDesc.INT, TypeDesc.INT, TypeDesc.INT
+ }),
+ null
+ );
+
+ private static final CallJava GET_OBJECTS_METHOD = new CallJava(
+ TVar.EMPTY_ARRAY,
+ GRAPH,
+ Types.vector(RESOURCE),
+ new Type[] { RESOURCE, RESOURCE },
+ new StackItem[] {
+ new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
+ new ParameterStackItem(0, RESOURCE),
+ new ParameterStackItem(1, RESOURCE),
+ },
+ new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getObjects", TypeDesc.INT.toArrayType(), new TypeDesc[] {
+ TypeDesc.INT, TypeDesc.INT
+ }),
+ null
+ );
+
+ private static final CallJava BLANK_METHOD = new CallJava(
+ TVar.EMPTY_ARRAY,
+ GRAPH,
+ RESOURCE,
+ new Type[] { Types.UNIT },
+ new StackItem[] {
+ new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH)
+ },
+ new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "blank", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY),
+ null
+ );
+
+ private static final CallJava GET_SUBJECTS_METHOD = new CallJava(
+ TVar.EMPTY_ARRAY,
+ GRAPH,
+ Types.vector(RESOURCE),
+ new Type[] { RESOURCE, RESOURCE },
+ new StackItem[] {
+ new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
+ new ParameterStackItem(0, RESOURCE),
+ new ParameterStackItem(1, RESOURCE),
+ },
+ new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getSubjects", TypeDesc.INT.toArrayType(), new TypeDesc[] {
+ TypeDesc.INT, TypeDesc.INT
+ }),
+ null
+ );
+
+ private static final CallJava RESOURCE_METHOD = new CallJava(
+ TVar.EMPTY_ARRAY,
+ GRAPH,
+ RESOURCE,
+ new Type[] { Types.STRING },
+ new StackItem[] {
+ new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
+ new ParameterStackItem(0, Types.STRING),
+ },
+ new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getResource", TypeDesc.INT, new TypeDesc[] {
+ TypeDesc.STRING
+ }),
+ null
+ );
+
+ private static final CallJava GET_URI_METHOD = new CallJava(
+ TVar.EMPTY_ARRAY,
+ GRAPH,
+ Types.STRING,
+ new Type[] { RESOURCE },
+ new StackItem[] {
+ new ThreadLocalStackItem(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH),
+ new ParameterStackItem(0, RESOURCE),
+ },
+ new ObjectMethodRef(false, MethodBuilderBase.getClassName(MINIGRAPH), "getUri", TypeDesc.STRING, new TypeDesc[] {
+ TypeDesc.INT
+ }),
+ null
+ );
+
+ private static final TVar A = Types.var(Kinds.STAR);
+ private static final TVar E = Types.var(Kinds.EFFECT);
+ private static final Type F = Types.functionE(Types.PUNIT, Types.union(new Type[] {GRAPH, E}), A);
+ private static final CallJava WITH_GRAPH_METHOD = new CallJava(
+ new TVar[] { A, E },
+ Types.union(new Type[] {Types.PROC, E}),
+ A,
+ new Type[] { F },
+ new StackItem[] {
+ new ParameterStackItem(0, F),
+ },
+ new StaticMethodRef(MethodBuilderBase.getClassName(MINIGRAPH), "withGraph", TypeDesc.OBJECT, new TypeDesc[] {
+ Constants.FUNCTION
+ }),
+ null
+ );
+
+ public static final MinigraphModule INSTANCE = new MinigraphModule();
+
+ private MinigraphModule() {
+ super(MODULE);
+ //addTypeConstructor("Resource", new StandardTypeConstructor(RESOURCE, Kinds.STAR, TypeDesc.INT));
+ EffectConstructor effect = new EffectConstructor(Types.con(MODULE, "Graph"));
+ effect.addThreadLocalVariable(new ThreadLocalVariable(THREAD_LOCAL_VARIABLE_NAME, MINIGRAPH));
+ addEffectConstructor("Graph", effect);
+ addValue("resource", RESOURCE_METHOD);
+ addValue("blank", BLANK_METHOD);
+ addValue("withGraph", WITH_GRAPH_METHOD);
+ addValue("uriOf", GET_URI_METHOD);
+ addRelation("Statement", new AbstractRelation() {
+
+ @Override
+ public TVar[] getTypeVariables() {
+ return TVar.EMPTY_ARRAY;
+ }
+
+ @Override
+ public double getSelectivity(int boundVariabes) {
+ switch(boundVariabes) {
+ case BBF: return 10.0;
+ case FBB: return 10.0;
+ case BBB: return 0.95;
+ default: return Double.POSITIVE_INFINITY;
+ }
+ }
+
+ @Override
+ public int getRequiredVariablesMask() {
+ return FBF;
+ }
+
+ @Override
+ public Type[] getParameterTypes() {
+ return new Type[] { RESOURCE, RESOURCE, RESOURCE };
+ }
+
+ @Override
+ public Expression generateEnforce(long location, EnforcingContext context,
+ Type[] typeParameters,
+ Variable[] parameters) {
+ return new EApply(new ELiteral(CLAIM_METHOD),
+ new Expression[] {
+ new EVariable(parameters[0]),
+ new EVariable(parameters[1]),
+ new EVariable(parameters[2])
+ });
+ }
+
+ @Override
+ public void generate(long location,
+ QueryCompilationContext context,
+ Type[] typeParameters, Variable[] parameters, int boundVariables) {
+ switch(boundVariables) {
+ case BBF:
+ context.iterateVector(parameters[2],
+ new EApply(new ELiteral(GET_OBJECTS_METHOD),
+ new Expression[] {
+ new EVariable(parameters[0]),
+ new EVariable(parameters[1]),
+ }));
+ break;
+ case FBB:
+ context.iterateVector(parameters[0],
+ new EApply(new ELiteral(GET_SUBJECTS_METHOD),
+ new Expression[] {
+ new EVariable(parameters[2]),
+ new EVariable(parameters[1]),
+ }));
+ break;
+ case BBB:
+ context.condition(
+ new EApply(new ELiteral(HAS_STATEMENT_METHOD),
+ new Expression[] {
+ new EVariable(parameters[0]),
+ new EVariable(parameters[1]),
+ new EVariable(parameters[2])
+ }));
+ break;
+ default: throw new IllegalArgumentException();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Statement";
+ }
+ });
+ addEntityType("Resource", new SCLEntityType() {
+ @Override
+ public Query generateQuery(TranslationContext context, Variable base,
+ AttributeBinding[] attributeBindings) {
+ Query[] queries = new Query[attributeBindings.length];
+ for(int i=0;i<attributeBindings.length;++i) {
+ AttributeBinding binding = attributeBindings[i];
+ queries[i] = new QAtom(getRelation("Statement"),
+ var(base),
+ apply(constant(getValue("resource")), string(((ResourceAttribute)binding.attribute).name)),
+ var(binding.variable));
+ }
+ return new QConjunction(queries);
+ }
+
+ @Override
+ public Attribute getAttribute(String name) {
+ return new ResourceAttribute(name);
+ }
+ });
+ }
+
+ private static class ResourceAttribute implements SCLEntityType.Attribute {
+ String name;
+
+ public ResourceAttribute(String name) {
+ this.name = name;
+ }
+ }
+}