patternMinor
RPN-Stack-Based Recursive Calculator Needs Tuneup
Viewed 0 times
stackneedsrpnrecursivebasedtuneupcalculator
Problem
This function takes an array of strings and numbers and recursively processes it as a kind of "calculating program". The structure is based on Reverse Polish Notation, so the top object in the stack (last in the array) determines what to do with the next one (or two) items in the program. For example, if the array was [1, 2, "+"], the solution would be 3.
-
In the case of errors, it should return an
error that happened.
-
If more than one error occurs in processing, it is not clear which
error should receive priority, so I've chosen to prioritize the first
error found and ignore any further errors.
I think that this code could be made much more simple, but I'm not sure how best to do that in Objective C. What suggestions do you have to improve this code?
```
+ (id)popOperandOffProgramStack:(NSMutableArray *)stack
{
id result;
double dResult;
id topOfStack = [stack lastObject];
if (topOfStack) [stack removeLastObject];
if ([topOfStack isKindOfClass:[NSNumber class]])
{
result = topOfStack;
}
else if ([topOfStack isKindOfClass:[NSString class]])
{
id rightSide = [self popOperandOffProgramStack:stack];
if (![rightSide isKindOfClass:[NSNumber class]]) {
return rightSide;
}
double r = [(NSNumber *)rightSide doubleValue];
NSString *operation = topOfStack;
if ([[self class] isBinaryOperation:operation]) {
id leftSide = [self popOperandOffProgramStack:stack];
if (![leftSide isKindOfClass:[NSNumber class]]) {
return leftSide;
}
double l = [(NSNumber *)leftSide doubleValue];
if([operation isEqualToString:@"+"]) {
dResult = l + r;
} else if([operation isEqualToString:@"-"]) {
dResult = l - r;
-
In the case of errors, it should return an
NSString describing theerror that happened.
-
If more than one error occurs in processing, it is not clear which
error should receive priority, so I've chosen to prioritize the first
error found and ignore any further errors.
I think that this code could be made much more simple, but I'm not sure how best to do that in Objective C. What suggestions do you have to improve this code?
```
+ (id)popOperandOffProgramStack:(NSMutableArray *)stack
{
id result;
double dResult;
id topOfStack = [stack lastObject];
if (topOfStack) [stack removeLastObject];
if ([topOfStack isKindOfClass:[NSNumber class]])
{
result = topOfStack;
}
else if ([topOfStack isKindOfClass:[NSString class]])
{
id rightSide = [self popOperandOffProgramStack:stack];
if (![rightSide isKindOfClass:[NSNumber class]]) {
return rightSide;
}
double r = [(NSNumber *)rightSide doubleValue];
NSString *operation = topOfStack;
if ([[self class] isBinaryOperation:operation]) {
id leftSide = [self popOperandOffProgramStack:stack];
if (![leftSide isKindOfClass:[NSNumber class]]) {
return leftSide;
}
double l = [(NSNumber *)leftSide doubleValue];
if([operation isEqualToString:@"+"]) {
dResult = l + r;
} else if([operation isEqualToString:@"-"]) {
dResult = l - r;
Solution
Instead of returning an error-String, I would pass in a nil'ed-NSError object by reference, and write an error to it, in case it occurred. the returned object would be nil
Usage:
this avoids type checking.
+ (NSNumber *)popOperandOffProgramStack:(NSMutableArray *)stack error:(NSError **)error
{
//…
error = [[NSError alloc] int…] ;
}Usage:
NSError *error = nil;
if ([Calculator popOperandOffProgramStack:parameters error:&error])
{
//returned object not nil -> success
} else {
//nil-object -> let's check the error
}this avoids type checking.
Code Snippets
+ (NSNumber *)popOperandOffProgramStack:(NSMutableArray *)stack error:(NSError **)error
{
//…
error = [[NSError alloc] int…] ;
}NSError *error = nil;
if ([Calculator popOperandOffProgramStack:parameters error:&error])
{
//returned object not nil -> success
} else {
//nil-object -> let's check the error
}Context
StackExchange Code Review Q#8693, answer score: 2
Revisions (0)
No revisions yet.