summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-07-07 19:25:37 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-07-07 19:25:37 +0200
commit3e9ae8c764257f14132b490531e63e4ba64dbe55 (patch)
treea7b8ad17549022f534faec24e49a2e0713b1ed3c
parentfec4301cb589a380c5a5faaca2dcf23f42bd9195 (diff)
Interpreter: Implement CATCH and THROW.
-rw-r--r--MLKInterpreter.m67
-rw-r--r--MLKPackage.m2
2 files changed, 69 insertions, 0 deletions
diff --git a/MLKInterpreter.m b/MLKInterpreter.m
index 37d4523..918aa1a 100644
--- a/MLKInterpreter.m
+++ b/MLKInterpreter.m
@@ -28,6 +28,7 @@
#import "MLKReader.h"
#import "MLKRoot.h"
#import "MLKSymbol.h"
+#import "NSObject-MLKPrinting.h"
#import "runtime-compatibility.h"
#import "util.h"
@@ -163,6 +164,44 @@ static MLKSymbol *_LAMBDA;
? (id)[rest array]
: (id)[NSArray array])];
}
+ else if (car == CATCH)
+ {
+ id catchTag;
+ NSArray *values;
+
+ NS_DURING
+ {
+ catchTag = denullify([[self eval:[[program cdr] car]
+ inLexicalContext:context
+ withEnvironment:lexenv]
+ objectAtIndex:0]);
+
+ values = [self eval:[MLKCons cons:PROGN with:[[program cdr] cdr]]
+ inLexicalContext:context
+ withEnvironment:lexenv];
+
+ NS_VALUERETURN (values, NSArray *);
+ }
+ NS_HANDLER
+ {
+ if ([[localException name] isEqualToString:@"MLKThrow"])
+ {
+ id thrownTag = [[localException userInfo]
+ objectForKey:@"THROWN TAG"];
+
+ if (thrownTag == catchTag)
+ return [[localException userInfo]
+ objectForKey:@"THROWN OBJECTS"];
+ else
+ [localException raise];
+ }
+ else
+ [localException raise];
+ }
+ NS_ENDHANDLER;
+
+ return nil;
+ }
else if (car == _DEFMACRO)
{
// No real lambda lists here. This SYS::%DEFMACRO is
@@ -444,6 +483,34 @@ static MLKSymbol *_LAMBDA;
{
//FIXME: ...
}
+ else if (car == THROW)
+ {
+ id catchTag;
+ NSArray *values;
+ NSDictionary *userInfo;
+
+ catchTag = denullify([[self eval:[[program cdr] car]
+ inLexicalContext:context
+ withEnvironment:lexenv]
+ objectAtIndex:0]);
+
+ values = [self eval:[[[program cdr] cdr] car]
+ inLexicalContext:context
+ withEnvironment:lexenv];
+
+ userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
+ catchTag, @"THROWN TAG",
+ values, @"THROWN OBJECTS", nil];
+
+ [[NSException exceptionWithName:@"MLKThrow"
+ reason:[NSString stringWithFormat:
+ @"THROW without a corresponding CATCH: tag %@, values %@.",
+ [catchTag descriptionForLisp],
+ [values descriptionForLisp]]
+ userInfo:userInfo] raise];
+
+ return nil;
+ }
else if (car == UNWIND_PROTECT)
{
NSArray *results;
diff --git a/MLKPackage.m b/MLKPackage.m
index 0f9c8ef..b4de534 100644
--- a/MLKPackage.m
+++ b/MLKPackage.m
@@ -64,6 +64,8 @@ static NSMutableDictionary *packages = nil;
[cl import:nil];
[cl export:nil];
[cl export:[cl intern:@"T"]];
+ [cl export:[cl intern:@"CATCH"]];
+ [cl export:[cl intern:@"THROW"]];
[cl export:[cl intern:@"IF"]];
[cl export:[cl intern:@"IN-PACKAGE"]];
[cl export:[cl intern:@"LET"]];