diff --git a/src/Notepad3.c b/src/Notepad3.c index 10ebe9126..7d2a47d51 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -677,6 +677,34 @@ static inline void ResetFileObservationData(const bool bResetEvt) { } // ---------------------------------------------------------------------------- +#define TE_ZERO (1.0E-8) +#define TE_FMTA "%.8G" +#define TE_FMTW L"%.8G" + +void TinyExprToStringA(LPSTR pszDest, size_t cchDest, const double dExprEval) +{ + double intpart = 0.0; + if ((fabs(modf(dExprEval, &intpart)) < TE_ZERO) && (fabs(intpart) < 1.0E+21)) { + StringCchPrintfA(pszDest, cchDest, "%.21G", intpart); // integer full number display + } + else { + StringCchPrintfA(pszDest, cchDest, TE_FMTA, dExprEval); + } +} +// ---------------------------------------------------------------------------- + +void TinyExprToString(LPWSTR pszDest, size_t cchDest, const double dExprEval) +{ + double intpart = 0.0; + if ((fabs(modf(dExprEval, &intpart)) < TE_ZERO) && (fabs(intpart) < 1.0E+21)) { + StringCchPrintf(pszDest, cchDest, L"%.21G", intpart); // integer full number display + } + else { + StringCchPrintf(pszDest, cchDest, TE_FMTW, dExprEval); + } +} +// ---------------------------------------------------------------------------- + //============================================================================= // @@ -2688,12 +2716,7 @@ static bool _EvalTinyExpr(bool qmark) if (!exprErr) { char chExpr[80] = { '\0' }; - double intpart; - if ((modf(dExprEval, &intpart) == 0) && (fabs(intpart) < 1.0E+21)) { - StringCchPrintfA(chExpr, COUNTOF(chExpr), "%.21G", intpart); // integer full number display - } else { - StringCchPrintfA(chExpr, COUNTOF(chExpr), "%.7G", dExprEval); - } + TinyExprToStringA(chExpr, COUNTOF(chExpr), dExprEval); SciCall_ReplaceSel(""); SciCall_SetSel(posBegin, posSelStart); SciCall_ReplaceSel(chExpr); @@ -9251,12 +9274,7 @@ LRESULT MsgNotify(HWND hwnd, WPARAM wParam, LPARAM lParam) case STATUS_TINYEXPR: { char chExpr[80] = { '\0' }; if (s_iExprError == 0) { - double intpart; - if ((modf(s_dExpression, &intpart) == 0) && (fabs(intpart) < 1.0E+21)) { - StringCchPrintfA(chExpr, COUNTOF(chExpr), "%.21G", intpart); // integer full number display - } else { - StringCchPrintfA(chExpr, COUNTOF(chExpr), "%.7G", s_dExpression); - } + TinyExprToStringA(chExpr, COUNTOF(chExpr), s_dExpression); } else if (s_iExprError > 0) { StringCchPrintfA(chExpr, COUNTOF(chExpr), "^[" TE_INT_FMT "]", s_iExprError); SciCall_CopyText((DocPos)StringCchLenA(chExpr, COUNTOF(chExpr)), chExpr); @@ -10437,7 +10455,7 @@ static void _UpdateStatusbarDelayed(bool bForceRedraw) } if (!s_iExprError) { - StringCchPrintf(tchExpression, COUNTOF(tchExpression), L"%.7G", s_dExpression); + TinyExprToString(tchExpression, COUNTOF(tchExpression), s_dExpression); } else if (s_iExprError > 0) { StringCchPrintf(tchExpression, COUNTOF(tchExpression), L"^[" _W(TE_INT_FMT) L"]", s_iExprError); } diff --git a/src/tinyexpr/Makefile b/src/tinyexpr/Makefile index cc9765c88..d3db7cfca 100644 --- a/src/tinyexpr/Makefile +++ b/src/tinyexpr/Makefile @@ -1,19 +1,26 @@ -CCFLAGS = -ansi -Wall -Wshadow -O2 +CC = gcc +CCFLAGS = -Wall -Wshadow -O2 LFLAGS = -lm .PHONY = all clean -all: test test_pr bench example example2 example3 +all: smoke smoke_pr repl bench example example2 example3 -test: test.c tinyexpr.c +smoke: smoke.c tinyexpr.c $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) ./$@ -test_pr: test.c tinyexpr.c +smoke_pr: smoke.c tinyexpr.c $(CC) $(CCFLAGS) -DTE_POW_FROM_RIGHT -DTE_NAT_LOG -o $@ $^ $(LFLAGS) ./$@ +repl: repl.o tinyexpr.o + $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) + +repl-readline: repl-readline.o tinyexpr.o + $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) -lreadline + bench: benchmark.o tinyexpr.o $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) @@ -26,8 +33,11 @@ example2: example2.o tinyexpr.o example3: example3.o tinyexpr.o $(CC) $(CCFLAGS) -o $@ $^ $(LFLAGS) +repl-readline.o: repl.c + $(CC) -c -DUSE_READLINE $(CCFLAGS) $< -o $@ + .c.o: $(CC) -c $(CCFLAGS) $< -o $@ clean: - rm -f *.o *.exe example example2 example3 bench test_pr test + rm -f *.o *.exe example example2 example3 bench repl smoke_pr smoke diff --git a/src/tinyexpr/README.md b/src/tinyexpr/README.md index ad9f45a45..1d5747d0b 100644 --- a/src/tinyexpr/README.md +++ b/src/tinyexpr/README.md @@ -1,4 +1,4 @@ -[![Build Status](https://travis-ci.org/codeplea/tinyexpr.svg?branch=master)](https://travis-ci.org/codeplea/tinyexpr) +[![Build Status](https://travis-ci.com/codeplea/tinyexpr.svg?branch=master)](https://travis-ci.com/codeplea/tinyexpr) TinyExpr logo @@ -6,15 +6,15 @@ # TinyExpr TinyExpr is a very small recursive descent parser and evaluation engine for -math expressions. It's handy when you want to add the ability to evaluation -math expressions at runtime without adding a bunch of cruft to you project. +math expressions. It's handy when you want to add the ability to evaluate +math expressions at runtime without adding a bunch of cruft to your project. In addition to the standard math operators and precedence, TinyExpr also supports the standard C math functions and runtime binding of variables. ## Features -- **ANSI C with no dependencies**. +- **C99 with no dependencies**. - Single source file and header file. - Simple and fast. - Implements standard operators precedence. @@ -85,7 +85,7 @@ be evaluated later using `te_eval()`. On failure, `te_compile()` will return 0 and optionally set the passed in `*error` to the location of the parse error. You may also compile expressions without variables by passing `te_compile()`'s second -and thrid arguments as 0. +and third arguments as 0. Give `te_eval()` a `te_expr*` from `te_compile()`. `te_eval()` will evaluate the expression using the current variable values. @@ -255,11 +255,10 @@ TinyExpr parses the following grammar: In addition, whitespace between tokens is ignored. -Valid variable names consist of a lower case letter followed by any combination -of: lower case letters *a* through *z*, the digits *0* through *9*, and -underscore. Constants can be integers, decimal numbers, or in scientific -notation (e.g. *1e3* for *1000*). A leading zero is not required (e.g. *.5* -for *0.5*) +Valid variable names consist of a letter followed by any combination of: +letters, the digits *0* through *9*, and underscore. Constants can be integers, +decimal numbers, or in scientific notation (e.g. *1e3* for *1000*). A leading +zero is not required (e.g. *.5* for *0.5*) ## Functions supported diff --git a/src/tinyexpr/benchmark.c b/src/tinyexpr/benchmark.c index 9e98acc50..788fb28d3 100644 --- a/src/tinyexpr/benchmark.c +++ b/src/tinyexpr/benchmark.c @@ -97,6 +97,14 @@ double a5(double a) { return a+5; } +double a55(double a) { + return 5+a+5; +} + +double a5abs(double a) { + return fabs(a+5); +} + double a52(double a) { return (a+5)*2; } @@ -116,8 +124,11 @@ double al(double a) { int main(int argc, char *argv[]) { - bench("sqrt(a^1.5+a^2.5)", as); bench("a+5", a5); + bench("5+a+5", a55); + bench("abs(a+5)", a5abs); + + bench("sqrt(a^1.5+a^2.5)", as); bench("a+(5*2)", a10); bench("(a+5)*2", a52); bench("(1/(a+1)+2/(a+2)+3/(a+3))", al); diff --git a/src/tinyexpr/tinyexpr.c b/src/tinyexpr/tinyexpr.c index e4b0ce357..540d59583 100644 --- a/src/tinyexpr/tinyexpr.c +++ b/src/tinyexpr/tinyexpr.c @@ -332,7 +332,7 @@ static double parse_number(const char *pstrg, char **pendptr) { break; } } - return strtod(pstrg, pendptr); + return (double)strtold(pstrg, pendptr); } #ifndef COUNTOF