Hello GitHub

This commit is contained in:
Howard Wolosky
2019-01-28 16:24:37 -08:00
parent 456fe5e355
commit c13b8a099e
822 changed files with 276650 additions and 75 deletions

View File

@@ -0,0 +1,214 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/****************************Module*Header***********************************
* Module Name: CCommand.h
*
* Module Descripton:
* Resource ID's for the Engine Commands exposed.
*
* Warnings:
*
* Created: 13-Feb-2008
*
\****************************************************************************/
// The following are the valid id's which can be passed to CCalcEngine::ProcessCommand
#define IDM_HEX 313
#define IDM_DEC 314
#define IDM_OCT 315
#define IDM_BIN 316
#define IDM_QWORD 317
#define IDM_DWORD 318
#define IDM_WORD 319
#define IDM_BYTE 320
#define IDM_DEG 321
#define IDM_RAD 322
#define IDM_GRAD 323
#define IDM_DEGREES 324
#define IDC_HEX IDM_HEX
#define IDC_DEC IDM_DEC
#define IDC_OCT IDM_OCT
#define IDC_BIN IDM_BIN
#define IDC_DEG IDM_DEG
#define IDC_RAD IDM_RAD
#define IDC_GRAD IDM_GRAD
#define IDC_DEGREES IDM_DEGREES
#define IDC_QWORD IDM_QWORD
#define IDC_DWORD IDM_DWORD
#define IDC_WORD IDM_WORD
#define IDC_BYTE IDM_BYTE
// Key IDs:
// These id's must be consecutive from IDC_FIRSTCONTROL to IDC_LASTCONTROL.
// The actual values don't matter but the order and sequence are very important.
// Also, the order of the controls must match the order of the control names
// in the string table.
// For example you want to declare the color for the control IDC_ST_AVE
// Find the string id for that control from the rc file
// Now define the control's id as IDC_FRISTCONTROL+stringID(IDC_ST_AVE)
#define IDC_FIRSTCONTROL IDC_SIGN
#define IDC_SIGN 80
#define IDC_CLEAR 81
#define IDC_CENTR 82
#define IDC_BACK 83
#define IDC_PNT 84
// Hole 85
#define IDC_AND 86 // Binary operators must be between IDC_AND and IDC_PWR
#define IDC_OR 87
#define IDC_XOR 88
#define IDC_LSHF 89
#define IDC_RSHF 90
#define IDC_DIV 91
#define IDC_MUL 92
#define IDC_ADD 93
#define IDC_SUB 94
#define IDC_MOD 95
#define IDC_ROOT 96
#define IDC_PWR 97
#define IDC_UNARYFIRST IDC_CHOP
#define IDC_CHOP 98 // Unary operators must be between IDC_CHOP and IDC_EQU
#define IDC_ROL 99
#define IDC_ROR 100
#define IDC_COM 101
#define IDC_SIN 102
#define IDC_COS 103
#define IDC_TAN 104
#define IDC_SINH 105
#define IDC_COSH 106
#define IDC_TANH 107
#define IDC_LN 108
#define IDC_LOG 109
#define IDC_SQRT 110
#define IDC_SQR 111
#define IDC_CUB 112
#define IDC_FAC 113
#define IDC_REC 114
#define IDC_DMS 115
#define IDC_CUBEROOT 116 //x ^ 1/3
#define IDC_POW10 117 // 10 ^ x
#define IDC_PERCENT 118
#define IDC_UNARYLAST IDC_PERCENT
#define IDC_FE 119
#define IDC_PI 120
#define IDC_EQU 121
#define IDC_MCLEAR 122
#define IDC_RECALL 123
#define IDC_STORE 124
#define IDC_MPLUS 125
#define IDC_MMINUS 126
#define IDC_EXP 127
#define IDC_OPENP 128
#define IDC_CLOSEP 129
#define IDC_0 130 // The controls for 0 through F must be consecutive and in order
#define IDC_1 131
#define IDC_2 132
#define IDC_3 133
#define IDC_4 134
#define IDC_5 135
#define IDC_6 136
#define IDC_7 137
#define IDC_8 138
#define IDC_9 139
#define IDC_A 140
#define IDC_B 141
#define IDC_C 142
#define IDC_D 143
#define IDC_E 144
#define IDC_F 145 // this is last control ID which must match the string table
#define IDC_INV 146
#define IDC_SET_RESULT 147
#define IDC_LASTCONTROL IDC_SET_RESULT
#define IDC_BINEDITSTART 700
#define IDC_BINPOS0 700
#define IDC_BINPOS1 701
#define IDC_BINPOS2 702
#define IDC_BINPOS3 703
#define IDC_BINPOS4 704
#define IDC_BINPOS5 705
#define IDC_BINPOS6 706
#define IDC_BINPOS7 707
#define IDC_BINPOS8 708
#define IDC_BINPOS9 709
#define IDC_BINPOS10 710
#define IDC_BINPOS11 711
#define IDC_BINPOS12 712
#define IDC_BINPOS13 713
#define IDC_BINPOS14 714
#define IDC_BINPOS15 715
#define IDC_BINPOS16 716
#define IDC_BINPOS17 717
#define IDC_BINPOS18 718
#define IDC_BINPOS19 719
#define IDC_BINPOS20 720
#define IDC_BINPOS21 721
#define IDC_BINPOS22 722
#define IDC_BINPOS23 723
#define IDC_BINPOS24 724
#define IDC_BINPOS25 725
#define IDC_BINPOS26 726
#define IDC_BINPOS27 727
#define IDC_BINPOS28 728
#define IDC_BINPOS29 729
#define IDC_BINPOS30 730
#define IDC_BINPOS31 731
#define IDC_BINPOS32 732
#define IDC_BINPOS33 733
#define IDC_BINPOS34 734
#define IDC_BINPOS35 735
#define IDC_BINPOS36 736
#define IDC_BINPOS37 737
#define IDC_BINPOS38 738
#define IDC_BINPOS39 739
#define IDC_BINPOS40 740
#define IDC_BINPOS41 741
#define IDC_BINPOS42 742
#define IDC_BINPOS43 743
#define IDC_BINPOS44 744
#define IDC_BINPOS45 745
#define IDC_BINPOS46 746
#define IDC_BINPOS47 747
#define IDC_BINPOS48 748
#define IDC_BINPOS49 749
#define IDC_BINPOS50 750
#define IDC_BINPOS51 751
#define IDC_BINPOS52 752
#define IDC_BINPOS53 753
#define IDC_BINPOS54 754
#define IDC_BINPOS55 755
#define IDC_BINPOS56 756
#define IDC_BINPOS57 757
#define IDC_BINPOS58 758
#define IDC_BINPOS59 759
#define IDC_BINPOS60 760
#define IDC_BINPOS61 761
#define IDC_BINPOS62 762
#define IDC_BINPOS63 763
#define IDC_BINEDITEND 763
// The strings in the following range IDS_ENGINESTR_FIRST ... IDS_ENGINESTR_MAX are strings allocated in the
// resource for the purpose internal to Engine and cant be used by the clients
#define IDS_ENGINESTR_FIRST 0
#define IDS_ENGINESTR_MAX 200

View File

@@ -0,0 +1,170 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
/****************************Module*Header***********************************\
* Module Name: CalcEngine.h
*
* Module Descripton:
* The class definition for the Calculator's engine class CCalcEngine
*
* Warnings:
*
* Created: 17-Jan-2008
*
\****************************************************************************/
#include "scimath.h"
#include "CCommand.h"
#include "EngineStrings.h"
#include "Command.h"
#include "CalculatorVector.h"
#include "ExpressionCommand.h"
#include "History.h" // for History Collector
#include "CalcInput.h"
#include "ICalcDisplay.h"
#include "Rational.h"
// The following are NOT real exports of CalcEngine, but for forward declarations
// The real exports follows later
// This is expected to be in same order as IDM_QWORD, IDM_DWORD etc.
enum eNUM_WIDTH {
QWORD_WIDTH, // Number width of 64 bits mode (default)
DWORD_WIDTH, // Number width of 32 bits mode
WORD_WIDTH, // Number width of 16 bits mode
BYTE_WIDTH // Number width of 16 bits mode
};
typedef enum eNUM_WIDTH NUM_WIDTH;
static constexpr size_t NUM_WIDTH_LENGTH = 4;
// This is expected to be in same order as IDM_HEX, IDM_DEC, IDM_OCT, IDM_BIN
enum eRADIX_TYPE {
HEX_RADIX,
DEC_RADIX,
OCT_RADIX,
BIN_RADIX
};
typedef enum eRADIX_TYPE RADIX_TYPE;
namespace CalculationManager
{
class IResourceProvider;
}
namespace CalculatorUnitTests
{
class CalcEngineTests;
}
class CCalcEngine {
public:
CCalcEngine(bool fPrecedence, bool fIntegerMode, CalculationManager::IResourceProvider* const pResourceProvider, __in_opt ICalcDisplay *pCalcDisplay, __in_opt std::shared_ptr<IHistoryDisplay> pHistoryDisplay);
void ProcessCommand(WPARAM wID);
void DisplayError (DWORD nError);
std::unique_ptr<CalcEngine::Rational> PersistedMemObject();
void PersistedMemObject(CalcEngine::Rational const& memObject);
bool FInErrorState() { return m_bError; }
bool FInRecordingState() { return m_bRecord; }
void SettingsChanged();
bool IsCurrentTooBigForTrig();
int GetCurrentRadix();
std::wstring GetCurrentResultForRadix(uint32_t radix, int32_t precision);
void ChangePrecision(int32_t precision) { m_precision = precision; ChangeConstants(m_radix, precision); }
std::wstring GroupDigitsPerRadix(std::wstring_view numberString, uint32_t radix);
std::wstring GetStringForDisplay(CalcEngine::Rational const& rat, uint32_t radix);
void UpdateMaxIntDigits();
wchar_t DecimalSeparator() const;
// Static methods for the instance
static void InitialOneTimeOnlySetup(CalculationManager::IResourceProvider& resourceProvider); // Once per load time to call to intialize all shared global variables
// returns the ptr to string representing the operator. Mostly same as the button, but few special cases for x^y etc.
static std::wstring_view GetString(int ids) { return s_engineStrings[ids]; }
static std::wstring_view OpCodeToString(int nOpCode) { return GetString(IdStrFromCmdId(nOpCode)); }
static std::wstring_view OpCodeToUnaryString(int nOpCode, bool fInv, ANGLE_TYPE angletype);
private:
bool m_fPrecedence;
bool m_fIntegerMode; /* This is true if engine is explicitly called to be in integer mode. All bases are restricted to be in integers only */
ICalcDisplay *m_pCalcDisplay;
CalculationManager::IResourceProvider* const m_resourceProvider;
int m_nOpCode; /* ID value of operation. */
int m_nPrevOpCode; // opcode which computed the number in m_currentVal. 0 if it is already bracketed or plain number or
// if it hasnt yet been computed
bool m_bChangeOp; /* Flag for changing operation. */
bool m_bRecord; // Global mode: recording or displaying
bool m_bSetCalcState; //Falg for setting teh engine result state
CalcEngine::CalcInput m_input; // Global calc input object for decimal strings
eNUMOBJ_FMT m_nFE; /* Scientific notation conversion flag. */
CalcEngine::Rational m_maxTrigonometricNum;
std::unique_ptr<CalcEngine::Rational> m_memoryValue; // Current memory value.
CalcEngine::Rational m_holdVal; // For holding the second operand in repetitive calculations ( pressing "=" continuously)
CalcEngine::Rational m_currentVal; // Currently displayed number used everywhere.
CalcEngine::Rational m_lastVal; // Number before operation (left operand).
std::array<CalcEngine::Rational, MAXPRECDEPTH> m_parenVals; // Holding array for parenthesis values.
std::array<CalcEngine::Rational, MAXPRECDEPTH> m_precedenceVals; // Holding array for precedence values.
bool m_bError; // Error flag.
bool m_bInv; // Inverse on/off flag.
bool m_bNoPrevEqu; /* Flag for previous equals. */
uint32_t m_radix;
int32_t m_precision;
int m_cIntDigitsSav;
std::vector<uint32_t> m_decGrouping; // Holds the decimal digit grouping number
std::wstring m_numberString;
int m_nTempCom; /* Holding place for the last command. */
int m_openParenCount; // Number of open parentheses.
std::array<int, MAXPRECDEPTH> m_nOp; /* Holding array for parenthesis operations. */
std::array<int, MAXPRECDEPTH> m_nPrecOp; /* Holding array for precedence operations. */
int m_nPrecNum; /* Current number of precedence ops in holding. */
int m_nLastCom; // Last command entered.
ANGLE_TYPE m_angletype; // Current Angle type when in dec mode. one of deg, rad or grad
NUM_WIDTH m_numwidth; // one of qword, dword, word or byte mode.
LONG m_dwWordBitWidth; // # of bits in currently selected word size
CHistoryCollector m_HistoryCollector; // Accumulator of each line of history as various commands are processed
std::array<CalcEngine::Rational, NUM_WIDTH_LENGTH> m_chopNumbers; // word size enforcement
std::array<std::wstring, NUM_WIDTH_LENGTH> m_maxDecimalValueStrings; // maximum values represented by a given word width based off m_chopNumbers
static std::array<std::wstring, CSTRINGSENGMAX> s_engineStrings; // the string table shared across all instances
wchar_t m_decimalSeparator;
wchar_t m_groupSeparator;
private:
void ProcessCommandWorker(WPARAM wParam);
void HandleErrorCommand(WPARAM idc);
void HandleMaxDigitsReached();
void DisplayNum(void);
int IsNumberInvalid(const std::wstring& numberString, int iMaxExp, int iMaxMantissa, uint32_t radix) const;
void DisplayAnnounceBinaryOperator();
void SetPrimaryDisplay(const std::wstring& szText, bool isError = false);
void ClearTemporaryValues();
CalcEngine::Rational TruncateNumForIntMath(CalcEngine::Rational const& rat);
CalcEngine::Rational SciCalcFunctions(CalcEngine::Rational const& rat, DWORD op);
CalcEngine::Rational DoOperation(int operation, CalcEngine::Rational const& lhs, CalcEngine::Rational const& rhs);
void SetRadixTypeAndNumWidth(RADIX_TYPE radixtype, NUM_WIDTH numwidth);
LONG DwWordBitWidthFromeNumWidth(NUM_WIDTH numwidth);
uint32_t NRadixFromRadixType( RADIX_TYPE radixtype);
bool TryToggleBit(CalcEngine::Rational& rat, DWORD wbitno);
void CheckAndAddLastBinOpToHistory(bool addToHistory = true);
int IdcSetAngleTypeDecMode(int idc);
void InitChopNumbers();
static void LoadEngineStrings(CalculationManager::IResourceProvider& resourceProvider);
static int IdStrFromCmdId(int id) { return id - IDC_FIRSTCONTROL + IDS_FIRSTENGSTR; }
static std::vector<uint32_t> DigitGroupingStringToGroupingVector(std::wstring_view groupingString);
std::wstring GroupDigits(std::wstring_view delimiter, std::vector<uint32_t> const& grouping, std::wstring_view displayString, bool isNumNegative = false);
static int QuickLog2(int iNum);
static void ChangeBaseConstants(uint32_t radix, int maxIntDigits, int32_t precision);
void BaseOrPrecisionChanged();
friend class CalculatorUnitTests::CalcEngineTests;
};

View File

@@ -0,0 +1,67 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "Rational.h"
// Space to hold enough digits for a quadword binary number (64) plus digit separator strings for that number (20)
constexpr int MAX_STRLEN = 84;
namespace CalcEngine
{
class CalcNumSec
{
public:
CalcNumSec() :
m_isNegative(false),
value()
{}
void Clear();
bool IsEmpty() { return value.empty(); }
bool IsNegative() { return m_isNegative; }
void IsNegative(bool value) { m_isNegative = value; }
std::wstring value;
private:
bool m_isNegative;
};
class CalcInput
{
public:
CalcInput() : CalcInput(L'.')
{}
CalcInput(wchar_t decSymbol) :
m_base(),
m_exponent(),
m_hasExponent(false),
m_hasDecimal(false),
m_decPtIndex(0),
m_decSymbol(decSymbol)
{}
void Clear();
bool TryToggleSign(bool isIntegerMode, std::wstring_view maxNumStr);
bool TryAddDigit(unsigned int value, uint32_t radix, bool isIntegerMode, std::wstring_view maxNumStr, long wordBitWidth, int maxDigits);
bool TryAddDecimalPt();
bool HasDecimalPt();
bool TryBeginExponent();
void Backspace();
void SetDecimalSymbol(wchar_t decSymbol);
std::wstring ToString(uint32_t radix, bool isIntegerMode);
Rational ToRational(uint32_t radix, int32_t precision);
private:
bool m_hasExponent;
bool m_hasDecimal;
size_t m_decPtIndex;
wchar_t m_decSymbol;
CalcNumSec m_base;
CalcNumSec m_exponent;
};
}

View File

@@ -0,0 +1,13 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
bool IsOpInRange(WPARAM op, uint32_t x, uint32_t y);
bool IsBinOpCode(WPARAM opCode);
// WARNING: IDC_SIGN is a special unary op but still this doesnt catch this. Caller has to be aware
// of it and catch it themself or not needing this
bool IsUnaryOpCode(WPARAM opCode);
bool IsDigitOpCode(WPARAM opCode);
bool IsGuiSettingOpCode(WPARAM opCode);

View File

@@ -0,0 +1,339 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/****************************Module*Header***********************************
* Module Name: EngineStrings.h
*
* Module Descripton:
* Resource String ID's for the private strings used by Engine. Internal to Engine related code
* not required by the clients
*
* Warnings:
*
* Created: 13-Feb-2008
*
\****************************************************************************/
#define IDS_FIRSTENGSTR IDS_ENGINESTR_FIRST
#define IDS_DECIMAL 4
// All unary op function names for easy history reading
// This is where the first string after all the commands in order have been placed, should be placed
// keeping in consecutive helps us to allocate 1 string table and index them
#define IDS_FNSZFIRST (IDC_F -IDC_FIRSTCONTROL)+1
#define IDS_FRAC IDS_FNSZFIRST
#define IDS_SIND IDS_FNSZFIRST+1
#define IDS_COSD IDS_FNSZFIRST+2
#define IDS_TAND IDS_FNSZFIRST+3
#define IDS_ASIND IDS_FNSZFIRST+4
#define IDS_ACOSD IDS_FNSZFIRST+5
#define IDS_ATAND IDS_FNSZFIRST+6
#define IDS_SINR IDS_FNSZFIRST+7
#define IDS_COSR IDS_FNSZFIRST+8
#define IDS_TANR IDS_FNSZFIRST+9
#define IDS_ASINR IDS_FNSZFIRST+10
#define IDS_ACOSR IDS_FNSZFIRST+11
#define IDS_ATANR IDS_FNSZFIRST+12
#define IDS_SING IDS_FNSZFIRST+13
#define IDS_COSG IDS_FNSZFIRST+14
#define IDS_TANG IDS_FNSZFIRST+15
#define IDS_ASING IDS_FNSZFIRST+16
#define IDS_ACOSG IDS_FNSZFIRST+17
#define IDS_ATANG IDS_FNSZFIRST+18
#define IDS_ASINH IDS_FNSZFIRST+19
#define IDS_ACOSH IDS_FNSZFIRST+20
#define IDS_ATANH IDS_FNSZFIRST+21
#define IDS_POWE IDS_FNSZFIRST+22
#define IDS_POW10 IDS_FNSZFIRST+23
#define IDS_SQRT IDS_FNSZFIRST+24
#define IDS_SQR IDS_FNSZFIRST+25
#define IDS_CUBE IDS_FNSZFIRST+26
#define IDS_CUBERT IDS_FNSZFIRST+27
#define IDS_FACT IDS_FNSZFIRST+28
#define IDS_REC IDS_FNSZFIRST+29
#define IDS_DEGREES IDS_FNSZFIRST+30
#define IDS_NEGATE IDS_FNSZFIRST+31
#define IDS_RSH IDS_FNSZFIRST+32
#define IDS_FNSZLAST IDS_RSH
#define IDS_ERRORS_FIRST IDS_FNSZLAST+1
// This is the list of error strings corresponding to SCERR_DIVIDEZERO..
#define IDS_DIVBYZERO IDS_ERRORS_FIRST
#define IDS_DOMAIN IDS_ERRORS_FIRST+1
#define IDS_UNDEFINED IDS_ERRORS_FIRST+2
#define IDS_POS_INFINITY IDS_ERRORS_FIRST+3
#define IDS_NEG_INFINITY IDS_ERRORS_FIRST+4
#define IDS_NOMEM IDS_ERRORS_FIRST+6
#define IDS_TOOMANY IDS_ERRORS_FIRST+7
#define IDS_OVERFLOW IDS_ERRORS_FIRST+8
#define IDS_NORESULT IDS_ERRORS_FIRST+9
#define IDS_INSUFFICIENT_DATA IDS_ERRORS_FIRST+10
#define CSTRINGSENGMAX IDS_INSUFFICIENT_DATA+1
// Arithmetic expression evaluator error strings
#define IDS_ERR_UNK_CH CSTRINGSENGMAX+1
#define IDS_ERR_UNK_FN CSTRINGSENGMAX+2
#define IDS_ERR_UNEX_NUM CSTRINGSENGMAX+3
#define IDS_ERR_UNEX_CH CSTRINGSENGMAX+4
#define IDS_ERR_UNEX_SZ CSTRINGSENGMAX+5
#define IDS_ERR_MISMATCH_CLOSE CSTRINGSENGMAX+6
#define IDS_ERR_UNEX_END CSTRINGSENGMAX+7
#define IDS_ERR_SG_INV_ERROR CSTRINGSENGMAX+8
#define IDS_ERR_INPUT_OVERFLOW CSTRINGSENGMAX+9
#define IDS_ERR_OUTPUT_OVERFLOW CSTRINGSENGMAX+10
#define SIDS_PLUS_MINUS L"0"
#define SIDS_CLEAR L"1"
#define SIDS_CE L"2"
#define SIDS_BACKSPACE L"3"
#define SIDS_DECIMAL_SEPARATOR L"4"
#define SIDS_EMPTY_STRING L"5"
#define SIDS_AND L"6"
#define SIDS_OR L"7"
#define SIDS_XOR L"8"
#define SIDS_LSH L"9"
#define SIDS_RSH L"10"
#define SIDS_DIVIDE L"11"
#define SIDS_MULTIPLY L"12"
#define SIDS_PLUS L"13"
#define SIDS_MINUS L"14"
#define SIDS_MOD L"15"
#define SIDS_YROOT L"16"
#define SIDS_POW_HAT L"17"
#define SIDS_INT L"18"
#define SIDS_ROL L"19"
#define SIDS_ROR L"20"
#define SIDS_NOT L"21"
#define SIDS_SIN L"22"
#define SIDS_COS L"23"
#define SIDS_TAN L"24"
#define SIDS_SINH L"25"
#define SIDS_COSH L"26"
#define SIDS_TANH L"27"
#define SIDS_LN L"28"
#define SIDS_LOG L"29"
#define SIDS_SQRT L"30"
#define SIDS_XPOW2 L"31"
#define SIDS_XPOW3 L"32"
#define SIDS_NFACTORIAL L"33"
#define SIDS_RECIPROCAL L"34"
#define SIDS_DMS L"35"
#define SIDS_CUBEROOT L"36"
#define SIDS_POWTEN L"37"
#define SIDS_PERCENT L"38"
#define SIDS_SCIENTIFIC_NOTATION L"39"
#define SIDS_PI L"40"
#define SIDS_EQUAL L"41"
#define SIDS_MC L"42"
#define SIDS_MR L"43"
#define SIDS_MS L"44"
#define SIDS_MPLUS L"45"
#define SIDS_MMINUS L"46"
#define SIDS_EXP L"47"
#define SIDS_OPEN_PAREN L"48"
#define SIDS_CLOSE_PAREN L"49"
#define SIDS_0 L"50"
#define SIDS_1 L"51"
#define SIDS_2 L"52"
#define SIDS_3 L"53"
#define SIDS_4 L"54"
#define SIDS_5 L"55"
#define SIDS_6 L"56"
#define SIDS_7 L"57"
#define SIDS_8 L"58"
#define SIDS_9 L"59"
#define SIDS_A L"60"
#define SIDS_B L"61"
#define SIDS_C L"62"
#define SIDS_D L"63"
#define SIDS_E L"64"
#define SIDS_F L"65"
#define SIDS_FRAC L"66"
#define SIDS_SIND L"67"
#define SIDS_COSD L"68"
#define SIDS_TAND L"69"
#define SIDS_ASIND L"70"
#define SIDS_ACOSD L"71"
#define SIDS_ATAND L"72"
#define SIDS_SINR L"73"
#define SIDS_COSR L"74"
#define SIDS_TANR L"75"
#define SIDS_ASINR L"76"
#define SIDS_ACOSR L"77"
#define SIDS_ATANR L"78"
#define SIDS_SING L"79"
#define SIDS_COSG L"80"
#define SIDS_TANG L"81"
#define SIDS_ASING L"82"
#define SIDS_ACOSG L"83"
#define SIDS_ATANG L"84"
#define SIDS_ASINH L"85"
#define SIDS_ACOSH L"86"
#define SIDS_ATANH L"87"
#define SIDS_POWE L"88"
#define SIDS_POWTEN2 L"89"
#define SIDS_SQRT2 L"90"
#define SIDS_SQR L"91"
#define SIDS_CUBE L"92"
#define SIDS_CUBERT L"93"
#define SIDS_FACT L"94"
#define SIDS_RECIPROC L"95"
#define SIDS_DEGREES L"96"
#define SIDS_NEGATE L"97"
#define SIDS_RSH2 L"98"
#define SIDS_DIVIDEBYZERO L"99"
#define SIDS_DOMAIN L"100"
#define SIDS_UNDEFINED L"101"
#define SIDS_POS_INFINITY L"102"
#define SIDS_NEG_INFINITY L"103"
#define SIDS_ABORTED L"104"
#define SIDS_NOMEM L"105"
#define SIDS_TOOMANY L"106"
#define SIDS_OVERFLOW L"107"
#define SIDS_NORESULT L"108"
#define SIDS_INSUFFICIENT_DATA L"109"
// 110 is skipped by CSTRINGSENGMAX
#define SIDS_ERR_UNK_CH L"111"
#define SIDS_ERR_UNK_FN L"112"
#define SIDS_ERR_UNEX_NUM L"113"
#define SIDS_ERR_UNEX_CH L"114"
#define SIDS_ERR_UNEX_SZ L"115"
#define SIDS_ERR_MISMATCH_CLOSE L"116"
#define SIDS_ERR_UNEX_END L"117"
#define SIDS_ERR_SG_INV_ERROR L"118"
#define SIDS_ERR_INPUT_OVERFLOW L"119"
#define SIDS_ERR_OUTPUT_OVERFLOW L"120"
__declspec(selectany) std::wstring g_sids[] =
{
std::wstring(SIDS_PLUS_MINUS),
std::wstring(SIDS_C),
std::wstring(SIDS_CE),
std::wstring(SIDS_BACKSPACE),
std::wstring(SIDS_DECIMAL_SEPARATOR),
std::wstring(SIDS_EMPTY_STRING),
std::wstring(SIDS_AND),
std::wstring(SIDS_OR),
std::wstring(SIDS_XOR),
std::wstring(SIDS_LSH),
std::wstring(SIDS_RSH),
std::wstring(SIDS_DIVIDE),
std::wstring(SIDS_MULTIPLY),
std::wstring(SIDS_PLUS),
std::wstring(SIDS_MINUS),
std::wstring(SIDS_MOD),
std::wstring(SIDS_YROOT),
std::wstring(SIDS_POW_HAT),
std::wstring(SIDS_INT),
std::wstring(SIDS_ROL),
std::wstring(SIDS_ROR),
std::wstring(SIDS_NOT),
std::wstring(SIDS_SIN),
std::wstring(SIDS_COS),
std::wstring(SIDS_TAN),
std::wstring(SIDS_SINH),
std::wstring(SIDS_COSH),
std::wstring(SIDS_TANH),
std::wstring(SIDS_LN),
std::wstring(SIDS_LOG),
std::wstring(SIDS_SQRT),
std::wstring(SIDS_XPOW2),
std::wstring(SIDS_XPOW3),
std::wstring(SIDS_NFACTORIAL),
std::wstring(SIDS_RECIPROCAL),
std::wstring(SIDS_DMS),
std::wstring(SIDS_CUBEROOT),
std::wstring(SIDS_POWTEN),
std::wstring(SIDS_PERCENT),
std::wstring(SIDS_SCIENTIFIC_NOTATION),
std::wstring(SIDS_PI),
std::wstring(SIDS_EQUAL),
std::wstring(SIDS_MC),
std::wstring(SIDS_MR),
std::wstring(SIDS_MS),
std::wstring(SIDS_MPLUS),
std::wstring(SIDS_MMINUS),
std::wstring(SIDS_EXP),
std::wstring(SIDS_OPEN_PAREN),
std::wstring(SIDS_CLOSE_PAREN),
std::wstring(SIDS_0),
std::wstring(SIDS_1),
std::wstring(SIDS_2),
std::wstring(SIDS_3),
std::wstring(SIDS_4),
std::wstring(SIDS_5),
std::wstring(SIDS_6),
std::wstring(SIDS_7),
std::wstring(SIDS_8),
std::wstring(SIDS_9),
std::wstring(SIDS_A),
std::wstring(SIDS_B),
std::wstring(SIDS_C),
std::wstring(SIDS_D),
std::wstring(SIDS_E),
std::wstring(SIDS_F),
std::wstring(SIDS_FRAC),
std::wstring(SIDS_SIND),
std::wstring(SIDS_COSD),
std::wstring(SIDS_TAND),
std::wstring(SIDS_ASIND),
std::wstring(SIDS_ACOSD),
std::wstring(SIDS_ATAND),
std::wstring(SIDS_SINR),
std::wstring(SIDS_COSR),
std::wstring(SIDS_TANR),
std::wstring(SIDS_ASINR),
std::wstring(SIDS_ACOSR),
std::wstring(SIDS_ATANR),
std::wstring(SIDS_SING),
std::wstring(SIDS_COSG),
std::wstring(SIDS_TANG),
std::wstring(SIDS_ASING),
std::wstring(SIDS_ACOSG),
std::wstring(SIDS_ATANG),
std::wstring(SIDS_ASINH),
std::wstring(SIDS_ACOSH),
std::wstring(SIDS_ATANH),
std::wstring(SIDS_POWE),
std::wstring(SIDS_POWTEN2),
std::wstring(SIDS_SQRT2),
std::wstring(SIDS_SQR),
std::wstring(SIDS_CUBE),
std::wstring(SIDS_CUBERT),
std::wstring(SIDS_FACT),
std::wstring(SIDS_RECIPROC),
std::wstring(SIDS_DEGREES),
std::wstring(SIDS_NEGATE),
std::wstring(SIDS_RSH),
std::wstring(SIDS_DIVIDEBYZERO),
std::wstring(SIDS_DOMAIN),
std::wstring(SIDS_UNDEFINED),
std::wstring(SIDS_POS_INFINITY),
std::wstring(SIDS_NEG_INFINITY),
std::wstring(SIDS_ABORTED),
std::wstring(SIDS_NOMEM),
std::wstring(SIDS_TOOMANY),
std::wstring(SIDS_OVERFLOW),
std::wstring(SIDS_NORESULT),
std::wstring(SIDS_INSUFFICIENT_DATA),
std::wstring(SIDS_ERR_UNK_CH),
std::wstring(SIDS_ERR_UNK_FN),
std::wstring(SIDS_ERR_UNEX_NUM),
std::wstring(SIDS_ERR_UNEX_CH),
std::wstring(SIDS_ERR_UNEX_SZ),
std::wstring(SIDS_ERR_MISMATCH_CLOSE),
std::wstring(SIDS_ERR_UNEX_END),
std::wstring(SIDS_ERR_SG_INV_ERROR),
std::wstring(SIDS_ERR_INPUT_OVERFLOW),
std::wstring(SIDS_ERR_OUTPUT_OVERFLOW)
};

View File

@@ -0,0 +1,59 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
#include "ICalcDisplay.h"
#include "IHistoryDisplay.h"
// maximum depth you can get by precedence. It is just an array's size limit.
static constexpr size_t MAXPRECDEPTH = 25;
// Helper class really a internal class to CCalcEngine, to accumulate each history line of text by collecting the
// operands, operator, unary operator etc. Since it is a seperate entity, it can be unit tested on its own but does
// rely on CCalcEngine calling it in appropriate order.
class CHistoryCollector {
public:
CHistoryCollector(ICalcDisplay *pCalcDisplay, std::shared_ptr<IHistoryDisplay> pHistoryDisplay, wchar_t decimalSymbol); // Can throw errors
~CHistoryCollector();
void AddOpndToHistory(std::wstring_view numStr, PRAT hNoNum, bool fRepetition = false);
void RemoveLastOpndFromHistory();
void AddBinOpToHistory(int nOpCode, bool fNoRepetition = true);
void ChangeLastBinOp(int nOpCode, bool fPrecInvToHigher);
void AddUnaryOpToHistory(int nOpCode, bool fInv, ANGLE_TYPE angletype);
void AddOpenBraceToHistory();
void AddCloseBraceToHistory();
void PushLastOpndStart(int ichOpndStart = -1);
void PopLastOpndStart();
void EnclosePrecInvertionBrackets();
bool FOpndAddedToHistory();
void CompleteHistoryLine(std::wstring_view numStr);
void ClearHistoryLine(std::wstring_view errStr);
int AddCommand(_In_ const std::shared_ptr<IExpressionCommand> & spCommand);
void UpdateHistoryExpression(uint32_t radix, int32_t precision);
void SetDecimalSymbol(wchar_t decimalSymbol);
private:
std::shared_ptr<IHistoryDisplay> m_pHistoryDisplay;
ICalcDisplay *m_pCalcDisplay;
int m_iCurLineHistStart; // index of the begginning of the current equation
// a sort of state, set to the index before 2 after 2 in the expression 2 + 3 say. Useful for auto correct portion of history and for
// attaching the unary op around the last operand
int m_lastOpStartIndex; // index of the beginning of the last operand added to the history
int m_lastBinOpStartIndex; // index of the beginning of the last binary operator added to the history
std::array<int, MAXPRECDEPTH> m_operandIndices; // Stack of index of opnd's beginning for each '('. A parallel array to m_hnoParNum, but abstracted independently of that
int m_curOperandIndex; // Stack index for the above stack
bool m_bLastOpndBrace; // iff the last opnd in history is already braced so we can avoid putting another one for unary operator
wchar_t m_decimalSymbol;
std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> m_spTokens;
std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> m_spCommands;
private:
void ReinitHistory();
int IchAddSzToEquationSz(std::wstring_view str, int icommandIndex);
void TruncateEquationSzFromIch(int ich);
void SetExpressionDisplay();
void InsertSzInEquationSz(std::wstring_view str, int icommandIndex, int ich);
std::shared_ptr<CalculatorVector<int>> GetOperandCommandsFromString(std::wstring_view numStr);
};

View File

@@ -0,0 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
// Callback interface to be implemented by the clients of CCalcEngine
class ICalcDisplay {
public:
virtual void SetPrimaryDisplay(const std::wstring& pszText, bool isError) = 0;
virtual void SetIsInError(bool isInError) = 0;
virtual void SetExpressionDisplay(_Inout_ std::shared_ptr<CalculatorVector<std::pair<std::wstring, int>>> const &tokens, _Inout_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands) = 0;
virtual void SetParenDisplayText(const std::wstring& pszText) = 0;
virtual void MaxDigitsReached() = 0; // not an error but still need to inform UI layer.
virtual void BinaryOperatorReceived() = 0;
virtual void OnHistoryItemAdded(_In_ unsigned int addedItemIndex) = 0;
virtual void SetMemorizedNumbers(const std::vector<std::wstring>& memorizedNumbers) = 0;
virtual void MemoryItemChanged(unsigned int indexOfMemory) = 0;
};

View File

@@ -0,0 +1,11 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#pragma once
// Callback interface to be implemented by the clients of CCalcEngine if they require equation history
class IHistoryDisplay {
public:
virtual ~IHistoryDisplay() {};
virtual unsigned int AddToHistory(_In_ std::shared_ptr<CalculatorVector <std::pair<std::wstring, int>>> const &tokens, _In_ std::shared_ptr<CalculatorVector<std::shared_ptr<IExpressionCommand>>> const &commands, _In_ std::wstring_view result) = 0;
};

View File

@@ -0,0 +1,29 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
#pragma once
#include "RatPack/ratpak.h"
namespace CalcEngine
{
class Number
{
public:
Number() noexcept;
Number(int32_t sign, int32_t exp, std::vector<uint32_t> const& mantissa) noexcept;
explicit Number(PNUMBER p) noexcept;
PNUMBER ToPNUMBER() const;
int32_t const& Sign() const;
int32_t const& Exp() const;
std::vector<uint32_t> const& Mantissa() const;
bool IsZero() const;
private:
int32_t m_sign;
int32_t m_exp;
std::vector<uint32_t> m_mantissa;
};
}

View File

@@ -0,0 +1,28 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
#pragma once
#include "Number.h"
namespace CalcEngine
{
class Rational
{
public:
Rational() noexcept;
Rational(Number const& n) noexcept;
Rational(Number const& p, Number const& q) noexcept;
explicit Rational(PRAT prat) noexcept;
PRAT ToPRAT() const;
Number const& P() const;
Number const& Q() const;
bool IsZero() const;
private:
Number m_p;
Number m_q;
};
}

View File

@@ -0,0 +1,79 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
/**************************************************************************\
* *
* *
* *
* # # ##### *
* # # # # # *
* # # # # # # # *
* # ### ### # # *
* # # ### # # # ### # # ### ##### # ### ### ### *
* # ## # # # ## # # # # # # ## # # # *
* # # # # # # # # # ##### # # ##### # *
* # # # # # # # # # # # # # # ## *
* # # # # # # # # # ### # # ### ### ## *
* *
* *
* Infinte Precision Production Version *
* *
\**************************************************************************/
//
// RETAIL version of NUMOBJ math that uses Infinite Precision
//
#include "Ratpack/ratpak.h"
//
// Unary functions
//
void NumObjInvert(PRAT *phno, int32_t precision);
void NumObjNegate(PRAT *phno);
void NumObjAbs(PRAT *phno);
void NumObjSin(PRAT *phno, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
void NumObjCos(PRAT *phno, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
void NumObjTan(PRAT *phno, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
void NumObjAntiLog10(PRAT *phno, uint32_t radix, int32_t precision);
void NumObjNot(PRAT *phno, bool fIntegerMode, PRAT chopNum, uint32_t radix, int32_t precision);
//
// Comparison functions
//
bool NumObjIsZero(PRAT hno);
bool NumObjIsLess(PRAT hno1, PRAT hno2, int32_t precision);
bool NumObjIsLessEq(PRAT hno1, PRAT hno2, int32_t precision);
bool NumObjIsGreaterEq(PRAT hno1, PRAT hno2, int32_t precision);
bool NumObjIsEq(PRAT hno1, PRAT hno2, int32_t precision);
//
// Assignment operator. ('=' in C language)
//
void NumObjAssign(PRAT *phnol, PRAT hnor);
//
// Data type conversion functions
//
void NumObjSetIntValue(PRAT *phnol, LONG i );
void NumObjSetUlonglongValue(PRAT *phnol, ULONGLONG ul, uint32_t radix, int32_t precision);
ULONGLONG NumObjGetUlValue( PRAT hnol, uint32_t radix, int32_t precision);
// Returns a string representation of hnoNum
std::wstring NumObjToString(PRAT hnoNum, uint32_t radix, NUMOBJ_FMT fmt, int32_t precision);
//
// NumObjGetExp
//
// returns an int that equals the exponent of the NumObj
//
int32_t NumObjGetExp(PRAT hno);
//
// NumObjDestroy( hno )
//
// call this when you nolonger need the NumObj. Failure to do so
// will result in memory leaks.
//
void NumObjDestroy(PRAT *phno);