Archived
1

Added Documentation

This commit is contained in:
Kim Wittenburg
2014-12-17 22:04:49 +01:00
parent 8f1f730358
commit 7f6ee6e118
31 changed files with 1141 additions and 533 deletions

View File

@@ -7,6 +7,7 @@
//
/*!
@header
The <code>MPExpression</code> class is used to represent a mathematical
@@ -21,22 +22,24 @@
elements. String elements are represented by the <code>NSString</code> class.
In a valid expression string elements can only contain ASCII valid characters.
(and some other special characters) that make sense in a mathematical context.
Functions are represented by the <code>MPFunction</code> class. Functions
represent everything beyond simple text (such as powers, parenthesis and roots).
Functions are represented by the <code>@link
//apple_ref/occ/cl/MPFunction@/link</code> class. Functions represent everything
beyond simple text (such as powers, parenthesis and roots).
An expression should be pictured as a sequence of symbols that can either be
characters or functions. For the purposes of easier processing of expressions
it is possible to access complete string or function elements. Also there is a
third way of accessing an expression's contents: You can query individual tokens
of an expression. Tokens represent logical units inside an expression. For more
information on tokens see the <code>MPToken</code> class.
information on tokens see the documentation for <code>@link
//apple_ref/doc/header/MPToken.h MPToken@/link</code>.
<h2>The Expression Tree</h2>
Like expressions functions can likewise have expressions as elements (also
called <i>children</i> in this context). Both expressions and functions are
mutable. Through this organization expression are organized in a tree-like
structure called the <i>expression tree</i>. See <code>MPFunction</code> for
details.
structure called the <i>expression tree</i>. See <code>@link
//apple_ref/occ/cl/MPFunction@/link</code> for details.
<h2>Terminology</h2>
@@ -44,17 +47,19 @@
expression's contents:
<b>Element:</b><br />
An element is either an instance of the <code>NSString</code> or <code>
MPFunction</code> class. String elements can be multiple characters long. For
example the expression <code>4+2²</code> consists of one string element
(<code>"4+2"</code>) and one function element (the square function). All
elements conform to the <code>MPExpressionElement</code> protocol.
An element is either an instance of the <code>NSString</code> or <code> @link
//apple_ref/occ/cl/MPFunction@/link</code> class. String elements can be
multiple characters long. For example the expression <code>4+2²</code> consists
of one string element (<code>"4+2"</code>) and one function element (the square
function). All elements conform to the <code>MPExpressionElement</code>
protocol.
<b>Token:</b><br />
Tokens are logical units within an expression. For example the expression
<code>4+2²</code> consists of 4 tokens: A number token (<code>4</code>), a plus
sign token (<code>+</code>), another number (<code>2</code>) and a power token
(the square function). All tokens conform to the <code>MPToken</code> protocol.
(the square function). All tokens conform to the <code>@link
//apple_ref/occ/intf/MPToken@/link</code> protocol.
<b>Symbol:</b><br />
Symbols are the smallest possible part of an expression. A symbol is either a
@@ -72,7 +77,7 @@
A reference frame is a way to specify what an <i>item</i> is supposed to mean in
a specific context. It can either be an <i>element</i>, a <i>symbol</i> or a
<i>token</i>. For more information about reference frames see
<code>MPReferenceFrame</code>.
<code>@link MPReferenceFrame@/link</code>.
<b>Children:</b><br />
Children are sub-elements of functions. The term <i>children</i> normally refers
@@ -81,29 +86,84 @@
This terminology is consistent within the MathKit Expression System. Because
symbols are the smalles possible unit of measurement elements and tokens both
consist of one or more symbols. Similarly elements consist of one or more
tokens. You can convert between different reference frames using one the
following methods:
<pre>
@textblock
- convertIndexFromReferenceFrame:toReferenceFrame:
- convertIndexFromReferenceFrame:toReferenceFrame:offset:
@/textblock
</pre>
tokens. You can convert between different reference frames using the following
methods:
<ul>
<li><code>@link convertIndex:fromReferenceFrame:toReferenceFrame:@/link</code></li>
<li><code>@link convertIndex:fromReferenceFrame:toReferenceFrame:offset:@/link</code></li>
<li><code>@link convertRange:fromReferenceFrame:toReferenceFrame:@/link</code></li>
<li><code>@link convertRange:fromReferenceFrame:toReferenceFrame:leadingOffset:trailingOffset:@/link</code></li>
</ul>
<h2>Evaluating Expressions</h2>
A <code>MPExpression</code> instance can not evaluate itself. There are however
the <code>-parse:</code> and
<code>-parseExpectingVariableDefinition:errors:</code> methods. These parse and
thereby convert a <code>MPExpression</code> instance into a
<code>MPParsedExpression</code> instance that can be evaluated. For more
information on evaluation see the <code>MPParsedExpression</code> and
<code>MPTerm</code> class as well as the previously mentioned methods.
*/
the <code>@link parse:@/link</code> and
<code>@link parseExpectingVariable:errors:@/link</code> methods. These parse and
thereby convert a <code>MPExpression</code> instance into a <code>@link
//apple_ref/occ/cl/MPParsedExpression@/link</code> instance that can be
evaluated. For more information on evaluation see the <code>@link
//apple_ref/occ/cl/MPParsedExpression@/link</code> and <code>@link
//apple_ref/occ/cl/MPTerm@/link</code> class as well as the previously mentioned
methods.
*/
/*!
@protocol MPExpressionElement
@abstract This protocol defines the functionality an element in an
expression must have.
*/
@protocol MPExpressionElement <NSObject, NSCopying, NSCoding>
/*!
@method isString
@abstract Returns wether the receiver is a string.
@discussion A string is defined by being an instance of
<code>NSString</code>. If this method returns <code>YES</code>
you can be sure the receiver is an <code>NSString</code>
instance.
@return <code>YES</code> if the receiver is a string, <code>NO</code>
otherwise.
*/
- (BOOL)isString;
/*!
@method isFunction
@abstract Returns wether the receiver is a function.
@discussion A function is defined by being an instance of
<code>@link //apple_ref/occ/cl/MPFunction@/link</code>. If this
method returns <code>YES</code> you can be sure the receiver is a
<code>@link //apple_ref/occ/cl/MPFunction@/link</code> instance.
@return <code>YES</code> if the receiver is a function, <code>NO</code>
otherwise.
*/
- (BOOL)isFunction;
/*!
@method length
@abstract Calculates the length of the receiver.
@discussion The length of a <code>MPExpressionElement</code> is the number of
symbols it consists of. For strings this is the number of
characters in it. Functions have a length of <code>1</code>.
@return The receiver's length.
*/
- (NSUInteger)length;
@end
/*!
@const MPIllegalElementException
@brief Name for an exception that is raised if an invalid element is
@abstract Name for an exception that is raised if an invalid element is
added to an expression.
@discussion This exception may be raised during initialization of an
@@ -117,7 +177,7 @@ FOUNDATION_EXPORT NSString *const MPIllegalElementException;
/*!
@const MPIllegalElementExceptionElementKey
@brief Predefined key for an invalid element that caused a
@abstract Predefined key for an invalid element that caused a
<code>MPIllegalElementException</code> to be raised.
@discussion The invalid element can be of any type. Numbers and structs are
@@ -129,7 +189,7 @@ FOUNDATION_EXPORT NSString *const MPIllegalElementExceptionElementKey;
/*!
@typedef MPReferenceFrame
@brief A reference frame specifies the way an <i>item</i> is to be
@abstract A reference frame specifies the way an <i>item</i> is to be
interpreted.
@constant MPElementReferenceFrame
@@ -155,17 +215,14 @@ typedef enum {
/*!
@class MPExpression
@brief A <code>MPExpression</code> instance represents a mathematical
@abstract A <code>MPExpression</code> instance represents a mathematical
expression.
@discussion Every expression consists of string elements (represented by the
<code>NSString</code> class) and function elements (represented
by the <code>MPFunction</code> class). Functions and expressions
make up the expression tree.
@discussion A expression consists of string elements and function elements.
Functions and expressions together make up the expression tree.
*/
@interface MPExpression : NSObject <NSCopying, NSCoding>
#pragma mark Creation Methods
/*!
@methodgroup Creation Methods
@@ -174,7 +231,7 @@ typedef enum {
/*!
@method init
@brief Initlializes a new expression.
@abstract Initlializes a new expression.
@discussion This method is a convenience initializer to initialize an
expression with <code>0</code> elements.
@@ -186,7 +243,7 @@ typedef enum {
/*!
@method initWithElement:
@brief Initializes a new expression with the specified
@abstract Initializes a new expression with the specified
<code>element</code>.
@discussion This method is a convenience initializer to initialize an
@@ -203,22 +260,23 @@ typedef enum {
/*!
@method initWithElements:
@brief Initializes a new expression with the specified
@abstract Initializes a new expression with the specified
<code>elements</code>.
@discussion All elements must conform to the <code>MPExpressionElement</code>
protocol. If one or more objects do not conform to that protocol
a <code>MPIllegalElementException</code> is raised.
@discussion All elements must conform to the <code>@link
MPExpressionElement@/link</code> protocol. If one or more objects
do not conform to that protocol a <code>@link
MPIllegalElementException@/link</code> is raised.
This method is the designated initializer for the
<code>MPExpression</code> class.
@param elements
The elements that should be added to the expression. Every
element must conform to the <code>MPExpressionElement</code>
protocol. Each element is copied and the copy is then added to
the expression. The object in the <code>elements</code> array is
not modified.
element must conform to the <code>@link
MPExpressionElement@/link</code> protocol. Each element is copied
and the copy is then added to the expression. The object in the
<code>elements</code> array is not modified.
@return An expression containing <code>elements</code>.
*/
@@ -233,13 +291,15 @@ typedef enum {
/*!
@property parent
@brief The receiver's parent.
@abstract The receiver's parent.
@discussion The receiver's parent is the function in the expression tree that
contains the receiver.
@warning You should never set this property manually. If you are
implementing a custom subclass of <code>MPFunction</code> use the
<code>MPFunctionAccessorImplementation</code> macro.
implementing a custom subclass of <code>@link
//apple_ref/occ/cl/MPFunction@/link</code> use the <code>@link
//apple_ref/occ/macro/MPFunctionAccessorImplementation@/link</code>
macro.
@return The parent of the receiver or <code>nil</code> if the receiver is
the root expression.
@@ -249,7 +309,7 @@ typedef enum {
/*!
@method rootExpression
@brief Returns the root expression from the receiver's expression tree.
@abstract Returns the root expression from the receiver's expression tree.
@discussion The root expression is the ultimate parent of all expressions and
functions in the expression tree. A root expression does not have
@@ -262,7 +322,7 @@ typedef enum {
/*!
@method indexPath
@brief Returns the index path of the receiver in the expression tree.
@abstract Returns the index path of the receiver in the expression tree.
@discussion The index path contains the indexes (starting from the root
expression of the receiver's expression tree) that lead to the
@@ -276,7 +336,7 @@ typedef enum {
/*!
@method countItemsInReferenceFrame:
@brief Returns the number of items in the receiver in the specified
@abstract Returns the number of items in the receiver in the specified
<code>referenceFrame</code>.
@param referenceFrame
@@ -290,10 +350,11 @@ typedef enum {
/*!
@method itemAtIndex:referenceFrame:
@brief Returns the item at <code>anIndex</code>.
@abstract Returns the item at <code>anIndex</code>.
@discussion The item is not copied before it is returned. So be aware that
if you mutate a <code>MPFunction</code> instance returned from
if you mutate a <code>@link
//apple_ref/occ/cl/MPFunction@/link</code> instance returned from
this function the receiver's expression tree will be updated to
reflect the change.
@@ -314,7 +375,7 @@ typedef enum {
/*!
@method elementAtIndex:referenceFrame:
@brief Returns the element at the specified index.
@abstract Returns the element at the specified index.
@discussion An element is either a string or a function. If
<code>anIndex</code> identifies a position inside a string
@@ -322,7 +383,7 @@ typedef enum {
This method always returns elements. To query items in the
specified reference frame use
<code>-itemAtIndex:referenceFrame:</code>.
<code>@link itemAtIndex:referenceFrame:@/link</code>.
@param anIndex
The index of the element.
@@ -337,7 +398,7 @@ typedef enum {
/*!
@method indexOfElement:
@brief Returns the index of <code>element</code> or
@abstract Returns the index of <code>element</code> or
<code>NSNotFound</code> if it was not found.
@param element
@@ -351,7 +412,7 @@ typedef enum {
/*!
@method itemsInRange:referenceFrame:
@brief Returns an array of the items that are located in the specified
@abstract Returns an array of the items that are located in the specified
range.
@discussion The objects in the returned array are copied before they are
@@ -376,7 +437,7 @@ typedef enum {
/*!
@method allItemsInReferenceFrame:
@brief Returns an array of all items in the receiver for the specified
@abstract Returns an array of all items in the receiver for the specified
reference frame.
@discussion The elements in the returned array are not copied before they are
@@ -391,15 +452,16 @@ typedef enum {
/*!
@method elementAtIndexPath:
@brief Returns the element at the specified index path.
@abstract Returns the element at the specified index path.
@discussion This method finds the elements at the respective indexes starting
at the root expression from the receiver's expression tree.
The returned object can be a <code>NSString</code>, a
<code>MPFunction</code> or an <code>MPExpression</code> instance
depending on the specified <code>indexPath</code>. If any of the
indexes exceed the bounds of the respective receiver a
<code>NSRangeException</code> is raised.
<code>@link //apple_ref/occ/cl/MPFunction@/link</code> or a
<code>MPExpression</code> instance depending on the specified
<code>indexPath</code>. If any of the indexes exceed the bounds
of the respective receiver a <code>NSRangeException</code> is
raised.
If the index path does not contain any indexes the receiver
itself is returned.
@@ -418,11 +480,12 @@ typedef enum {
/*!
@method convertIndex:fromReferenceFrame:toReferenceFrame:
@brief Converts an index from one reference frame to another.
@abstract Converts an index from one reference frame to another.
@discussion This method ignores any offsets into items the conversion between
reference frames can cause. If you are interested in the offset
use <code>-convertIndex:fromReferenceFrame:toReferenceFrame:offset:</code>
use <code>@link
convertIndex:fromReferenceFrame:toReferenceFrame:offset:@/link</code>
instead.
@param anIndex
@@ -446,7 +509,7 @@ typedef enum {
/*!
@method convertIndex:fromReferenceFrame:toReferenceFrame:offset:
@brief Converts an index from one reference frame to another.
@abstract Converts an index from one reference frame to another.
@discussion If <code>anIndex</code> identifies a location inside an item in
the <code>toReferenceFrame</code> the index of the corresponding
@@ -481,18 +544,20 @@ typedef enum {
/*!
@method convertRange:fromReferenceFrame:toReferenceFrame:
@brief Converts a range from one reference frame to another.
@abstract Converts a range from one reference frame to another.
@discussion This method just converts the location and target of the range
separately using
<code>-convertIndex:fromReferenceFrame:toReferenceFrame:</code>.
<code>@link
convertIndex:fromReferenceFrame:toReferenceFrame:@/link</code>.
It ensures that the returned range definitely includes all items
that were specified by <code>aRange</code>.
The possibility that the returned range may
include more symbols than <code>aRange</code> is ignored. If you
need that information use
<code>-convertRange:fromReferenceFrame:toReferenceFrame:leadingOffset:trailingOffset:</code>.
<code>@link
convertRange:fromReferenceFrame:toReferenceFrame:leadingOffset:trailingOffset:@/link</code>.
@param aRange
The range to be converted.
@@ -513,11 +578,12 @@ typedef enum {
/*!
@method convertRange:fromReferenceFrame:toReferenceFrame:leadingOffset:trailingOffset:
@brief Converts a range from one reference frame to another.
@abstract Converts a range from one reference frame to another.
@discussion This method just converts the location and target of the range
separately using
<code>-convertIndex:fromReferenceFrame:toReferenceFrame:</code>.
<code>@link
convertIndex:fromReferenceFrame:toReferenceFrame:@/link</code>.
It ensures that the returned range definitely includes all items
that were specified by <code>aRange</code>.
@@ -538,8 +604,8 @@ typedef enum {
The offset of the last index in the range in respect to the last
index of <code>aRange</code>.
@return A range in the <code>toReferenceFrame</code> that includes the the items
specified by <code>aRange</code>.
@return A range in the <code>toReferenceFrame</code> that includes the
the items specified by <code>aRange</code>.
*/
- (NSRange)convertRange:(NSRange)aRange
fromReferenceFrame:(MPReferenceFrame)fromReferenceFrame
@@ -556,7 +622,7 @@ typedef enum {
/*!
@method replaceItemsInRange:referenceFrame:withElements:
@brief Replaces the elements in the specified range with the contents of
@abstract Replaces the elements in the specified range with the contents of
the <code>elements</code> array.
@discussion This is the most primitive mutation method of
@@ -567,8 +633,9 @@ typedef enum {
is restored. That basically means that subsequent strings are
joined and empty strings removed. After restoring integrity the
receiver sends a
<code>-changedElementsInIndexedRangePath:replacementLength:</code>
to itself. For more information see the documentation on that
<code>@link
changedElementsInRangePath:replacementLength:@/link</code> to
itself. For more information see the documentation on that
method.
@param aRange
@@ -588,16 +655,16 @@ typedef enum {
/*!
@method changedElementsInRangePath:replacementLength:
@brief This is a notification message that is sent from the receiver to
@abstract This is a notification message that is sent from the receiver to
itself after it has been mutated.
@discussion This method does nothing more than notify it's parent that it has
been mutated at the respective range path. If you want to get
notified about changes in an expression you should override this
method instead of
<code>-replaceSymbolsInRange:withElements:</code> because this
method gives you information about the elements that changed
during the mutation.
method instead of <code>@link
replaceItemsInRange:referenceFrame:withElements:@/link</code>
because this method gives you information about the elements that
changed during the mutation.
@param rangePath
The range path at which the receiver was changed starting at the
@@ -615,7 +682,7 @@ typedef enum {
/*!
@method subexpressionFromIndex:referenceFrame:
@brief Creates an expression from the items in the receiver from the
@abstract Creates an expression from the items in the receiver from the
specified index to the end.
@discussion The items from the receiver are copied. Mutations to the returned
@@ -636,7 +703,7 @@ typedef enum {
/*!
@method subexpressionToIndex:referenceFrame:
@brief Creates an expression from the items in the receiver from the
@abstract Creates an expression from the items in the receiver from the
first to the specified item.
@discussion The items from the receiver are copied. Mutations to the returned
@@ -658,7 +725,7 @@ typedef enum {
/*!
@method subexpressionWithRange:referenceFrame:
@brief Creates an expression from the items in the receiver within the
@abstract Creates an expression from the items in the receiver within the
specified range.
@discussion The items from the receiver are copied. Mutations to the returned
@@ -685,10 +752,10 @@ typedef enum {
/*!
@method parse:
@brief Parses the receiver.
@abstract Parses the receiver.
@discussion This is a convenience method that calls
<code>-parseExpectingVariable:errors:</code> with <code>NO</code>
@discussion This is a convenience method that calls <code>@link
parseExpectingVariable:errors:@/link</code> with <code>NO</code>
as the first argument.
@param errors
@@ -698,17 +765,18 @@ typedef enum {
set to an empty array. Pass <code>NULL</code> if you are not
interested in any errors that might occur.
@return A <code>MPParsedExpression</code> instance that represents the
receiver and can be evaluated or <code>nil</code> if an error
occurs. In that case the <code>errors</code> parameter is set to
an array containing at least one <code>NSError</code> instance.
@return A <code>@link //apple_ref/occ/cl/MPParsedExpression@/link</code>
instance that represents the receiver and can be evaluated or
<code>nil</code> if an error occurs. In that case the
<code>errors</code> parameter is set to an array containing at
least one <code>NSError</code> instance.
*/
- (MPParsedExpression *)parse:(NSArray *__autoreleasing *)errors;
/*!
@method parseExpectingVariable:errors:
@brief Parses the receiver.
@abstract Parses the receiver.
@param flag
If <code>YES</code> the receiver must (exept for whitespaces)
@@ -723,10 +791,11 @@ typedef enum {
set to an empty array. Pass <code>NULL</code> if you are not
interested in any errors that might occur.
@return A <code>MPParsedExpression</code> instance that represents the
receiver and can be evaluated or <code>nil</code> if an error
occurs. In that case the <code>errors</code> parameter is set to
an array containing at least one <code>NSError</code> instance.
@return A <code>@link //apple_ref/occ/cl/MPParsedExpression@/link</code>
instance that represents the receiver and can be evaluated or
<code>nil</code> if an error occurs. In that case the
<code>errors</code> parameter is set to an array containing at
least one <code>NSError</code> instance.
*/
- (MPParsedExpression *)parseExpectingVariable:(BOOL)flag
errors:(NSArray *__autoreleasing *)errors;
@@ -737,7 +806,7 @@ typedef enum {
/*!
@category MPExpression (MPExpressionConvenience)
@brief This category defines convenience methods for the
@abstract This category defines convenience methods for the
<code>MPExpression</code> class.
@discussion All convenience methods are completely defined in terms of other
@@ -753,7 +822,7 @@ typedef enum {
/*!
@method countElements
@brief Returns the number of elements in the receiver.
@abstract Returns the number of elements in the receiver.
@return The number of elements in the receiver expressed in the element
reference frame.
@@ -763,7 +832,7 @@ typedef enum {
/*!
@method countSymbols
@brief Returns the number of symbols in the receiver.
@abstract Returns the number of symbols in the receiver.
@return The number of symbols in the receiver expressed in the symbol
reference frame.
@@ -773,7 +842,7 @@ typedef enum {
/*!
@method countTokens
@brief Returns the number of tokens in the receiver.
@abstract Returns the number of tokens in the receiver.
@return The number of tokens in the receiver expressed in the token
reference frame.
@@ -783,7 +852,7 @@ typedef enum {
/*!
@method elementAtIndex:
@brief Returns the element at the specified index.
@abstract Returns the element at the specified index.
@param anIndex
The index of the element specified in the element reference
@@ -796,7 +865,7 @@ typedef enum {
/*!
@method symbolAtIndex:
@brief Returns the symbol at the specified index.
@abstract Returns the symbol at the specified index.
@param anIndex
The index of the symbol specified in the symbol reference frame.
@@ -808,7 +877,7 @@ typedef enum {
/*!
@method tokenAtIndex:
@brief Returns the token at the specified index.
@abstract Returns the token at the specified index.
@param anIndex
The index of the token specified in the token reference frame.
@@ -826,7 +895,7 @@ typedef enum {
/*!
@method appendElement:
@brief Appends <code>anElement</code> to the receiver.
@abstract Appends <code>anElement</code> to the receiver.
@param anElement
The element to append to the receiver.
@@ -836,12 +905,12 @@ typedef enum {
/*!
@method appendElements:
@brief Appends the objects from <code>elements</code> to the receiver.
@abstract Appends the objects from <code>elements</code> to the receiver.
@discussion All objects in the <code>elements</code> array must conform to
the <code>MPExpressionElement</code> protocol. If at least one
element does not conform to that protocol a
<code>MPIllegalElementException</code> is raised.
the <code>@link MPExpressionElement@/link</code> protocol. If at
least one element does not conform to that protocol a <code>@link
MPIllegalElementException@/link</code> is raised.
@param elements
The elements to append to the receiver.
@@ -851,7 +920,7 @@ typedef enum {
/*!
@method insertElement:atIndex:referenceFrame:
@brief Inserts <code>anElement</code> at the specified index.
@abstract Inserts <code>anElement</code> at the specified index.
@param anElement
The element to be inserted.
@@ -869,12 +938,12 @@ typedef enum {
/*!
@method insertElements:atIndex:referenceFrame:
@brief Inserts <code>elements</code> at the specified index.
@abstract Inserts <code>elements</code> at the specified index.
@discussion All objects in the <code>elements</code> array must conform to
the <code>MPExpressionElement</code> protocol. If at least one
element does not conform to that protocol a
<code>MPIllegalElementException</code> is raised.
the <code>@link MPExpressionElement@/link</code> protocol. If at
least one element does not conform to that protocol a <code>@link
MPIllegalElementException@/link</code> is raised.
@param elements
The elements to be inserted.
@@ -891,8 +960,8 @@ typedef enum {
/*!
@method deleteElementsInRange:
@brief Removes the elements identified by <code>range</code> from the
@method deleteElementsInRange:referenceFrame:
@abstract Removes the elements identified by <code>range</code> from the
receiver.
@discussion If <code>range</code> exceeds the receiver's bounds a