001: package sisc.util;
002:
003: import sisc.data.*;
004: import java.io.*;
005: import java.util.Collections;
006: import java.util.Set;
007: import java.util.HashSet;
008: import sisc.ser.Serializer;
009: import sisc.ser.Deserializer;
010: import sisc.env.SymbolicEnvironment;
011: import sisc.util.ExpressionVisitor;
012:
013: public class FreeReference implements ExpressionVisitee {
014:
015: private static Set allReferences = Collections
016: .synchronizedSet(new HashSet());
017:
018: private Symbol sym;
019: private SymbolicEnvironment senv;
020: private transient int envLoc = -1;
021:
022: public FreeReference(Symbol sym, SymbolicEnvironment senv) {
023: this .senv = senv;
024: this .sym = sym;
025: //allReferences.add(this);
026: }
027:
028: public static FreeReference[] allReferences() {
029: return (FreeReference[]) allReferences
030: .toArray(new FreeReference[] {});
031: }
032:
033: public Symbol getName() {
034: return sym;
035: }
036:
037: public void resolve() throws UndefinedVarException {
038: //this is an optimization that ensures we short-circuit
039: //any DelegatingSymEnvs
040: senv = (SymbolicEnvironment) senv.asValue();
041: envLoc = senv.getLoc(sym);
042: if (envLoc < 0)
043: throw new UndefinedVarException(sym.toString());
044: }
045:
046: public Value getValue() throws UndefinedVarException {
047: if (envLoc < 0)
048: resolve();
049: return senv.lookup(envLoc);
050: }
051:
052: public void setValue(Value v) throws UndefinedVarException {
053: if (envLoc < 0)
054: resolve();
055: senv.set(envLoc, v);
056: Util.updateName(v, sym);
057: }
058:
059: public void define(Value v) {
060: senv.define(sym, v);
061: Util.updateName(v, sym);
062: }
063:
064: public Value express() {
065: return Util.list(sym, (Value) senv);
066: }
067:
068: public void serialize(Serializer s) throws IOException {
069: s.writeExpression(sym);
070: s.writeSymbolicEnvironment(senv);
071: }
072:
073: public FreeReference() {
074: }
075:
076: public void deserialize(Deserializer s) throws IOException {
077: sym = (Symbol) s.readExpression();
078: senv = s.readSymbolicEnvironment();
079: envLoc = -1;
080: //allReferences.add(this);
081: }
082:
083: public boolean equals(Object o) {
084: if (!(o instanceof FreeReference))
085: return false;
086: FreeReference e = (FreeReference) o;
087: return sym.equals(e.sym) && senv.equals(e.senv);
088: }
089:
090: public int hashCode() {
091: return sym.hashCode() ^ senv.hashCode();
092: }
093:
094: public boolean visit(ExpressionVisitor v) {
095: return v.visit(sym) && v.visit(senv);
096: }
097:
098: }
099: /*
100: * The contents of this file are subject to the Mozilla Public
101: * License Version 1.1 (the "License"); you may not use this file
102: * except in compliance with the License. You may obtain a copy of
103: * the License at http://www.mozilla.org/MPL/
104: *
105: * Software distributed under the License is distributed on an "AS
106: * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
107: * implied. See the License for the specific language governing
108: * rights and limitations under the License.
109: *
110: * The Original Code is the Second Interpreter of Scheme Code (SISC).
111: *
112: * The Initial Developer of the Original Code is Scott G. Miller.
113: * Portions created by Scott G. Miller are Copyright (C) 2000-2007
114: * Scott G. Miller. All Rights Reserved.
115: *
116: * Contributor(s):
117: * Matthias Radestock
118: *
119: * Alternatively, the contents of this file may be used under the
120: * terms of the GNU General Public License Version 2 or later (the
121: * "GPL"), in which case the provisions of the GPL are applicable
122: * instead of those above. If you wish to allow use of your
123: * version of this file only under the terms of the GPL and not to
124: * allow others to use your version of this file under the MPL,
125: * indicate your decision by deleting the provisions above and
126: * replace them with the notice and other provisions required by
127: * the GPL. If you do not delete the provisions above, a recipient
128: * may use your version of this file under either the MPL or the
129: * GPL.
130: */
|