summaryrefslogtreecommitdiff
path: root/MLKEnvironment.m
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-06-15 12:48:38 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-06-15 12:48:38 +0200
commitf5348e04a2d52fbf707a7def7ebcee944795dede (patch)
tree4363b366be3ba3c3e0d6185cbd35c46a90a90410 /MLKEnvironment.m
parent77fd838075b8729e7911a522465e92eacf1e0545 (diff)
MLKDynamicContext, MLKEnvironment: Add -addBinding:, -boundp:, and -makunbound:.
Diffstat (limited to 'MLKEnvironment.m')
-rw-r--r--MLKEnvironment.m55
1 files changed, 49 insertions, 6 deletions
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);