1 package org.simantics.scl.compiler.elaboration.expressions.list;
3 import org.simantics.scl.compiler.elaboration.contexts.SimplificationContext;
4 import org.simantics.scl.compiler.elaboration.contexts.TranslationContext;
5 import org.simantics.scl.compiler.elaboration.contexts.TypingContext;
6 import org.simantics.scl.compiler.elaboration.expressions.Expression;
7 import org.simantics.scl.compiler.errors.Locations;
8 import org.simantics.scl.compiler.types.TMetaVar;
9 import org.simantics.scl.compiler.types.Type;
10 import org.simantics.scl.compiler.types.Types;
11 import org.simantics.scl.compiler.types.exceptions.UnificationException;
12 import org.simantics.scl.compiler.types.kinds.Kinds;
14 public class ListThen extends ListQualifier {
15 public ListQualifier left;
16 public Expression transformer;
17 public Expression by; // optional
20 public ListThen(Expression transformer, Expression by) {
21 this.transformer = transformer;
25 public void setLeft(ListQualifier inner) {
30 public void checkType(TypingContext context) {
31 left.checkType(context);
33 cType = Types.metaVar(Kinds.STAR);
34 Type transformerType = Types.function(Types.list(cType), Types.list(cType));
36 by = by.checkType(context, Types.metaVar(Kinds.STAR));
37 transformerType = Types.function(Types.function(cType, by.getType()), transformerType);
39 transformer = transformer.checkType(context, transformerType);
40 if(!(Types.canonical(cType) instanceof TMetaVar)) {
41 context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
46 public CompiledQualifier compile(SimplificationContext context) {
47 CompiledQualifier q = left.compile(context);
50 Types.unify(cType, q.pattern.getType());
51 } catch (UnificationException e) {
52 context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
56 q.value = context.apply(transformer, q.value);
58 q.value = context.apply(transformer, context.lambda(q.pattern.copy(), by), q.value);
63 public void resolve(TranslationContext context) {
64 transformer = transformer.resolve(context);
65 left.resolve(context);
67 by = by.resolve(context);
71 public void setLocationDeep(long loc) {
72 if(location == Locations.NO_LOCATION) {
74 left.setLocationDeep(loc);
75 transformer.setLocationDeep(loc);
77 by.setLocationDeep(loc);
82 public void accept(ListQualifierVisitor visitor) {
87 public ListQualifier accept(ListQualifierTransformer transformer) {
88 return transformer.transform(this);