// // MPEvaluationContext.m // MathKit // // Created by Kim Wittenburg on 12.09.14. // Copyright (c) 2014 Kim Wittenburg. All rights reserved. // #import "MPEvaluationContext.h" @interface MPEvaluationContext () @property (nonatomic, strong) NSMutableArray *stack; @end @implementation MPEvaluationContext static MPEvaluationContext *sharedContext; + (MPEvaluationContext *)sharedContext { if (!sharedContext) { sharedContext = [[MPEvaluationContext alloc] init]; } return sharedContext; } - (instancetype)init { if (sharedContext) { return sharedContext; } self = [super init]; if (self) { _stack = [[NSMutableArray alloc] init]; [self push]; [self defineVariable:@"e" value:[[NSDecimalNumber alloc] initWithDouble:M_E]]; [self defineVariable:@"π" value:[[NSDecimalNumber alloc] initWithDouble:M_PI]]; } return self; } - (void)push { [self.stack addObject:[[NSMutableDictionary alloc] init]]; } - (void)pop { [self.stack removeLastObject]; } - (BOOL)defineVariable:(NSString *)variable value:(NSDecimalNumber *)value { [self undefineVariable:variable]; if ([self isVariableDefined:variable]) { return NO; } NSMutableDictionary *currentBindings = self.stack.lastObject; currentBindings[variable] = value; return YES; } - (void)undefineVariable:(NSString *)variable { NSMutableDictionary *currentBindings = self.stack.lastObject; [currentBindings removeObjectForKey:variable]; } - (BOOL)isVariableDefined:(NSString *)variable { return [self valueForVariable:variable] != nil; } - (NSDecimalNumber *)valueForVariable:(NSString *)variable { NSUInteger currentIndex = self.stack.count; NSDictionary *currentBindings; NSDecimalNumber *value = nil; while (!value && currentIndex > 0) { currentBindings = self.stack[--currentIndex]; value = currentBindings[variable]; } return value; } @end