//
//  MPEvaluationContext.h
//  MathKit
//
//  Created by Kim Wittenburg on 12.09.14.
//  Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//


/*!
 @header
 This file contains the <code>MPEvaluationContext</code> class.
 
 The evaluation context is organized in so called levels. Every level of a
 context contains a unique set of variables. Only the highest level is
 accessible. Before any lower level can be accessed the higher ones have to be
 discarded. A higher level can not define variables that are already defined in
 a lower level. Similarly variables can only be undefined if they are defined at
 the current level. Discarding (popping) a level always undefines all variables
 defined on that level.
 */



@class MPEvaluationContext;


/*!
    @class      MPEvaluationContext
    @abstract   The evaluation context maintains a map of variables and
                associates them with a certain level.
 
    @discussion Different levels are nested using <code>@link
                //apple_ref/occ/instm/MPEvaluationContext/push@/link</code> and
                <code>@link
                //apple_ref/occ/instm/MPEvaluationContext/pop@/link</code>
                messages.
 
                <code>MPEvaluationContext</code> is a singletone class. There can
                only exist one instance (the shared instance) at any time.
 */
@interface MPEvaluationContext : NSObject

/*!
    @method     sharedContext
    @abstract   Returns the shared evaluation context.
 */
+ (MPEvaluationContext *)sharedContext;


/*!
    @method     push
    @abstract   Pushes a new level on context.
 */
- (void)push;


/*!
    @method     pop
    @abstract   Pops a level off the context.
 
    @discussion Popping a level also undefines all variables that were defined in
                that level.
 */
- (void)pop;


/*!
    @method     defineVariable:value:
    @abstract   Defines a variable with the specified value at the current level.
 
    @discussion The variable can only be defined if it has not been defined
                previously in a lower level. If the variable has been defined at
                the current level its value will be overwritten to the specified
                one.
 
    @param      variable
                The name of the variable. Typically this is a one-letter string.
 
    @param      value
                The value of the variable.
 
    @return     <code>YES</code> if the variable was defined successfully,
                <code>NO</code> if it is already defined in a lower level.
 */
- (BOOL)defineVariable:(NSString *)variable
                 value:(NSDecimalNumber *)value;


/*!
    @method     undefineVariable:
    @abstract   Undefines a variable that has previously been defined.
 
    @discussion Variables can only be undefined if they have been defined at the
                same level. If the variable to be undefined was defined at a
                different level this method does nothing.
 
                Normally there is very little reason to call this method since
                all variables defined on one level are automatically undefined
                when the level is popped.
 
    @param      variable
                The variable to be undefined.
 */
- (void)undefineVariable:(NSString *)variable;


/*!
    @method     valueForVariable:
    @abstract   Returns the value for the specified variable.
 
    @discussion If the <code>variable</code> has not been defined previously this
                method returns <code>nil</code>.
 
    @param      variable
                The variable whose value is to be retrieved.
 
    @return     The value <code>variable</code> was defined with or
                <code>nil</code> if it was not defined.
 */
- (NSDecimalNumber *)valueForVariable:(NSString *)variable;

@end
