001package jmri.jmrit.logixng.implementation;
002
003import jmri.InstanceManager;
004import jmri.jmrit.logixng.*;
005
006/**
007 * The default implementation of a NamedTable
008 *
009 * @author Daniel Bergqvist 2018
010 */
011public class DefaultStack implements Stack {
012
013    static final int INITIAL_SIZE = 100;
014    static final int GROW_SIZE = 100;
015
016    int _size;
017    int _count;
018
019    private ValueAndType[] _stack = new ValueAndType[INITIAL_SIZE];
020
021    /** {@inheritDoc} */
022    @Override
023    public void push(ValueAndType valueAndType) {
024        if (_count+1 >= _size) {
025            ValueAndType[] newStack = new ValueAndType[_size + GROW_SIZE];
026            System.arraycopy(_stack, 0, newStack, 0, _size);
027            _stack = newStack;
028            _size += GROW_SIZE;
029        }
030        _stack[_count++] = valueAndType;
031    }
032
033    /** {@inheritDoc} */
034    @Override
035    public Object pop() {
036        if (_count <= 0) throw new ArrayIndexOutOfBoundsException("Stack is empty");
037        return _stack[--_count]._value;
038    }
039
040    /** {@inheritDoc} */
041    @Override
042    public Object getValueAtIndex(int index) {
043        return _stack[index]._value;
044    }
045
046    /** {@inheritDoc} */
047    @Override
048    public void setValueAtIndex(int index, Object value) {
049        LogixNGPreferences prefs = InstanceManager.getDefault(LogixNGPreferences.class);
050        if (prefs.getStrictTypingLocalVariables()) {
051            _stack[index]._value = SymbolTable.validateStrictTyping(
052                    _stack[index]._type, _stack[index]._value, value);
053        } else {
054            _stack[index]._value = value;
055        }
056    }
057
058    /** {@inheritDoc} */
059    @Override
060    public ValueAndType getValueAndTypeAtIndex(int index) {
061        return _stack[index];
062    }
063
064    /** {@inheritDoc} */
065    @Override
066    public void setValueAndTypeAtIndex(int index, ValueAndType valueAndType) {
067        _stack[index] = valueAndType;
068    }
069
070    /** {@inheritDoc} */
071    @Override
072    public int getCount() {
073        return _count;
074    }
075
076    /** {@inheritDoc} */
077    @Override
078    public void setCount(int newCount) {
079        if ((newCount < 0) || (newCount > _count)) throw new IllegalArgumentException("newCount has invalid value: " + Integer.toString(newCount));
080        _count = newCount;
081    }
082
083}