Archived
1
This repository has been archived on 2022-08-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
mathpad/MathKit/MPTerm.h
2015-01-04 22:16:27 +01:00

202 lines
7.6 KiB
Objective-C

//
// MPTerm.h
// MathKit
//
// Created by Kim Wittenburg on 11.11.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
/*!
@header
This file contains the <code>MPTerm</code> class.
The <code>MPTerm</code> class is used to evaluate a mathematical expression. A
term is a purely mathematical representation of a part of an expression. A term
can be defined with three rules:
1. A number is a term.
2. A variable is a term.
3. A connection of terms with zero or more symbols is also a term.
Every mathematical operation (term) is defined in terms of a concrete subclass
of <code>MPTerm</code> and sub-terms (children). For example the expression
<code>2+3⋅4</code> would be a @link //apple_ref/occ/cl/MPSumTerm sum term@/link
with two children: A @link //apple_ref/occ/cl/MPNumber number@/link and a @link
//apple_ref/occ/cl/MPProductTerm product term@/link. The product term in turn
has two children which are both numbers.
Subclasses should do the following:
1. Subclasses must implement the <code>@link doEvaluation:@/link</code> method.
2. Subclasses should be immutable and thus define <code>readonly</code>
accessors for any children as well as an <code>init</code> method that
supplies the necessary values.
If a term has children that define variables to be used in one or more of the
other children <code>MPTerm</code> offers methods for defining, accessing and
undefining variable values. Because a term can not define variables that are
accessible in any of its sibling or parent terms all variables defined in a term
are automatically undefined when the term is finished evaluating.
*/
/*!
@define ReturnIfNil
@abstract This macro returns a <code>value</code> if a <code>test</code>
object is <code>nil</code>.
@param test
The object to be tested. If this parameter is <code>nil</code>
the macro returns <code>value</code>.
@param value
The value to be returned if <code>test</code> is
<code>nil</code>.
*/
#define ReturnIfNil(test, value) if (test == nil) return value
/*!
@define ReturnNilIfNil
@abstract This macro returns <code>nil</code> if a <code>test</code> object
is <code>nil</code>.
@param test
The object to be tested. If this parameter is <code>nil</code>
the macro returns <code>nil</code>.
*/
#define ReturnNilIfNil(test) if (test == nil) return nil
@class MPTerm;
/*!
@class MPTerm
@abstract <code>MPTerm</code> is a half abstract class that is the base
class for representing an evaluatable mathematical expression.
@discussion <code>MPTerm</code> should not be instanciated directly. Instead
one of the concrete subclasses should be used.
*/
@interface MPTerm : NSObject
/*!
@method evaluate:
@abstract Evaluates the receiver.
@discussion The result of the evaluation is up to the concrete subclass of
<code>MPTerm</code>. Note however that subclasses should
<b>not</b> override this method. To implement the custom
evaluation behaviour implement the <code>@link
doEvaluation:@/link</code> method. To evaluate a term (including
children of terms) do use this method.
@param error
If an error occurs during evaluation it is indirecly returned
through this parameter. If you are not interested in errors, pass
<code>NULL</code>.
@return A <code>NSDecimalNumber</code> containing the result of the
evaluation. Depending on the term this should be double precision
or higher.
*/
- (NSDecimalNumber *)evaluate:(NSError *__autoreleasing *)error;
/*!
@method doEvaluation:
@abstract Performs the actual evaluation of the receiver.
@discussion This method must be implemented by subclasses but should never be
called directly. Call <code>@link evaluate:@/link</code> instead.
@param error
If an error occurs during evaluation it is indirecly returned
through this parameter. If you are not interested in errors, pass
<code>NULL</code>.
@return A <code>NSDecimalNumber</code> containing the result of the
evaluation. Depending on the term this should be double precision
or higher.
*/
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error;
/*!
@method defineVariable:value:error:
@abstract Defines a variable in the shared evaluation context.
@discussion A defined variable is available until it is either undefined or
the end of the <code>@link doEvaluation:@/link</code> method is
reached at which point all variables defined in that method are
undefined automatically. If the <code>variableName</code> has
already been defined in the same method this method overwrites
the value for the variable. If it has been defined in the
evaluation method of a parent term this method fails and returns
<code>NO</code>.
@param variableName
The variable to be defined.
@param value
The value for the variable.
@param error
If <code>variableName</code> has already been defined in a parent
term this parameter is set to an error object that informs the
user about a variable redefinition. If you are not interested in
errors, pass <code>NULL</code>.
@return <code>YES</code> if the variable could be defined,
<code>NO</code> if it has previously been declared in a parent
term of the currently evaluated one.
*/
- (BOOL)defineVariable:(NSString *)variableName
value:(NSDecimalNumber *)value
error:(NSError *__autoreleasing *)error;
/*!
@method valueForVariable:
@abstract Returns the value for a variable from the shared evaluation
context.
@discussion If <code>variableName</code> is not defined this method returns
<code>nil</code>. Normally you do not need to call this method
yourself.
@param variableName
The variable whose value is requested.
@param error
If <code>variableName</code> is not defined this parameter is set
to an error object that informs the user about an undefined
variable. If you are not interested in errors, pass
<code>NULL</code>.
@return The value associated with <code>variableName</code> or
<code>nil</code> if it is undefined.
*/
- (NSDecimalNumber *)valueForVariable:(NSString *)variableName
error:(NSError *__autoreleasing *)error;
/*!
@method undefineVariable:
@abstract Removes <code>variableName</code> from the shared evaluation
context.
@discussion The variable is only removed if it exists and was defined in the
same evaluation method. Variables defined by parent terms can not
be undefined. Normally you do not need to call this method
yourself since all variables defined during the evaluation of a
term are automatically undefined afterwards.
@param variableName
The name of the variable to be undefined.
*/
- (void)undefineVariable:(NSString *)variableName;
@end