Skip to content

Commit

Permalink
return-from operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Burks committed Nov 25, 2010
1 parent 3c27800 commit 1ebb73c
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 3 deletions.
6 changes: 6 additions & 0 deletions objc/block.m
Expand Up @@ -158,6 +158,9 @@ - (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)calling_context
}
@catch (NuReturnException *exception) {
value = [exception value];
if ([exception blockForReturn] && ([exception blockForReturn] != self)) {
@throw(exception);
}
}
@catch (id exception) {
@throw(exception);
Expand Down Expand Up @@ -230,6 +233,9 @@ - (id) evalWithArguments:(id)cdr context:(NSMutableDictionary *)calling_context
}
@catch (NuReturnException *exception) {
value = [exception value];
if ([exception blockForReturn] && ([exception blockForReturn] != self)) {
@throw(exception);
}
}
@catch (id exception) {
@throw(exception);
Expand Down
2 changes: 2 additions & 0 deletions objc/nuinternals.h
Expand Up @@ -52,9 +52,11 @@ limitations under the License.
@interface NuReturnException : NSException
{
id value;
id blockForReturn;
}

- (id) value;
- (id) blockForReturn;
@end

// use this to test a value for "truth"
Expand Down
42 changes: 40 additions & 2 deletions objc/operator.m
Expand Up @@ -53,11 +53,20 @@ - (id) init
@end

@implementation NuReturnException
- (id) initWithValue:(id) v;
- (id) initWithValue:(id) v
{
[super initWithName:@"NuReturnException" reason:@"A return operator was evaluated" userInfo:nil];
value = [v retain];
return self; ;
blockForReturn = nil;
return self;
}

- (id) initWithValue:(id) v blockForReturn:(id) b
{
[super initWithName:@"NuReturnException" reason:@"A return operator was evaluated" userInfo:nil];
value = [v retain];
blockForReturn = b; // weak reference
return self;
}

- (void) dealloc
Expand All @@ -71,6 +80,11 @@ - (id) value
return value;
}

- (id) blockForReturn
{
return blockForReturn;
}

@end

@implementation NuOperator : NSObject
Expand Down Expand Up @@ -2007,6 +2021,29 @@ - (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context

@end

@interface Nu_return_from_operator : NuOperator {}
@end

@implementation Nu_return_from_operator

- (id) callWithArguments:(id)cdr context:(NSMutableDictionary *)context
{
id block = nil;
id value = nil;
id cursor = cdr;
if (cursor && cursor != Nu__null) {
block = [[cursor car] evalWithContext:context];
cursor = [cursor cdr];
}
if (cursor && cursor != Nu__null) {
value = [[cursor car] evalWithContext:context];
}
@throw [[[NuReturnException alloc] initWithValue:value blockForReturn:block] autorelease];
return nil; // unreached
}

@end

@interface Nu_version_operator : NuOperator {}
@end

Expand Down Expand Up @@ -2160,6 +2197,7 @@ void load_builtins(NuSymbolTable *symbolTable)
install("break", Nu_break_operator);
install("continue", Nu_continue_operator);
install("return", Nu_return_operator);
install("return-from", Nu_return_from_operator);

install("try", Nu_try_operator);

Expand Down
10 changes: 9 additions & 1 deletion test/test_return.nu
Expand Up @@ -50,4 +50,12 @@
(assert_equal "positive" (rtc sign:1))
(assert_equal "-" (ReturnTestClass sign:-1))
(assert_equal "0" (ReturnTestClass sign:0))
(assert_equal "+" (ReturnTestClass sign:1))))
(assert_equal "+" (ReturnTestClass sign:1)))

(- testReturnFromOperator is
(set outer (do ()
(10 times:
(do (i) (10 times:
(do (j) (if (and (eq i 3) (eq j 4))
(return-from outer (+ i j)))))))))
(assert_equal 7 (outer))))

0 comments on commit 1ebb73c

Please sign in to comment.