/* This file is part of jpcsp. Jpcsp is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Jpcsp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Jpcsp. If not, see <http://www.gnu.org/licenses/>. */ package jpcsp.format.rco.vsmx.interpreter; public class VSMXArray extends VSMXObject { private static final String className = "Array"; private int length; public VSMXArray(VSMXInterpreter interpreter) { super(interpreter, className); } public VSMXArray(VSMXInterpreter interpreter, int size) { super(interpreter, className); if (size > 0) { length = size; for (int i = 0; i < size; i++) { create(i); } } } public int getLength() { return length; } private void create(int index) { super.setPropertyValue(Integer.toString(index), VSMXUndefined.singleton); } private void delete(int index) { super.deletePropertyValue(Integer.toString(index)); } private void updateLength(int index) { if (index >= length) { for (int i = length; i <= index; i++) { create(i); } length = index + 1; } } @Override public VSMXBaseObject getPropertyValue(String name) { if (lengthName.equals(name)) { return new VSMXNumber(interpreter, length); } int index = getIndex(name); if (index >= 0) { return getPropertyValue(index); } return super.getPropertyValue(name); } @Override public void setPropertyValue(String name, VSMXBaseObject value) { if (lengthName.equals(name)) { int newLength = value.getIntValue(); if (newLength > length) { for (int i = length; i < newLength; i++) { create(i); } } else if (newLength < length) { for (int i = newLength; i < length; i++) { delete(i); } } return; } int index = getIndex(name); if (index >= 0) { setPropertyValue(index, value); } else { super.setPropertyValue(name, value); } } @Override public void deletePropertyValue(String name) { if (lengthName.equals(name)) { // Cannot delete "length" property return; } int index = getIndex(name); if (index >= 0) { deletePropertyValue(index); } else { super.deletePropertyValue(name); } } @Override public VSMXBaseObject getPropertyValue(int index) { if (index < 0) { return VSMXUndefined.singleton; } updateLength(index); return super.getPropertyValue(Integer.toString(index)); } @Override public void setPropertyValue(int index, VSMXBaseObject value) { if (index >= 0) { updateLength(index); super.setPropertyValue(Integer.toString(index), value); } } @Override public void deletePropertyValue(int index) { if (index >= 0) { if (index == length - 1) { // Deleting the last element of the array? delete(index); length = index; } else if (index < length) { // Deleting in the middle of the array? create(index); } } } @Override public boolean hasPropertyValue(String name) { if (lengthName.equals(name)) { return true; } return super.hasPropertyValue(name); } @Override public boolean getBooleanValue() { // "if" on an empty array seems to return false. E.g. // x = {}; // if (x) { notexecuted; } return length > 0; } @Override public String toString() { StringBuilder s = new StringBuilder(); s.append(String.format("[length=%d", length)); toString(s); s.append("]"); return s.toString(); } @Override public boolean equals(VSMXBaseObject value) { if (value instanceof VSMXArray) { // Empty arrays are always equal if (getLength() == 0 && ((VSMXArray) value).getLength() == 0) { return true; } } return super.equals(value); } }