001/*
002 * Copyright (C) 2009-2011 Mathias Doenitz
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.parboiled.support;
018
019import org.parboiled.errors.GrammarException;
020
021/**
022 * A ValueStack is a stack implementation for parser values. The current state of the stack can be saved and restored
023 * with the methods {@link #takeSnapshot()} and {@link #restoreSnapshot(Object)} ()}, whose implementations should be
024 * super efficient since they are being used extensively during a parsing run. A ValueStack also serves as an Iterable
025 * over the current stack values (the values are being provided with the last value (on top of the stack) first).
026 *
027 * @param <V> the type of the value objects
028 */
029public interface ValueStack<V> extends Iterable<V> {
030
031    /**
032     * Determines whether the stack is empty.
033     *
034     * @return true if empty
035     */
036    boolean isEmpty();
037
038    /**
039     * Returns the number of elements currently on the stack.
040     *
041     * @return the number of elements
042     */
043    int size();
044
045    /**
046     * Clears all values.
047     */
048    void clear();
049
050    /**
051     * Returns an object representing the current state of the stack.
052     * This cost of running this operation is negligible and independent from the size of the stack.
053     *
054     * @return an object representing the current state of the stack
055     */
056    Object takeSnapshot();
057
058    /**
059     * Restores the stack state as previously returned by {@link #takeSnapshot()}.
060     * This cost of running this operation is negligible and independent from the size of the stack.
061     *
062     * @param snapshot a snapshot object previously returned by {@link #takeSnapshot()}
063     */
064    void restoreSnapshot(Object snapshot);
065
066    /**
067     * Pushes the given value onto the stack. Equivalent to push(0, value).
068     *
069     * @param value the value
070     */
071    void push(V value);
072
073    /**
074     * Inserts the given value a given number of elements below the current top of the stack.
075     *
076     * @param down  the number of elements to skip before inserting the value (0 being equivalent to push(value))
077     * @param value the value
078     * @throws IllegalArgumentException if the stack does not contain enough elements to perform this operation
079     */
080    void push(int down, V value);
081
082    /**
083     * Pushes all given elements onto the stack (in the order as given).
084     *
085     * @param firstValue the first value
086     * @param moreValues the other values
087     */
088    void pushAll(V firstValue, V... moreValues);
089
090    /**
091     * Pushes all given elements onto the stack (in the order as given).
092     *
093     * @param values the values
094     */
095    void pushAll(Iterable<V> values);
096
097    /**
098     * Removes the value at the top of the stack and returns it.
099     *
100     * @return the current top value
101     * @throws IllegalArgumentException if the stack is empty
102     */
103    V pop();
104
105    /**
106     * Removes the value the given number of elements below the top of the stack.
107     *
108     * @param down the number of elements to skip before removing the value (0 being equivalent to pop())
109     * @return the value
110     * @throws IllegalArgumentException if the stack does not contain enough elements to perform this operation
111     */
112    V pop(int down);
113
114    /**
115     * Returns the value at the top of the stack without removing it.
116     *
117     * @return the current top value
118     * @throws IllegalArgumentException if the stack is empty
119     */
120    V peek();
121
122    /**
123     * Returns the value the given number of elements below the top of the stack without removing it.
124     *
125     * @param down the number of elements to skip (0 being equivalent to peek())
126     * @return the value
127     * @throws IllegalArgumentException if the stack does not contain enough elements to perform this operation
128     */
129    V peek(int down);
130
131    /**
132     * Replaces the current top value with the given value. Equivalent to poke(0, value).
133     *
134     * @param value the value
135     * @throws IllegalArgumentException if the stack is empty
136     */
137    void poke(V value);
138
139    /**
140     * Replaces the element the given number of elements below the current top of the stack.
141     *
142     * @param down  the number of elements to skip before replacing the value (0 being equivalent to poke(value))
143     * @param value the value to replace with
144     * @throws IllegalArgumentException if the stack does not contain enough elements to perform this operation
145     */
146    void poke(int down, V value);
147
148    /**
149     * Duplicates the top value. Equivalent to push(peek()).
150     *
151     * @throws IllegalArgumentException if the stack is empty
152     */
153    void dup();
154
155    /**
156     * Swaps the top two stack values.
157     *
158     * @throws GrammarException
159     *          if the stack does not contain at least two elements
160     */
161    void swap();
162
163    /**
164     * Reverses the order of the top 3 stack values.
165     *
166     * @throws GrammarException
167     *          if the stack does not contain at least 3 elements
168     */
169    void swap3();
170
171    /**
172     * Reverses the order of the top 4 stack values.
173     *
174     * @throws GrammarException
175     *          if the stack does not contain at least 4 elements
176     */
177    void swap4();
178
179    /**
180     * Reverses the order of the top 5 stack values.
181     *
182     * @throws GrammarException
183     *          if the stack does not contain at least 5 elements
184     */
185    void swap5();
186
187    /**
188     * Reverses the order of the top 5 stack values.
189     *
190     * @throws GrammarException
191     *          if the stack does not contain at least 5 elements
192     */
193    void swap6();
194
195}