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.elaboration.expressions.Variable;
8 import org.simantics.scl.compiler.errors.Locations;
9 import org.simantics.scl.compiler.types.TMetaVar;
10 import org.simantics.scl.compiler.types.Type;
11 import org.simantics.scl.compiler.types.Types;
12 import org.simantics.scl.compiler.types.exceptions.UnificationException;
13 import org.simantics.scl.compiler.types.kinds.Kinds;
15 import gnu.trove.map.hash.TObjectIntHashMap;
16 import gnu.trove.set.hash.TIntHashSet;
18 public class ListThen extends ListQualifier {
19 public ListQualifier left;
20 public Expression transformer;
21 public Expression by; // optional
24 public ListThen(Expression transformer, Expression by) {
25 this.transformer = transformer;
29 public void setLeft(ListQualifier inner) {
34 public void checkType(TypingContext context) {
35 left.checkType(context);
37 cType = Types.metaVar(Kinds.STAR);
38 Type transformerType = Types.function(Types.list(cType), Types.list(cType));
40 by = by.checkType(context, Types.metaVar(Kinds.STAR));
41 transformerType = Types.function(Types.function(cType, by.getType()), transformerType);
43 transformer = transformer.checkType(context, transformerType);
44 if(!(Types.canonical(cType) instanceof TMetaVar)) {
45 context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
50 public void collectVars(TObjectIntHashMap<Variable> allVars,
52 left.collectVars(allVars, vars);
53 transformer.collectVars(allVars, vars);
55 by.collectVars(allVars, vars);
59 public CompiledQualifier compile(SimplificationContext context) {
60 CompiledQualifier q = left.compile(context);
63 Types.unify(cType, q.pattern.getType());
64 } catch (UnificationException e) {
65 context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
69 q.value = context.apply(transformer, q.value);
71 q.value = context.apply(transformer, context.lambda(q.pattern.copy(), by), q.value);
76 public void resolve(TranslationContext context) {
77 transformer = transformer.resolve(context);
78 left.resolve(context);
80 by = by.resolve(context);
84 public void setLocationDeep(long loc) {
85 if(location == Locations.NO_LOCATION) {
87 left.setLocationDeep(loc);
88 transformer.setLocationDeep(loc);
90 by.setLocationDeep(loc);
95 public void accept(ListQualifierVisitor visitor) {
100 public ListQualifier accept(ListQualifierTransformer transformer) {
101 return transformer.transform(this);