summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MLKDynamicContext.h5
-rw-r--r--MLKDynamicContext.m15
-rw-r--r--MLKEnvironment.h6
-rw-r--r--MLKEnvironment.m55
4 files changed, 75 insertions, 6 deletions
diff --git a/MLKDynamicContext.h b/MLKDynamicContext.h
index 0bfac44..c6df58f 100644
--- a/MLKDynamicContext.h
+++ b/MLKDynamicContext.h
@@ -47,9 +47,14 @@
-(id) findRestart:(MLKSymbol *)symbol;
-(id) findHandler:(MLKSymbol *)symbol;
-(id) findCatchTag:(MLKSymbol *)symbol;
+
-(id) valueForBinding:(MLKSymbol *)symbol;
-(void) setValue:(id)value forBinding:(MLKSymbol *)symbol;
-(void) addValue:(id)value forBinding:(MLKSymbol *)symbol;
+-(void) addBinding:(MLKSymbol *)symbol;
+
+-(BOOL) boundp:(MLKSymbol *)symbol;
+-(void) makunbound:(MLKSymbol *)symbol;
-(void) dealloc;
@end
diff --git a/MLKDynamicContext.m b/MLKDynamicContext.m
index 9b61bb6..5b44db7 100644
--- a/MLKDynamicContext.m
+++ b/MLKDynamicContext.m
@@ -157,6 +157,21 @@
[[self environment] addValue:value forBinding:symbol];
}
+-(void) addBinding:(MLKSymbol *)symbol
+{
+ [[self environment] addBinding:symbol];
+}
+
+-(BOOL) boundp:(MLKSymbol *)symbol
+{
+ return [[self environment] boundp:symbol];
+}
+
+-(void) makunbound:(MLKSymbol *)symbol
+{
+ [[self environment] makunbound:symbol];
+}
+
-(void) dealloc
{
RELEASE (_conditionHandlers);
diff --git a/MLKEnvironment.h b/MLKEnvironment.h
index 20cf7ce..b1f8feb 100644
--- a/MLKEnvironment.h
+++ b/MLKEnvironment.h
@@ -27,6 +27,8 @@
NSMutableDictionary *_bindings;
}
++(void) initialize;
+
-(MLKEnvironment *) init;
-(MLKEnvironment *) initWithParent:(MLKEnvironment *)parent;
-(MLKEnvironment *) initWithBindings:(NSDictionary *)bindings;
@@ -34,6 +36,7 @@
-(MLKEnvironment *) parent;
+-(void) addBinding:(MLKSymbol *)symbol;
-(void) addBindings:(NSDictionary *)bindings;
-(void) addValue:(id)value forBinding:(MLKSymbol *)symbol;
-(void) setValue:(id)value forBinding:(MLKSymbol *)symbol;
@@ -45,5 +48,8 @@
-(void) setBinding:(MLKSymbol *)symbol to:(id)value inEnvironment:(MLKEnvironment *)env;
-(id) valueForBinding:(MLKSymbol *)symbol inEnvironment:(MLKEnvironment *)env;
+-(BOOL) boundp:(MLKSymbol *)symbol;
+-(void) makunbound:(MLKSymbol *)symbol;
+
-(void) dealloc;
@end
diff --git a/MLKEnvironment.m b/MLKEnvironment.m
index 8c26519..8488dd2 100644
--- a/MLKEnvironment.m
+++ b/MLKEnvironment.m
@@ -16,14 +16,23 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#import <Foundation/NSDictionary.h>
#import <Foundation/NSArray.h>
+#import <Foundation/NSDictionary.h>
+#import <Foundation/NSNull.h>
#import "MLKEnvironment.h"
#import "MLKUndefinedVariableException.h"
+static id UNBOUND;
+
+
@implementation MLKEnvironment
++(void) initialize
+{
+ UNBOUND = [[NSObject alloc] init];
+}
+
-(MLKEnvironment *) init
{
return [self initWithParent:nil bindings:nil];
@@ -60,7 +69,7 @@
-(void) setBinding:(MLKSymbol *)symbol to:(id)value inEnvironment:(MLKEnvironment *)env
{
- if ([[_bindings allKeys] containsObject:symbol])
+ if ([_bindings objectForKey:symbol])
[_bindings setObject:value forKey:symbol];
else
if (_parent)
@@ -78,8 +87,18 @@
-(id) valueForBinding:(MLKSymbol *)symbol inEnvironment:(MLKEnvironment *)env
{
- if ([[_bindings allKeys] containsObject:symbol])
- return [_bindings objectForKey:symbol];
+ id value;
+ if ((value = [_bindings objectForKey:symbol]))
+ {
+ if (value == [NSNull null])
+ return nil;
+ else if (value == UNBOUND)
+ [[[MLKUndefinedVariableException alloc] initWithEnvironment:env
+ variableName:symbol]
+ raise];
+ else
+ return value;
+ }
else
if (_parent)
return [_parent valueForBinding:symbol];
@@ -87,7 +106,7 @@
[[[MLKUndefinedVariableException alloc] initWithEnvironment:env
variableName:symbol]
raise];
-
+
return nil; // avoid a stupid compiler warning
}
@@ -101,9 +120,14 @@
[_bindings setObject:value forKey:symbol];
}
+-(void) addBinding:(MLKSymbol *)symbol
+{
+ [_bindings setObject:UNBOUND forKey:symbol];
+}
+
-(MLKEnvironment *) environmentForBinding:(MLKSymbol *)symbol
{
- if ([[_bindings allKeys] containsObject:symbol])
+ if ([_bindings objectForKey:symbol])
return self;
else if (_parent)
return [_parent environmentForBinding:symbol];
@@ -111,6 +135,25 @@
return nil;
}
+-(BOOL) boundp:(MLKSymbol *)symbol
+{
+ id value;
+ if ((value = [_bindings objectForKey:symbol]))
+ return (value != UNBOUND);
+ else if (_parent)
+ return [_parent boundp:symbol];
+ else
+ return NO;
+}
+
+-(void) makunbound:(MLKSymbol *)symbol
+{
+ if ([_bindings objectForKey:symbol])
+ [_bindings setObject:UNBOUND forKey:symbol];
+ else if (_parent)
+ return [_parent makunbound:symbol];
+}
+
-(void) dealloc
{
RELEASE (_bindings);