From 3e9ae8c764257f14132b490531e63e4ba64dbe55 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Mon, 7 Jul 2008 19:25:37 +0200 Subject: Interpreter: Implement CATCH and THROW. --- MLKInterpreter.m | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'MLKInterpreter.m') 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; -- cgit v1.2.3