Added Factorial, added parts of exponents
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13E28" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="6245" systemVersion="13F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="6245"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<objects>
|
<objects>
|
||||||
<customObject id="-2" userLabel="File's Owner" customClass="MPDocument">
|
<customObject id="-2" userLabel="File's Owner" customClass="MPDocument">
|
||||||
@@ -13,22 +13,20 @@
|
|||||||
</connections>
|
</connections>
|
||||||
</customObject>
|
</customObject>
|
||||||
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
|
||||||
<customObject id="-3" userLabel="Application"/>
|
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
|
||||||
<window title="MathPad" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
|
<window title="MathPad" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" visibleAtLaunch="NO" animationBehavior="default" id="xOd-HO-29H" userLabel="Window">
|
||||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||||
<rect key="contentRect" x="525" y="411" width="507" height="251"/>
|
<rect key="contentRect" x="525" y="411" width="507" height="249"/>
|
||||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
|
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
|
||||||
<view key="contentView" id="gIp-Ho-8D9">
|
<view key="contentView" id="gIp-Ho-8D9">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="507" height="251"/>
|
<rect key="frame" x="0.0" y="0.0" width="507" height="249"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<customView translatesAutoresizingMaskIntoConstraints="NO" id="lcd-Ip-jjR" customClass="MPExpressionView">
|
<customView translatesAutoresizingMaskIntoConstraints="NO" id="lcd-Ip-jjR" customClass="MPExpressionView">
|
||||||
<rect key="frame" x="20" y="70" width="467" height="161"/>
|
<rect key="frame" x="20" y="70" width="467" height="159"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
</customView>
|
</customView>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ar2-1O-Kl1">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="ar2-1O-Kl1">
|
||||||
<rect key="frame" x="18" y="45" width="47" height="17"/>
|
<rect key="frame" x="18" y="45" width="47" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="43" id="EI3-gZ-BdS"/>
|
<constraint firstAttribute="width" constant="43" id="EI3-gZ-BdS"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
@@ -40,7 +38,6 @@
|
|||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jQo-M8-to6">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="jQo-M8-to6">
|
||||||
<rect key="frame" x="18" y="20" width="40" height="17"/>
|
<rect key="frame" x="18" y="20" width="40" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" constant="36" id="v3s-bP-5SY"/>
|
<constraint firstAttribute="width" constant="36" id="v3s-bP-5SY"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
@@ -52,7 +49,6 @@
|
|||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B5H-rE-1e9">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="B5H-rE-1e9">
|
||||||
<rect key="frame" x="71" y="45" width="418" height="17"/>
|
<rect key="frame" x="71" y="45" width="418" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="KBm-kx-spX">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="KBm-kx-spX">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
@@ -61,7 +57,6 @@
|
|||||||
</textField>
|
</textField>
|
||||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fw3-bj-cPR">
|
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="fw3-bj-cPR">
|
||||||
<rect key="frame" x="75" y="20" width="414" height="17"/>
|
<rect key="frame" x="75" y="20" width="414" height="17"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
|
||||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="uaX-CN-Uoz">
|
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" id="uaX-CN-Uoz">
|
||||||
<font key="font" metaFont="system"/>
|
<font key="font" metaFont="system"/>
|
||||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||||
@@ -89,6 +84,7 @@
|
|||||||
<connections>
|
<connections>
|
||||||
<outlet property="delegate" destination="-2" id="0bl-1N-x8E"/>
|
<outlet property="delegate" destination="-2" id="0bl-1N-x8E"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
<point key="canvasLocation" x="139.5" y="146.5"/>
|
||||||
</window>
|
</window>
|
||||||
<collectionViewItem id="J9S-PW-LCL">
|
<collectionViewItem id="J9S-PW-LCL">
|
||||||
<connections>
|
<connections>
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
#import "MPTokenStream.h"
|
#import "MPTokenStream.h"
|
||||||
|
|
||||||
#import "MPEvaluationContext.h"
|
#import "MPEvaluationContext.h"
|
||||||
|
#import "MPPowerFunction.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -171,7 +172,7 @@
|
|||||||
switch (token.tokenType) {
|
switch (token.tokenType) {
|
||||||
case MPNumberToken:
|
case MPNumberToken:
|
||||||
{
|
{
|
||||||
return [[MPTerm alloc] initWithNumber:token.number];
|
return [self decoratedTerm:[[MPTerm alloc] initWithNumber:token.number]];
|
||||||
}
|
}
|
||||||
|
|
||||||
case MPVariableToken:
|
case MPVariableToken:
|
||||||
@@ -180,12 +181,12 @@
|
|||||||
self.error = MPParseError(token.range, @"Undefined Variable");
|
self.error = MPParseError(token.range, @"Undefined Variable");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
return [[MPTerm alloc] initWithVariable:token.variable];
|
return [self decoratedTerm:[[MPTerm alloc] initWithVariable:token.variable]];
|
||||||
}
|
}
|
||||||
|
|
||||||
case MPGenericFunctionToken:
|
case MPGenericFunctionToken:
|
||||||
{
|
{
|
||||||
return [((MPFunction *)token) parseWithError:_error];
|
return [self decoratedTerm:[((MPFunction *)token) parseWithError:_error]];
|
||||||
}
|
}
|
||||||
|
|
||||||
case MPSinToken:
|
case MPSinToken:
|
||||||
@@ -241,4 +242,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (MPTerm *)decoratedTerm:(MPTerm *)term
|
||||||
|
{
|
||||||
|
MPTerm *decoratedTerm = term;
|
||||||
|
MPToken *facultyToken = [tokenStream nextTokenOfType:MPFactorialToken];
|
||||||
|
if (facultyToken) {
|
||||||
|
decoratedTerm = [[MPTerm alloc] initWithFactorialOfTerm:term];
|
||||||
|
}
|
||||||
|
MPToken *powerToken = [tokenStream nextTokenOfType:MPGenericFunctionToken];
|
||||||
|
if ([powerToken isKindOfClass:[MPPowerFunction class]]) {
|
||||||
|
MPPowerFunction *powerFunction = (MPPowerFunction *)powerToken;
|
||||||
|
powerFunction.baseTerm = decoratedTerm;
|
||||||
|
return [powerFunction parseWithError:_error];
|
||||||
|
} else {
|
||||||
|
tokenStream.currentLocation--;
|
||||||
|
}
|
||||||
|
return decoratedTerm;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -45,6 +45,7 @@
|
|||||||
@"(cos)|"
|
@"(cos)|"
|
||||||
@"(tan)|"
|
@"(tan)|"
|
||||||
@"([A-Za-z])|"
|
@"([A-Za-z])|"
|
||||||
|
@"(!)|"
|
||||||
@"(=)|"
|
@"(=)|"
|
||||||
@"(\\s)"
|
@"(\\s)"
|
||||||
@")";
|
@")";
|
||||||
@@ -66,8 +67,9 @@
|
|||||||
NSRange cosRange = [match rangeAtIndex:5];
|
NSRange cosRange = [match rangeAtIndex:5];
|
||||||
NSRange tanRange = [match rangeAtIndex:6];
|
NSRange tanRange = [match rangeAtIndex:6];
|
||||||
NSRange variableRange = [match rangeAtIndex:7];
|
NSRange variableRange = [match rangeAtIndex:7];
|
||||||
NSRange equalsRange = [match rangeAtIndex:8];
|
NSRange factorialRange = [match rangeAtIndex:8];
|
||||||
NSRange whitespaceRange = [match rangeAtIndex:9];
|
NSRange equalsRange = [match rangeAtIndex:9];
|
||||||
|
NSRange whitespaceRange = [match rangeAtIndex:10];
|
||||||
|
|
||||||
if (MPRangeExists(multiplicationSymbolRange)) {
|
if (MPRangeExists(multiplicationSymbolRange)) {
|
||||||
range = multiplicationSymbolRange;
|
range = multiplicationSymbolRange;
|
||||||
@@ -90,6 +92,9 @@
|
|||||||
} else if (MPRangeExists(variableRange)) {
|
} else if (MPRangeExists(variableRange)) {
|
||||||
range = variableRange;
|
range = variableRange;
|
||||||
tokenType = MPVariableToken;
|
tokenType = MPVariableToken;
|
||||||
|
} else if (MPRangeExists(factorialRange)) {
|
||||||
|
range = factorialRange;
|
||||||
|
tokenType = MPFactorialToken;
|
||||||
} else if (MPRangeExists(equalsRange)) {
|
} else if (MPRangeExists(equalsRange)) {
|
||||||
range = equalsRange;
|
range = equalsRange;
|
||||||
tokenType = MPEqualsToken;
|
tokenType = MPEqualsToken;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
- (instancetype)initWithFactors:(NSArray *)factors; // array of MPTerms
|
- (instancetype)initWithFactors:(NSArray *)factors; // array of MPTerms
|
||||||
- (instancetype)initWithVariable:(NSString *)variable;
|
- (instancetype)initWithVariable:(NSString *)variable;
|
||||||
|
|
||||||
|
- (instancetype)initWithFactorialOfTerm:(MPTerm *)term;
|
||||||
|
|
||||||
- (instancetype)initWithSinOfTerm:(MPTerm *)term;
|
- (instancetype)initWithSinOfTerm:(MPTerm *)term;
|
||||||
- (instancetype)initWithCosOfTerm:(MPTerm *)term;
|
- (instancetype)initWithCosOfTerm:(MPTerm *)term;
|
||||||
- (instancetype)initWithTanOfTerm:(MPTerm *)term;
|
- (instancetype)initWithTanOfTerm:(MPTerm *)term;
|
||||||
|
|||||||
@@ -62,27 +62,36 @@
|
|||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFactorialOfTerm:(MPTerm *)term
|
||||||
|
{
|
||||||
|
return [self initWithBlock:^NSDecimalNumber *{
|
||||||
|
NSDecimalNumber *termValue = [term evaluate];
|
||||||
|
NSLog(@"Factorial of %@ = %f", termValue, tgamma(termValue.doubleValue + 1));
|
||||||
|
return [[NSDecimalNumber alloc] initWithDouble:tgamma(termValue.doubleValue + 1)];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
- (instancetype)initWithSinOfTerm:(MPTerm *)term
|
- (instancetype)initWithSinOfTerm:(MPTerm *)term
|
||||||
{
|
{
|
||||||
return [self initWithBlock:^NSDecimalNumber *{
|
return [self initWithBlock:^NSDecimalNumber *{
|
||||||
NSDecimalNumber *sinValue = [term evaluate];
|
NSDecimalNumber *termValue = [term evaluate];
|
||||||
return [[NSDecimalNumber alloc] initWithDouble:sin(sinValue.doubleValue)];
|
return [[NSDecimalNumber alloc] initWithDouble:sin(termValue.doubleValue)];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithCosOfTerm:(MPTerm *)term
|
- (instancetype)initWithCosOfTerm:(MPTerm *)term
|
||||||
{
|
{
|
||||||
return [self initWithBlock:^NSDecimalNumber *{
|
return [self initWithBlock:^NSDecimalNumber *{
|
||||||
NSDecimalNumber *cosValue = [term evaluate];
|
NSDecimalNumber *termValue = [term evaluate];
|
||||||
return [[NSDecimalNumber alloc] initWithDouble:cos(cosValue.doubleValue)];
|
return [[NSDecimalNumber alloc] initWithDouble:cos(termValue.doubleValue)];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithTanOfTerm:(MPTerm *)term
|
- (instancetype)initWithTanOfTerm:(MPTerm *)term
|
||||||
{
|
{
|
||||||
return [self initWithBlock:^NSDecimalNumber *{
|
return [self initWithBlock:^NSDecimalNumber *{
|
||||||
NSDecimalNumber *tanValue = [term evaluate];
|
NSDecimalNumber *termValue = [term evaluate];
|
||||||
return [[NSDecimalNumber alloc] initWithDouble:tan(tanValue.doubleValue)];
|
return [[NSDecimalNumber alloc] initWithDouble:tan(termValue.doubleValue)];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ typedef NS_ENUM(NSUInteger, MPTokenType) {
|
|||||||
MPTanToken,
|
MPTanToken,
|
||||||
MPNumberToken,
|
MPNumberToken,
|
||||||
MPVariableToken,
|
MPVariableToken,
|
||||||
|
MPFactorialToken,
|
||||||
MPEqualsToken,
|
MPEqualsToken,
|
||||||
MPGenericFunctionToken,
|
MPGenericFunctionToken,
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
@property (nonatomic, copy) NSArray *tokens;
|
@property (nonatomic, copy) NSArray *tokens;
|
||||||
@property (nonatomic, getter=isIgnoringWhitespaceTokens) BOOL ignoringWhitespaceTokens; // Default: YES
|
@property (nonatomic, getter=isIgnoringWhitespaceTokens) BOOL ignoringWhitespaceTokens; // Default: YES
|
||||||
|
|
||||||
@property (readonly, nonatomic) NSUInteger currentLocation;
|
@property (nonatomic) NSUInteger currentLocation;
|
||||||
|
|
||||||
- (void)reset;
|
- (void)reset;
|
||||||
- (BOOL)hasMoreTokens;
|
- (BOOL)hasMoreTokens;
|
||||||
|
|||||||
@@ -8,10 +8,6 @@
|
|||||||
|
|
||||||
#import "MPTokenStream.h"
|
#import "MPTokenStream.h"
|
||||||
|
|
||||||
@interface MPTokenStream ()
|
|
||||||
@property (readwrite, nonatomic) NSUInteger currentLocation;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation MPTokenStream {
|
@implementation MPTokenStream {
|
||||||
NSUInteger currentTokenIndex;
|
NSUInteger currentTokenIndex;
|
||||||
NSUInteger eofLocation;
|
NSUInteger eofLocation;
|
||||||
|
|||||||
Reference in New Issue
Block a user