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 xtc.util.Utilities;
024:
025: /**
026: * Representation of a reference to a constant string. A string
027: * reference neither has a base nor an offset.
028: *
029: * @author Robert Grimm
030: * @version $Revision: 1.8 $
031: */
032: public class StringReference extends Reference {
033:
034: /** The string. */
035: private final String literal;
036:
037: /**
038: * Create a new string reference. The specified type must be a
039: * valid character type.
040: *
041: * @param literal The string literal.
042: * @param type The literal's declared type.
043: * @throws IllegalArgumentException Signals that the type is not a
044: * string type.
045: */
046: public StringReference(String literal, Type type) {
047: super (type);
048: this .literal = literal;
049:
050: // Validate the type.
051: /*
052: if ((! this.type.isCString()) && (! this.type.isWideCString())) {
053: throw new IllegalArgumentException("not a C string");
054: }
055: */
056: normalize();
057: }
058:
059: public boolean isString() {
060: return true;
061: }
062:
063: /**
064: * Get this string reference's literal.
065: *
066: * @return The literal.
067: */
068: public String getLiteral() {
069: return literal;
070: }
071:
072: public boolean isConstant() {
073: return true;
074: }
075:
076: public int hashCode() {
077: return literal.hashCode();
078: }
079:
080: public boolean equals(Object o) {
081: if (this == o)
082: return true;
083: if (!(o instanceof StringReference))
084: return false;
085: StringReference other = (StringReference) o;
086: return (this .type.equals(other.type) && this .literal
087: .equals(other.literal));
088: }
089:
090: public void write(Appendable out) throws IOException {
091: // If the type is not a character, we assume it's a wide character.
092: if (type.hasTag(Type.Tag.INTEGER)) {
093: switch (type.resolve().toInteger().getKind()) {
094: default:
095: out.append('L');
096: break;
097: case CHAR:
098: case S_CHAR:
099: case U_CHAR:
100: // Nothing to do.
101: }
102: }
103:
104: out.append('"');
105: Utilities.escape(literal, out, Utilities.C_ESCAPES);
106: out.append('"');
107: }
108:
109: }
|