summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/bjc/esodata/Stack.java274
1 files changed, 197 insertions, 77 deletions
diff --git a/src/main/java/bjc/esodata/Stack.java b/src/main/java/bjc/esodata/Stack.java
index f28e882..1a15764 100644
--- a/src/main/java/bjc/esodata/Stack.java
+++ b/src/main/java/bjc/esodata/Stack.java
@@ -47,18 +47,6 @@ public abstract class Stack<T> {
public abstract void push(T elm);
/**
- * Push multiple elements onto the stack.
- *
- * @param elms
- * The elements to insert.
- */
- public void pushAll(T... elms) {
- for (T elm : elms) {
- push(elm);
- }
- }
-
- /**
* Pop an element off of the stack.
*
* @return The element on top of the stack.
@@ -99,6 +87,70 @@ public abstract class Stack<T> {
}
/*
+ * Multi-item add/remove.
+ */
+
+ /**
+ * Push multiple elements onto the stack.
+ *
+ * @param elms
+ * The elements to insert.
+ */
+ public void pushAll(T... elms) {
+ for (T elm : elms) {
+ push(elm);
+ }
+ }
+
+ /**
+ * Push multiple elements onto the stack.
+ *
+ * @param elms
+ * The elements to insert.
+ */
+ public void pushAll(List<T> elms) {
+ for (T elm : elms) {
+ push(elm);
+ }
+ }
+
+ /**
+ * Pop n items off of the stack and return them.
+ *
+ * @param n
+ * The number of items to pop off of the stack.
+ *
+ * @return A list of the popped items, in the order they were popped.
+ */
+ public List<T> multipop(int n) {
+ List<T> lst = new LinkedList<>();
+
+ for (int i = 0; i < n; n++) {
+ lst.add(pop());
+ }
+
+ return lst;
+ }
+
+ /**
+ * Pop n items off of the stack and return them.
+ *
+ * @param n
+ * The number of items to pop off of the stack.
+ *
+ * @return A list of the popped items, in the reverse order they were popped.
+ */
+ public List<T> multipoprev(int n) {
+ LinkedList<T> lst = new LinkedList<>();
+
+ for (int i = 0; i < n; i++) {
+ lst.addFirst(pop());
+ }
+
+ return lst;
+ }
+
+ /*
* Basic combinators
*/
@@ -148,16 +200,10 @@ public abstract class Stack<T> {
* The number of times to duplicate items.
*/
public void multidup(final int n, final int m) {
- final List<T> lst = new ArrayList<>(n);
-
- for(int i = n; i > 0; i--) {
- lst.add(0, pop());
- }
+ List<T> lst = multipoprev(n);
for(int i = 0; i <= m; i++) {
- for(final T elm : lst) {
- push(elm);
- }
+ pushAll(lst);
}
}
@@ -186,23 +232,18 @@ public abstract class Stack<T> {
* The number of times to duplicate items.
*/
public void multiover(final int n, final int m) {
- final List<T> lst = new ArrayList<>(n);
+ T elm = pop();
- final T elm = pop();
-
- for(int i = n; i > 0; i--) {
- lst.set(i - 1, pop());
- }
+ List<T> lst = multipoprev(n);
for(final T nelm : lst) {
push(nelm);
}
+
push(elm);
- for(int i = 1; i < m; i++) {
- for(final T nelm : lst) {
- push(nelm);
- }
+ for(int i = 0; i < m; i++) {
+ pushAll(lst);
}
}
@@ -213,7 +254,7 @@ public abstract class Stack<T> {
* The number of items to duplicate.
*/
public void over(final int n) {
- multiover(n, 2);
+ multiover(n, 1);
}
/** Duplicate the second item in the stack. */
@@ -233,13 +274,44 @@ public abstract class Stack<T> {
push(x);
}
+ /**
+ * Rotate the n items m deep on the stack i positions.
+ *
+ * @param n
+ * The number of items to rotate.
+ * @param m
+ * The number of positions the item is down in the stack.
+ * @param i
+ * The number of steps to rotate. Pass a negative number to rotate things in the opposite
+ * direction.
+ */
+ public void deepmultirot(int n, int m, int i) {
+ List<T> kep = multipoprev(m);
+
+ List<T> lst = multipoprev(n);
+
+ Collections.rotate(lst, i);
+
+ pushAll(lst);
+ pushAll(kep);
+ }
+
+ /**
+ * Rotate the n items on top of the stack i positions.
+ *
+ * @param n
+ * The number of items to rotate.
+ * @param i
+ * The number of steps to rotate. Pass a negative number to rotate things in the opposite
+ * direction.
+ */
+ public void multirot(int n, int i) {
+ deepmultirot(n, 0, i);
+ }
+
/** Swap the top two items on the stack. */
public void swap() {
- final T y = pop();
- final T x = pop();
-
- push(y);
- push(x);
+ multirot(2, 1);
}
/** Duplicate the second item below the first item. */
@@ -254,16 +326,12 @@ public abstract class Stack<T> {
/** Swap the second and third items in the stack. */
public void deepswap() {
- final T z = pop();
- final T y = pop();
- final T x = pop();
-
- push(y);
- push(x);
- push(z);
+ deepmultirot(2, 1, 1);
}
- /** Rotate the top three items on the stack */
+ /**
+ * Rotate the top three items on the stack
+ */
public void rot() {
final T z = pop();
final T y = pop();
@@ -286,10 +354,6 @@ public abstract class Stack<T> {
}
/*
- * :StackCombinators Add a general rotate/roll operator.
- */
-
- /*
* Dataflow Combinators
*/
@@ -303,17 +367,11 @@ public abstract class Stack<T> {
* The action to hide the elements from
*/
public void dip(final int n, final Consumer<Stack<T>> action) {
- final List<T> elms = new ArrayList<>(n);
-
- for(int i = n; i > 0; i--) {
- elms.set(i - 1, pop());
- }
+ List<T> elms = multipoprev(n);
action.accept(this);
- for(final T elm : elms) {
- push(elm);
- }
+ pushAll(elms);
}
/**
@@ -337,14 +395,23 @@ public abstract class Stack<T> {
* The action to execute.
*/
public void keep(final int n, final Consumer<Stack<T>> action) {
- /*
- * @NOTE Is this correct?
- */
dup(n);
+
dip(n, action);
}
/**
+ * Copy the first element on the stack, replacing them once an action
+ * is done.
+ *
+ * @param action
+ * The action to execute.
+ */
+ public void keep(final Consumer<Stack<T>> action) {
+ keep(1, action);
+ }
+
+ /**
* Apply all the actions in a list to the top n elements of the stack.
*
* @param n
@@ -354,16 +421,29 @@ public abstract class Stack<T> {
* The actions to execute.
*/
public void multicleave(final int n, final List<Consumer<Stack<T>>> actions) {
- final List<T> elms = new ArrayList<>(n);
+ List<T> elms = multipoprev(n);
- for(int i = n; i > 0; i--) {
- elms.set(i - 1, pop());
+ for(final Consumer<Stack<T>> action : actions) {
+ pushAll(elms);
+
+ action.accept(this);
}
+ }
+
+ /**
+ * Apply all the actions in a list to the top n elements of the stack.
+ *
+ * @param n
+ * The number of elements to give to cons.
+ *
+ * @param actions
+ * The actions to execute.
+ */
+ public void multicleave(final int n, final Consumer<Stack<T>>... actions) {
+ List<T> elms = multipoprev(n);
for(final Consumer<Stack<T>> action : actions) {
- for(final T elm : elms) {
- push(elm);
- }
+ pushAll(elms);
action.accept(this);
}
@@ -380,6 +460,16 @@ public abstract class Stack<T> {
}
/**
+ * Apply all the actions in a list to the top element of the stack.
+ *
+ * @param actions
+ * The actions to execute.
+ */
+ public void cleave(final Consumer<Stack<T>>... actions) {
+ multicleave(1, actions);
+ }
+
+ /**
* Apply every action in a list of actions to n arguments.
*
* @param n
@@ -389,26 +479,45 @@ public abstract class Stack<T> {
* The actions to execute.
*/
public void multispread(final int n, final List<Consumer<Stack<T>>> actions) {
- final List<List<T>> nelms = new ArrayList<>(actions.size());
+ List<List<T>> nelms = new LinkedList<>();
+
+ for (int i = 0; i < actions.size(); i++) {
+ List<T> elms = multipoprev(n);
+
+ nelms.add(elms);
+ }
+
+ Iterator<Consumer<Stack<T>>> itr = actions.iterator();
+ for(final List<T> elms : nelms) {
+ pushAll(elms);
+
+ itr.next().accept(this);
+ }
+ }
- for(int i = actions.size(); i > 0; i--) {
- final List<T> elms = new ArrayList<>(n);
+ /**
+ * Apply every action in a list of actions to n arguments.
+ *
+ * @param n
+ * The number of parameters each action takes.
+ *
+ * @param actions
+ * The actions to execute.
+ */
+ public void multispread(final int n, final Consumer<Stack<T>>... actions) {
+ List<List<T>> nelms = new LinkedList<>();
- for(int j = n; j > 0; j--) {
- elms.set(j, pop());
- }
+ for (int i = 0; i < actions.length; i++) {
+ List<T> elms = multipoprev(n);
- nelms.set(i, elms);
+ nelms.add(elms);
}
int i = 0;
for(final List<T> elms : nelms) {
- for(final T elm : elms) {
- push(elm);
- }
+ pushAll(elms);
- actions.get(i).accept(this);
- i += 1;
+ actions[i++].accept(this);
}
}
@@ -424,6 +533,17 @@ public abstract class Stack<T> {
}
/**
+ * Apply the actions in a list of actions to corresponding elements from
+ * the stack.
+ *
+ * @param conses
+ * The actions to execute.
+ */
+ public void spread(final Consumer<Stack<T>>... conses) {
+ multispread(1, conses);
+ }
+
+ /**
* Apply an action to the first m groups of n arguments.
*
* @param n