diff --git a/SA_DiceEvaluator.m b/SA_DiceEvaluator.m index 882ad93..2e68826 100644 --- a/SA_DiceEvaluator.m +++ b/SA_DiceEvaluator.m @@ -41,7 +41,7 @@ return _maxDieCount; } -(void) setMaxDieCount:(NSUInteger)maxDieCount { - if (maxDieCount > NSUIntegerMax / _maxDieSize) { + if (maxDieCount > (NSUIntegerMax / _maxDieSize)) { _maxDieCount = NSUIntegerMax / _maxDieSize; } else { _maxDieCount = maxDieCount; @@ -52,9 +52,11 @@ return _maxDieSize; } -(void) setMaxDieSize:(NSUInteger)maxDieSize { - if (maxDieSize > [_diceBag biggestPossibleDieSize] || - maxDieSize > NSIntegerMax / _maxDieCount) { - _maxDieSize = ([_diceBag biggestPossibleDieSize] < (NSIntegerMax / _maxDieCount)) ? [_diceBag biggestPossibleDieSize] : NSIntegerMax / _maxDieCount; + if ( maxDieSize > [_diceBag biggestPossibleDieSize] + || maxDieSize > (NSIntegerMax / _maxDieCount)) { + _maxDieSize = (([_diceBag biggestPossibleDieSize] < (NSIntegerMax / _maxDieCount)) + ? [_diceBag biggestPossibleDieSize] + : (NSIntegerMax / _maxDieCount)); } else { _maxDieSize = maxDieSize; } @@ -65,12 +67,14 @@ /**************************/ -(instancetype) init { - if (self = [super init]) { - _maxDieCount = DEFAULT_MAX_DIE_COUNT; - _maxDieSize = DEFAULT_MAX_DIE_SIZE; - - _diceBag = [SA_DiceBag new]; - } + if (!(self = [super init])) + return nil; + + _maxDieCount = DEFAULT_MAX_DIE_COUNT; + _maxDieSize = DEFAULT_MAX_DIE_SIZE; + + _diceBag = [SA_DiceBag new]; + return self; } @@ -78,6 +82,8 @@ #pragma mark - Public methods /****************************/ +// TODO: Possibly refuse to evaluate an expression that’s already evaluated? +// (i.e., it has a ... .result?? .value??) -(SA_DiceExpression *) resultOfExpression:(SA_DiceExpression *)expression { // Check to see if the expression is erroneous (i.e. the parser has judged // that it is malformed, etc.). If so, decline to evaluate the expression; @@ -87,26 +93,27 @@ } /* - Even if an expression is not erroneous (i.e. if it has no syntax errors), - it may still not be possible to evaluate it. For example, ‘5d0’ is a - perfectly well-formed die string, and will yield an expression tree as follows: + NOTE: Even if an expression is not erroneous (i.e. if it has no syntax + errors), it may still not be possible to evaluate it. For example, ‘5d0’ + is a perfectly well-formed die string, and will yield an expression tree + as follows: - @{SA_DB_TERM_TYPE : SA_DB_TERM_TYPE_ROLL_COMMAND, - SA_DB_ROLL_COMMAND : SA_DB_ROLL_COMMAND_SUM, - SA_DB_ROLL_DIE_COUNT : @{SA_DB_TERM_TYPE : SA_DB_TERM_TYPE_VALUE, - SA_DB_VALUE : @(5) - }, - SA_DB_ROLL_DIE_SIZE : @{SA_DB_TERM_TYPE : SA_DB_TERM_TYPE_VALUE, - SA_DB_VALUE : @(0) - } - } + [ type : SA_DiceExpressionTerm_ROLL_COMMAND, + rollCommand : SA_DiceExpressionRollCommand_SUM, + dieCount : [ type : SA_DiceExpressionTerm_VALUE, + value : @(5) + ], + dieSize : [ type : SA_DiceExpressionTerm_VALUE, + value : @(0) + ] + ] This is, of course, an illegal expression; we can’t roll a die of size 0 (a die with zero sides?). If we encounter such an illegal expression, we add an appropriate error to - the term. We are not required to set a value for the SA_DB_RESULT key in - such a case. + the -[errorBitMask]. We are not required to set a value (-[value] property) + in such a case. */ switch (expression.type) { @@ -146,7 +153,7 @@ SA_DiceExpression *result = [expression copy]; // For now, only sum and exploding sum (i.e., sum but with exploding dice) - // are supported Other sorts of roll commands may be added later. + // are supported. Other sorts of roll commands may be added later. switch (result.rollCommand) { case SA_DiceExpressionRollCommand_SUM: case SA_DiceExpressionRollCommand_SUM_EXPLODING: { @@ -256,9 +263,10 @@ // If the left-hand operand is not a roll-and-sum, then the KEEP // modifier cannot be applied to it. In that case, we add an error // and return the result without evaluating. - if (result.leftOperand.type != SA_DiceExpressionTerm_ROLL_COMMAND || - (result.leftOperand.rollCommand != SA_DiceExpressionRollCommand_SUM && - result.leftOperand.rollCommand != SA_DiceExpressionRollCommand_SUM_EXPLODING)) { + if ( result.leftOperand.type != SA_DiceExpressionTerm_ROLL_COMMAND + || ( result.leftOperand.rollCommand != SA_DiceExpressionRollCommand_SUM + && result.leftOperand.rollCommand != SA_DiceExpressionRollCommand_SUM_EXPLODING) + ) { result.errorBitMask |= SA_DiceExpressionError_ROLL_MODIFIER_INAPPLICABLE; return result; } @@ -347,12 +355,14 @@ switch (result.operator) { case SA_DiceExpressionOperator_MINUS: { // First, we check for possible overflow... - if (leftOperand > 0 && rightOperand < 0 && - NSIntegerMax + rightOperand < leftOperand) { + if ( leftOperand > 0 + && rightOperand < 0 + && (NSIntegerMax + rightOperand) < leftOperand) { result.errorBitMask |= SA_DiceExpressionError_INTEGER_OVERFLOW_SUBTRACTION; break; - } else if (leftOperand < 0 && rightOperand > 0 && - NSIntegerMin + rightOperand > leftOperand) { + } else if ( leftOperand < 0 + && rightOperand > 0 + && (NSIntegerMin + rightOperand) > leftOperand) { result.errorBitMask |= SA_DiceExpressionError_INTEGER_UNDERFLOW_SUBTRACTION; break; } @@ -363,11 +373,14 @@ } case SA_DiceExpressionOperator_PLUS: { // First, we check for possible overflow... - if (rightOperand > 0 && leftOperand > 0 && - NSIntegerMax - rightOperand < leftOperand) { + if ( rightOperand > 0 + && leftOperand > 0 + && (NSIntegerMax - rightOperand) < leftOperand) { result.errorBitMask |= SA_DiceExpressionError_INTEGER_OVERFLOW_ADDITION; break; - } else if(rightOperand < 0 && leftOperand < 0 && NSIntegerMin - rightOperand > leftOperand) { + } else if ( rightOperand < 0 + && leftOperand < 0 + && (NSIntegerMin - rightOperand) > leftOperand) { result.errorBitMask |= SA_DiceExpressionError_INTEGER_UNDERFLOW_ADDITION; break; } @@ -378,11 +391,19 @@ } case SA_DiceExpressionOperator_TIMES: { // First, we check for possible overflow... - if (( leftOperand == NSIntegerMin && ( rightOperand != 0 || rightOperand != 1 )) || - ( rightOperand == NSIntegerMin && ( leftOperand != 0 || leftOperand != 1 )) || - ( leftOperand != 0 && ( (NSIntegerMax / ABS(leftOperand)) < rightOperand ))) { - if ((leftOperand > 0 && rightOperand > 0) || - (leftOperand < 0 && rightOperand < 0)) { + if ( ( leftOperand == NSIntegerMin + && ( rightOperand != 0 + || rightOperand != 1 )) + || ( rightOperand == NSIntegerMin + && ( leftOperand != 0 + || leftOperand != 1 )) + || ( leftOperand != 0 + && ((NSIntegerMax / ABS(leftOperand)) < rightOperand)) + ) { + if ( ( leftOperand > 0 + && rightOperand > 0) + || ( leftOperand < 0 + && rightOperand < 0)) { result.errorBitMask |= SA_DiceExpressionError_INTEGER_OVERFLOW_MULTIPLICATION; } else { result.errorBitMask |= SA_DiceExpressionError_INTEGER_UNDERFLOW_MULTIPLICATION;