Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions DDMathParser/DDExpression.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ typedef NS_ENUM(NSInteger, DDExpressionType) {
- (DDExpression *)simplifiedExpression;
- (DDExpression *)simplifiedExpressionWithEvaluator:(DDMathEvaluator *)evaluator error:(NSError **)error;

/// describe salesforce type of expression value(like CS_SALES_FORCE_TYPE_DATE, ... , ) if the field in not a nil
@property NSString *salesforceReturnType;

#pragma mark Number methods
@property (readonly) NSNumber *number;

Expand Down
2 changes: 1 addition & 1 deletion DDMathParser/DDExpression.m
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ - (DDExpressionType)expressionType {
return DDExpressionTypeNumber;
}
- (NSNumber *)evaluateWithSubstitutions:(NSDictionary *)substitutions evaluator:(DDMathEvaluator *)evaluator error:(NSError **)error {
return [evaluator evaluateExpression:self withSubstitutions:substitutions error:error];
return [evaluator unwrapFromMathResult:[evaluator evaluateExpression:self withSubstitutions:substitutions error:error]];
}
- (DDExpression *)simplifiedExpression {
NSError *error = nil;
Expand Down
9 changes: 6 additions & 3 deletions DDMathParser/DDMathEvaluator.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#import <Foundation/Foundation.h>
#import "DDTypes.h"
#import "DDMathEvaluatorResult.h"

@class DDMathOperatorSet;
@class DDExpression;
Expand All @@ -30,14 +31,16 @@ typedef NSNumber* (^DDVariableResolver)(NSString *);
- (BOOL)registerFunction:(DDMathFunction)function forName:(NSString *)functionName;
- (NSArray *)registeredFunctions;

- (NSNumber *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions;
- (NSNumber *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error;
- (DDMathEvaluatorResult *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions;
- (DDMathEvaluatorResult *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error;

- (NSNumber *)evaluateExpression:(DDExpression *)expression withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error;
- (DDMathEvaluatorResult *)evaluateExpression:(DDExpression *)expression withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error;

- (BOOL)addAlias:(NSString *)alias forFunctionName:(NSString *)functionName;
- (void)removeAlias:(NSString *)alias;

-(id)unwrapFromMathResult:(id)value;

@end

@interface DDMathEvaluator (Deprecated)
Expand Down
51 changes: 33 additions & 18 deletions DDMathParser/DDMathEvaluator.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "_DDPrecisionFunctionEvaluator.h"
#import "DDExpressionRewriter.h"
#import <objc/runtime.h>
#import "DDMathEvaluatorResult.h"


@implementation DDMathEvaluator {
Expand Down Expand Up @@ -178,16 +179,16 @@ - (void)removeAlias:(NSString *)alias {

#pragma mark - Evaluation

- (NSNumber *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions {
- (DDMathEvaluatorResult *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions {
NSError *error = nil;
NSNumber *returnValue = [self evaluateString:expressionString withSubstitutions:substitutions error:&error];
DDMathEvaluatorResult *returnValue = [self evaluateString:expressionString withSubstitutions:substitutions error:&error];
if (!returnValue) {
NSLog(@"error: %@", error);
}
return returnValue;
}

- (NSNumber *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
- (DDMathEvaluatorResult *)evaluateString:(NSString *)expressionString withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
DDMathStringTokenizer *tokenizer = [[DDMathStringTokenizer alloc] initWithString:expressionString operatorSet:self.operatorSet error:error];
if (!tokenizer) { return nil; }

Expand All @@ -200,9 +201,9 @@ - (NSNumber *)evaluateString:(NSString *)expressionString withSubstitutions:(NSD
return [self evaluateExpression:expression withSubstitutions:substitutions error:error];
}

- (NSNumber *)evaluateExpression:(DDExpression *)expression withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
- (DDMathEvaluatorResult *)evaluateExpression:(DDExpression *)expression withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
if ([expression expressionType] == DDExpressionTypeNumber) {
return [expression number];
return [[DDMathEvaluatorResult alloc] initWithNumber: [self unwrapFromMathResult: [expression number]] salesforceType:expression.salesforceReturnType];
} else if ([expression expressionType] == DDExpressionTypeVariable) {
return [self _evaluateVariableExpression:expression withSubstitutions:substitutions error:error];
} else if ([expression expressionType] == DDExpressionTypeFunction) {
Expand All @@ -211,47 +212,52 @@ - (NSNumber *)evaluateExpression:(DDExpression *)expression withSubstitutions:(N
return nil;
}

- (NSNumber *)_evaluateVariableExpression:(DDExpression *)e withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
- (DDMathEvaluatorResult *)_evaluateVariableExpression:(DDExpression *)e withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
id variableValue = [substitutions objectForKey:[e variable]];

if (variableValue == nil) {
// the substitutions dictionary was insufficient
// use the variable resolver (if available)
variableValue = [self variableWithName:[e variable]];
}

NSNumber *numberValue = [self _evaluateValue:variableValue withSubstitutions:substitutions error:error];
if (numberValue == nil && error != nil && *error == nil) {
DDMathEvaluatorResult *value = [self _evaluateValue:variableValue withSubstitutions:substitutions error:error];
if (value == nil && error != nil && *error == nil) {
*error = [NSError errorWithDomain:DDMathParserErrorDomain
code:DDErrorCodeUnresolvedVariable
userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"unable to resolve variable: %@", e],
DDUnknownVariableKey: [e variable]}];
}
return numberValue;

// тут может вернуться строка в качестве результата расчета (неожиданно ...).
if(value != nil && [value isKindOfClass:[DDMathEvaluatorResult class]] && value.salesforceType == nil) {
value = [[DDMathEvaluatorResult alloc] initWithNumber:value.number salesforceType:e.salesforceReturnType];
}
return value;
}

- (NSNumber *)_evaluateFunctionExpression:(_DDFunctionExpression *)e withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
- (DDMathEvaluatorResult *)_evaluateFunctionExpression:(_DDFunctionExpression *)e withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {

id result = [_functionEvaluator evaluateFunction:e variables:substitutions error:error];

if (!result) { return nil; }
NSNumber *numberValue = [self _evaluateValue:result withSubstitutions:substitutions error:error];
if (numberValue == nil && error != nil && *error == nil) {

DDMathEvaluatorResult *value = [self _evaluateValue:result withSubstitutions:substitutions error:error];
if (value == nil && error != nil && *error == nil) {
*error = ERR(DDErrorCodeInvalidFunctionReturnType, @"invalid return type from %@ function", [e function]);
}
return numberValue;
if(value != nil && [value isKindOfClass:DDMathEvaluatorResult.class] && value.salesforceType == nil) {
value = [[DDMathEvaluatorResult alloc] initWithNumber:value.number salesforceType:e.salesforceReturnType];
}
return value;
}

- (NSNumber *)_evaluateValue:(id)value withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
- (DDMathEvaluatorResult *)_evaluateValue:(id)value withSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
// given an object of unknown type, this evaluates it as best as it can
if ([value isKindOfClass:[DDExpression class]]) {
return [self evaluateExpression:value withSubstitutions:substitutions error:error];
} else if ([value isKindOfClass:[NSString class]]) {
return [self evaluateString:value withSubstitutions:substitutions error:error];
} else if ([value isKindOfClass:[NSNumber class]]) {
return value;
return [[DDMathEvaluatorResult alloc] initWithNumber:value];
}
return nil;
}
Expand Down Expand Up @@ -294,4 +300,13 @@ - (void)addRewriteRule:(NSString *)rule forExpressionsMatchingTemplate:(NSString
[[DDExpressionRewriter defaultRewriter] addRewriteRule:rule forExpressionsMatchingTemplate:templateString condition:condition];
}

-(id)unwrapFromMathResult:(id)value {
id valueUnwrapped = value;
if ([value isKindOfClass:[DDMathEvaluatorResult class]]) {
DDMathEvaluatorResult *valueBuffer = value;
valueUnwrapped = valueBuffer.number;
}
return valueUnwrapped;
}

@end
22 changes: 22 additions & 0 deletions DDMathParser/DDMathEvaluatorResult.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// DDMathEvaluatorResult.h
// DDMathParser
//
// Created by Artem Viter on 08.12.2023.
//

#import <Foundation/Foundation.h>


@interface DDMathEvaluatorResult : NSObject

@property (readonly) NSNumber * number;

@property (readonly) NSString * salesforceType;


- (instancetype)initWithNumber:(NSNumber *)number salesforceType:(NSString *)salesforceType;

- (instancetype)initWithNumber:(NSNumber *)number;

@end
63 changes: 63 additions & 0 deletions DDMathParser/DDMathEvaluatorResult.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// DDMathEvaluatorResult.m
// DDMathParser
//
// Created by Artem Viter on 08.12.2023.
//

#import <Foundation/Foundation.h>
#import "DDMathEvaluatorResult.h"

@implementation DDMathEvaluatorResult

- (instancetype)initWithNumber:(NSNumber *)number salesforceType:(NSString *)salesforceType {
self = [super init];
if (self) {
_number = [number copy];
_salesforceType = [salesforceType copy];
}
return self;
}

- (instancetype)initWithNumber:(NSNumber *)number {
return [self initWithNumber:number salesforceType:nil];
}

- (BOOL)isEqual:(id)object {
if (self == object) {
return YES;
}

if (![object isKindOfClass:[DDMathEvaluatorResult class]]) {
return NO;
}

DDMathEvaluatorResult *otherEvaluatorResult = (DDMathEvaluatorResult *)object;

return [self.number isEqual:otherEvaluatorResult.number];
}

- (id)copyWithZone:(NSZone *)zone {
// Create a new instance of DDMathEvaluatorResult
DDMathEvaluatorResult *copy = [[[self class] allocWithZone:zone] init];

// Copy the properties to the new instance
copy->_number = [self.number copy];
copy->_salesforceType = [self.salesforceType copy];

return copy;
}

- (NSComparisonResult)compare:(DDMathEvaluatorResult *)otherResult {
// Compare the numbers of self and otherResult
NSNumber* compareWith = nil;
if(otherResult == nil) {
return [self.number compare:nil];
} else if([otherResult isKindOfClass: DDMathEvaluatorResult.class]) {
return [self.number compare:otherResult.number];
} else {
return [self.number compare:otherResult];
}
}

@end
8 changes: 4 additions & 4 deletions DDMathParser/NSString+DDMathParsing.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
//

#import <Foundation/Foundation.h>

#import "DDMathEvaluatorResult.h"

@interface NSString (DDMathParsing)

- (NSNumber *)numberByEvaluatingString;
- (NSNumber *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions;
- (NSNumber *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions error:(NSError **)error;
- (DDMathEvaluatorResult *)numberByEvaluatingString;
- (DDMathEvaluatorResult *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions;
- (DDMathEvaluatorResult *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions error:(NSError **)error;

@end
6 changes: 3 additions & 3 deletions DDMathParser/NSString+DDMathParsing.m
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@

@implementation NSString (DDMathParsing)

- (NSNumber *)numberByEvaluatingString {
- (DDMathEvaluatorResult *)numberByEvaluatingString {
return [self numberByEvaluatingStringWithSubstitutions:nil];
}

- (NSNumber *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions {
- (DDMathEvaluatorResult *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions {
NSError *error = nil;
NSNumber *returnValue = [self numberByEvaluatingStringWithSubstitutions:substitutions error:&error];
if (returnValue == nil) {
Expand All @@ -25,7 +25,7 @@ - (NSNumber *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitu
return returnValue;
}

- (NSNumber *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
- (DDMathEvaluatorResult *)numberByEvaluatingStringWithSubstitutions:(NSDictionary *)substitutions error:(NSError **)error {
return [[DDMathEvaluator defaultMathEvaluator] evaluateString:self withSubstitutions:substitutions error:error];
}

Expand Down
Loading