+fix: TinyExpr output formatter

This commit is contained in:
METANEOCORTEX\Kotti 2023-07-18 00:42:49 +02:00
parent ced7c18e43
commit e51a1799e0
5 changed files with 68 additions and 30 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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)
<img alt="TinyExpr logo" src="https://codeplea.com/public/content/tinyexpr_logo.png" align="right"/>
@ -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

View File

@ -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);

View File

@ -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