Archived
1

Updated Schemes

This commit is contained in:
Kim Wittenburg
2014-09-28 23:56:17 +02:00
parent 898a87058c
commit 0972e158f1
39 changed files with 84 additions and 1675 deletions

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3B85830C19BB5E5500D76A8D"
BuildableName = "MathKit.framework"
BlueprintName = "MathKit"
ReferencedContainer = "container:MathPad.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
buildConfiguration = "Debug">
<Testables>
</Testables>
</TestAction>
<LaunchAction
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
buildConfiguration = "Debug"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
allowLocationSimulation = "YES">
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
buildConfiguration = "Release"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -38,6 +38,16 @@
ReferencedContainer = "container:MathPad.xcodeproj"> ReferencedContainer = "container:MathPad.xcodeproj">
</BuildableReference> </BuildableReference>
</TestableReference> </TestableReference>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "3B85831C19BB5E5500D76A8D"
BuildableName = "MathKitTests.xctest"
BlueprintName = "MathKitTests"
ReferencedContainer = "container:MathPad.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables> </Testables>
<MacroExpansion> <MacroExpansion>
<BuildableReference <BuildableReference

View File

@@ -4,6 +4,11 @@
<dict> <dict>
<key>SchemeUserState</key> <key>SchemeUserState</key>
<dict> <dict>
<key>MathKit.xcscheme</key>
<dict>
<key>orderHint</key>
<integer>1</integer>
</dict>
<key>MathPad.xcscheme</key> <key>MathPad.xcscheme</key>
<dict> <dict>
<key>orderHint</key> <key>orderHint</key>
@@ -12,6 +17,16 @@
</dict> </dict>
<key>SuppressBuildableAutocreation</key> <key>SuppressBuildableAutocreation</key>
<dict> <dict>
<key>3B85830C19BB5E5500D76A8D</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>3B85831C19BB5E5500D76A8D</key>
<dict>
<key>primary</key>
<true/>
</dict>
<key>3BF9976A18DE623E009CF6C4</key> <key>3BF9976A18DE623E009CF6C4</key>
<dict> <dict>
<key>primary</key> <key>primary</key>

View File

@@ -1,21 +0,0 @@
//
// MPExpression+MPDisplayExtension.h
// MathPad
//
// Created by Kim Wittenburg on 23.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPModel.h"
@interface MPExpression (MPDisplayExtension)
- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath;
@end
@interface MPFunction (MPDisplayExtension)
- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath;
@end

View File

@@ -1,33 +0,0 @@
//
// MPExpression+MPDisplayExtension.m
// MathPad
//
// Created by Kim Wittenburg on 23.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPDisplayExtension.h"
@implementation MPExpression (MPDisplayExtension)
- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath
{
NSUInteger index = [self.parent indexOfChild:self];
NSIndexPath *newLocation = [rangePath.location indexPathByPrecedingIndex:index];
[self.parent subexpressionChangedAtRangePath:[[MPRangePath alloc] initWithLocation:newLocation
length:rangePath.length]];
}
@end
@implementation MPFunction (MPDisplayExtension)
- (void)subexpressionChangedAtRangePath:(MPRangePath *)rangePath
{
NSUInteger index = [self.parent indexOfSymbol:self];
NSIndexPath *newLocation = [rangePath.location indexPathByPrecedingIndex:index];
[self.parent subexpressionChangedAtRangePath:[[MPRangePath alloc] initWithLocation:newLocation
length:rangePath.length]];
}
@end

View File

@@ -1,28 +0,0 @@
//
// MPElementParser.h
// MathPad
//
// Created by Kim Wittenburg on 10.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MPParsedProduct.h"
#import "MPParseError.h"
#define MPMaximumOperatorChainLength NSUIntegerMax
@interface MPElementParser : NSObject
- (NSArray *)parseElement:(NSString *)string
previousProduct:(MPParsedProduct *)previousProduct
nextFactor:(id<MPParsedFactor>)nextFactor
definesVariable:(BOOL)flag
definedVariable:(NSString *__autoreleasing *)variableName
error:(out MPParseError *__autoreleasing *)error;
- (NSArray *)parseElement:(NSString *)string
previousProduct:(MPParsedProduct *)previousProduct
nextFactor:(id<MPParsedFactor>)nextFactor
error:(out MPParseError *__autoreleasing *)error;
@end

View File

@@ -1,345 +0,0 @@
//
// MPElementParser.m
// MathPad
//
// Created by Kim Wittenburg on 10.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPElementParser.h"
#import "NSRegularExpression+MPParsingAdditions.h"
#import "MPMathRules.h"
#import "MPParsedFactor.h"
#import "MPParsedNumber.h"
#import "MPParsedVariable.h"
#import "MPParsedOperator.h"
#define MPMultiplicationSymbol @"*"
@interface MPElementParser ()
@property (nonatomic) NSString *input;
@property (nonatomic) NSUInteger parsePosition;
- (BOOL)allowsImplicitMultiplication;
- (BOOL)maximumOperatorChainLength;
- (BOOL)maximumOperatorChainLengthInMultiplication;
- (BOOL)maximumOperatorChainLengthInFunction;
- (void)setError:(MPParseError *)error;
- (BOOL)isAtEnd;
- (NSRange)parseVariableDefinition:(NSString *__autoreleasing *)variableName;
- (NSRange)parseWhitespaces;
- (NSRange)parseMultiplicationSymbol;
- (MPParsedOperator *)parseOperators;
- (id<MPParsedFactor>)parseValue;
- (MPParsedNumber *)parseNumber;
- (MPParsedVariable *)parseVariable;
@end
@implementation MPElementParser {
MPParseError *__autoreleasing *outError;
}
#pragma mark Helpers
- (BOOL)allowsImplicitMultiplication
{
return [MPMathRules sharedRules].allowsImplicitMultiplication;
}
- (BOOL)maximumOperatorChainLength
{
return [MPMathRules sharedRules].maximumOperatorChainLength;
}
- (BOOL)maximumOperatorChainLengthInFunction
{
return [MPMathRules sharedRules].maximumOperatorChainLengthInFunction;
}
- (BOOL)maximumOperatorChainLengthInMultiplication
{
return [MPMathRules sharedRules].maximumOperatorChainLengthInMultiplication;
}
#pragma mark Parsing Methods
- (BOOL)isAtEnd
{
return self.parsePosition >= self.input.length;
}
- (void)setError:(MPParseError *)error
{
if (outError != NULL) {
*outError = error;
}
}
- (NSArray *)parseElement:(NSString *)string
previousProduct:(MPParsedProduct *)previousProduct
nextFactor:(id<MPParsedFactor>)nextFactor
error:(out MPParseError *__autoreleasing *)error
{
return [self parseElement:string
previousProduct:previousProduct
nextFactor:nextFactor
definesVariable:NO
definedVariable:NULL
error:error];
}
- (NSArray *)parseElement:(NSString *)string
previousProduct:(MPParsedProduct *)previousProduct
nextFactor:(id<MPParsedFactor>)nextFactor
definesVariable:(BOOL)flag
definedVariable:(NSString *__autoreleasing *)variableName
error:(out MPParseError *__autoreleasing *)error
{
self.input = string;
outError = error;
self.parsePosition = 0;
NSString *definedVariable;
NSRange variableDefinitionRange = [self parseVariableDefinition:&definedVariable];
if (flag) {
if (!definedVariable) {
self.error = MPParseError(NSMakeRange(0, 0), @"Expected Variable Definition");
return nil;
} else if (variableName) {
*variableName = definedVariable;
}
} else if (definedVariable) {
self.error = MPParseError(variableDefinitionRange, @"Unexpected Variable Definition");
return nil;
}
NSMutableArray *products = [[NSMutableArray alloc] init];
MPParsedProduct *currentProduct = previousProduct;
while (YES) {
[self parseWhitespaces];
NSRange multiplicationSymbolRange = [self parseMultiplicationSymbol];
BOOL hasMultiplicationSymbol = multiplicationSymbolRange.location != NSNotFound;
MPParsedOperator *operators = [self parseOperators];
// NSRange functionRange = ...
// BOOL hasFunction = functionRange.location != NSNotFound;
id<MPParsedFactor> value = [self parseValue];
if (!value.exists) {
if ([self isAtEnd] && nextFactor != nil) {
if (hasMultiplicationSymbol) {
if (operators.numberOfOperators > self.maximumOperatorChainLengthInFunction) {
self.error = MPParseError(operators.range, @"Too many operators in multiplication.");
return nil;
}
[currentProduct addFactor:operators];
} else if (operators.exists) {
if (operators.numberOfOperators > self.maximumOperatorChainLength) {
self.error = MPParseError(operators.range, @"Too many operators.");
return nil;
}
[products addObject:currentProduct];
currentProduct = [[MPParsedProduct alloc] init];
[currentProduct addFactor:operators];
} else if (self.allowsImplicitMultiplication) {
if (!currentProduct) {
currentProduct = [[MPParsedProduct alloc] init];
}
} else {
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Implicit Multiplication not allowed.");
return nil;
}
break;
} else if ([self isAtEnd]) {
if (hasMultiplicationSymbol || operators.exists) {
self.error = MPParseError(NSMakeRange(self.parsePosition, 0), @"Unexpected End. Expected Number.");
return nil;
}
} else {
self.error = MPParseError(NSMakeRange(self.parsePosition, 1), @"Unexpected Symbol. Expected Number.");
return nil;
}
break;
} else {
if (hasMultiplicationSymbol) {
if (currentProduct) {
if (operators.numberOfOperators > self.maximumOperatorChainLengthInMultiplication) {
self.error = MPParseError(operators.range, @"Too many operators in multiplication.");
return nil;
}
[currentProduct addFactor:operators];
[currentProduct addFactor:value];
} else {
self.error = MPParseError(multiplicationSymbolRange, @"Unexpected Symbol. Expected Number.");
return nil;
}
} else if (operators.exists) {
if (operators.numberOfOperators > self.maximumOperatorChainLength) {
self.error = MPParseError(operators.range, @"Too many operators.");
return nil;
}
if (currentProduct) {
[products addObject:currentProduct];
}
currentProduct = [[MPParsedProduct alloc] initWithFactor:operators];
[currentProduct addFactor:value];
} else if (!currentProduct) {
currentProduct = [[MPParsedProduct alloc] initWithFactor:value];
} else if (self.allowsImplicitMultiplication) {
[currentProduct addFactor:value];
} else {
self.error = MPParseError(NSMakeRange(value.range.location, 0), @"Implicit Multiplication not allowed.");
return nil;
}
}
}
if (nextFactor) {
[currentProduct addFactor:nextFactor];
}
[products addObject:currentProduct];
return products;
}
static NSRegularExpression *variableDefinitionRegex;
- (NSRange)parseVariableDefinition:(NSString *__autoreleasing *)variableName
{
if (!variableDefinitionRegex) {
variableDefinitionRegex = [NSRegularExpression regularExpressionWithPattern:@"\\A\\s*([A-Za-z])\\s*=\\s*"
options:0
error:NULL];
}
NSTextCheckingResult *match = [variableDefinitionRegex firstMatchInString:self.input
fromIndex:self.parsePosition];
if (!match) {
return NSMakeRange(NSNotFound, 0);
}
self.parsePosition = NSMaxRange(match.range);
NSRange variableDefinitionRange = [match rangeAtIndex:1];
*variableName = [self.input substringWithRange:variableDefinitionRange];
return variableDefinitionRange;
}
static NSRegularExpression *whitespaceRegex;
- (NSRange)parseWhitespaces
{
if (!whitespaceRegex) {
whitespaceRegex = [NSRegularExpression regularExpressionWithPattern:@"\\A\\s*"
options:0
error:NULL];
}
NSTextCheckingResult *match = [whitespaceRegex firstMatchInString:self.input
fromIndex:self.parsePosition];
if (match) {
self.parsePosition = NSMaxRange(match.range);
return match.range;
} else {
return NSMakeRange(NSNotFound, 0);
}
}
static NSRegularExpression *multiplicationSymbolRegex;
- (NSRange)parseMultiplicationSymbol
{
if (!multiplicationSymbolRegex) {
NSString *multiplicationSymbolString = [NSRegularExpression escapedPatternForString:MPMultiplicationSymbol];
NSString *multiplicationSymbolRegexString = [NSString stringWithFormat:@"\\A\\s*(%@)\\s*", multiplicationSymbolString];
multiplicationSymbolRegex = [NSRegularExpression regularExpressionWithPattern:multiplicationSymbolRegexString
options:0
error:NULL];
}
NSTextCheckingResult *match = [multiplicationSymbolRegex firstMatchInString:self.input
fromIndex:self.parsePosition];
if (!match) {
return NSMakeRange(NSNotFound, 0);
}
self.parsePosition = NSMaxRange(match.range);
return [match rangeAtIndex:1];
}
static NSRegularExpression *operatorsRegex;
- (MPParsedOperator *)parseOperators
{
if (!operatorsRegex) {
operatorsRegex = [NSRegularExpression regularExpressionWithPattern:@"\\A\\s*([+-](?:\\s*[+-])*)\\s*"
options:0
error:NULL];
}
NSTextCheckingResult *match = [operatorsRegex firstMatchInString:self.input
fromIndex:self.parsePosition];
NSRange matchRange;
if (!match) {
matchRange = NSMakeRange(NSNotFound, 0);
} else {
self.parsePosition = NSMaxRange(match.range);
matchRange = [match rangeAtIndex:1];
}
return [[MPParsedOperator alloc] initWithRange:matchRange
inString:self.input];
}
- (id<MPParsedFactor>)parseValue
{
MPParsedNumber *parsedNumber = [self parseNumber];
if (!parsedNumber.exists) {
MPParsedVariable *parsedVariable = [self parseVariable];
if (parsedVariable.exists) {
return parsedVariable;
}
}
return parsedNumber;
}
- (MPParsedNumber *)parseNumber
{
NSString *decimalSeparatorRegexString = [NSRegularExpression escapedPatternForString:[[NSLocale currentLocale] objectForKey:NSLocaleDecimalSeparator]];
NSString *numberRegexFormat = [NSString stringWithFormat:@"\\A\\s*((?:\\d+(?:%@\\d+)?)|(?:%@\\d+))\\s*", decimalSeparatorRegexString, decimalSeparatorRegexString];
NSRegularExpression *numberRegex = [NSRegularExpression regularExpressionWithPattern:numberRegexFormat
options:0
error:NULL];
NSTextCheckingResult *match = [numberRegex firstMatchInString:self.input
fromIndex:self.parsePosition];
NSRange matchRange;
if (!match) {
matchRange = NSMakeRange(NSNotFound, 0);
} else {
self.parsePosition = NSMaxRange(match.range);
matchRange = [match rangeAtIndex:1];
}
return [[MPParsedNumber alloc] initWithRange:matchRange
inString:self.input];
}
static NSRegularExpression *variableRegex;
- (MPParsedVariable *)parseVariable
{
if (!variableRegex) {
variableRegex = [NSRegularExpression regularExpressionWithPattern:@"\\A\\s*([A-Za-z])\\s*"
options:0
error:NULL];
}
NSTextCheckingResult *match = [variableRegex firstMatchInString:self.input
fromIndex:self.parsePosition];
NSRange matchRange;
if (!match) {
matchRange = NSMakeRange(NSNotFound, 0);
} else {
self.parsePosition = NSMaxRange(match.range);
matchRange = [match rangeAtIndex:1];
}
return [[MPParsedVariable alloc] initWithRange:matchRange
inString:self.input];
}
@end

View File

@@ -1,14 +0,0 @@
//
// 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

View File

@@ -1,14 +0,0 @@
//
// MPFunction+MPParsedFactor.h
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <MathKit/MathKit.h>
#import "MPParsedFactor.h"
@interface MPFunction (MPParsedFactor) <MPParsedFactor>
@end

View File

@@ -1,30 +0,0 @@
//
// MPFunction+MPParsedFactor.m
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPFunction+MPParsedFactor.h"
@implementation MPFunction (MPParsedFactor)
- (instancetype)initWithRange:(NSRange)range
inString:(NSString *)string
{
return [self init];
}
- (BOOL)exists
{
return YES;
}
- (NSRange)range
{
NSUInteger selfIndex = [self.parent indexOfElement:self];
return NSMakeRange([self.parent locationOfElementAtIndex:selfIndex], 1);
}
@end

View File

@@ -1,20 +0,0 @@
//
// YYParse.h
// MathPad
//
// Created by Kim Wittenburg on 05.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPMath.yy.h"
#import "MPMath.tab.h"
#import "MPParsedElement.h"
#ifndef MathPad_YYParse_h
#define MathPad_YYParse_h
extern MPParsedElement *parseResult;
int yyparse();
#endif

View File

@@ -1,16 +0,0 @@
%option noyywrap
%{
@import Foundation;
#include "MPMath.tab.h"
%}
%%
/* Ignore Whitespaces */
[ \t\n] ;
/* Operators. Divisions are automatically transformed into fractions and dealt
with elsewhere. */
\+ { return PLUS; }
- { return MINUS; }
\* { return DOT; }
/* Numbers */
[0-9]+(\.[0-9]+)? { yylval.number = atof(yytext); return NUMBER; }
%%

View File

@@ -1,126 +0,0 @@
%{
#import "MPMath.h"
#define AT @
MPParsedElement *parseResult;
int yylex();
int yyparse();
FILE *yyin;
void yyerror(const char *s);
%}
%error-verbose
%initial-action
{
parseResult = [[MPParsedElement alloc] init];
};
%union {
double number;
}
/* Terminals */
%token PLUS
%left MINUS
%token DOT
%token <number> NUMBER
/* Nonterminals */
%type <number> summands
%type <number> factor
%type <number> product
%%
element:
factor { parseResult.isFactor = YES;
parseResult.factor = $1;
}
| operator
| prefix summands suffix
;
factor:
DOT product DOT { $$ = $2;
}
| DOT product { $$ = $2;
}
| product DOT { $$ = $1;
}
| product { $$ = $1;
}
;
product:
product DOT product { $$ = $1 * $3;
}
| product product { $$ = $1 * $2;
}
| NUMBER { $$ = $1;
}
;
operator:
PLUS { parseResult.suffixMultiplicator = 1;
parseResult.hasSuffixMultiplicator = YES;
}
| MINUS { parseResult.suffixMultiplicator = -1;
parseResult.hasSuffixMultiplicator = YES;
NSLog(AT"Op");
}
| DOT { parseResult.isFactor = YES;
parseResult.factor = 1;
}
| { parseResult.isFactor = YES;
parseResult.factor = 1;
}
;
prefix:
DOT product { parseResult.prefixMultiplicator = $2;
parseResult.hasPrefixMultiplicator = YES;
parseResult.prefixOperatorExplicit = YES;
}
| product { parseResult.prefixMultiplicator = $1;
parseResult.hasPrefixMultiplicator = YES;
parseResult.prefixOperatorExplicit = YES;
}
| { parseResult.hasPrefixMultiplicator = NO;
}
;
summands:
summands summand
| summand
;
summand:
PLUS product { [parseResult.summands addObject:AT($2)];
}
| MINUS product { [parseResult.summands addObject:AT(-$2)];
}
;
suffix:
PLUS { parseResult.suffixMultiplicator = 1;
parseResult.hasSuffixMultiplicator = YES;
}
| MINUS { parseResult.suffixMultiplicator = -1;
parseResult.hasSuffixMultiplicator = YES;
}
| DOT { parseResult.suffixMultiplicator = 0;
parseResult.hasSuffixMultiplicator = YES;
}
| { parseResult.hasSuffixMultiplicator = NO;
}
;
%%
void yyerror(const char *s) {
NSLog(@"EEK, parse error! Message: %s", s);
// might as well halt now:
exit(-1);
}

View File

@@ -1,23 +0,0 @@
//
// MPModel.h
// MathPad
//
// Created by Kim Wittenburg on 20.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
/*
This is a convenience header which imports all model classes defined by MathPad.
*/
#ifndef MathPad_MPModel_h
#define MathPad_MPModel_h
#import "MPException.h"
#import "MPExpression.h"
#import "MPFunction.h"
#import "MPRangePath.h"
#import "NSIndexPath+MPAdditions.h"
#endif

View File

@@ -1,44 +0,0 @@
//
// MPParsedElement.h
// MathPad
//
// Created by Kim Wittenburg on 05.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MPParseError.h"
@interface MPParsedElement : NSObject <NSCopying>
@property (nonatomic, copy) NSString *definedVariable;
@property (nonatomic) NSUInteger afterVariableDefinitionIndex; // Only set if defineVariable != nil
@property (nonatomic) BOOL isFactor;
// If isFactor is YES this is the factor otherwise it is the independant summant
// of the element (may be 0).
@property (nonatomic) NSDecimalNumber *value;
@property (nonatomic, getter = isPrefixOperatorExplicit) BOOL prefixOperatorExplicit;
@property (nonatomic, getter = isPrefixValueExplicit) BOOL prefixValueExplicit;
@property (nonatomic) NSDecimalNumber *prefixMultiplicator;
@property (nonatomic, getter = isSuffixOperatorExplicit) BOOL suffixOperatorExplicit;
@property (nonatomic, getter = isSuffixValueExplicit) BOOL suffixValueExplicit;
@property (nonatomic) NSDecimalNumber *suffixMultiplicator;
@property (nonatomic) NSUInteger suffixIndex;
// No error checking done
- (NSDecimalNumber *)valueAtBeginning;
- (NSDecimalNumber *)valueAtEnd;
- (NSDecimalNumber *)standaloneValue;
// For error checking
- (BOOL)isValidElementAtBeginning:(MPParseError **)error;
- (BOOL)isValidStandaloneElement:(MPParseError **)error;
- (BOOL)isValidElementAtEnd:(MPParseError **)error;
- (BOOL)isValidVariableDefinition:(MPParseError **)error;
@end

View File

@@ -1,123 +0,0 @@
//
// MPParsedElement.m
// MathPad
//
// Created by Kim Wittenburg on 05.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPParsedElement.h"
@implementation MPParsedElement
- (instancetype)init
{
self = [super init];
if (self) {
}
return self;
}
- (NSDecimalNumber *)valueAtBeginning
{
NSDecimalNumber *value = self.value;
if (self.prefixValueExplicit) {
value = [value decimalNumberByAdding:self.prefixMultiplicator];
}
return value;
}
- (NSDecimalNumber *)valueAtEnd
{
NSDecimalNumber *value = self.value;
if (self.suffixValueExplicit) {
value = [value decimalNumberByAdding:self.suffixMultiplicator];
}
return value;
}
- (NSDecimalNumber *)standaloneValue
{
if (self.isFactor) {
return self.value;
}
NSDecimalNumber *value = self.value;
if (self.prefixValueExplicit) {
value = [value decimalNumberByAdding:self.prefixMultiplicator];
}
if (self.suffixValueExplicit) {
value = [value decimalNumberByAdding:self.suffixMultiplicator];
}
return value;
}
- (BOOL)isValidElementAtBeginning:(MPParseError *__autoreleasing *)error
{
if (self.prefixOperatorExplicit) {
if (error) {
*error = MPParseError(0, @"Expected Number");
}
return NO;
}
return YES;
}
- (BOOL)isValidStandaloneElement:(MPParseError *__autoreleasing *)error
{
return [self isValidElementAtBeginning:error] && [self isValidElementAtEnd:error];
}
- (BOOL)isValidElementAtEnd:(MPParseError *__autoreleasing *)error
{
if (self.suffixOperatorExplicit) {
if (error) {
*error = MPParseError(self.suffixIndex, @"Expected Number");
}
return NO;
}
return YES;
}
- (BOOL)isValidVariableDefinition:(MPParseError *__autoreleasing *)error
{
if (self.definedVariable == nil) {
if (error) {
*error = MPParseError(0, @"Expected Variable Definition");
}
return NO;
}
return [self isValidElementAtBeginning:error];
}
#pragma mark - NSObject Overrides
- (NSString *)description
{
NSMutableString *description = [[NSMutableString alloc] initWithString:@"MPParsedElement<"];
if (self.isFactor) {
[description appendFormat:@"factor=%@%@%@", self.prefixOperatorExplicit?@"*":@"", self.value, self.suffixOperatorExplicit?@"*":@""];
} else {
[description appendFormat:@"prefix=%@%@ prefixValueExplicit=%@", self.prefixOperatorExplicit?@"*":@"", self.prefixMultiplicator, self.prefixValueExplicit?@"YES":@"NO"];
[description appendFormat:@" suffix=%@%@ suffixValueExplicit=%@", self.suffixMultiplicator, self.suffixOperatorExplicit?@"*":@"", self.suffixValueExplicit?@"YES":@"NO"];
[description appendFormat:@" value=%@", self.value];
}
[description appendString:@">"];
return [description copy];
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
MPParsedElement *copy = [[MPParsedElement allocWithZone:zone] init];
copy.isFactor = self.isFactor;
copy.value = self.value;
copy.prefixOperatorExplicit = self.prefixOperatorExplicit;
copy.prefixValueExplicit = self.prefixValueExplicit;
copy.prefixMultiplicator = self.prefixMultiplicator;
copy.suffixOperatorExplicit = self.suffixOperatorExplicit;
copy.suffixValueExplicit = self.suffixValueExplicit;
copy.suffixMultiplicator = self.suffixMultiplicator;
return copy;
}
@end

View File

@@ -1,20 +0,0 @@
//
// MPParsedFactor.h
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MPParseError.h"
@protocol MPParsedFactor <NSObject>
- (instancetype)initWithRange:(NSRange)range inString:(NSString *)string;
- (NSRange)range;
- (BOOL)exists;
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error;
@end

View File

@@ -1,60 +0,0 @@
//
// MPParsedFactor.m
// MathPad
//
// Created by Kim Wittenburg on 10.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPParsedFactor.h"
@implementation MPParsedFactor {
NSDecimalNumber *_value;
}
+ (MPParsedFactor *)factorWithDecimalNumber:(NSDecimalNumber *)number
{
return [[MPParsedFactor alloc] initWithDecimalNumber:number];
}
+ (MPParsedFactor *)sinFactorWithFactor:(MPParsedFactor *)factor
{
double value = factor.value.doubleValue;
NSDecimalNumber *actualNumber = [[NSDecimalNumber alloc] initWithDouble:sin(value)];
return [[MPParsedFactor alloc] initWithDecimalNumber:actualNumber];
}
+ (MPParsedFactor *)cosFactorWithFactor:(MPParsedFactor *)factor
{
double value = factor.value.doubleValue;
NSDecimalNumber *actualNumber = [[NSDecimalNumber alloc] initWithDouble:cos(value)];
return [[MPParsedFactor alloc] initWithDecimalNumber:actualNumber];
}
+ (MPParsedFactor *)tanFactorWithFactor:(MPParsedFactor *)factor
{
double value = factor.value.doubleValue;
NSDecimalNumber *actualNumber = [[NSDecimalNumber alloc] initWithDouble:tan(value)];
return [[MPParsedFactor alloc] initWithDecimalNumber:actualNumber];
}
- (instancetype)initWithDecimalNumber:(NSDecimalNumber *)number
{
self = [super init];
if (self) {
_value = number;
}
return self;
}
- (NSDecimalNumber *)value
{
return _value;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"MPParsedFactor<%@>", _value];
}
@end

View File

@@ -1,16 +0,0 @@
//
// MPParsedNumber.h
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MPParsedFactor.h"
@interface MPParsedNumber : NSObject <MPParsedFactor>
- (NSDecimalNumber *)number;
@end

View File

@@ -1,42 +0,0 @@
//
// MPParsedNumber.m
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPParsedNumber.h"
@interface MPParsedNumber ()
@property (nonatomic) NSRange range;
@property (nonatomic, strong) NSDecimalNumber *number;
@end
@implementation MPParsedNumber
- (instancetype)initWithRange:(NSRange)range
inString:(NSString *)string
{
self = [super init];
if (self) {
_range = range;
if (range.location != NSNotFound) {
NSString *stringValue = [string substringWithRange:range];
_number = [NSDecimalNumber decimalNumberWithString:stringValue];
}
}
return self;
}
- (BOOL)exists
{
return self.range.location != NSNotFound;
}
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
{
return self.number;
}
@end

View File

@@ -1,17 +0,0 @@
//
// MPParsedOperator.h
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MPParsedFactor.h"
@interface MPParsedOperator : NSObject <MPParsedFactor>
- (NSUInteger)numberOfOperators;
- (NSDecimalNumber *)multiplicator;
@end

View File

@@ -1,54 +0,0 @@
//
// MPParsedOperator.m
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPParsedOperator.h"
@interface MPParsedOperator ()
@property (nonatomic) NSRange range;
@property (nonatomic) NSUInteger numberOfOperators;
@property (nonatomic, strong) NSDecimalNumber *multiplicator;
@end
@implementation MPParsedOperator
- (instancetype)initWithRange:(NSRange)range
inString:(NSString *)string
{
self = [super init];
if (self) {
_range = range;
if (range.location == NSNotFound) {
_multiplicator = [NSDecimalNumber one];
_numberOfOperators = 0;
} else {
NSString *stringValue = [string substringWithRange:range];
NSString *operators = [[stringValue componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] componentsJoinedByString:@""];
NSInteger multiplicator = 1;
for (NSUInteger characterIndex = 0; characterIndex < operators.length; characterIndex++) {
if ([[operators substringWithRange:NSMakeRange(characterIndex, 1)] isEqualToString:@"-"]) {
multiplicator *= -1;
}
}
_multiplicator = [[NSDecimalNumber alloc] initWithInteger:multiplicator];
_numberOfOperators = operators.length;
}
}
return self;
}
- (BOOL)exists
{
return self.range.location != NSNotFound;
}
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
{
return self.multiplicator;
}
@end

View File

@@ -1,22 +0,0 @@
//
// MPParsedSummand.h
// MathPad
//
// Created by Kim Wittenburg on 10.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MPParsedFactor.h"
@interface MPParsedProduct : NSObject
- (instancetype)init; // designated initializer
- (instancetype)initWithFactor:(id<MPParsedFactor>)factor; // designated initializer.
@property (readonly, nonatomic, strong) NSArray *factors;
- (void)addFactor:(id<MPParsedFactor>)factor;
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error;
@end

View File

@@ -1,64 +0,0 @@
//
// MPParsedSummand.m
// MathPad
//
// Created by Kim Wittenburg on 10.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPParsedProduct.h"
@implementation MPParsedProduct {
NSMutableArray *_factors;
}
- (instancetype)init
{
self = [super init];
if (self) {
_factors = [[NSMutableArray alloc] init];
}
return self;
}
- (instancetype)initWithFactor:(id<MPParsedFactor>)factor
{
self = [super init];
if (self) {
_factors = [[NSMutableArray alloc] initWithObjects:factor, nil];
}
return self;
}
- (NSArray *)factors
{
return _factors;
}
- (void)addFactor:(id<MPParsedFactor>)factor
{
[_factors addObject:factor];
}
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
{
if (_factors.count == 0) {
return [NSDecimalNumber zero];
}
NSDecimalNumber *value = [NSDecimalNumber one];
for (id<MPParsedFactor> factor in _factors) {
NSDecimalNumber *factorValue = [factor evaluateWithError:error];
if (!factorValue) {
return nil;
}
value = [value decimalNumberByMultiplyingBy:factorValue];
}
return value;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"MPParsedProduct<%@>", [_factors componentsJoinedByString:@"*"]];
}
@end

View File

@@ -1,16 +0,0 @@
//
// MPParsedVariable.h
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "MPParsedFactor.h"
@interface MPParsedVariable : NSObject <MPParsedFactor>
- (NSString *)variableName;
@end

View File

@@ -1,47 +0,0 @@
//
// MPParsedVariable.m
// MathPad
//
// Created by Kim Wittenburg on 13.09.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPParsedVariable.h"
#import "MPEvaluationContext.h"
@interface MPParsedVariable ()
@property (nonatomic) NSRange range;
@property (nonatomic, strong) NSString *variableName;
@end
@implementation MPParsedVariable
- (instancetype)initWithRange:(NSRange)range
inString:(NSString *)string
{
self = [super init];
if (self) {
_range = range;
if (range.location != NSNotFound) {
_variableName = [string substringWithRange:range];
}
}
return self;
}
- (BOOL)exists
{
return self.range.location != NSNotFound;
}
- (NSDecimalNumber *)evaluateWithError:(MPParseError *__autoreleasing *)error
{
NSDecimalNumber *value = [[MPEvaluationContext sharedContext] valueForVariableName:self.variableName];
if (!value) {
*error = MPParseError(self.range, @"Undefined Variable.");
return nil;
}
return value;
}
@end

View File

@@ -1,39 +0,0 @@
//
// MPRange.h
// MathPad
//
// Created by Kim Wittenburg on 18.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
@interface MPRange : NSObject <NSCopying, NSCoding>
#pragma mark Creation Methods
- (instancetype)init;
- (instancetype)initWithLocation:(NSIndexPath *)location
length:(NSUInteger)length;
- (instancetype)initWithRange:(NSRange)aRange;
+ (instancetype)emptyRange;
+ (instancetype)rangeWithLocation:(NSIndexPath *)location
length:(NSUInteger)length;
+ (instancetype)rangeWithRange:(NSRange)aRange;
#pragma mark Properties
@property (nonatomic, strong) NSIndexPath *location;
@property (nonatomic) NSUInteger length;
- (NSIndexPath *)maxRange;
- (NSRange)rangeAtLastIndex;
#pragma mark Working with Ranges
- (BOOL)containsRange:(MPRange *)aRange;
- (BOOL)containsLocation:(NSIndexPath *)location;
- (BOOL)isEqual:(id)object;
- (BOOL)isEqualToRange:(MPRange *)aRange;
@end

View File

@@ -1,140 +0,0 @@
//
// MPRange.m
// MathPad
//
// Created by Kim Wittenburg on 18.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPRange.h"
@implementation MPRange
#pragma mark Creation Methods
- (instancetype)init
{
return [self initWithLocation:[[NSIndexPath alloc] init]
length:0];
}
- (instancetype)initWithLocation:(NSIndexPath *)location
length:(NSUInteger)length
{
self = [super init];
if (self) {
_location = location;
_length = length;
}
return self;
}
- (instancetype)initWithRange:(NSRange)aRange
{
return [self initWithLocation:[[NSIndexPath alloc] initWithIndex:aRange.location]
length:aRange.length];
}
+ (instancetype)emptyRange
{
return [[self alloc] init];
}
+ (instancetype)rangeWithLocation:(NSIndexPath *)location
length:(NSUInteger)length
{
return [[self alloc] initWithLocation:location
length:length];
}
+ (instancetype)rangeWithRange:(NSRange)aRange
{
return [[self alloc] initWithRange:aRange];
}
#pragma mark Properties
- (NSIndexPath *)maxRange
{
NSUInteger lastIndex = [self.location indexAtPosition:self.location.length-1];
NSUInteger newLastIndex = lastIndex + self.length;
return [[self.location indexPathByRemovingLastIndex] indexPathByAddingIndex:newLastIndex];
}
- (NSRange)rangeAtLastIndex
{
return NSMakeRange([self.location indexAtPosition:self.location.length-1], self.length);
}
#pragma mark Working with Ranges
- (BOOL)containsRange:(MPRange *)aRange
{
if (aRange.location.length < self.location.length) {
return NO;
}
// Compare indices (except the last one)
for (NSUInteger pos = 0; pos < self.location.length-1; pos++) {
NSUInteger selfIndex = [self.location indexAtPosition:pos];
NSUInteger otherIndex = [aRange.location indexAtPosition:pos];
if (selfIndex != otherIndex) {
return NO;
}
}
// Compare range at last index
NSUInteger selfIndex = [self.location indexAtPosition:self.location.length-1];
NSUInteger otherIndex = [aRange.location indexAtPosition:self.location.length-1];
if (aRange.location.length > self.location.length) {
return NSLocationInRange(otherIndex, self.rangeAtLastIndex);
} else {
return otherIndex >= selfIndex && NSMaxRange(aRange.rangeAtLastIndex) <= NSMaxRange(self.rangeAtLastIndex);
}
}
- (BOOL)containsLocation:(NSIndexPath *)location
{
return [self containsRange:[[MPRange alloc] initWithLocation:location length:0]];
}
- (BOOL)isEqual:(id)object
{
if (self == object) {
return YES;
}
if (object == nil) {
return NO;
}
if (![object isKindOfClass:[MPRange class]]) {
return NO;
}
return [self isEqualToRange:(MPRange *)object];
}
- (BOOL)isEqualToRange:(MPRange *)aRange
{
return [self.location isEqual:aRange.location] && self.length == aRange.length;
}
#pragma mark - NSCopying
- (id)copyWithZone:(NSZone *)zone
{
MPRange *copy = [[MPRange allocWithZone:zone] initWithLocation:self.location.copy length:self.length];
return copy;
}
#pragma mark - NSCoding
- (id)initWithCoder:(NSCoder *)aDecoder
{
return [self initWithLocation:[aDecoder decodeObjectForKey:@"location"]
length:[aDecoder decodeIntegerForKey:@"length"]];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.location forKey:@"location"];
[aCoder encodeInteger:self.length forKey:@"length"];
}
@end

View File

@@ -1,19 +0,0 @@
//
// MPView.h
// MathPad
//
// Created by Kim Wittenburg on 21.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
/*
This is a convenience header which imports all view classes defined by MathPad.
*/
#ifndef MathPad_MPView_h
#define MathPad_MPView_h
#import "MPExpressionView.h"
#import "MPExpressionStorage.h"
#endif

View File

@@ -1,21 +0,0 @@
//
// NSIndexPath+MPRemoveFirstIndex.h
// MathPad
//
// Created by Kim Wittenburg on 23.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSIndexPath (MPRemoveFirstIndex)
/*!
@method indexPathByRemovingFirstIndex
@brief Provides an index path with the indexes in the receiving index path, excluding the first one.
@discussion Returns an empty NSIndexPath instance if the receiving index paths length is 1 or less.
@return New index path with the receiving index paths indexes, excluding the first one.
*/
- (NSIndexPath *)indexPathByRemovingFirstIndex;
@end

View File

@@ -1,27 +0,0 @@
//
// NSIndexPath+MPRemoveFirstIndex.m
// MathPad
//
// Created by Kim Wittenburg on 23.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "NSIndexPath+MPRemoveFirstIndex.h"
@implementation NSIndexPath (MPRemoveFirstIndex)
- (NSIndexPath *)indexPathByRemovingFirstIndex
{
if (self.length <= 1) {
return [[NSIndexPath alloc] init];
}
NSUInteger indexes[self.length];
[self getIndexes:indexes];
NSUInteger newIndexes[self.length-1];
for (NSUInteger i = 0; i < self.length-1; i++) {
newIndexes[i] = indexes[i+1];
}
return [[NSIndexPath alloc] initWithIndexes:newIndexes length:self.length-1];
}
@end

View File

@@ -1,23 +0,0 @@
//
// NSIndexPath+MPRemoveFirstIndex.h
// MathPad
//
// Created by Kim Wittenburg on 23.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSIndexPath (MPReverseIndexPath)
/*!
@method indexPathByRemovingFirstIndex
@brief Provides an index path with the indexes in the receiving index path, excluding the first one.
@discussion Returns an empty NSIndexPath instance if the receiving index paths length is 1 or less.
@return New index path with the receiving index paths indexes, excluding the first one.
*/
- (NSIndexPath *)indexPathByRemovingFirstIndex;
- (NSIndexPath *)indexPathByPrecedingIndex:(NSUInteger)index;
@end

View File

@@ -1,37 +0,0 @@
//
// NSIndexPath+MPRemoveFirstIndex.m
// MathPad
//
// Created by Kim Wittenburg on 23.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "NSIndexPath+MPReverseIndexPath.h"
@implementation NSIndexPath (MPReverseIndexPath)
- (NSIndexPath *)indexPathByRemovingFirstIndex
{
if (self.length <= 1) {
return [[NSIndexPath alloc] init];
}
NSUInteger indexes[self.length];
[self getIndexes:indexes];
NSUInteger newIndexes[self.length-1];
for (NSUInteger i = 0; i < self.length-1; i++) {
newIndexes[i] = indexes[i+1];
}
return [[NSIndexPath alloc] initWithIndexes:newIndexes length:self.length-1];
}
- (NSIndexPath *)indexPathByPrecedingIndex:(NSUInteger)index
{
NSUInteger newIndexes[self.length+1];
newIndexes[0] = index;
for (NSUInteger i = 0; i < self.length; i++) {
newIndexes[i+1] = [self indexAtPosition:i];
}
return [[NSIndexPath alloc] initWithIndexes:newIndexes length:self.length+1];
}
@end

View File

@@ -1,21 +0,0 @@
//
// NSObject+MPStringTest.h
// MathPad
//
// Created by Kim Wittenburg on 20.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSObject (MPStringTest)
/*!
@method isString
@brief Returns wether the receiver is a string object.
@discussion A string object is an instance of the @c NSString class or any of its subclasses (for example @c NSMutableString). For an @c NSAttributedString this method returns @c NO.
@return @c YES if the receiver is an instance of @c NSString or a subclass, @c NO otherwise.
*/
- (BOOL)isString;
@end

View File

@@ -1,18 +0,0 @@
//
// NSObject+MPStringTest.m
// MathPad
//
// Created by Kim Wittenburg on 20.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "NSObject+MPStringTest.h"
@implementation NSObject (MPStringTest)
- (BOOL)isString
{
return [self isKindOfClass:[NSString class]];
}
@end

View File

@@ -1,21 +0,0 @@
//
// NSTextStorage+MPSetContents.h
// MathPad
//
// Created by Kim Wittenburg on 21.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <Cocoa/Cocoa.h>
@interface NSTextStorage (MPSetContents)
/*!
@method setString:
@brief Replaces the contents of the receiver with @c aString.
@discussion This method sends the receiver a @c replaceCharactersInRange:withString: with a range including all characters of the receiver and @c aString. See @c replaceCharactersInRange:withString: for details.
@param aString A string specifying the characters to replace the receiver's current contents.
*/
- (void)setString:(NSString *)aString;
@end

View File

@@ -1,19 +0,0 @@
//
// NSTextStorage+MPSetContents.m
// MathPad
//
// Created by Kim Wittenburg on 21.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "NSTextStorage+MPSetContents.h"
@implementation NSTextStorage (MPSetContents)
- (void)setString:(NSString *)string
{
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string];
[self setAttributedString:attributedString];
}
@end

View File

@@ -1,61 +0,0 @@
//
// MPMutableExpressionTests.m
// MathPad
//
// Created by Kim Wittenburg on 19.04.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <XCTest/XCTest.h>
#import "MPExpression.h"
#import "MPFunction.h"
@interface MPMutableExpressionTests : XCTestCase
@end
@implementation MPMutableExpressionTests
- (void)testMutating {
MPMutableExpression *testExpression = [[MPMutableExpression alloc] initWithSymbols:@[@"1234", [[MPFunction alloc] init], @"5678", [[MPFunction alloc] init]]];
[testExpression appendString:@"90"];
XCTAssertEqual([testExpression numberOfSymbols], 5);
// 1234 [] 5678 [] 90
[testExpression deleteSymbolsInRange:NSMakeRange(2, 4)];
XCTAssertEqual([testExpression numberOfSymbols], 3);
// 12678 [] 90
[testExpression insertFunction:[[MPFunction alloc] init]
atIndex:2];
XCTAssertEqual([testExpression numberOfSymbols], 5);
// 12 [] 678 [] 90
[testExpression replaceSymbolsInRange:NSMakeRange(2, 5)
withSymbols:@[[[MPFunction alloc] init]]];
XCTAssertEqual([testExpression numberOfSymbols], 3);
// 12 [] 90
[testExpression setString:@"abc"];
XCTAssertEqual([testExpression numberOfSymbols], 1);
// abc
[testExpression setString:@""];
XCTAssertEqual([testExpression numberOfSymbols], 0);
//
[testExpression setString:@"1234"];
XCTAssertEqual([testExpression numberOfSymbols], 1);
}
- (void)testInvalidMutatingRange {
@try {
MPMutableExpression *testExpression = [[MPMutableExpression alloc] initWithSymbols:@[@"1234", [[MPFunction alloc] init], @"5678", [[MPFunction alloc] init]]];
[testExpression deleteSymbolsInRange:NSMakeRange(5, 17)];
XCTFail(@"Should have raised an exception");
}
@catch (NSException *exception) {}
}
@end

View File

@@ -1,34 +0,0 @@
//
// MathPadTests.m
// MathPadTests
//
// Created by Kim Wittenburg on 23.03.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import <XCTest/XCTest.h>
@interface MathPadTests : XCTestCase
@end
@implementation MathPadTests
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample
{
XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
}
@end