]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.scl.compiler / src / org / simantics / scl / compiler / elaboration / java / MinigraphModule.java
diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/elaboration/java/MinigraphModule.java
new file mode 100644 (file)
index 0000000..b9534f7
--- /dev/null
@@ -0,0 +1,291 @@
+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;
+        }
+    }
+}