diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/Graph.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/Graph.java deleted file mode 100644 index deb4ef115..000000000 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/Graph.java +++ /dev/null @@ -1,26 +0,0 @@ -package de.peeeq.datastructures; - -import java.util.List; -import java.util.function.Function; - -/** - * - */ -public class Graph { - private final List nodes; - private final Function> edges; - - public Graph(List nodes, Function> edges) { - this.nodes = nodes; - this.edges = edges; - } - - public List getNodes() { - return nodes; - } - - public List adjacentNodes(Node n) { - return edges.apply(n); - } - -} diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/ImmutableTree.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/ImmutableTree.java deleted file mode 100644 index 63008db27..000000000 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/ImmutableTree.java +++ /dev/null @@ -1,147 +0,0 @@ -package de.peeeq.datastructures; - -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableList.Builder; -import org.eclipse.jdt.annotation.Nullable; - -import java.util.Collections; -import java.util.Iterator; - -public class ImmutableTree implements Iterable> { - - // invariant: children == null <--> elem != null - private final @Nullable ImmutableList> children; - private final @Nullable T elem; - - private ImmutableTree(@Nullable ImmutableList> children, @Nullable T elem) { - Preconditions.checkArgument((children == null) != (elem == null)); - this.children = children; - this.elem = elem; - } - - public static ImmutableTree node(ImmutableList> children) { - return new ImmutableTree<>(children, null); - } - - public static ImmutableTree leaf(T t) { - return new ImmutableTree<>(null, t); - } - - public int size() { - ImmutableList> ch = children; - if (ch == null) { - return 1; - } else { - int size = 0; - for (ImmutableTree c : ch) { - size += c.size(); - } - return size; - } - } - - - @Override - public Iterator> iterator() { - final ImmutableList> children2 = children; - if (children2 != null) { - return children2.iterator(); - } else { - return Collections.emptyIterator(); - } - } - - public ImmutableList allValues() { - Builder b = ImmutableList.builder(); - addValues(b); - return b.build(); - } - - private void addValues(Builder<@Nullable T> b) { - ImmutableList> ch = children; - if (ch == null) { - b.add(elem); - } else { - for (ImmutableTree c : ch) { - c.addValues(b); - } - } - } - - public static ImmutableTree empty() { - return node(ImmutableList.of()); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - ImmutableList> c = children; - @Nullable T e = elem; - result = prime * result + ((c == null) ? 0 : c.hashCode()); - result = prime * result + ((e == null) ? 0 : e.hashCode()); - return result; - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - ImmutableTree other = (ImmutableTree) obj; - ImmutableList> c = children; - if (c == null) { - if (other.children != null) - return false; - } else if (!c.equals(other.children)) - return false; - @Nullable T e = elem; - if (e == null) { - return other.elem == null; - } else return e.equals(other.elem); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - ImmutableList> c = children; - if (c == null) { - sb.append("["); - sb.append(elem); - sb.append("]"); - } else { - sb.append("["); - boolean first = true; - for (ImmutableTree t : c) { - if (!first) { - sb.append(", "); - } - sb.append(t); - first = false; - } - sb.append("]"); - } - return sb.toString(); - } - - public T getOnlyEment() { - ImmutableList> ch = children; - @Nullable T el = elem; - if (el != null) { - return el; - } else if (ch != null && !ch.isEmpty()) { - return ch.get(0).getOnlyEment(); - } - throw new RuntimeException("There are " + size() + " elements in this tree."); - } - - public boolean isLeaf() { - return children == null; - } - - -} diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/IntTuple.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/IntTuple.java deleted file mode 100644 index fb1bd7441..000000000 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/datastructures/IntTuple.java +++ /dev/null @@ -1,55 +0,0 @@ -package de.peeeq.datastructures; - -import org.eclipse.jdt.annotation.Nullable; - -import java.util.Arrays; - -public class IntTuple { - private final int[] ar; - - private IntTuple(int len) { - ar = new int[len]; - } - - public static IntTuple of(int... is) { - IntTuple r = new IntTuple(is.length); - System.arraycopy(is, 0, r.ar, 0, is.length); - return r; - } - - - public int head() { - return ar[0]; - } - - public IntTuple tail() { - IntTuple r = new IntTuple(ar.length - 1); - System.arraycopy(ar, 1, r.ar, 0, ar.length - 1); - return r; - } - - - @Override - public String toString() { - return Arrays.toString(ar); - } - - @Override - public int hashCode() { - return Arrays.hashCode(ar); - } - - @Override - public boolean equals(@Nullable Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - IntTuple other = (IntTuple) obj; - return Arrays.equals(ar, other.ar); - } - - -} diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/immutablecollections/ImmutableList.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/immutablecollections/ImmutableList.java index 5fd71d212..b906944c9 100644 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/immutablecollections/ImmutableList.java +++ b/de.peeeq.wurstscript/src/main/java/de/peeeq/immutablecollections/ImmutableList.java @@ -1,40 +1,62 @@ package de.peeeq.immutablecollections; -import com.google.common.base.Preconditions; +import io.vavr.collection.List; import org.eclipse.jdt.annotation.Nullable; -import java.util.Arrays; import java.util.Iterator; -import java.util.NoSuchElementException; +import java.util.Objects; -public abstract class ImmutableList implements Iterable { +/** + * Lightweight wrapper around {@link List} to keep the existing API surface + * while using Vavr's efficient persistent list implementation. + */ +public final class ImmutableList implements Iterable { - private int hashCode = 0; + private static final ImmutableList EMPTY = new ImmutableList<>(List.empty()); + + private final List delegate; + + private ImmutableList(List delegate) { + this.delegate = delegate; + } /** * adds an element to the front of the list */ - abstract public ImmutableList appFront(T elem); + public ImmutableList appFront(T elem) { + Objects.requireNonNull(elem, "elem"); + return wrap(delegate.prepend(elem)); + } /** * adds another ImmutableList to the end */ - abstract public ImmutableList cons(ImmutableList other); - - abstract public T head(); + public ImmutableList cons(ImmutableList other) { + if (other.isEmpty()) { + return this; + } + return wrap(delegate.appendAll(other.delegate)); + } - abstract public ImmutableList tail(); + public T head() { + return delegate.head(); + } + public ImmutableList tail() { + return wrap(delegate.tail()); + } - abstract public int size(); + public int size() { + return delegate.size(); + } public boolean isEmpty() { - return size() == 0; + return delegate.isEmpty(); } public boolean contains(T elem) { for (T t : this) { - if (t.equals(elem)) { + if (Objects.equals(t, elem)) { return true; } } @@ -44,324 +66,64 @@ public boolean contains(T elem) { /** * @return an empty list */ + @SuppressWarnings("unchecked") public static ImmutableList emptyList() { - return ImmutableListEmpty.instance(); + return (ImmutableList) EMPTY; } @SafeVarargs public static ImmutableList of(T... elems) { - ImmutableList result = emptyList(); + List list = List.empty(); for (int i = elems.length - 1; i >= 0; i--) { - T elem = elems[i]; - if (elem == null) { - throw new IllegalArgumentException("Elem " + i + " is null."); - } - result = result.appFront(elem); + T elem = Objects.requireNonNull(elems[i], "Elem " + i + " is null."); + list = list.prepend(elem); } - return result; + return wrap(list); } - @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("List("); - boolean first = true; - for (T t : this) { - if (!first) { - sb.append(", "); - } - sb.append(t); - first = false; - } - sb.append(")"); - return sb.toString(); + return delegate.mkString("List(", ", ", ")"); } @Override public int hashCode() { - if (hashCode == 0) { - Object[] elements = new Object[size()]; - int i = 0; - for (T t : this) { - elements[i] = t; - i++; - } - hashCode = Arrays.hashCode(elements); - } - return hashCode; + return delegate.hashCode(); } @Override public boolean equals(@Nullable Object obj) { - if (obj instanceof ImmutableList) { - ImmutableList other = (ImmutableList) obj; - if (other.size() != size() || other.hashCode() != hashCode()) { - return false; - } - if (size() == 0) { - return true; - } - if (!other.head().equals(head())) { - return false; - } - if (size() > 1) { - return other.tail().equals(tail()); - } else { - return true; - } + if (this == obj) { + return true; + } + if (obj instanceof ImmutableList other) { + return delegate.equals(other.delegate); } return false; } public ImmutableList appBack(T elem) { - return this.cons(ImmutableList.emptyList().appFront(elem)); - } - - public abstract ImmutableList removeAll(T t); -} - - -class ImmutableListEmpty extends ImmutableList { - - private final static ImmutableList instance = new ImmutableListEmpty<>(); - - @SuppressWarnings("unchecked") - static ImmutableList instance() { - return (ImmutableList) instance; - } - - private ImmutableListEmpty() { - + Objects.requireNonNull(elem, "elem"); + return wrap(delegate.append(elem)); } - private static class MyIterator implements Iterator { - - @Override - public boolean hasNext() { - return false; - } - - @Override - public T next() { - throw new NoSuchElementException(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - - } - - @Override - public Iterator iterator() { - return new ImmutableListEmpty.MyIterator<>(); - } - - @Override - public ImmutableList appFront(T elem) { - Preconditions.checkNotNull(elem); - return new ImmutableListImpl<>(elem); - } - - @Override - public int size() { - return 0; - } - - @Override - public T head() { - throw new Error("Tried to get head of empty list"); - } - - @Override - public ImmutableList tail() { - throw new Error("Tried to get tail of empty list"); - } - - - @Override - public ImmutableList cons(ImmutableList other) { - // just return other since this list is empty - @SuppressWarnings("unchecked") // this is safe because the list is immutable - ImmutableList result = (ImmutableList) other; - return result; - } - - @Override public ImmutableList removeAll(T t) { - return this; - } - -} - - -class ImmutableListIterator implements Iterator { - private @Nullable ImmutableList pos; - - public ImmutableListIterator(ImmutableList list) { - this.pos = list; - } - - @Override - public boolean hasNext() { - ImmutableList p = pos; - return p != null && !p.isEmpty(); - } - - @Override - public T next() { - ImmutableList p = pos; - if (p == null || p.isEmpty()) { - pos = null; - throw new RuntimeException("Calling next on finished iterator."); - } else { - T res = p.head(); - pos = p.tail(); - return res; - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - -} - -class ImmutableListImpl extends ImmutableList { - - - private final T head; - private final ImmutableList tail; - private final int size; - - ImmutableListImpl(T elem) { - this.head = elem; - this.tail = ImmutableList.emptyList(); - this.size = 1; - } - - ImmutableListImpl(T head, ImmutableList tail) { - this.head = head; - this.tail = tail; - this.size = 1 + tail.size(); - } - - - @Override - public Iterator iterator() { - return new ImmutableListIterator<>(this); - } - - @Override - public ImmutableList appFront(T elem) { - Preconditions.checkNotNull(elem); - return new ImmutableListImpl<>(elem, this); - } - - @Override - public int size() { - return size; - } - - @Override - public T head() { - return head; - } - - @Override - public ImmutableList tail() { - return tail; - } - - @Override - public ImmutableList cons(ImmutableList other) { - if (other.isEmpty()) { + List filtered = delegate.filter(e -> !Objects.equals(e, t)); + if (filtered == delegate) { return this; - } else { - return new ImmutableListImplCons<>(this, other); } - } - - @Override - public ImmutableList removeAll(T t) { - if (head.equals(t)) { - return tail.removeAll(t); - } else { - return tail.removeAll(t).appFront(head); - } - } - -} - -class ImmutableListImplCons extends ImmutableList { - - - // invariant: size(left) > 0 && size(right) > 0 - - private final ImmutableList left; - private final ImmutableList right; - private final int size; - - ImmutableListImplCons(ImmutableList left, ImmutableList right) { - if (left.size() == 0) throw new IllegalArgumentException("left list is empty"); - if (right.size() == 0) throw new IllegalArgumentException("right list is empty"); - this.left = left; - this.right = right; - this.size = left.size() + right.size(); + return wrap(filtered); } @Override public Iterator iterator() { - return new ImmutableListIterator<>(this); - } - - @Override - public ImmutableList appFront(T elem) { - Preconditions.checkNotNull(elem); - return new ImmutableListImpl<>(elem, this); - } - - @Override - public ImmutableList cons(ImmutableList other) { - if (other.isEmpty()) { - return this; - } else { - return new ImmutableListImplCons<>(this, other); - } - } - - @Override - public T head() { - return left.head(); + return delegate.iterator(); } - @SuppressWarnings("unchecked") - @Override - public ImmutableList tail() { - ImmutableList leftTail = (ImmutableList) left.tail(); - if (leftTail.isEmpty()) { - return (ImmutableList) right; + private static ImmutableList wrap(List list) { + if (list.isEmpty()) { + return emptyList(); } - return new ImmutableListImplCons<>(leftTail, right); + return new ImmutableList<>(list); } - - @Override - public int size() { - return size; - } - - @SuppressWarnings("unchecked") - @Override - public ImmutableList removeAll(T t) { - ImmutableList l = left.removeAll((L) t); - ImmutableList r = right.removeAll((R) t); - if (left == l && right == r) { - return this; - } - return ((ImmutableList) l).cons(r); - } - } diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/ILconstMultiArray.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/ILconstMultiArray.java index caefd26e6..19e670264 100644 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/ILconstMultiArray.java +++ b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/ILconstMultiArray.java @@ -1,14 +1,15 @@ package de.peeeq.wurstscript.intermediatelang; -import com.google.common.collect.Maps; -import de.peeeq.datastructures.IntTuple; +import it.unimi.dsi.fastutil.ints.IntArrayList; +import it.unimi.dsi.fastutil.ints.IntList; +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; -import java.util.Map; +import java.util.Arrays; public class ILconstMultiArray extends ILconstAbstract { - private final Map contents = Maps.newHashMap(); + private final Object2ObjectOpenHashMap contents = new Object2ObjectOpenHashMap<>(); @Override @@ -21,12 +22,28 @@ public String print() { return contents.toString(); } - public ILconst get(IntTuple key) { + public ILconst get(IntList key) { return contents.get(key); } - public void set(IntTuple key, ILconst val) { - contents.put(key, val); + public ILconst get(int... key) { + return contents.get(copyKey(key)); + } + + public void set(IntList key, ILconst val) { + contents.put(copyKey(key), val); + } + + public void set(ILconst val, int... key) { + contents.put(copyKey(key), val); + } + + private static IntArrayList copyKey(IntList key) { + return new IntArrayList(key); + } + + private static IntArrayList copyKey(int... key) { + return IntArrayList.wrap(Arrays.copyOf(key, key.length)); } }