Fix bug with leading negation operator in roll commands

This commit is contained in:
Said Achmiz 2016-04-05 01:11:56 -04:00
parent eab4f6e0b8
commit f8c6031507

View File

@ -180,8 +180,71 @@ static NSDictionary *_validCharactersDict;
{
NSString *operator = [dieRollString substringWithRange:lastOperatorRange];
// If the last (and thus only) operator is the leading character of
// the expression, then this is one of several possible special cases.
if(lastOperatorRange.location == 0)
{
NSMutableDictionary *expression;
// First, we check for whether there even is anything more to the
// roll string besides the operator. If not, then the string is
// definitely malformed...
if(dieRollString.length == lastOperatorRange.length)
{
expression = [NSMutableDictionary dictionary];
expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION;
expression[SA_DB_INPUT_STRING] = dieRollString;
addErrorToExpression(SA_DB_ERROR_INVALID_EXPRESSION, expression);
return expression;
}
// If the last operator is the leading character (i.e. there's just
// one operator in the expression, and it's at the beginning), and
// there's more to the expression than just the operator, then
// this is either an expression whose first term (which may or may
// not be its only term) is a simple value expression which
// represents a negative number - or, it's a malformed expression
// (because operators other than negation cannot begin an
// expression).
// In the former case, we do nothing, letting the testing for
// expression type fall through to the remaining cases (roll command
// or simple value).
// In the latter case, we register an error and return.
if([[SA_DiceParser validCharactersForOperator:SA_DB_OPERATOR_MINUS] containsCharactersInString:operator])
{
// We've determined that this expression begins with a simple
// value expression that represents a negative number.
// This next line is a hack to account for the fact that Cocoa's
// Unicode compliance is incomplete. :( NSString's integerValue
// method only accepts the hyphen as a negation sign when reading a
// number - not any of the Unicode characters which officially
// symbolize negation! But we are more modern-minded, and accept
// arbitrary symbols as minus-sign. For proper parsing, though,
// we have to replace it like this...
dieRollString = [dieRollString stringByReplacingCharactersInRange:lastOperatorRange withString:@"-"];
// Now we skip the remainder of the "is it an operator?" code
// and fall through to "is it a roll command, or maybe a simple
// value?"...
}
else
{
expression = [NSMutableDictionary dictionary];
expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION;
expression[SA_DB_INPUT_STRING] = dieRollString;
addErrorToExpression(SA_DB_ERROR_INVALID_EXPRESSION, expression);
return expression;
}
}
else
{
return [self legacyExpressionForStringDescribingOperation:dieRollString withOperator:operator atRange:lastOperatorRange];
}
}
// If not an operation, the top-level term might be a die roll command.
// Look for one of the characters recognized as valid die roll delimiters.
@ -202,10 +265,6 @@ static NSDictionary *_validCharactersDict;
{
NSMutableDictionary *expression;
// If the operator is at the beginning, this may be negation; we handle that
// case later below. Otherwise, it's a binary operator.
if(operatorRange.location != 0)
{
expression = [NSMutableDictionary dictionary];
expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION;
expression[SA_DB_INPUT_STRING] = dieRollString;
@ -245,48 +304,6 @@ static NSDictionary *_validCharactersDict;
{
addErrorToExpression(SA_DB_ERROR_UNKNOWN_OPERATOR, expression);
}
}
// Check to see if the term is a negation operation (we can only reach this
// case if the subtraction operator is at the beginning).
else
{
if(dieRollString.length == operatorRange.length)
{
expression = [NSMutableDictionary dictionary];
expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION;
expression[SA_DB_INPUT_STRING] = dieRollString;
addErrorToExpression(SA_DB_ERROR_INVALID_EXPRESSION, expression);
return expression;
}
if([[SA_DiceParser validCharactersForOperator:SA_DB_OPERATOR_MINUS] containsCharactersInString:operator])
{
// It turns out this isn't actually an operation expression. It's a
// simple value expression with a negative number.
// This next line is a hack to account for the fact that Cocoa's
// Unicode compliance is incomplete. :( NSString's integerValue
// method only accepts the hyphen as a negation sign when reading a
// number - not any of the Unicode characters which officially
// symbolize negation! But we are more modern-minded, and accept
// arbitrary symbols as minus-sign. For proper parsing, though,
// we have to replace it like this...
NSString *fixedRollString = [dieRollString stringByReplacingCharactersInRange:operatorRange withString:@"-"];
return [self legacyExpressionForStringDescribingNumericValue:fixedRollString];
}
else
{
expression = [NSMutableDictionary dictionary];
expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION;
expression[SA_DB_INPUT_STRING] = dieRollString;
addErrorToExpression(SA_DB_ERROR_INVALID_EXPRESSION, expression);
return expression;
}
}
// The operands have now been parsed recursively; this parsing may have
// generated one or more errors. Inherit any error(s) from the