980 lines
36 KiB
Objective-C
980 lines
36 KiB
Objective-C
//
|
|
// MPExpression.h
|
|
// MathPad
|
|
//
|
|
// Created by Kim Wittenburg on 10.08.14.
|
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
|
//
|
|
|
|
|
|
|
|
/*!
|
|
@header
|
|
The <code>MPExpression</code> class is used to represent a mathematical
|
|
expression. It is used in the storage layer of the MathKit Expression System. An
|
|
instance of the <code>MPExpression</code> class stores all contents related to
|
|
an expression and can manipulate them. However it is not able to evaluate the
|
|
represented expression by itself.
|
|
|
|
<h2>Structure of an Expression</h2>
|
|
|
|
Expressions consist of two types of elements: string elements and function
|
|
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>@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 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>@link
|
|
//apple_ref/occ/cl/MPFunction@/link</code> for details.
|
|
|
|
<h2>Terminology</h2>
|
|
|
|
When working with expressions note that there is a special terminology for an
|
|
expression's contents:
|
|
|
|
<b>Element:</b><br />
|
|
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>@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
|
|
single character or a single function. For example the expression
|
|
<code>4+2²</code> consists of 4 symbols: The characters <code>"4"</code>,
|
|
<code>"+"</code> and <code>"2"</code> and the square function.
|
|
|
|
<b>Item:</b></br />
|
|
The term <i>item</i> is used to describe any of the previous. When the term
|
|
<i>item</i> is used in the name of a function or method it necessary to specify
|
|
what exactly an item is supposed to be. Usually this is done through reference
|
|
frames.
|
|
|
|
<b>Reference Frame:</b><br />
|
|
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>@link MPReferenceFrame@/link</code>.
|
|
|
|
<b>Children:</b><br />
|
|
Children are sub-elements of functions. The term <i>children</i> normally refers
|
|
to any kind of elements in the context of the expression tree.
|
|
|
|
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 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>@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
|
|
@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
|
|
expression or when the expression is mutated. This exception
|
|
contains the invalid element in its <code>userInfo</code>
|
|
dictionary. You can query it using the
|
|
<code>MPIllegalElementExceptionElementKey</code> key.
|
|
*/
|
|
FOUNDATION_EXPORT NSString *const MPIllegalElementException;
|
|
|
|
|
|
/*!
|
|
@const MPIllegalElementExceptionElementKey
|
|
@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
|
|
wrapped in an <code>NSNumber</code> or <code>NSValue</code>
|
|
instance respectively.
|
|
*/
|
|
FOUNDATION_EXPORT NSString *const MPIllegalElementExceptionElementKey;
|
|
|
|
|
|
/*!
|
|
@typedef MPReferenceFrame
|
|
@abstract A reference frame specifies the way an <i>item</i> is to be
|
|
interpreted.
|
|
|
|
@constant MPElementReferenceFrame
|
|
Specifies that items should be interpreted as elements.
|
|
|
|
@constant MPSymbolReferenceFrame
|
|
Specifies that items should be interpreted as symbols.
|
|
|
|
@constant MPTokenReferenceFrame
|
|
Specifies that items should be interpreted as tokens.
|
|
*/
|
|
typedef enum {
|
|
MPElementReferenceFrame,
|
|
MPSymbolReferenceFrame,
|
|
MPTokenReferenceFrame
|
|
} MPReferenceFrame;
|
|
|
|
|
|
|
|
@class MPExpression, MPFunction, MPRangePath, MPParsedExpression;
|
|
@protocol MPExpressionElement, MPToken;
|
|
|
|
|
|
/*!
|
|
@class MPExpression
|
|
@abstract A <code>MPExpression</code> instance represents a mathematical
|
|
expression.
|
|
|
|
@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
|
|
*/
|
|
|
|
|
|
/*!
|
|
@method init
|
|
@abstract Initlializes a new expression.
|
|
|
|
@discussion This method is a convenience initializer to initialize an
|
|
expression with <code>0</code> elements.
|
|
|
|
@return An empty expression.
|
|
*/
|
|
- (instancetype)init;
|
|
|
|
|
|
/*!
|
|
@method initWithElement:
|
|
@abstract Initializes a new expression with the specified
|
|
<code>element</code>.
|
|
|
|
@discussion This method is a convenience initializer to initialize an
|
|
expression with a single element.
|
|
|
|
@param element
|
|
The element to be added to the expression. The
|
|
<code>element</code> will be copied.
|
|
|
|
@return An expression initialized with <code>element</code>.
|
|
*/
|
|
- (instancetype)initWithElement:(id<MPExpressionElement>)element;
|
|
|
|
|
|
/*!
|
|
@method initWithElements:
|
|
@abstract Initializes a new expression with the specified
|
|
<code>elements</code>.
|
|
|
|
@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>@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>.
|
|
*/
|
|
- (instancetype)initWithElements:(NSArray *)elements; /* designated initializer */
|
|
|
|
|
|
#pragma mark Querying Expressions
|
|
/*!
|
|
@methodgroup Querying Expressions
|
|
*/
|
|
|
|
|
|
/*!
|
|
@property 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>@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.
|
|
*/
|
|
@property (nonatomic, weak) MPFunction *parent;
|
|
|
|
|
|
/*!
|
|
@method rootExpression
|
|
@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
|
|
a parent.
|
|
|
|
@return The root expression from the receiver's expression tree.
|
|
*/
|
|
- (MPExpression *)rootExpression;
|
|
|
|
|
|
/*!
|
|
@method indexPath
|
|
@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
|
|
receiver. The indexes are expressed in the element reference
|
|
frame.
|
|
|
|
@return The index path of the receiver in the expression tree.
|
|
*/
|
|
- (NSIndexPath *)indexPath;
|
|
|
|
|
|
/*!
|
|
@method countItemsInReferenceFrame:
|
|
@abstract Returns the number of items in the receiver in the specified
|
|
<code>referenceFrame</code>.
|
|
|
|
@param referenceFrame
|
|
The reference frame that should be used to count the items.
|
|
|
|
@return The current number of items in the receiver counted in the
|
|
specified <code>referenceFrame</code>.
|
|
*/
|
|
- (NSUInteger)countItemsInReferenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@method itemAtIndex:referenceFrame:
|
|
@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>@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.
|
|
|
|
@param anIndex
|
|
The index of the item. If the index is greater than the number of
|
|
items for the respective reference frame a
|
|
<code>NSRangeException</code> is raised.
|
|
|
|
@param referenceFrame
|
|
The reference frame that should be used to identify the item at
|
|
<code>anIndex</code>.
|
|
|
|
@return The item at <code>anIndex</code>.
|
|
*/
|
|
- (id)itemAtIndex:(NSUInteger)anIndex
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@method elementAtIndex:referenceFrame:
|
|
@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
|
|
element the complete element is returned.
|
|
|
|
This method always returns elements. To query items in the
|
|
specified reference frame use
|
|
<code>@link itemAtIndex:referenceFrame:@/link</code>.
|
|
|
|
@param anIndex
|
|
The index of the element.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>anIndex</code> is specified in.
|
|
|
|
@return The element at <code>anIndex</code>.
|
|
*/
|
|
- (id<MPExpressionElement>)elementAtIndex:(NSUInteger)anIndex
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
/*!
|
|
@method indexOfElement:
|
|
@abstract Returns the index of <code>element</code> or
|
|
<code>NSNotFound</code> if it was not found.
|
|
|
|
@param element
|
|
The element to find.
|
|
|
|
@return The index of <code>element</code> expressed in the element
|
|
reference frame.
|
|
*/
|
|
- (NSUInteger)indexOfElement:(id<MPExpressionElement>)element;
|
|
|
|
|
|
/*!
|
|
@method itemsInRange:referenceFrame:
|
|
@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
|
|
returned.
|
|
|
|
If the <code>range</code> exceeds the receiver's bounds a
|
|
<code>NSRangeException</code> is raised.
|
|
|
|
@param aRange
|
|
The requested range within the receiver's bounds.
|
|
|
|
@param referenceFrame
|
|
The referenceFrame <code>aRange</code> is expressed in.
|
|
|
|
@return An array containing all elements in the specified range. The type
|
|
of the objects depends on the specified
|
|
<code>referenceFrame</code>.
|
|
*/
|
|
- (NSArray *)itemsInRange:(NSRange)aRange
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@method allItemsInReferenceFrame:
|
|
@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
|
|
returned so be aware that mutations to any of the returned
|
|
objects will update the receiver's expression tree to reflect the
|
|
change.
|
|
|
|
@return An array of all items in the receiver.
|
|
*/
|
|
- (NSArray *)allItemsInReferenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@method elementAtIndexPath:
|
|
@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>@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.
|
|
|
|
@param indexPath
|
|
The index path the required object is located at. The indexes are
|
|
expressed in the element reference frame.
|
|
|
|
@return The element located at <code>indexPath</code>. The element is not
|
|
copied before it is returned. Be aware of the fact that any
|
|
mutations made to the returned object will update the receiver's
|
|
expression tree to reflect the change.
|
|
*/
|
|
- (id)elementAtIndexPath:(NSIndexPath *)indexPath;
|
|
|
|
|
|
/*!
|
|
@method convertIndex:fromReferenceFrame:toReferenceFrame:
|
|
@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>@link
|
|
convertIndex:fromReferenceFrame:toReferenceFrame:offset:@/link</code>
|
|
instead.
|
|
|
|
@param anIndex
|
|
The index to be converted.
|
|
|
|
@param fromReferenceFrame
|
|
The reference frame <code>anIndex</code> is specified in.
|
|
|
|
@param toReferenceFrame
|
|
The reference frame <code>anIndex</code> should be converted to.
|
|
|
|
@return An index specified in the <code>toReferenceFrame</code>. If
|
|
<code>anIndex</code> identifies a location inside an item in the
|
|
<code>toReferenceFrame</code> the index of the corresponding item
|
|
is returned.
|
|
*/
|
|
- (NSUInteger)convertIndex:(NSUInteger)anIndex
|
|
fromReferenceFrame:(MPReferenceFrame)fromReferenceFrame
|
|
toReferenceFrame:(MPReferenceFrame)toReferenceFrame;
|
|
|
|
|
|
/*!
|
|
@method convertIndex:fromReferenceFrame:toReferenceFrame:offset:
|
|
@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
|
|
item is returned. In that case the <code>offset</code> parameter
|
|
will be set to the number of symbols the offset goes into the
|
|
item at the returned index.
|
|
|
|
@param anIndex
|
|
The index to be converted.
|
|
|
|
@param fromReferenceFrame
|
|
The reference frame <code>anIndex</code> is specified in.
|
|
|
|
@param toReferenceFrame
|
|
The reference frame <code>anIndex</code> should be converted to.
|
|
|
|
@param offset
|
|
This output parameter will be set to the number of symbols that
|
|
are between the location identified by <code>anIndex</code> and
|
|
the index that is actually returned. The offset is specified in
|
|
the symbol reference frame. If you are not interested in the
|
|
offset pass <code>NULL</code>.
|
|
|
|
@return An index specified in the <code>toReferenceFrame</code>
|
|
corresponding to <code>anIndex</code>.
|
|
*/
|
|
- (NSUInteger)convertIndex:(NSUInteger)anIndex
|
|
fromReferenceFrame:(MPReferenceFrame)fromReferenceFrame
|
|
toReferenceFrame:(MPReferenceFrame)toReferenceFrame
|
|
offset:(NSUInteger *)offset;
|
|
|
|
|
|
/*!
|
|
@method convertRange:fromReferenceFrame:toReferenceFrame:
|
|
@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>@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>@link
|
|
convertRange:fromReferenceFrame:toReferenceFrame:leadingOffset:trailingOffset:@/link</code>.
|
|
|
|
@param aRange
|
|
The range to be converted.
|
|
|
|
@param fromReferenceFrame
|
|
The reference frame <code>aRange</code> is specified in.
|
|
|
|
@param toReferenceFrame
|
|
The reference frame <code>aRange</code> is to be converted to.
|
|
|
|
@return A range in the <code>toReferenceFrame</code> that includes the
|
|
the items identified by <code>aRange</code>.
|
|
*/
|
|
- (NSRange)convertRange:(NSRange)aRange
|
|
fromReferenceFrame:(MPReferenceFrame)fromReferenceFrame
|
|
toReferenceFrame:(MPReferenceFrame)toReferenceFrame;
|
|
|
|
|
|
/*!
|
|
@method convertRange:fromReferenceFrame:toReferenceFrame:leadingOffset:trailingOffset:
|
|
@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>@link
|
|
convertIndex:fromReferenceFrame:toReferenceFrame:@/link</code>.
|
|
It ensures that the returned range definitely includes all items
|
|
that were specified by <code>aRange</code>.
|
|
|
|
@param aRange
|
|
The range to be converted.
|
|
|
|
@param fromReferenceFrame
|
|
The reference frame <code>aRange</code> is specified in.
|
|
|
|
@param toReferenceFrame
|
|
The reference frame <code>aRange</code> is to be converted to.
|
|
|
|
@param leadingOffset
|
|
The offset of the location of the returned range in respect to
|
|
the location of <code>aRange</code>.
|
|
|
|
@param trailingOffset
|
|
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>.
|
|
*/
|
|
- (NSRange)convertRange:(NSRange)aRange
|
|
fromReferenceFrame:(MPReferenceFrame)fromReferenceFrame
|
|
toReferenceFrame:(MPReferenceFrame)toReferenceFrame
|
|
leadingOffset:(NSUInteger *)leadingOffset
|
|
trailingOffset:(NSUInteger *)trailingOffset;
|
|
|
|
|
|
#pragma mark Mutating Expressions
|
|
/*!
|
|
@methodgroup Mutating Expressions
|
|
*/
|
|
|
|
|
|
/*!
|
|
@method replaceItemsInRange:referenceFrame:withElements:
|
|
@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
|
|
<code>MPExpression</code>. Every other mutating method must
|
|
ultimately call this method.
|
|
|
|
After the receiver has been mutated the integrety of the receiver
|
|
is restored. That basically means that subsequent strings are
|
|
joined and empty strings removed. After restoring integrity the
|
|
receiver sends a
|
|
<code>@link
|
|
changedElementsInRangePath:replacementLength:@/link</code> to
|
|
itself. For more information see the documentation on that
|
|
method.
|
|
|
|
@param aRange
|
|
The range of symbols (including functions) to replace.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>aRange</code> is specified in.
|
|
|
|
@param elements
|
|
The elements that should replace the symbols specified by
|
|
<code>range</code>.
|
|
*/
|
|
- (void)replaceItemsInRange:(NSRange)aRange
|
|
referenceFrame:(MPReferenceFrame)referenceFrame
|
|
withElements:(NSArray *)elements;
|
|
|
|
|
|
/*!
|
|
@method changedElementsInRangePath:replacementLength:
|
|
@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>@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
|
|
receiver. The range addressed by <code>rangePath</code> is
|
|
expressed in the element reference frame.
|
|
|
|
@param replacementLength
|
|
The number of elements replacing the elements specified by
|
|
<code>rangePath</code> (also specified in the element reference
|
|
frame).
|
|
*/
|
|
- (void)changedElementsInRangePath:(MPRangePath *)rangePath
|
|
replacementLength:(NSUInteger)replacementLength;
|
|
|
|
|
|
/*!
|
|
@method subexpressionFromIndex:referenceFrame:
|
|
@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
|
|
expression will not change the receiver's expression tree.
|
|
|
|
@param from
|
|
The index from which to start constructing the subexpression.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>from</code> is specified in.
|
|
|
|
@return An expression containing the items from the specified index to
|
|
the end of the receiver.
|
|
*/
|
|
- (MPExpression *)subexpressionFromIndex:(NSUInteger)from
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@method subexpressionToIndex:referenceFrame:
|
|
@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
|
|
expression will not change the receiver's expression tree.
|
|
|
|
@param to
|
|
The index of the first element not to include in the newly
|
|
constructed subexpression.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>to</code> is specified in.
|
|
|
|
@return An expression containing the items from the first item to the one
|
|
at the specified index.
|
|
*/
|
|
- (MPExpression *)subexpressionToIndex:(NSUInteger)to
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@method subexpressionWithRange:referenceFrame:
|
|
@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
|
|
expression will not change the receiver's expression tree.
|
|
|
|
@param aRange
|
|
Specifies the items to be included in the newly created
|
|
subexpression.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>aRange</code> is specified in.
|
|
|
|
@return An expression containing the items in <code>aRange</code>.
|
|
*/
|
|
- (MPExpression *)subexpressionWithRange:(NSRange)aRange
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
#pragma mark Evaluating Expressions
|
|
/*!
|
|
@methodgroup Evaluating Expressions
|
|
*/
|
|
|
|
|
|
/*!
|
|
@method parse:
|
|
@abstract Parses the receiver.
|
|
|
|
@discussion This is a convenience method that calls <code>@link
|
|
parseExpectingVariable:errors:@/link</code> with <code>NO</code>
|
|
as the first argument.
|
|
|
|
@param errors
|
|
If the receiver (or any of its elements) contain syntax errors
|
|
this parameter is set to an appropriate value. All items in the
|
|
array are <code>NSError</code> instances. This parameter is never
|
|
set to an empty array. Pass <code>NULL</code> if you are not
|
|
interested in any errors that might occur.
|
|
|
|
@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:
|
|
@abstract Parses the receiver.
|
|
|
|
@param flag
|
|
If <code>YES</code> the receiver must (exept for whitespaces)
|
|
begin with a single letter followed by an equals sign. If it
|
|
doesn't the expression is considered invalid. Specify
|
|
<code>NO</code> If the expression should be evaluatable by itself.
|
|
|
|
@param errors
|
|
If the receiver (or any of its elements) contain syntax errors
|
|
this parameter is set to an appropriate value. All items in the
|
|
array are <code>NSError</code> instances. This parameter is never
|
|
set to an empty array. Pass <code>NULL</code> if you are not
|
|
interested in any errors that might occur.
|
|
|
|
@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;
|
|
|
|
@end
|
|
|
|
|
|
|
|
/*!
|
|
@category MPExpression (MPExpressionConvenience)
|
|
@abstract This category defines convenience methods for the
|
|
<code>MPExpression</code> class.
|
|
|
|
@discussion All convenience methods are completely defined in terms of other
|
|
methods of the <code>MPExpression</code> class.
|
|
*/
|
|
@interface MPExpression (MPExpressionConvenience)
|
|
|
|
#pragma mark Querying Expressions
|
|
/*!
|
|
@methodgroup Querying Expressions
|
|
*/
|
|
|
|
|
|
/*!
|
|
@method countElements
|
|
@abstract Returns the number of elements in the receiver.
|
|
|
|
@return The number of elements in the receiver expressed in the element
|
|
reference frame.
|
|
*/
|
|
- (NSUInteger)countElements;
|
|
|
|
|
|
/*!
|
|
@method countSymbols
|
|
@abstract Returns the number of symbols in the receiver.
|
|
|
|
@return The number of symbols in the receiver expressed in the symbol
|
|
reference frame.
|
|
*/
|
|
- (NSUInteger)countSymbols;
|
|
|
|
|
|
/*!
|
|
@method countTokens
|
|
@abstract Returns the number of tokens in the receiver.
|
|
|
|
@return The number of tokens in the receiver expressed in the token
|
|
reference frame.
|
|
*/
|
|
- (NSUInteger)countTokens;
|
|
|
|
|
|
/*!
|
|
@method elementAtIndex:
|
|
@abstract Returns the element at the specified index.
|
|
|
|
@param anIndex
|
|
The index of the element specified in the element reference
|
|
frame.
|
|
|
|
@return The element at <code>anIndex</code>.
|
|
*/
|
|
- (id<MPExpressionElement>)elementAtIndex:(NSUInteger)anIndex;
|
|
|
|
|
|
/*!
|
|
@method symbolAtIndex:
|
|
@abstract Returns the symbol at the specified index.
|
|
|
|
@param anIndex
|
|
The index of the symbol specified in the symbol reference frame.
|
|
|
|
@return The symbol at <code>anIndex</code>.
|
|
*/
|
|
- (id<MPExpressionElement>)symbolAtIndex:(NSUInteger)anIndex;
|
|
|
|
|
|
/*!
|
|
@method tokenAtIndex:
|
|
@abstract Returns the token at the specified index.
|
|
|
|
@param anIndex
|
|
The index of the token specified in the token reference frame.
|
|
|
|
@return The token at <code>anIndex</code>.
|
|
*/
|
|
- (id<MPToken>)tokenAtIndex:(NSUInteger)anIndex;
|
|
|
|
|
|
#pragma mark Mutating Expressions
|
|
/*!
|
|
@methodgroup Mutating Expressions
|
|
*/
|
|
|
|
|
|
/*!
|
|
@method appendElement:
|
|
@abstract Appends <code>anElement</code> to the receiver.
|
|
|
|
@param anElement
|
|
The element to append to the receiver.
|
|
*/
|
|
- (void)appendElement:(id<MPExpressionElement>)anElement;
|
|
|
|
|
|
/*!
|
|
@method appendElements:
|
|
@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>@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.
|
|
*/
|
|
- (void)appendElements:(NSArray *)elements;
|
|
|
|
|
|
/*!
|
|
@method insertElement:atIndex:referenceFrame:
|
|
@abstract Inserts <code>anElement</code> at the specified index.
|
|
|
|
@param anElement
|
|
The element to be inserted.
|
|
|
|
@param index
|
|
The index where to insert <code>anElement</code>.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>index</code> is specified in.
|
|
*/
|
|
- (void)insertElement:(id<MPExpressionElement>)anElement
|
|
atIndex:(NSUInteger)index
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@method insertElements:atIndex:referenceFrame:
|
|
@abstract Inserts <code>elements</code> at the specified index.
|
|
|
|
@discussion All objects in the <code>elements</code> array must conform to
|
|
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.
|
|
|
|
@param index
|
|
The index where to insert <code>elements</code>.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>index</code> is specified in.
|
|
*/
|
|
- (void)insertElements:(NSArray *)elements
|
|
atIndex:(NSUInteger)index
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
|
|
/*!
|
|
@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
|
|
<code>NSRangeException</code> is raised.
|
|
|
|
@param range
|
|
The range of items to remove from the receiver.
|
|
|
|
@param referenceFrame
|
|
The reference frame <code>range</code> is specified in.
|
|
*/
|
|
- (void)deleteElementsInRange:(NSRange)range
|
|
referenceFrame:(MPReferenceFrame)referenceFrame;
|
|
|
|
@end
|