- public static Object compileAndEvaluate(ReadGraph graph, Variable context) throws DatabaseException {
- SCLContext sclContext = SCLContext.getCurrent();
- Object oldGraph = sclContext.get("graph");
- try {
- Function1<Object,Object> exp = graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context),
- TransientCacheListener.instance());
- sclContext.put("graph", graph);
- return exp.apply(context);
- } catch (DatabaseException e) {
- throw (DatabaseException)e;
- } catch (Throwable t) {
- throw new DatabaseException(t);
- } finally {
- sclContext.put("graph", oldGraph);
- }
- }
-
- public static Function1<Object, Object> compile(ReadGraph graph, Variable context) throws DatabaseException {
- return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context), TransientCacheListener.instance());
- }
-
- public static Function1<Object, Object> compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException {
- return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, s, o, p), TransientCacheListener.<Function1<Object,Object>>instance());
- }
-
- @Override
- protected String getExpressionText(ReadGraph graph)
- throws DatabaseException {
- Layer0 L0 = Layer0.getInstance(graph);
- String exp = graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING);
- return "\\context -> " + exp;
- }
-
- protected RuntimeEnvironmentRequest2 getRuntimeEnvironmentRequest(Resource componentType, Resource indexRoot) {
- return new RuntimeEnvironmentRequest2(componentType, indexRoot) {
- @Override
- protected void fillEnvironmentSpecification(
- EnvironmentSpecification environmentSpecification) {
- }
- };
- }
-
- @Override
- protected CompilationContext getCompilationContext(ReadGraph graph) throws DatabaseException {
- return graph.syncRequest(new UnaryRead<Pair<Resource,Resource>,CompilationContext>(componentTypeAndRoot) {
- @Override
- public CompilationContext perform(ReadGraph graph) throws DatabaseException {
- RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second));
- Map<String, ComponentTypeProperty> propertyMap =
- graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()),
- TransientCacheListener.<Map<String, ComponentTypeProperty>>instance());
- return new CompilationContext(runtimeEnvironment, propertyMap);
- }
- });
- }
-
- @Override
- protected Type getContextVariableType() {
- return VARIABLE;
- }
-
- private static Expression accessInputVariable(Environment environment,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable) {
- SCLValue variableParentFunction = environment.getValue(VARIABLE_PARENT);
- return new EApply(new EConstant(variableParentFunction),
- new EApply(new EConstant(variableParentFunction),
- new EVariable(contextVariable)));
- }
-
- protected static Expression standardGetProperty(
- Environment environment,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
- String name,
- Type type) {
- return getPropertyFlexible(environment, accessInputVariable(environment, contextVariable), name, type);
- }
-
- @Override
- protected Expression getVariableAccessExpression(
- ReadGraph graph,
- CompilationContext context,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
- String name) throws DatabaseException {
- ComponentTypeProperty property = context.propertyMap.get(name);
- if(property != null)
- return standardGetProperty(
- context.runtimeEnvironment.getEnvironment(),
- contextVariable,
- name,
- property.type == null ? Types.metaVar(Kinds.STAR) : property.type);
- else {
-
-// if(context.propertyMap.containsKey(name)) {
-//
-// org.simantics.scl.compiler.elaboration.expressions.Variable parametersVariable = new org.simantics.scl.compiler.elaboration.expressions.Variable("context", COMMAND_CONTEXT);
-//
-// Environment environment = context.runtimeEnvironment.getEnvironment();
-//
-//// return new EApply(
-//// new EConstant(environment.getValue(FROM_DYNAMIC), Types.STRING),
-// return new EApply(
-// new EConstant(environment.getValue(CONTEXT_VARIABLE), Types.DYNAMIC),
-// new EVariable(parametersVariable),
-// new ELiteral(new StringConstant(name)));
-//
-// }
-
- return getSpecialVariableAccessExpression(graph, context, contextVariable, name);
-
- }
- }
-
- protected Expression getSpecialVariableAccessExpression(ReadGraph graph,
- CompilationContext context,
- org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
- String name) throws DatabaseException {
- if(name.equals("input")) {
- Environment environment = context.runtimeEnvironment.getEnvironment();
- return accessInputVariable(environment, contextVariable);
- } else if(name.equals("self"))
- return new EVariable(contextVariable);
- else
- return null;
- }
+ public static Function1<Object, Object> compile(ReadGraph graph, Variable context) throws DatabaseException {
+ return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, context), TransientCacheListener.instance());
+ }
+
+ public static Function1<Object, Object> compile(ReadGraph graph, Resource s, Resource o, Resource p) throws DatabaseException {
+ return graph.syncRequest(new ServerSCLHandlerValueRequest(graph, s, o, p), TransientCacheListener.instance());
+ }
+
+ public static class HandlerFn extends FunctionImpl1<Object,Object> {
+
+ Function1<Object,Object> handler;
+ ArrayList<TCon> effects;
+
+ HandlerFn(Function1<Object,Object> handler, Type type) {
+ try {
+ this.handler = handler;
+ this.effects = new ArrayList<TCon>();
+ MultiFunction mfun = Types.matchFunction(type, 1);
+ mfun.effect.collectConcreteEffects(this.effects);
+ } catch(MatchException e) {
+ // Should not happen!
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public Object apply(Object p0) {
+ return handler.apply(p0);
+ }
+
+ }
+
+ @Override
+ public Function1<Object, Object> perform(ReadGraph graph) throws DatabaseException {
+
+ CompilationContext context = getCompilationContext(graph);
+ Type expectedType = getExpectedType(graph, context);
+ Function1<Object,Object> handler = eval(prepareEvaluator(graph, context, expectedType), graph);
+ return new HandlerFn(handler, expectedType);
+
+ }
+
+ @Override
+ protected String getExpressionText(ReadGraph graph)
+ throws DatabaseException {
+ Layer0 L0 = Layer0.getInstance(graph);
+ String exp = graph.getRelatedValue(literal, L0.SCLValue_expression, Bindings.STRING);
+ return "\\context -> " + exp;
+ }
+
+ protected RuntimeEnvironmentRequest2 getRuntimeEnvironmentRequest(Resource componentType, Resource indexRoot) {
+ return new RuntimeEnvironmentRequest2(componentType, indexRoot) {
+ @Override
+ protected void fillEnvironmentSpecification(
+ EnvironmentSpecification environmentSpecification) {
+ }
+ };
+ }
+
+ @Override
+ protected CompilationContext getCompilationContext(ReadGraph graph) throws DatabaseException {
+ return graph.syncRequest(new UnaryRead<Pair<Resource,Resource>,CompilationContext>(componentTypeAndRoot) {
+ @Override
+ public CompilationContext perform(ReadGraph graph) throws DatabaseException {
+ RuntimeEnvironment runtimeEnvironment = graph.syncRequest(getRuntimeEnvironmentRequest(parameter.first, parameter.second));
+ Map<String, ComponentTypeProperty> propertyMap;
+ if (parameter.first != null) {
+ propertyMap =
+ graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()),
+ TransientCacheListener.<Map<String, ComponentTypeProperty>>instance());
+ } else {
+ // TODO: Antti to consider
+ // To handle procedural user components
+ propertyMap = Collections.emptyMap();
+ }
+// Map<String, ComponentTypeProperty> propertyMap =
+// graph.syncRequest(new ReadComponentTypeInterfaceRequest(parameter.first, runtimeEnvironment.getEnvironment()),
+// TransientCacheListener.<Map<String, ComponentTypeProperty>>instance());
+ return new CompilationContext(runtimeEnvironment, propertyMap);
+ }
+ });
+ }
+
+ @Override
+ protected Type getContextVariableType() {
+ return VARIABLE;
+ }
+
+ private static Expression accessInputVariable(Environment environment,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable) {
+ SCLValue variableParentFunction = environment.getValue(VARIABLE_PARENT);
+ return new EApply(new EConstant(variableParentFunction),
+ new EApply(new EConstant(variableParentFunction),
+ new EVariable(contextVariable)));
+ }
+
+ protected static Expression standardGetProperty(
+ Environment environment,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
+ String name,
+ Type type) {
+ return getPropertyFlexible(environment, accessInputVariable(environment, contextVariable), name, type);
+ }
+
+ @Override
+ protected Expression getVariableAccessExpression(
+ ReadGraph graph,
+ CompilationContext context,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
+ String name) throws DatabaseException {
+ ComponentTypeProperty property = context.propertyMap.get(name);
+ if(property != null)
+ return standardGetProperty(
+ context.runtimeEnvironment.getEnvironment(),
+ contextVariable,
+ name,
+ property.type == null ? Types.metaVar(Kinds.STAR) : property.type);
+ else {
+
+// if(context.propertyMap.containsKey(name)) {
+//
+// org.simantics.scl.compiler.elaboration.expressions.Variable parametersVariable = new org.simantics.scl.compiler.elaboration.expressions.Variable("context", COMMAND_CONTEXT);
+//
+// Environment environment = context.runtimeEnvironment.getEnvironment();
+//
+//// return new EApply(
+//// new EConstant(environment.getValue(FROM_DYNAMIC), Types.STRING),
+// return new EApply(
+// new EConstant(environment.getValue(CONTEXT_VARIABLE), Types.DYNAMIC),
+// new EVariable(parametersVariable),
+// new ELiteral(new StringConstant(name)));
+//
+// }
+
+ return getSpecialVariableAccessExpression(graph, context, contextVariable, name);
+
+ }
+ }
+
+ protected Expression getSpecialVariableAccessExpression(ReadGraph graph,
+ CompilationContext context,
+ org.simantics.scl.compiler.elaboration.expressions.Variable contextVariable,
+ String name) throws DatabaseException {
+ if(name.equals("input")) {
+ Environment environment = context.runtimeEnvironment.getEnvironment();
+ return accessInputVariable(environment, contextVariable);
+ } else if(name.equals("self"))
+ return new EVariable(contextVariable);
+ else
+ return null;
+ }