From aa4a4594b2758582d54c0367ef2a54535759df1f Mon Sep 17 00:00:00 2001 From: Said Achmiz Date: Tue, 5 Apr 2016 19:26:27 -0400 Subject: [PATCH] Add method to SA_DiceParser to join two already-parsed expressions --- SA_DiceEvaluator.m | 2 +- SA_DiceExpressionStringConstants.h | 12 ++---- SA_DiceFormatter.h | 2 + SA_DiceParser.h | 2 + SA_DiceParser.m | 60 +++++++++++++++++++++++++++++- 5 files changed, 68 insertions(+), 10 deletions(-) diff --git a/SA_DiceEvaluator.m b/SA_DiceEvaluator.m index a64fe84..a2c6de5 100644 --- a/SA_DiceEvaluator.m +++ b/SA_DiceEvaluator.m @@ -304,7 +304,7 @@ // No overflow will occur. We can perform the subtraction operation. result[SA_DB_RESULT] = @(leftOperand - rightOperand); - // Return the successfully evaluated negation expression. + // Return the successfully evaluated subtraction expression. return result; } // Check to see if the operation is addition. diff --git a/SA_DiceExpressionStringConstants.h b/SA_DiceExpressionStringConstants.h index 6f9439b..2acccb1 100644 --- a/SA_DiceExpressionStringConstants.h +++ b/SA_DiceExpressionStringConstants.h @@ -35,9 +35,6 @@ extern NSString * const SA_DB_ERROR_ROLL_STRING_HAS_ILLEGAL_CHARACTERS; // val // listed below. // Operation expressions also have a value for the SA_DB_OPERAND_RIGHT key, // and, possibly, a value for the SA_DB_OPERAND_LEFT key as well. -// (An operation expression with an SA_DB_OPERATOR value of SA_DB_OPERATOR_MINUS -// that does not have an SA_DB_OPERAND_LEFT value is simply a negation of the -// SA_DB_OPERAND_RIGHT value.) // The values for the SA_DB_OPERAND_RIGHT (and, if present, SA_DB_OPERAND_LEFT) // are themselves expressions of some type (i.e. NSDictionary objects), which // must be recursively evaluated. @@ -62,7 +59,6 @@ extern NSString * const SA_DB_ROLL_DIE_SIZE; // key // Terms of type SA_DB_TERM_TYPE_VALUE (a.k.a. simple value expressions) have a // value for the SA_DB_VALUE key, which is an NSNumber that represents an // NSInteger value. -// NOTE: Despite being an NSInteger, this numeric value may not be negative. extern NSString * const SA_DB_VALUE; // key // All terms that were generated via parsing a string should have a value for @@ -113,10 +109,10 @@ extern NSString * const SA_DB_ROLLS; // key extern NSString * const SA_DB_STRING_FORMAT_RULES_PLIST_NAME; /* - The string format rules file (whose filename - minus the .plist extension - - is given by the SA_DB_STRING_FORMAT_RULES_PLIST_NAME string) contains - values for variables that define the properties of legal die roll strings, - as well as certain variables that define the format of result strings. + The string format rules file (whose basename (i.e., filename minus the .plist + extension) is given by the SA_DB_STRING_FORMAT_RULES_PLIST_NAME string) + contains values for variables that define the properties of legal die roll + strings, as well as certain variables that define the format of result strings. The file is organized as a dictionary contaning several sub-dictionaries. The valid keys (those for which values are present in the file), and the values diff --git a/SA_DiceFormatter.h b/SA_DiceFormatter.h index c6df034..28e2712 100644 --- a/SA_DiceFormatter.h +++ b/SA_DiceFormatter.h @@ -153,4 +153,6 @@ typedef enum - (NSString *)stringFromExpression:(NSDictionary *)expression; - (NSAttributedString *)attributedStringFromExpression:(NSDictionary *)expression; ++ (NSString *)canonicalRepresentationForOperator:(NSString *)operatorName; + @end diff --git a/SA_DiceParser.h b/SA_DiceParser.h index 4dbc351..c784bd7 100644 --- a/SA_DiceParser.h +++ b/SA_DiceParser.h @@ -152,4 +152,6 @@ typedef enum - (NSDictionary *)expressionForString:(NSString *)dieRollString; +- (NSDictionary *)expressionByJoiningExpression:(NSDictionary *)leftHandExpression toExpression:(NSDictionary *)rightHandExpression withOperator:(NSString *)operatorName; + @end diff --git a/SA_DiceParser.m b/SA_DiceParser.m index 3cb4f56..4cf8b25 100644 --- a/SA_DiceParser.m +++ b/SA_DiceParser.m @@ -11,6 +11,7 @@ #import "SA_DiceExpressionStringConstants.h" #import "SA_DiceErrorHandling.h" #import "NSString+SA_NSStringExtensions.h" +#import "SA_DiceFormatter.h" /********************************/ #pragma mark File-scope variables @@ -135,6 +136,63 @@ static NSDictionary *_validCharactersDict; } } +- (NSDictionary *)expressionByJoiningExpression:(NSDictionary *)leftHandExpression toExpression:(NSDictionary *)rightHandExpression withOperator:(NSString *)operatorName +{ + NSMutableDictionary *expression = [NSMutableDictionary dictionary]; + + // First, we check that the operands and operator are not nil. If they are, + // then the expression is invalid... + if(leftHandExpression == nil || rightHandExpression == nil || operatorName == nil) + { + expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_NONE; + + addErrorToExpression(SA_DB_ERROR_INVALID_EXPRESSION, expression); + + return expression; + } + + // If the operands and operator are present, then the expression is an + // operation expression... + expression[SA_DB_TERM_TYPE] = SA_DB_TERM_TYPE_OPERATION; + + // ... but does it have a valid operator? + if([operatorName isEqualToString:SA_DB_OPERATOR_PLUS] || + [operatorName isEqualToString:SA_DB_OPERATOR_MINUS] || + [operatorName isEqualToString:SA_DB_OPERATOR_TIMES] + ) + { + expression[SA_DB_OPERATOR] = operatorName; + } + else + { + addErrorToExpression(SA_DB_ERROR_UNKNOWN_OPERATOR, expression); + + return expression; + } + + // The operator is valid. Set the operands... + expression[SA_DB_OPERAND_LEFT] = leftHandExpression; + expression[SA_DB_OPERAND_RIGHT] = rightHandExpression; + + // And inherit any errors that they may have. + addErrorsFromExpressionToExpression(expression[SA_DB_OPERAND_LEFT], expression); + addErrorsFromExpressionToExpression(expression[SA_DB_OPERAND_RIGHT], expression); + + // Since this top-level expression was NOT generated by parsing an input + // string, for completeness and consistency, we have to generate a fake + // input string ourselves! We do this by wrapping each operand in + // parentheses and putting the canonical representation of the operator + // between them. + NSString *fakeInputString = [NSString stringWithFormat:@"(%@)%@(%@)", + expression[SA_DB_OPERAND_LEFT][SA_DB_INPUT_STRING], + [SA_DiceFormatter canonicalRepresentationForOperator:expression[SA_DB_OPERATOR]], + expression[SA_DB_OPERAND_RIGHT][SA_DB_INPUT_STRING]]; + expression[SA_DB_INPUT_STRING] = fakeInputString; + + // The joining is complete. (Power overwhelming.) + return expression; +} + /**********************************************/ #pragma mark - "Legacy" behavior implementation /**********************************************/ @@ -188,7 +246,7 @@ static NSDictionary *_validCharactersDict; // 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... + // malformed by definition... if(dieRollString.length == lastOperatorRange.length) { expression = [NSMutableDictionary dictionary];