From fd148a8d1278631873c3f307ceae66122bc15cde Mon Sep 17 00:00:00 2001 From: s-hadinger <49731213+s-hadinger@users.noreply.github.com> Date: Mon, 29 Apr 2024 22:55:57 +0200 Subject: [PATCH] Berry `math.inf`, `math.isinf()` and fixed json ouput for `inf` and `nan` (#21304) --- CHANGELOG.md | 1 + lib/libesp32/berry/src/be_jsonlib.c | 10 +++++++++ lib/libesp32/berry/src/be_mathlib.c | 15 ++++++++++++++ lib/libesp32/berry/tests/math.be | 32 +++++++++++++++++++++++++++++ 4 files changed, 58 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1fcdd262a..4d0e3c043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ All notable changes to this project will be documented in this file. - LVGL fix memory allocation of flush buffers - Berry `web_add_handler` called before `Webserver` is initialized - Put back wifi IPv6 workaround +- Berry `math.inf`, `math.isinf()` and fixed json ouput for `inf` and `nan` ### Removed - LVGL disabled vector graphics diff --git a/lib/libesp32/berry/src/be_jsonlib.c b/lib/libesp32/berry/src/be_jsonlib.c index db2b20677..615e8bebc 100644 --- a/lib/libesp32/berry/src/be_jsonlib.c +++ b/lib/libesp32/berry/src/be_jsonlib.c @@ -8,6 +8,7 @@ #include "be_object.h" #include "be_mem.h" #include +#include #if BE_USE_JSON_MODULE @@ -515,6 +516,15 @@ static void value_dump(bvm *vm, int *indent, int idx, int fmt) } else if (be_isnil(vm, idx)) { /* convert to json null */ be_stack_require(vm, 1 + BE_STACK_FREE_MIN); be_pushstring(vm, "null"); + } else if (be_isreal(vm, idx)) { + be_stack_require(vm, 1 + BE_STACK_FREE_MIN); + breal v = be_toreal(vm, idx); + if (isnan(v) || isinf(v)) { + be_pushstring(vm, "null"); + } else { + be_tostring(vm, idx); + be_pushvalue(vm, idx); /* push to top */ + }; } else if (be_isnumber(vm, idx) || be_isbool(vm, idx)) { /* convert to json number and boolean */ be_stack_require(vm, 1 + BE_STACK_FREE_MIN); be_tostring(vm, idx); diff --git a/lib/libesp32/berry/src/be_mathlib.c b/lib/libesp32/berry/src/be_mathlib.c index b9598f525..52abeffd7 100644 --- a/lib/libesp32/berry/src/be_mathlib.c +++ b/lib/libesp32/berry/src/be_mathlib.c @@ -45,6 +45,17 @@ static int m_isnan(bvm *vm) be_return(vm); } +static int m_isinf(bvm *vm) +{ + if (be_top(vm) >= 1 && be_isreal(vm, 1)) { + breal x = be_toreal(vm, 1); + be_pushbool(vm, isinf(x)); + } else { + be_pushbool(vm, bfalse); + } + be_return(vm); +} + static int m_abs(bvm *vm) { if (be_top(vm) >= 1 && be_isnumber(vm, 1)) { @@ -284,6 +295,7 @@ static int m_rand(bvm *vm) #if !BE_USE_PRECOMPILED_OBJECT be_native_module_attr_table(math) { be_native_module_function("isnan", m_isnan), + be_native_module_function("isinf", m_isinf), be_native_module_function("abs", m_abs), be_native_module_function("ceil", m_ceil), be_native_module_function("floor", m_floor), @@ -308,6 +320,7 @@ be_native_module_attr_table(math) { be_native_module_function("rand", m_rand), be_native_module_real("pi", M_PI), be_native_module_real("nan", NAN), + be_native_module_real("inf", INFINITY), be_native_module_int("imax", M_IMAX), be_native_module_int("imin", M_IMIN), }; @@ -317,6 +330,7 @@ be_define_native_module(math, NULL); /* @const_object_info_begin module math (scope: global, depend: BE_USE_MATH_MODULE) { isnan, func(m_isnan) + isinf, func(m_isinf) abs, func(m_abs) ceil, func(m_ceil) floor, func(m_floor) @@ -341,6 +355,7 @@ module math (scope: global, depend: BE_USE_MATH_MODULE) { rand, func(m_rand) pi, real(M_PI) nan, real(NAN) + inf, real(INFINITY) imax, int(M_IMAX) imin, int(M_IMIN) } diff --git a/lib/libesp32/berry/tests/math.be b/lib/libesp32/berry/tests/math.be index 12facca63..232ffa285 100644 --- a/lib/libesp32/berry/tests/math.be +++ b/lib/libesp32/berry/tests/math.be @@ -10,5 +10,37 @@ assert(math.isnan(n*0)) assert(!math.isnan(0)) assert(!math.isnan(1.5)) +assert(!math.isnan(math.inf)) assert(n != n) #- nan is never identical to itself -# + +#- inf -# +i = math.inf +assert(str(i) == 'inf') +assert(str(-i) == '-inf') # inf has a sign +assert(math.isinf(i)) +assert(math.isinf(i+i)) +assert(math.isinf(i+1)) +# the following result in nan +assert(math.isnan(i*0)) +assert(math.isnan(i-i)) +assert(math.isnan(i/i)) + +assert(!math.isinf(0)) +assert(!math.isinf(1.5)) +assert(!math.isinf(math.nan)) + +assert(i == i) #- equality works for inf -# +assert(i == i+1) + +#- nan and inf convert to null in json -# +import json + +m_nan = {"v": math.nan} +assert(json.dump(m_nan) == '{"v":null}') +m_inf1 = {"v": math.inf} +assert(json.dump(m_inf1) == '{"v":null}') +m_inf2 = {"v": -math.inf} +assert(json.dump(m_inf2) == '{"v":null}') +m_v = {"v": 3.5} +assert(json.dump(m_v) == '{"v":3.5}')