HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

RPN-Stack-Based Recursive Calculator Needs Tuneup

Submitted by: @import:stackexchange-codereview··
0
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 NSString describing the
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;

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

+ (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.