001: /*
002: * Environment.java
003: *
004: * Copyright (C) 2002-2003 Peter Graves
005: * $Id: Environment.java,v 1.6 2003/11/15 11:03:33 beedlem Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.lisp;
023:
024: public final class Environment extends LispObject {
025: private Binding lastBinding;
026: private Binding lastFunctionalBinding;
027:
028: private Binding blocks;
029:
030: public Environment() {
031: }
032:
033: public Environment(Environment parent) {
034: if (parent != null) {
035: this .lastBinding = parent.lastBinding;
036: this .lastFunctionalBinding = parent.lastFunctionalBinding;
037: this .blocks = parent.blocks;
038: }
039: }
040:
041: public boolean isEmpty() {
042: return (lastBinding == null && lastFunctionalBinding == null);
043: }
044:
045: public void bind(Symbol symbol, LispObject value) {
046: lastBinding = new Binding(symbol, value, lastBinding);
047: }
048:
049: public void rebind(Symbol symbol, LispObject value) {
050: Binding binding = getBinding(symbol);
051: binding.value = value;
052: }
053:
054: public LispObject lookup(LispObject symbol) {
055: Binding binding = lastBinding;
056: while (binding != null) {
057: if (binding.symbol == symbol)
058: return binding.value;
059: binding = binding.next;
060: }
061: return null;
062: }
063:
064: public Binding getBinding(LispObject symbol) {
065: Binding binding = lastBinding;
066: while (binding != null) {
067: if (binding.symbol == symbol)
068: return binding;
069: binding = binding.next;
070: }
071: return null;
072: }
073:
074: // Functional bindings.
075: public void bindFunctional(Symbol symbol, LispObject value) {
076: lastFunctionalBinding = new Binding(symbol, value,
077: lastFunctionalBinding);
078: }
079:
080: public LispObject lookupFunctional(LispObject symbol)
081: throws ConditionThrowable {
082: Binding binding = lastFunctionalBinding;
083: while (binding != null) {
084: if (binding.symbol == symbol)
085: return binding.value;
086: binding = binding.next;
087: }
088: // Not found in environment.
089: return symbol.getSymbolFunction();
090: }
091:
092: public void addBlock(LispObject tag, Block block) {
093: blocks = new Binding(tag, block, blocks);
094: }
095:
096: public Block lookupBlock(LispObject symbol) {
097: Binding binding = blocks;
098: while (binding != null) {
099: if (binding.symbol == symbol)
100: return (Block) binding.value;
101: binding = binding.next;
102: }
103: return null;
104: }
105:
106: public String toString() {
107: StringBuffer sb = new StringBuffer();
108: sb.append("#<ENVIRONMENT");
109: Binding binding = lastBinding;
110: while (binding != null) {
111: sb.append(' ');
112: sb.append(binding.symbol.getName());
113: sb.append(" = ");
114: sb.append(binding.value);
115: binding = binding.next;
116: if (binding != null)
117: sb.append(",");
118: }
119: sb.append(">");
120: return sb.toString();
121: }
122: }
|