First implementation (incomplete) of MPExpression and MPFunction.
Declared custom exceptions in MPException.h
This commit is contained in:
15
MathPad/MPException.h
Normal file
15
MathPad/MPException.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// MPException.h
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 19.04.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MathPad_MPException_h
|
||||||
|
#define MathPad_MPException_h
|
||||||
|
|
||||||
|
extern NSString *MPIllegalSymbolException;
|
||||||
|
extern NSString *MPIllegalSymbolExceptionSymbolKey;
|
||||||
|
|
||||||
|
#endif
|
||||||
14
MathPad/MPException.m
Normal file
14
MathPad/MPException.m
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// MPException.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 19.04.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPException.h"
|
||||||
|
#import "MPException_Private.h"
|
||||||
|
|
||||||
|
NSString *MPIllegalSymbolException = @"MPIllegalSymbolException";
|
||||||
|
NSString *MPIllegalSymbolExceptionReason = @"Only NSString and MPFunction objects are valid symbols.";
|
||||||
|
NSString *MPIllegalSymbolExceptionSymbolKey = @"MPIllegalSymbolExceptionSymbolKey";
|
||||||
14
MathPad/MPException_Private.h
Normal file
14
MathPad/MPException_Private.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// MPException_Private.h
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 19.04.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef MathPad_MPException_Private_h
|
||||||
|
#define MathPad_MPException_Private_h
|
||||||
|
|
||||||
|
extern NSString *MPIllegalSymbolExceptionReason;
|
||||||
|
|
||||||
|
#endif
|
||||||
540
MathPad/MPExpression.m
Normal file
540
MathPad/MPExpression.m
Normal file
@@ -0,0 +1,540 @@
|
|||||||
|
//
|
||||||
|
// MPExpression.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 17.04.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPExpression.h"
|
||||||
|
#import "MPFunction.h"
|
||||||
|
#import "MPException.h"
|
||||||
|
#import "MPException_Private.h"
|
||||||
|
|
||||||
|
@interface MPExpression (MPExpressionPrivate)
|
||||||
|
|
||||||
|
- (NSInteger)lengthOfSymbol:(id)symbol;
|
||||||
|
- (void)validateSymbols:(NSArray *)symbols;
|
||||||
|
- (NSArray *)repairedSymbols:(NSArray *)symbols; // Merges subsequent strings
|
||||||
|
- (void)repairSymbols:(NSMutableArray *)symbols;
|
||||||
|
- (void)getSplitOffset:(out NSUInteger *)offset inSymbolAtIndex:(out NSUInteger *)symbolIndex forSplitLocation:(NSUInteger)loc;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPExpression {
|
||||||
|
@package
|
||||||
|
__strong NSArray *_symbols;
|
||||||
|
NSInteger _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Creation Methods
|
||||||
|
|
||||||
|
- (instancetype)initWithSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
[self validateSymbols:symbols];
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
symbols = [self repairedSymbols:symbols];
|
||||||
|
_symbols = [[NSArray alloc] initWithArray:symbols
|
||||||
|
copyItems:YES];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Primitive Methods
|
||||||
|
|
||||||
|
- (NSUInteger)numberOfSymbols
|
||||||
|
{
|
||||||
|
return [_symbols count];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)symbolAtIndex:(NSUInteger)index
|
||||||
|
{
|
||||||
|
return _symbols[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (double)doubleValue
|
||||||
|
{
|
||||||
|
#warning Unimplemented Method
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSCopying
|
||||||
|
|
||||||
|
- (id)copyWithZone:(NSZone *)zone
|
||||||
|
{
|
||||||
|
MPExpression *copy = [[MPExpression allocWithZone:zone] initWithSymbols:_symbols];
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSMutableCopying
|
||||||
|
|
||||||
|
- (id)mutableCopyWithZone:(NSZone *)zone
|
||||||
|
{
|
||||||
|
// TODO: Test Copying
|
||||||
|
MPMutableExpression *mutableCopy = [[MPMutableExpression allocWithZone:zone] initWithSymbols:_symbols];
|
||||||
|
return mutableCopy;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSCoding
|
||||||
|
|
||||||
|
- (id)initWithCoder:(NSCoder *)aDecoder
|
||||||
|
{
|
||||||
|
// TODO: Test Coding
|
||||||
|
return [self initWithSymbols:[aDecoder decodeObject]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(NSCoder *)aCoder
|
||||||
|
{
|
||||||
|
[aCoder encodeObject:_symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPExpression (MPExpressionPrivate)
|
||||||
|
|
||||||
|
- (NSInteger)lengthOfSymbol:(id)symbol
|
||||||
|
{
|
||||||
|
if ([symbol isKindOfClass:[NSString class]]) {
|
||||||
|
return [symbol length];
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Deal with subsequent strings
|
||||||
|
- (void)validateSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
for (id symbol in symbols) {
|
||||||
|
if (!([symbol isKindOfClass:[NSString class]]
|
||||||
|
|| [symbol isKindOfClass:[MPFunction class]])) {
|
||||||
|
@throw [NSException exceptionWithName:MPIllegalSymbolException
|
||||||
|
reason:MPIllegalSymbolExceptionReason
|
||||||
|
userInfo:@{MPIllegalSymbolExceptionSymbolKey: symbol}];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)repairedSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
NSMutableArray *mutableSymbols = [symbols mutableCopy];
|
||||||
|
[self repairSymbols:mutableSymbols];
|
||||||
|
return [mutableSymbols copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)repairSymbols:(NSMutableArray *)symbols
|
||||||
|
{
|
||||||
|
for (NSInteger index = 1; index < symbols.count; index++) {
|
||||||
|
id last = symbols[index-1];
|
||||||
|
id current = symbols[index];
|
||||||
|
if ([last isKindOfClass:[NSString class]] && [current isKindOfClass:[NSString class]]) {
|
||||||
|
NSMutableString *new = [NSMutableString stringWithFormat:@"%@%@", last, current];
|
||||||
|
[symbols replaceObjectAtIndex:index-1 withObject:new];
|
||||||
|
[symbols removeObjectAtIndex:index];
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)getSplitOffset:(out NSUInteger *)offset inSymbolAtIndex:(out NSUInteger *)symbolIndex forSplitLocation:(NSUInteger)loc
|
||||||
|
{
|
||||||
|
NSUInteger length = 0;
|
||||||
|
NSUInteger index = 0;
|
||||||
|
NSUInteger symbolLength = 0;
|
||||||
|
for (id symbol in _symbols) {
|
||||||
|
symbolLength = [self lengthOfSymbol:symbol];
|
||||||
|
length += symbolLength;
|
||||||
|
if (length >= loc) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
*offset = symbolLength - (length - loc);
|
||||||
|
*symbolIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPExpression (MPExpressionExtensionMethods)
|
||||||
|
|
||||||
|
#pragma mark Creation Methods
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
return [self initWithSymbols:@[]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithString:(NSString *)aString
|
||||||
|
{
|
||||||
|
return [self initWithSymbols:@[aString]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFunction:(MPFunction *)aFunction
|
||||||
|
{
|
||||||
|
return [self initWithSymbols:@[aFunction]];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)expression
|
||||||
|
{
|
||||||
|
return [[self alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)expressionWithString:(NSString *)aString
|
||||||
|
{
|
||||||
|
return [[self alloc] initWithString:aString];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)expressionWithFunction:(MPFunction *)aFunction
|
||||||
|
{
|
||||||
|
return [[self alloc] initWithFunction:aFunction];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (instancetype)expressionWithSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
return [[self alloc] initWithSymbols:symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Working with Expressions
|
||||||
|
|
||||||
|
- (NSUInteger)length
|
||||||
|
{
|
||||||
|
if (_length == 0) {
|
||||||
|
for (id symbol in _symbols) {
|
||||||
|
_length += [self lengthOfSymbol:symbol];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _length;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPExpression *)subexpressionFromIndex:(NSUInteger)from
|
||||||
|
{
|
||||||
|
return [self subexpressionWithRange:NSMakeRange(from, [self length] - from)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPExpression *)subexpressionToIndex:(NSUInteger)to
|
||||||
|
{
|
||||||
|
return [self subexpressionWithRange:NSMakeRange(0, to)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPExpression *)subexpressionWithRange:(NSRange)range
|
||||||
|
{
|
||||||
|
if (NSMaxRange(range) > self.length) {
|
||||||
|
@throw [NSException exceptionWithName:NSRangeException reason:@"Range outside bounds of expression." userInfo:nil];
|
||||||
|
}
|
||||||
|
if (range.location == self.length || NSMaxRange(range) == 0 || range.length == 0) {
|
||||||
|
// Speed this up
|
||||||
|
return [[MPExpression alloc] init];
|
||||||
|
}
|
||||||
|
NSUInteger startOffset;
|
||||||
|
NSUInteger startSymbolIndex;
|
||||||
|
[self getSplitOffset:&startOffset inSymbolAtIndex:&startSymbolIndex forSplitLocation:range.location];
|
||||||
|
id startSymbol = _symbols[startSymbolIndex];
|
||||||
|
if (startOffset == [self lengthOfSymbol:startSymbol]) {
|
||||||
|
startOffset = 0;
|
||||||
|
startSymbolIndex++;
|
||||||
|
startSymbol = _symbols[startSymbolIndex];
|
||||||
|
} else if ([startSymbol isKindOfClass:[NSString class]]) {
|
||||||
|
startSymbol = [startSymbol substringFromIndex:startOffset];
|
||||||
|
}
|
||||||
|
NSUInteger endOffset;
|
||||||
|
NSUInteger endSymbolIndex;
|
||||||
|
[self getSplitOffset:&endOffset inSymbolAtIndex:&endSymbolIndex forSplitLocation:NSMaxRange(range)];
|
||||||
|
id endSymbol = _symbols[endSymbolIndex];
|
||||||
|
if ([endSymbol isKindOfClass:[NSString class]]) {
|
||||||
|
endSymbol = [endSymbol substringToIndex:endOffset];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
NSMutableArray *symbols = [[NSMutableArray alloc] initWithCapacity:endSymbolIndex-startSymbolIndex+1];
|
||||||
|
[symbols addObject:startSymbol];
|
||||||
|
if (endSymbolIndex > startSymbolIndex + 1) {
|
||||||
|
NSInteger restLength = endSymbolIndex - startSymbolIndex - 1;
|
||||||
|
[symbols addObjectsFromArray:[_symbols subarrayWithRange:NSMakeRange(startSymbolIndex+1, restLength)]];
|
||||||
|
}
|
||||||
|
if (endSymbolIndex > startSymbolIndex) {
|
||||||
|
[symbols addObject:endSymbol];
|
||||||
|
} else if (endSymbolIndex == startSymbolIndex && [startSymbol isKindOfClass:[NSString class]]) {
|
||||||
|
NSString *result = [_symbols[startSymbolIndex] substringWithRange:NSMakeRange(startOffset, endOffset-startOffset)];
|
||||||
|
[symbols replaceObjectAtIndex:0 withObject:result];
|
||||||
|
}
|
||||||
|
return [[MPExpression alloc] initWithSymbols:symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isEqual:(id)object
|
||||||
|
{
|
||||||
|
if (self == object) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
if (object == nil) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
if (![object isKindOfClass:[MPExpression class]]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return [self isEqualToExpression:(MPExpression *)object];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isEqualToExpression:(MPExpression *)anExpression
|
||||||
|
{
|
||||||
|
// TODO: Use ->_symbols or .symbols
|
||||||
|
return [_symbols isEqualToArray:anExpression->_symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: prefix and suffix operators
|
||||||
|
|
||||||
|
- (MPExpression *)expressionByAppendingString:(NSString *)aString
|
||||||
|
{
|
||||||
|
return [self expressionByAppendingSymbols:@[aString]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPExpression *)expressionByAppendingFunction:(MPFunction *)aFunction
|
||||||
|
{
|
||||||
|
return [self expressionByAppendingSymbols:@[aFunction]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPExpression *)expressionByAppendingExpression:(MPExpression *)anExpression
|
||||||
|
{
|
||||||
|
return [self expressionByAppendingSymbols:anExpression.symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPExpression *)expressionByAppendingSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
return [[MPExpression alloc] initWithSymbols:[_symbols arrayByAddingObjectsFromArray:symbols]];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Evaluating Expressions
|
||||||
|
|
||||||
|
- (float)floatValue
|
||||||
|
{
|
||||||
|
return (float)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)intValue
|
||||||
|
{
|
||||||
|
return (int)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)integerValue
|
||||||
|
{
|
||||||
|
return (NSInteger)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (long long)longLongValue
|
||||||
|
{
|
||||||
|
return (long long)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Querying an Expression's Contents
|
||||||
|
|
||||||
|
- (NSArray *)symbols
|
||||||
|
{
|
||||||
|
// _symbols is immutable so it is ok to just return it instead of making a copy
|
||||||
|
return _symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)description
|
||||||
|
{
|
||||||
|
#warning Unimplemented Method
|
||||||
|
/*
|
||||||
|
Join the symbols regarding pre- and suffix operators. If there is no operator a * should be inserted
|
||||||
|
*/
|
||||||
|
return [super description];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)hash
|
||||||
|
{
|
||||||
|
return [_symbols hash];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface MPMutableExpression (MPMutableExpressionPrivate)
|
||||||
|
|
||||||
|
- (NSArray *)makeSymbols:(NSArray *)symbols mutable:(BOOL)mutable copySymbols:(BOOL)copy;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPMutableExpression (MPMutableExpressionPrivate)
|
||||||
|
|
||||||
|
- (NSArray *)makeSymbols:(NSArray *)symbols mutable:(BOOL)mutable copySymbols:(BOOL)copy
|
||||||
|
{
|
||||||
|
NSMutableArray *newSymbols = [[NSMutableArray alloc] initWithCapacity:symbols.count];
|
||||||
|
for (id symbol in symbols) {
|
||||||
|
id newSymbol;
|
||||||
|
if ([symbol isKindOfClass:[NSString class]]) {
|
||||||
|
if (mutable) {
|
||||||
|
newSymbol = [symbol mutableCopy];
|
||||||
|
} else {
|
||||||
|
newSymbol = [symbol copy];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (copy) {
|
||||||
|
newSymbol = [symbol copy];
|
||||||
|
} else {
|
||||||
|
newSymbol = symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[newSymbols addObject:newSymbol];
|
||||||
|
}
|
||||||
|
return newSymbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
// A mutable expression uses NSMutableString objects instead of NSString objects
|
||||||
|
@implementation MPMutableExpression
|
||||||
|
|
||||||
|
- (instancetype)initWithSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
[self validateSymbols:symbols];
|
||||||
|
self = [super initWithSymbols:nil];
|
||||||
|
if (self) {
|
||||||
|
symbols = [self repairedSymbols:symbols];
|
||||||
|
_symbols = [self makeSymbols:symbols
|
||||||
|
mutable:YES
|
||||||
|
copySymbols:YES];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)symbolAtIndex:(NSUInteger)index
|
||||||
|
{
|
||||||
|
id symbol = _symbols[index];
|
||||||
|
if ([symbol isKindOfClass:[NSString class]]) {
|
||||||
|
return [symbol copy];
|
||||||
|
}
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *)symbols
|
||||||
|
{
|
||||||
|
return [self makeSymbols:_symbols mutable:NO copySymbols:NO];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)replaceSymbolsInRange:(NSRange)range withSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
if (NSMaxRange(range) > self.length) {
|
||||||
|
@throw [NSException exceptionWithName:NSRangeException reason:@"Range out of bounds of expression." userInfo:nil];
|
||||||
|
}
|
||||||
|
[self validateSymbols:symbols];
|
||||||
|
|
||||||
|
// Locate the position, split the symbols
|
||||||
|
NSUInteger startIndex;
|
||||||
|
[self splitSymbolsAtLocation:range.location insertionIndex:&startIndex];
|
||||||
|
|
||||||
|
// Perform the deletion
|
||||||
|
if (range.length > 0) {
|
||||||
|
NSUInteger endIndex;
|
||||||
|
[self splitSymbolsAtLocation:NSMaxRange(range) insertionIndex:&endIndex];
|
||||||
|
NSMutableIndexSet *indexes = [[NSMutableIndexSet alloc] init];
|
||||||
|
for (NSUInteger index = startIndex; index < endIndex; index++) {
|
||||||
|
[indexes addIndex:index];
|
||||||
|
}
|
||||||
|
[(NSMutableArray *)_symbols removeObjectsAtIndexes:indexes];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Perform the insertion
|
||||||
|
if (symbols.count > 0) {
|
||||||
|
NSArray *newSymbols = [self makeSymbols:symbols mutable:YES copySymbols:YES];
|
||||||
|
[(NSMutableArray *)_symbols replaceObjectsInRange:NSMakeRange(startIndex, 0) withObjectsFromArray:newSymbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Revalidate structure and invalidate length
|
||||||
|
[self repairSymbols:(NSMutableArray *)_symbols];
|
||||||
|
_length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)splitSymbolsAtLocation:(NSUInteger)loc insertionIndex:(out NSUInteger *)insertionIndex
|
||||||
|
{
|
||||||
|
NSUInteger splitSymbolIndex;
|
||||||
|
NSUInteger splitOffset;
|
||||||
|
[self getSplitOffset:&splitOffset inSymbolAtIndex:&splitSymbolIndex forSplitLocation:loc];
|
||||||
|
id splitSymbol = _symbols[splitSymbolIndex];
|
||||||
|
NSInteger splitSymbolLength = [self lengthOfSymbol:splitSymbol];
|
||||||
|
if (splitOffset == splitSymbolLength) {
|
||||||
|
splitOffset = 0;
|
||||||
|
splitSymbolIndex++;
|
||||||
|
}
|
||||||
|
if (splitOffset != 0) {
|
||||||
|
NSMutableString *leftPart = [[splitSymbol substringToIndex:splitOffset] mutableCopy];
|
||||||
|
NSMutableString *rightPart = [[splitSymbol substringFromIndex:splitOffset] mutableCopy];
|
||||||
|
[(NSMutableArray *)_symbols replaceObjectAtIndex:splitSymbolIndex withObject:leftPart];
|
||||||
|
splitSymbolIndex++;
|
||||||
|
[(NSMutableArray *)_symbols insertObject:rightPart atIndex:splitSymbolIndex];
|
||||||
|
}
|
||||||
|
*insertionIndex = splitSymbolIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPMutableExpression (MPMutableExpressionExtensionMethods)
|
||||||
|
|
||||||
|
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)loc
|
||||||
|
{
|
||||||
|
[self insertSymbols:@[aString] atIndex:loc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)insertFunction:(MPFunction *)aFunction atIndex:(NSUInteger)loc
|
||||||
|
{
|
||||||
|
[self insertSymbols:@[aFunction] atIndex:loc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)insertExpression:(MPExpression *)anExpression atIndex:(NSUInteger)loc
|
||||||
|
{
|
||||||
|
[self insertSymbols:anExpression.symbols atIndex:loc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)insertSymbols:(NSArray *)symbols atIndex:(NSUInteger)loc
|
||||||
|
{
|
||||||
|
[self replaceSymbolsInRange:NSMakeRange(loc, 0)
|
||||||
|
withSymbols:symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)deleteSymbolsInRange:(NSRange)range
|
||||||
|
{
|
||||||
|
[self replaceSymbolsInRange:range
|
||||||
|
withSymbols:@[]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)appendString:(NSString *)aString
|
||||||
|
{
|
||||||
|
[self appendSymbols:@[aString]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)appendFunction:(MPFunction *)aFunction
|
||||||
|
{
|
||||||
|
[self appendSymbols:@[aFunction]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)appendExpression:(MPExpression *)anExpression
|
||||||
|
{
|
||||||
|
[self appendSymbols:anExpression.symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)appendSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
[self replaceSymbolsInRange:NSMakeRange(self.length, 0)
|
||||||
|
withSymbols:symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setString:(NSString *)aString
|
||||||
|
{
|
||||||
|
[self setSymbols:@[aString]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFunction:(MPFunction *)aFunction
|
||||||
|
{
|
||||||
|
[self setSymbols:@[aFunction]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setExpression:(MPExpression *)anExpression
|
||||||
|
{
|
||||||
|
[self setSymbols:anExpression.symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setSymbols:(NSArray *)symbols
|
||||||
|
{
|
||||||
|
[self replaceSymbolsInRange:NSMakeRange(0, self.length)
|
||||||
|
withSymbols:symbols];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
135
MathPad/MPFunction.m
Normal file
135
MathPad/MPFunction.m
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
//
|
||||||
|
// MPFunction.m
|
||||||
|
// MathPad
|
||||||
|
//
|
||||||
|
// Created by Kim Wittenburg on 18.04.14.
|
||||||
|
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "MPFunction.h"
|
||||||
|
|
||||||
|
@implementation MPFunction
|
||||||
|
|
||||||
|
#pragma mark Creation Methods
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Children
|
||||||
|
|
||||||
|
- (NSUInteger)numberOfChildren
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (MPExpression *)childAtIndex:(NSUInteger)index
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setChild:(MPExpression *)child atIndex:(NSUInteger)index
|
||||||
|
{}
|
||||||
|
|
||||||
|
#pragma mark Evaluating Functions
|
||||||
|
|
||||||
|
- (double)doubleValue
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Working With Functions
|
||||||
|
|
||||||
|
- (BOOL)isEqual:(id)object
|
||||||
|
{
|
||||||
|
if (self == object) {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
if (object == nil) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
if (![object isKindOfClass:[MPFunction class]]) {
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
return [self isEqualToFunction:(MPFunction *)object];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)isEqualToFunction:(MPFunction *)aFunction
|
||||||
|
{
|
||||||
|
return [aFunction isMemberOfClass:[MPFunction class]] && [self isMemberOfClass:[MPFunction class]];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSCopying
|
||||||
|
|
||||||
|
- (id)copyWithZone:(NSZone *)zone
|
||||||
|
{
|
||||||
|
return [[MPFunction allocWithZone:zone] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark - NSCoding
|
||||||
|
|
||||||
|
- (id)initWithCoder:(NSCoder *)aDecoder
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)encodeWithCoder:(NSCoder *)aCoder
|
||||||
|
{}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation MPFunction (MPFunctionExtensionMethods)
|
||||||
|
|
||||||
|
#pragma mark Children
|
||||||
|
|
||||||
|
- (NSArray *)children
|
||||||
|
{
|
||||||
|
NSUInteger childCount = [self numberOfChildren];
|
||||||
|
NSMutableArray *children = [[NSMutableArray alloc] initWithCapacity:childCount];
|
||||||
|
for (NSInteger i = 0; i < childCount; i++) {
|
||||||
|
[children addObject:[self childAtIndex:i]];
|
||||||
|
}
|
||||||
|
return [children copy];
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma mark Evaluating Functions
|
||||||
|
|
||||||
|
- (float)floatValue
|
||||||
|
{
|
||||||
|
return (float)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)intValue
|
||||||
|
{
|
||||||
|
return (int)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger)integerValue
|
||||||
|
{
|
||||||
|
return (NSInteger)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (long long)longLongValue
|
||||||
|
{
|
||||||
|
return (long long)[self doubleValue];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *)description
|
||||||
|
{
|
||||||
|
return @"[]";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSUInteger)hash
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
Reference in New Issue
Block a user