summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile4
-rw-r--r--MLKDynamicContext.h26
-rw-r--r--MLKDynamicContext.m63
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