diff options
-rw-r--r-- | GNUmakefile | 4 | ||||
-rw-r--r-- | MLKDynamicContext.h | 26 | ||||
-rw-r--r-- | MLKDynamicContext.m | 63 |
3 files changed, 91 insertions, 2 deletions
diff --git a/GNUmakefile b/GNUmakefile index 53176e7..4655041 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -18,8 +18,8 @@ include $(GNUSTEP_MAKEFILES)/common.make TOOL_NAME = etoilisp -etoilisp_OBJC_FILES = MLKCons.m MLKEnvironment.m MLKLinkedList.m \ - MLKLispValue.m MLKSymbol.m \ +etoilisp_OBJC_FILES = MLKCons.m MLKDynamicContext.m MLKEnvironment.m \ + MLKLinkedList.m MLKLispValue.m MLKSymbol.m \ MLKUndefinedVariableException.m BUNDLE_NAME = Test diff --git a/MLKDynamicContext.h b/MLKDynamicContext.h new file mode 100644 index 0000000..f515901 --- /dev/null +++ b/MLKDynamicContext.h @@ -0,0 +1,26 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Copyright 2008, Matthias Benkard. */ + +@class MLKClosure, MLKEnvironment, NSLinkedList, NSMutableDictionary, NSString; + + +@interface MLKDynamicContext +{ + MLKEnvironment *_conditionHandlers; + MLKEnvironment *_restarts; + MLKClosure *_currentConditionHandler; + MLKEnvironment *_environment; + MLKDynamicContext *_parent; +} + +-(MLKDynamicContext *) initWithParent:(MLKDynamicContext *)aContext + variables:(NSDictionary *)vars + handlers:(NSDictionary *)handlers + restarts:(NSDictionary *)restarts + currentHandler:(MLKClosure *)handler; + +-(MLKDynamicContext *) pushContext; + ++(MLKDynamicContext *) currentContext; ++(MLKDynamicContext *) popContext; +@end diff --git a/MLKDynamicContext.m b/MLKDynamicContext.m new file mode 100644 index 0000000..2d8312f --- /dev/null +++ b/MLKDynamicContext.m @@ -0,0 +1,63 @@ +/* -*- mode: objc; coding: utf-8 -*- */ +/* Copyright 2008, Matthias Benkard. */ + +#import <Foundation/NSDictionary.h> +#import <Foundation/NSArray.h> +#import <Foundation/NSThread.h> + +#import "MLKDynamicContext.h" +#import "MLKEnvironment.h" +#import "MLKLinkedList.h" + + +#define MAKE_ENVIRONMENT(variable, parent, parent_member) \ + (variable \ + ? (id) [[MLKEnvironment alloc] \ + initWithParent:(parent \ + ? (id) parent_member \ + : nil) \ + bindings:vars] \ + : (id) (parent ? (id) parent_member : nil)); + + +@implementation MLKDynamicContext +-(MLKDynamicContext *) initWithParent:(MLKDynamicContext *)aContext + variables:(NSDictionary *)vars + handlers:(NSDictionary *)handlers + restarts:(NSDictionary *)restarts + currentHandler:(MLKClosure *)handler +{ + _parent = (aContext ? aContext : [MLKDynamicContext currentContext]); + _environment = MAKE_ENVIRONMENT(vars, _parent, _parent->_environment); + _conditionHandlers = MAKE_ENVIRONMENT(handlers, + _parent, + _parent->_conditionHandlers); + _restarts = MAKE_ENVIRONMENT(restarts, _parent, _parent->_restarts); + _currentConditionHandler = (handler + ? (id) handler + : (_parent + ? (id) _parent->_currentConditionHandler + : nil)); + return self; +} + +-(MLKDynamicContext *) pushContext +{ + return [[[NSThread currentThread] threadDictionary] + objectForKey:@"MLKDynamicContext"]; +} + ++(MLKDynamicContext *) currentContext +{ + return [[[NSThread currentThread] threadDictionary] + objectForKey:@"MLKDynamicContext"]; +} + ++(MLKDynamicContext *) popContext +{ + MLKDynamicContext *context = [self currentContext]; + [[[NSThread currentThread] threadDictionary] setObject:context->_parent + forKey:@"MLKDynamicContext"]; + return context; +} +@end |