001: /*
002: * xtc - The eXTensible Compiler
003: * Copyright (C) 2006-2007 Robert Grimm
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License
007: * version 2 as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU General Public License for more details.
013: *
014: * You should have received a copy of the GNU General Public License
015: * along with this program; if not, write to the Free Software
016: * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
017: * USA.
018: */
019: package xtc.type;
020:
021: import java.io.IOException;
022:
023: import java.math.BigInteger;
024:
025: /**
026: * Representation of an index reference.
027: *
028: * @author Robert Grimm
029: * @version $Revision: 1.7 $
030: */
031: public class IndexReference extends RelativeReference {
032:
033: /** The index. */
034: final BigInteger index;
035:
036: /**
037: * Create a new index reference.
038: *
039: * @param base The base reference.
040: * @param index The index.
041: */
042: public IndexReference(Reference base, BigInteger index) {
043: super (base.type, base);
044: this .index = index;
045: }
046:
047: /**
048: * Create a new index reference.
049: *
050: * @param type The type.
051: * @param base The base.
052: * @param index The index.
053: */
054: IndexReference(Type type, Reference base, BigInteger index) {
055: super (type, base);
056: this .index = index;
057: }
058:
059: public boolean isNull() {
060: return 0 == index.signum() ? base.isNull() : false;
061: }
062:
063: public boolean hasIndex() {
064: return true;
065: }
066:
067: public BigInteger getIndex() {
068: return index;
069: }
070:
071: public boolean hasLocation() {
072: return base.hasLocation();
073: }
074:
075: public BigInteger getLocation() {
076: if (base.isNull()) {
077: return index;
078: } else if (base.hasLocation()) {
079: return base.getLocation().add(index);
080: } else {
081: return super .getLocation();
082: }
083: }
084:
085: public Reference add(BigInteger val) {
086: if (val.signum() == 0) {
087: return this ;
088: } else {
089: return new IndexReference(type, base, index.add(val));
090: }
091: }
092:
093: public Reference subtract(BigInteger val) {
094: if (val.signum() == 0) {
095: return this ;
096: } else {
097: return new IndexReference(type, base, index.subtract(val));
098: }
099: }
100:
101: public int hashCode() {
102: return index.hashCode();
103: }
104:
105: public boolean equals(Object o) {
106: if (this == o)
107: return true;
108: if (!(o instanceof IndexReference))
109: return false;
110: IndexReference other = (IndexReference) o;
111: return (this .index.equals(other.index)
112: && this .base.equals(other.base) && this .type
113: .equals(other.type));
114: }
115:
116: /** The minimum limit for decimal printouts. */
117: private static final BigInteger MIN = BigInteger.valueOf(-255);
118:
119: /** The maximum limit for decimal printouts. */
120: private static final BigInteger MAX = BigInteger.valueOf(255);
121:
122: public void write(Appendable out) throws IOException {
123: if (base.isPrefix())
124: out.append('(');
125: base.write(out);
126: if (base.isPrefix())
127: out.append(')');
128: out.append('[');
129: if ((MIN.compareTo(index) <= 0) && (index.compareTo(MAX) <= 0)) {
130: out.append(index.toString());
131: } else if (-1 == index.signum()) {
132: out.append("-0x");
133: out.append(index.negate().toString(16));
134: } else {
135: out.append("0x");
136: out.append(index.toString(16));
137: }
138: out.append(']');
139: }
140:
141: }
|