X-Git-Url: https://gerrit.simantics.org/r/gitweb?a=blobdiff_plain;f=bundles%2Forg.simantics.scl.compiler%2Fsrc%2Forg%2Fsimantics%2Fscl%2Fcompiler%2Finternal%2Felaboration%2Fconstraints%2FInstanceTree.java;h=e36d0fe18a7e8249a77e087c65c3aac6cfbe8b7b;hb=0861b325fcbbfa8c5985f1e11cfc39154a3808d1;hp=871fc012517df58faae3027ea43ed47ecd4ccac3;hpb=eecd74faded034bd067094b42bbac0d286d8d9fa;p=simantics%2Fplatform.git diff --git a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java index 871fc0125..e36d0fe18 100644 --- a/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java +++ b/bundles/org.simantics.scl.compiler/src/org/simantics/scl/compiler/internal/elaboration/constraints/InstanceTree.java @@ -1,124 +1,124 @@ -package org.simantics.scl.compiler.internal.elaboration.constraints; - -import java.util.ArrayList; - -import org.simantics.scl.compiler.types.TApply; -import org.simantics.scl.compiler.types.TCon; -import org.simantics.scl.compiler.types.Type; -import org.simantics.scl.compiler.types.Types; -import org.simantics.scl.compiler.types.util.MultiApply; - -import gnu.trove.map.hash.THashMap; -import gnu.trove.procedure.TObjectObjectProcedure; - -public class InstanceTree { - - Node root; - - private static interface Node { - T get(ArrayList types); - } - - private static class SplitNode implements Node { - int pId; - THashMap> map; - Node alternative; - - public SplitNode(int pId, THashMap> map, Node alternative) { - this.pId = pId; - this.map = map; - this.alternative = alternative; - } - - @Override - public T get(ArrayList types) { - MultiApply apply = Types.matchApply(types.get(pId)); - Node node = map.get(apply.constructor); - if(node == null) - return null; - for(Type parameter : apply.parameters) - types.add(parameter); - return node.get(types); - } - } - - private static class Entry { - Type[] types; - T value; - } - - private static boolean isIndexable(Type type) { - type = Types.canonical(type); - while(true) { - if(type instanceof TCon) - return true; - else if(type instanceof TApply) - type = Types.canonical(((TApply)type).function); - else - return false; - } - } - - private static int choosePId(ArrayList> entries) { - int arity = entries.get(0).types.length; - if(arity == 1) - return 0; - int[] indexableCount = new int[arity]; - for(Entry entry : entries) - for(int i=0;i bestIndexableCount) { - bestIndexableCount = indexableCount[i]; - bestPId = i; - } - return bestPId; - } - - private static Node create(ArrayList> entries) { - int pId = choosePId(entries); - THashMap>> map1 = new THashMap>>(); - ArrayList> otherEntries = new ArrayList>(); - for(Entry entry : entries) { - Type[] types = entry.types; - Type type = types[pId]; - MultiApply apply = Types.matchApply(type); - if(apply.constructor instanceof TCon) { - ArrayList> l = map1.get((TCon)apply.constructor); - if(l == null) { - l = new ArrayList>(); - map1.put((TCon)apply.constructor, l); - } - Type[] newTypes = new Type[types.length-1+apply.parameters.length]; - int j=0; - for(int i=0;i> map = new THashMap>(); - map1.forEachEntry(new TObjectObjectProcedure>>() { - @Override - public boolean execute(TCon a, ArrayList> b) { - map.put(a, create(b)); - return true; - } - }); - return new SplitNode(pId, map, create(otherEntries)); - } - - public T get(ArrayList types) { - return root.get(types); - } -} +package org.simantics.scl.compiler.internal.elaboration.constraints; + +import java.util.ArrayList; + +import org.simantics.scl.compiler.types.TApply; +import org.simantics.scl.compiler.types.TCon; +import org.simantics.scl.compiler.types.Type; +import org.simantics.scl.compiler.types.Types; +import org.simantics.scl.compiler.types.util.MultiApply; + +import gnu.trove.map.hash.THashMap; +import gnu.trove.procedure.TObjectObjectProcedure; + +public class InstanceTree { + + Node root; + + private static interface Node { + T get(ArrayList types); + } + + private static class SplitNode implements Node { + int pId; + THashMap> map; + Node alternative; + + public SplitNode(int pId, THashMap> map, Node alternative) { + this.pId = pId; + this.map = map; + this.alternative = alternative; + } + + @Override + public T get(ArrayList types) { + MultiApply apply = Types.matchApply(types.get(pId)); + Node node = map.get(apply.constructor); + if(node == null) + return null; + for(Type parameter : apply.parameters) + types.add(parameter); + return node.get(types); + } + } + + private static class Entry { + Type[] types; + T value; + } + + private static boolean isIndexable(Type type) { + type = Types.canonical(type); + while(true) { + if(type instanceof TCon) + return true; + else if(type instanceof TApply) + type = Types.canonical(((TApply)type).function); + else + return false; + } + } + + private static int choosePId(ArrayList> entries) { + int arity = entries.get(0).types.length; + if(arity == 1) + return 0; + int[] indexableCount = new int[arity]; + for(Entry entry : entries) + for(int i=0;i bestIndexableCount) { + bestIndexableCount = indexableCount[i]; + bestPId = i; + } + return bestPId; + } + + private static Node create(ArrayList> entries) { + int pId = choosePId(entries); + THashMap>> map1 = new THashMap>>(); + ArrayList> otherEntries = new ArrayList>(); + for(Entry entry : entries) { + Type[] types = entry.types; + Type type = types[pId]; + MultiApply apply = Types.matchApply(type); + if(apply.constructor instanceof TCon) { + ArrayList> l = map1.get((TCon)apply.constructor); + if(l == null) { + l = new ArrayList>(); + map1.put((TCon)apply.constructor, l); + } + Type[] newTypes = new Type[types.length-1+apply.parameters.length]; + int j=0; + for(int i=0;i> map = new THashMap>(); + map1.forEachEntry(new TObjectObjectProcedure>>() { + @Override + public boolean execute(TCon a, ArrayList> b) { + map.put(a, create(b)); + return true; + } + }); + return new SplitNode(pId, map, create(otherEntries)); + } + + public T get(ArrayList types) { + return root.get(types); + } +}