diff options
author | Matthias Andreas Benkard <matthias@benkard.de> | 2008-07-07 19:25:37 +0200 |
---|---|---|
committer | Matthias Andreas Benkard <matthias@benkard.de> | 2008-07-07 19:25:37 +0200 |
commit | 3e9ae8c764257f14132b490531e63e4ba64dbe55 (patch) | |
tree | a7b8ad17549022f534faec24e49a2e0713b1ed3c | |
parent | fec4301cb589a380c5a5faaca2dcf23f42bd9195 (diff) |
Interpreter: Implement CATCH and THROW.
-rw-r--r-- | MLKInterpreter.m | 67 | ||||
-rw-r--r-- | MLKPackage.m | 2 |
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"]]; |