Improved Documentation and Code Style
This commit is contained in:
@@ -6,8 +6,6 @@
|
||||
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||
//
|
||||
|
||||
// TODO: Reorganise header/implementation order. Drop the primitive/not primitive Approach
|
||||
|
||||
#import "MPExpression.h"
|
||||
#import "MPFunction.h"
|
||||
#import "MPRangePath.h"
|
||||
@@ -17,31 +15,32 @@
|
||||
|
||||
#import "MPExpressionEvaluator.h"
|
||||
|
||||
|
||||
|
||||
@interface MPExpression () {
|
||||
NSMutableArray *__strong _elements;
|
||||
}
|
||||
|
||||
- (void)fixElements;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface MPExpression (MPExpressionPrivate)
|
||||
|
||||
- (void)validateElements:(NSArray *)elements;
|
||||
|
||||
- (NSUInteger)lengthOfElements:(NSArray *)elements;
|
||||
|
||||
- (void)validateElements:(NSArray *)elements;
|
||||
- (BOOL)splitElementsAtLocation:(NSUInteger)location
|
||||
insertionIndex:(out NSUInteger *)insertionIndex;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MPExpression (MPExpressionPrivate)
|
||||
|
||||
- (NSUInteger)lengthOfElements:(NSArray *)elements
|
||||
{
|
||||
NSUInteger length = 0;
|
||||
for (id<MPExpressionElement> element in elements) {
|
||||
length += element.length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
@implementation MPExpression (MPExpressionPrivate)
|
||||
|
||||
- (void)validateElements:(NSArray *)elements
|
||||
{
|
||||
@@ -54,6 +53,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)lengthOfElements:(NSArray *)elements
|
||||
{
|
||||
NSUInteger length = 0;
|
||||
for (id<MPExpressionElement> element in elements) {
|
||||
length += element.length;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
- (BOOL)splitElementsAtLocation:(NSUInteger)location
|
||||
insertionIndex:(out NSUInteger *)insertionIndex
|
||||
{
|
||||
@@ -63,7 +71,7 @@
|
||||
}
|
||||
|
||||
NSUInteger splitOffset;
|
||||
NSUInteger splitElementIndex = [self indexOfElementAtSymbolLocation:location
|
||||
NSUInteger splitElementIndex = [self indexOfElementAtLocation:location
|
||||
offset:&splitOffset];
|
||||
if (splitOffset != 0) {
|
||||
NSString *splitElement = (NSString *)self.elements[splitElementIndex];
|
||||
@@ -79,6 +87,8 @@
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation MPExpression {
|
||||
NSUInteger _cachedLength;
|
||||
NSRange _editedRange;
|
||||
@@ -86,7 +96,10 @@
|
||||
NSUInteger _replacementLength;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Creation Methods
|
||||
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
return [self initWithElements:@[]];
|
||||
@@ -101,6 +114,7 @@
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self validateElements:elements];
|
||||
_cachedLength = 0;
|
||||
_elements = [[NSMutableArray alloc] initWithArray:elements
|
||||
copyItems:YES];
|
||||
@@ -109,7 +123,10 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark Working With the Expression Tree
|
||||
|
||||
#pragma mark Private Methods
|
||||
|
||||
|
||||
- (void)fixElements
|
||||
{
|
||||
for (NSUInteger index = 0; index < self.elements.count; index++) {
|
||||
@@ -145,90 +162,33 @@
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Primitive Methods
|
||||
- (NSUInteger)length
|
||||
{
|
||||
if (_cachedLength == 0) {
|
||||
_cachedLength = [self lengthOfElements:self.elements];
|
||||
}
|
||||
return _cachedLength;
|
||||
}
|
||||
|
||||
#pragma mark Querying Expressions
|
||||
|
||||
|
||||
- (NSUInteger)numberOfElements
|
||||
{
|
||||
return self.elements.count;
|
||||
}
|
||||
|
||||
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx
|
||||
{
|
||||
[self replaceSymbolsInRange:NSMakeRange(idx, 1)
|
||||
withElements:@[obj]];
|
||||
}
|
||||
|
||||
- (id)objectAtIndexedSubscript:(NSUInteger)idx
|
||||
{
|
||||
return [self elementAtIndex:idx];
|
||||
}
|
||||
|
||||
- (id<MPExpressionElement>)elementAtIndex:(NSUInteger)anIndex
|
||||
{
|
||||
return self.elements[anIndex];
|
||||
}
|
||||
|
||||
- (NSArray *)elementsInRange:(NSRange)range
|
||||
- (NSArray *)elementsInIndexedRange:(NSRange)range
|
||||
{
|
||||
return [self.elements subarrayWithRange:range];
|
||||
}
|
||||
|
||||
#warning If multiple equal expressions exist errors may occur...
|
||||
- (NSUInteger)indexOfElement:(id<MPExpressionElement>)element
|
||||
- (NSArray *)elements
|
||||
{
|
||||
return [self.elements indexOfObject:element];
|
||||
return _elements;
|
||||
}
|
||||
|
||||
- (NSUInteger)indexOfElementAtSymbolLocation:(NSUInteger)location
|
||||
offset:(out NSUInteger *)offset
|
||||
{
|
||||
if (location == 0) {
|
||||
if (offset != NULL) {
|
||||
*offset = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculating elementIndex and splitOffset
|
||||
NSUInteger totalLength = 0;
|
||||
NSUInteger elementIndex = 0;
|
||||
NSUInteger elementLength = 0;
|
||||
for (id<MPExpressionElement> element in self.elements) {
|
||||
elementLength = element.length;
|
||||
totalLength += elementLength;
|
||||
if (totalLength >= location) {
|
||||
break;
|
||||
}
|
||||
++elementIndex;
|
||||
}
|
||||
NSUInteger splitOffset = elementLength - (totalLength - location);
|
||||
|
||||
id<MPExpressionElement> element = self.elements[elementIndex];
|
||||
if (splitOffset == element.length) {
|
||||
splitOffset = 0;
|
||||
elementIndex++;
|
||||
}
|
||||
if (offset != NULL) {
|
||||
*offset = splitOffset;
|
||||
}
|
||||
return elementIndex;
|
||||
}
|
||||
#pragma mark Mutating Expressions
|
||||
|
||||
- (NSUInteger)locationOfElementAtIndex:(NSUInteger)index
|
||||
{
|
||||
NSUInteger location = 0;
|
||||
for (NSUInteger i = 0; i < index; i++) {
|
||||
location += [self elementAtIndex:i].length;
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
- (void)replaceSymbolsInRange:(NSRange)range
|
||||
withElements:(NSArray *)elements
|
||||
@@ -268,14 +228,13 @@
|
||||
_replacementLength = elements.count + (didSplitStart ? 1 : 0) + (didSplitEnd ? 1 : 0);
|
||||
|
||||
[self fixElements];
|
||||
[self didChangeElementsInRangePath:[[MPRangePath alloc] initWithRange:_editedRange]
|
||||
[self didChangeElementsInIndexedRangePath:[[MPRangePath alloc] initWithRange:_editedRange]
|
||||
replacementLength:_replacementLength];
|
||||
}
|
||||
|
||||
- (NSArray *)elements
|
||||
{
|
||||
return _elements;
|
||||
}
|
||||
|
||||
#pragma mark Evaluating Expressions
|
||||
|
||||
|
||||
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
|
||||
{
|
||||
@@ -291,8 +250,11 @@
|
||||
return _evaluator;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Notifications
|
||||
- (void)didChangeElementsInRangePath:(MPRangePath *)rangePath
|
||||
|
||||
|
||||
- (void)didChangeElementsInIndexedRangePath:(MPRangePath *)rangePath
|
||||
replacementLength:(NSUInteger)replacementLength
|
||||
{
|
||||
NSUInteger selfIndex = [self.parent indexOfChild:self];
|
||||
@@ -301,7 +263,10 @@
|
||||
replacementLength:replacementLength];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Basic NSObject Methods
|
||||
|
||||
|
||||
/*
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
@@ -322,6 +287,7 @@
|
||||
return [self.elements isEqualToArray:anExpression.elements];
|
||||
}
|
||||
*/
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
#warning Bad Implementation
|
||||
@@ -361,14 +327,20 @@
|
||||
return [self.elements hash];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
|
||||
- (id)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
MPExpression *copy = [[MPExpression allocWithZone:zone] initWithElements:self.elements];
|
||||
return copy;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
// TODO: Test Coding
|
||||
@@ -382,9 +354,22 @@
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@implementation MPExpression (MPExpressionExtension)
|
||||
|
||||
#pragma mark Working With the Expression Tree
|
||||
|
||||
#pragma mark Querying Expressions
|
||||
|
||||
|
||||
- (NSUInteger)length
|
||||
{
|
||||
if (_cachedLength == 0) {
|
||||
_cachedLength = [self lengthOfElements:self.elements];
|
||||
}
|
||||
return _cachedLength;
|
||||
}
|
||||
|
||||
- (MPExpression *)rootExpression
|
||||
{
|
||||
if (self.parent == nil) {
|
||||
@@ -393,6 +378,31 @@
|
||||
return [self.parent rootExpression];
|
||||
}
|
||||
|
||||
- (NSIndexPath *)indexPath
|
||||
{
|
||||
if (self.parent) {
|
||||
NSUInteger selfIndex = [self.parent indexOfChild:self];
|
||||
return [[self.parent indexPath] indexPathByAddingIndex:selfIndex];
|
||||
} else {
|
||||
return [[NSIndexPath alloc] init];
|
||||
}
|
||||
}
|
||||
|
||||
- (id)objectAtIndexedSubscript:(NSUInteger)idx
|
||||
{
|
||||
return [self elementAtIndex:idx];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Working With Expressions
|
||||
|
||||
|
||||
- (id<MPExpressionElement>)elementAtLocation:(NSUInteger)location
|
||||
{
|
||||
NSUInteger index = [self indexOfElementAtLocation:location offset:NULL];
|
||||
return [self elementAtIndex:index];
|
||||
}
|
||||
|
||||
- (id)elementAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (indexPath.length == 0) {
|
||||
@@ -408,23 +418,106 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray *)elementsInRangePath:(MPRangePath *)rangePath
|
||||
- (NSArray *)elementsInIndexedRangePath:(MPRangePath *)rangePath
|
||||
{
|
||||
MPExpression *targetExpression = [self elementAtIndexPath:[rangePath.location indexPathByRemovingLastIndex]];
|
||||
return [targetExpression elementsInRange:rangePath.rangeAtLastIndex];
|
||||
return [targetExpression elementsInIndexedRange:rangePath.rangeAtLastIndex];
|
||||
}
|
||||
|
||||
- (NSIndexPath *)indexPath
|
||||
#warning If multiple equal expressions exist errors may occur...
|
||||
- (NSUInteger)indexOfElement:(id<MPExpressionElement>)element
|
||||
{
|
||||
if (self.parent) {
|
||||
NSUInteger selfIndex = [self.parent indexOfChild:self];
|
||||
return [[self.parent indexPath] indexPathByAddingIndex:selfIndex];
|
||||
} else {
|
||||
return [[NSIndexPath alloc] init];
|
||||
}
|
||||
return [self.elements indexOfObject:element];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Converting Between Indexes and Locations
|
||||
|
||||
|
||||
- (NSUInteger)indexOfElementAtLocation:(NSUInteger)location
|
||||
offset:(out NSUInteger *)offset
|
||||
{
|
||||
if (location == 0) {
|
||||
if (offset != NULL) {
|
||||
*offset = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Calculating elementIndex and splitOffset
|
||||
NSUInteger totalLength = 0;
|
||||
NSUInteger elementIndex = 0;
|
||||
NSUInteger elementLength = 0;
|
||||
for (id<MPExpressionElement> element in self.elements) {
|
||||
elementLength = element.length;
|
||||
totalLength += elementLength;
|
||||
if (totalLength >= location) {
|
||||
break;
|
||||
}
|
||||
++elementIndex;
|
||||
}
|
||||
NSUInteger elementOffset = elementLength - (totalLength - location);
|
||||
|
||||
id<MPExpressionElement> element = self.elements[elementIndex];
|
||||
if (elementOffset == element.length) {
|
||||
elementOffset = 0;
|
||||
elementIndex++;
|
||||
}
|
||||
if (offset != NULL) {
|
||||
*offset = elementOffset;
|
||||
}
|
||||
return elementIndex;
|
||||
}
|
||||
|
||||
- (NSUInteger)locationOfElementAtIndex:(NSUInteger)index
|
||||
{
|
||||
NSUInteger location = 0;
|
||||
for (NSUInteger i = 0; i < index; i++) {
|
||||
location += [self elementAtIndex:i].length;
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
- (NSRange)indexedRangeForRange:(NSRange)aRange
|
||||
{
|
||||
NSUInteger startLocation = aRange.location;
|
||||
NSUInteger endLocation = NSMaxRange(aRange);
|
||||
NSUInteger startIndex = [self indexOfElementAtLocation:startLocation offset:NULL];
|
||||
NSUInteger endIndex = [self indexOfElementAtLocation:endLocation offset:NULL];
|
||||
return NSMakeRange(startIndex, endIndex-startIndex);
|
||||
}
|
||||
|
||||
- (NSRange)rangeForIndexedRange:(NSRange)aRange
|
||||
{
|
||||
NSUInteger startIndex = aRange.location;
|
||||
NSUInteger endIndex = NSMaxRange(aRange);
|
||||
NSUInteger startLocation = [self locationOfElementAtIndex:startIndex];
|
||||
NSUInteger endLocation = [self locationOfElementAtIndex:endIndex];
|
||||
return NSMakeRange(startLocation, endLocation-startLocation);
|
||||
}
|
||||
|
||||
|
||||
#pragma mark Mutating Expressions
|
||||
|
||||
|
||||
- (MPExpression *)subexpressionFromIndex:(NSUInteger)from
|
||||
{
|
||||
NSUInteger fromLocation = [self locationOfElementAtIndex:from];
|
||||
return [self subexpressionFromLocation:fromLocation];
|
||||
}
|
||||
|
||||
- (MPExpression *)subexpressionToIndex:(NSUInteger)to
|
||||
{
|
||||
NSUInteger toLocation = [self locationOfElementAtIndex:to];
|
||||
return [self subexpressionToLocation:toLocation];
|
||||
}
|
||||
|
||||
- (MPExpression *)subexpressionWithIndexedRange:(NSRange)range
|
||||
{
|
||||
NSRange locationRange = [self rangeForIndexedRange:range];
|
||||
return [self subexpressionWithRange:locationRange];
|
||||
}
|
||||
|
||||
#pragma mark Working With Expressions
|
||||
- (MPExpression *)subexpressionFromLocation:(NSUInteger)from
|
||||
{
|
||||
return [self subexpressionWithRange:NSMakeRange(from, self.length - from)];
|
||||
@@ -446,7 +539,13 @@
|
||||
return subexpression;
|
||||
}
|
||||
|
||||
#pragma mark Mutating Expressions
|
||||
- (void)replaceElementsInIndexedRange:(NSRange)range
|
||||
withElements:(NSArray *)elements
|
||||
{
|
||||
[self replaceSymbolsInRange:[self rangeForIndexedRange:range]
|
||||
withElements:elements];
|
||||
}
|
||||
|
||||
- (void)appendElement:(id<MPExpressionElement>)anElement
|
||||
{
|
||||
[self appendElements:@[anElement]];
|
||||
@@ -457,6 +556,20 @@
|
||||
[self replaceSymbolsInRange:NSMakeRange(self.length, 0) withElements:elements];
|
||||
}
|
||||
|
||||
- (void)insertElement:(id<MPExpressionElement>)anElement
|
||||
atIndex:(NSUInteger)index
|
||||
{
|
||||
[self insertElement:anElement
|
||||
atLocation:[self locationOfElementAtIndex:index]];
|
||||
}
|
||||
|
||||
- (void)insertElements:(NSArray *)elements
|
||||
atIndex:(NSUInteger)index
|
||||
{
|
||||
[self insertElements:elements
|
||||
atLocation:[self locationOfElementAtIndex:index]];
|
||||
}
|
||||
|
||||
- (void)insertElement:(id<MPExpressionElement>)anElement
|
||||
atLocation:(NSUInteger)location
|
||||
{
|
||||
@@ -469,9 +582,20 @@
|
||||
[self replaceSymbolsInRange:NSMakeRange(location, 0) withElements:elements];
|
||||
}
|
||||
|
||||
- (void)deleteElementsInIndexedRange:(NSRange)range
|
||||
{
|
||||
[self deleteElementsInIndexedRange:[self rangeForIndexedRange:range]];
|
||||
}
|
||||
|
||||
- (void)deleteElementsInRange:(NSRange)range
|
||||
{
|
||||
[self replaceSymbolsInRange:range withElements:@[]];
|
||||
}
|
||||
|
||||
- (void)setObject:(id)obj atIndexedSubscript:(NSUInteger)idx
|
||||
{
|
||||
[self replaceSymbolsInRange:NSMakeRange(idx, 1)
|
||||
withElements:@[obj]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user