911 lines
33 KiB
Objective-C
911 lines
33 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>MPFunction</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.
|
|
|
|
<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.
|
|
|
|
<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>
|
|
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.
|
|
|
|
<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.
|
|
|
|
<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>MPReferenceFrame</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 one the
|
|
following methods:
|
|
<pre>
|
|
@textblock
|
|
- convertIndexFromReferenceFrame:toReferenceFrame:
|
|
- convertIndexFromReferenceFrame:toReferenceFrame:offset:
|
|
@/textblock
|
|
</pre>
|
|
|
|
<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.
|
|
*/
|
|
|
|
|
|
/*!
|
|
@const MPIllegalElementException
|
|
@brief 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
|
|
@brief 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
|
|
@brief 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
|
|
@brief 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.
|
|
*/
|
|
@interface MPExpression : NSObject <NSCopying, NSCoding>
|
|
|
|
|
|
#pragma mark Creation Methods
|
|
/*!
|
|
@methodgroup Creation Methods
|
|
*/
|
|
|
|
|
|
/*!
|
|
@method init
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief 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.
|
|
|
|
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.
|
|
|
|
@return An expression containing <code>elements</code>.
|
|
*/
|
|
- (instancetype)initWithElements:(NSArray *)elements; /* designated initializer */
|
|
|
|
|
|
#pragma mark Querying Expressions
|
|
/*!
|
|
@methodgroup Querying Expressions
|
|
*/
|
|
|
|
|
|
/*!
|
|
@property parent
|
|
@brief 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.
|
|
|
|
@return The parent of the receiver or <code>nil</code> if the receiver is
|
|
the root expression.
|
|
*/
|
|
@property (nonatomic, weak) MPFunction *parent;
|
|
|
|
|
|
/*!
|
|
@method rootExpression
|
|
@brief 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
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief 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
|
|
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:
|
|
@brief 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>-itemAtIndex:referenceFrame:</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:
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief 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.
|
|
|
|
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:
|
|
@brief 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>
|
|
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:
|
|
@brief 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:
|
|
@brief 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>.
|
|
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>.
|
|
|
|
@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:
|
|
@brief 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>.
|
|
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:
|
|
@brief 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>-changedElementsInIndexedRangePath:replacementLength:</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:
|
|
@brief 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.
|
|
|
|
@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:
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief Parses the receiver.
|
|
|
|
@discussion This is a convenience method that calls
|
|
<code>-parseExpectingVariable:errors:</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>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.
|
|
*/
|
|
- (MPParsedExpression *)parse:(NSArray *__autoreleasing *)errors;
|
|
|
|
|
|
/*!
|
|
@method parseExpectingVariable:errors:
|
|
@brief 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>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.
|
|
*/
|
|
- (MPParsedExpression *)parseExpectingVariable:(BOOL)flag
|
|
errors:(NSArray *__autoreleasing *)errors;
|
|
|
|
@end
|
|
|
|
|
|
|
|
/*!
|
|
@category MPExpression (MPExpressionConvenience)
|
|
@brief 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
|
|
@brief 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
|
|
@brief 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
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief 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:
|
|
@brief Appends <code>anElement</code> to the receiver.
|
|
|
|
@param anElement
|
|
The element to append to the receiver.
|
|
*/
|
|
- (void)appendElement:(id<MPExpressionElement>)anElement;
|
|
|
|
|
|
/*!
|
|
@method appendElements:
|
|
@brief 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.
|
|
|
|
@param elements
|
|
The elements to append to the receiver.
|
|
*/
|
|
- (void)appendElements:(NSArray *)elements;
|
|
|
|
|
|
/*!
|
|
@method insertElement:atIndex:referenceFrame:
|
|
@brief 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:
|
|
@brief 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.
|
|
|
|
@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:
|
|
@brief 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
|