Fix bug with leading negation operator in roll commands
This commit is contained in:
parent
eab4f6e0b8
commit
f8c6031507
109
SA_DiceParser.m
109
SA_DiceParser.m
@ -180,8 +180,71 @@ static NSDictionary *_validCharactersDict;
|
|||||||
{
|
{
|
||||||
NSString *operator = [dieRollString substringWithRange:lastOperatorRange];
|
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];
|
return [self legacyExpressionForStringDescribingOperation:dieRollString withOperator:operator atRange:lastOperatorRange];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If not an operation, the top-level term might be a die roll command.
|
// 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.
|
// Look for one of the characters recognized as valid die roll delimiters.
|
||||||
@ -202,10 +265,6 @@ static NSDictionary *_validCharactersDict;
|
|||||||
{
|
{
|
||||||
NSMutableDictionary *expression;
|
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 = [NSMutableDictionary dictionary];
|
||||||
expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION;
|
expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION;
|
||||||
expression[SA_DB_INPUT_STRING] = dieRollString;
|
expression[SA_DB_INPUT_STRING] = dieRollString;
|
||||||
@ -245,48 +304,6 @@ static NSDictionary *_validCharactersDict;
|
|||||||
{
|
{
|
||||||
addErrorToExpression(SA_DB_ERROR_UNKNOWN_OPERATOR, expression);
|
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
|
// The operands have now been parsed recursively; this parsing may have
|
||||||
// generated one or more errors. Inherit any error(s) from the
|
// generated one or more errors. Inherit any error(s) from the
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user