001: package jsint;
002:
003: /** Environments store mappings from symbols to locations.
004: * At compile time, we can lookup to see if a symbol names a location,
005: * and at run time we can get or set the value in a location.
006: * @author Peter Norvig, Copyright 1998, peter@norvig.com, <a href="license.txt">license</a>
007: * subsequently modified by Jscheme project members
008: * licensed under zlib licence (see license.txt)
009: **/
010:
011: public class LexicalEnvironment implements java.io.Serializable {
012:
013: /** The global environment. All info is in the Symbols themselves. **/
014: public static final LexicalEnvironment NULLENV = new LexicalEnvironment(
015: Pair.EMPTY, null, null, true);
016:
017: /** The parent LexicalEnvironment: where you look if you can't find
018: * a variable.
019: **/
020: private LexicalEnvironment parent;
021: /** A list of variables in this env. May be dotted or a lone
022: * symbol.
023: **/
024: private Object vars;
025: /** An array of values in a 1-1 correspondance with the vars. **/
026: private Object[] vals;
027:
028: private boolean isNullEnv = false;
029:
030: /** Create an LexicalEnvironment with local variables and values,
031: * and a parent LexicalEnvironment.
032: **/
033: public LexicalEnvironment(Object vars, Object[] vals,
034: LexicalEnvironment parent) {
035: this (vars, vals, parent, false);
036: }
037:
038: public LexicalEnvironment(Object vars, Object[] vals,
039: LexicalEnvironment parent, boolean isNullEnv) {
040: this .vars = vars;
041: this .vals = vals;
042: this .parent = parent;
043: this .isNullEnv = isNullEnv;
044: }
045:
046: private Object readResolve() throws java.io.ObjectStreamException {
047: return isNullEnv ? NULLENV : this ;
048: }
049:
050: public LocalVariable lookup(Symbol var) {
051: return lookup(var, 0, 0, vars);
052: }
053:
054: /** Lookup the symbol in the environment. Return either a
055: * LocalVariable a Symbol representing the global variable.
056: **/
057: public LocalVariable lookup(Symbol var, int up, int in, Object vars) {
058: if (this == NULLENV)
059: return null;
060: else if (vars == var)
061: return new LocalVariable(up, in, var);
062: else if (!U.isPair(vars))
063: return parent.lookup(var, up + 1, 0, parent.vars);
064: else if (U.first(vars) == var)
065: return new LocalVariable(up, in, var);
066: else
067: return lookup(var, up, in + 1, U.rest(vars));
068: }
069:
070: /** Get the value of the LocalVariable in this LexicalEnvironment. **/
071: public Object get(LocalVariable var) {
072: return this .up(var.up).vals[var.in];
073: }
074:
075: /** Set the value of the LocalVariable in this LexicalEnvironment to
076: * a new value.
077: **/
078: public Object set(LocalVariable var, Object newVal) {
079: return this .up(var.up).vals[var.in] = newVal;
080: }
081:
082: /** Go up a specified number of levels in the parent chain. **/
083: LexicalEnvironment up(int levels) {
084: return (levels == 0) ? this : this .parent.up(levels - 1);
085: }
086:
087: public String toString() {
088: return "{|" + toString0() + "|}";
089: }
090:
091: private String toString0() {
092: if (this == NULLENV)
093: return "";
094: else
095: return U.stringify(vars)
096: + " "
097: + U.stringify(vals)
098: + ((parent == null) ? "" : "|" + parent.toString0());
099: }
100:
101: public void show(java.io.PrintWriter s) {
102: LexicalEnvironment e = this ;
103: while (e != NULLENV) {
104: Object vars = e.vars;
105: Object[] vals = e.vals;
106: int i = 0;
107: while (U.isPair(vars)) {
108: show0(s, U.first(vars), vals[i]);
109: vars = U.rest(vars);
110: i = i + 1;
111: }
112: if (vars != Pair.EMPTY)
113: show0(s, vars, vals[i]);
114: e = e.parent;
115: }
116: }
117:
118: private static void show0(java.io.PrintWriter s, Object var,
119: Object val) {
120: String sval = showValue(val);
121: if (sval.length() > 100)
122: sval = sval.substring(0, 100) + "...";
123: s.println(" " + U.stringify(var) + " = " + sval);
124: }
125:
126: private static String showValue(Object x) {
127: if (BacktraceException.checkBacktrace()) {
128: Object btvsProc = Scheme.currentEvaluator()
129: .getInteractionEnvironment().getValue(
130: Symbol.intern("backtraceValueString"));
131: return (String) U.toProc(btvsProc).apply(
132: jscheme.JScheme.list(x));
133: } else
134: return (x == null) ? "null" : x.toString();
135: }
136: }
|