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.elaboration.expressions.VariableProcedure;
9 import org.simantics.scl.compiler.errors.Locations;
10 import org.simantics.scl.compiler.types.TMetaVar;
11 import org.simantics.scl.compiler.types.Type;
12 import org.simantics.scl.compiler.types.Types;
13 import org.simantics.scl.compiler.types.exceptions.UnificationException;
14 import org.simantics.scl.compiler.types.kinds.Kinds;
16 import gnu.trove.map.hash.TObjectIntHashMap;
17 import gnu.trove.set.hash.THashSet;
18 import gnu.trove.set.hash.TIntHashSet;
20 public class ListThen extends ListQualifier {
21 public ListQualifier left;
22 public Expression transformer;
23 public Expression by; // optional
26 public ListThen(Expression transformer, Expression by) {
27 this.transformer = transformer;
31 public void setLeft(ListQualifier inner) {
36 public void checkType(TypingContext context) {
37 left.checkType(context);
39 cType = Types.metaVar(Kinds.STAR);
40 Type transformerType = Types.function(Types.list(cType), Types.list(cType));
42 by = by.checkType(context, Types.metaVar(Kinds.STAR));
43 transformerType = Types.function(Types.function(cType, by.getType()), transformerType);
45 transformer = transformer.checkType(context, transformerType);
46 if(!(Types.canonical(cType) instanceof TMetaVar)) {
47 context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
52 public void collectRefs(TObjectIntHashMap<Object> allRefs,
54 left.collectRefs(allRefs, refs);
55 transformer.collectRefs(allRefs, refs);
57 by.collectRefs(allRefs, refs);
61 public void collectVars(TObjectIntHashMap<Variable> allVars,
63 left.collectVars(allVars, vars);
64 transformer.collectVars(allVars, vars);
66 by.collectVars(allVars, vars);
70 public void collectFreeVariables(THashSet<Variable> vars) {
71 left.collectFreeVariables(vars);
72 transformer.collectFreeVariables(vars);
74 by.collectFreeVariables(vars);
78 public CompiledQualifier compile(SimplificationContext context) {
79 CompiledQualifier q = left.compile(context);
82 Types.unify(cType, q.pattern.getType());
83 } catch (UnificationException e) {
84 context.getErrorLog().log(location, "Transformation function must be generic on list elements.");
88 q.value = context.apply(transformer, q.value);
90 q.value = context.apply(transformer, context.lambda(q.pattern.copy(), by), q.value);
95 public void resolve(TranslationContext context) {
96 transformer = transformer.resolve(context);
97 left.resolve(context);
99 by = by.resolve(context);
103 public void collectEffects(THashSet<Type> effects) {
104 left.collectEffects(effects);
105 transformer.collectEffects(effects);
107 by.collectEffects(effects);
111 public void setLocationDeep(long loc) {
112 if(location == Locations.NO_LOCATION) {
114 left.setLocationDeep(loc);
115 transformer.setLocationDeep(loc);
117 by.setLocationDeep(loc);
122 public void accept(ListQualifierVisitor visitor) {
127 public void forVariables(VariableProcedure procedure) {
128 left.forVariables(procedure);
129 transformer.forVariables(procedure);
131 by.forVariables(procedure);
135 public ListQualifier accept(ListQualifierTransformer transformer) {
136 return transformer.transform(this);