From a5f4bc3fe04f697c1077d70e6c44fee2b7571c9e Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Mon, 22 Jan 2024 22:29:39 +0000 Subject: [PATCH] Add builtin::inf and builtin::nan --- builtin.c | 29 +++++++++++++++++++++++++++++ lib/builtin.pm | 19 ++++++++++++++++++- lib/builtin.t | 12 ++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) diff --git a/builtin.c b/builtin.c index 415c84d00d27c..4dcb2d41e2808 100644 --- a/builtin.c +++ b/builtin.c @@ -87,15 +87,40 @@ XS(XS_builtin_false) XSRETURN_NO; } +XS(XS_builtin_inf); +XS(XS_builtin_inf) +{ + dXSARGS; + if(items) + croak_xs_usage(cv, ""); + mPUSHn(PL_inf.nv); + XSRETURN(1); +} + +XS(XS_builtin_nan); +XS(XS_builtin_nan) +{ + dXSARGS; + if(items) + croak_xs_usage(cv, ""); + mPUSHn(PL_nan.nv); + XSRETURN(1); +} + enum { BUILTIN_CONST_FALSE, BUILTIN_CONST_TRUE, + BUILTIN_CONST_INF, + BUILTIN_CONST_NAN, }; static OP *ck_builtin_const(pTHX_ OP *entersubop, GV *namegv, SV *ckobj) { const struct BuiltinFuncDescriptor *builtin = NUM2PTR(const struct BuiltinFuncDescriptor *, SvUV(ckobj)); + if(builtin->is_experimental) + warn_experimental_builtin(builtin->name); + SV *prototype = newSVpvs(""); SAVEFREESV(prototype); @@ -107,6 +132,8 @@ static OP *ck_builtin_const(pTHX_ OP *entersubop, GV *namegv, SV *ckobj) switch(builtin->ckval) { case BUILTIN_CONST_FALSE: constval = &PL_sv_no; break; case BUILTIN_CONST_TRUE: constval = &PL_sv_yes; break; + case BUILTIN_CONST_INF: constval = newSVnv(PL_inf.nv); break; + case BUILTIN_CONST_NAN: constval = newSVnv(PL_nan.nv); break; default: DIE(aTHX_ "panic: unrecognised builtin_const value %" IVdf, builtin->ckval); @@ -516,6 +543,8 @@ static const struct BuiltinFuncDescriptor builtins[] = { /* constants */ { "true", SHORTVER(5,39), &XS_builtin_true, &ck_builtin_const, BUILTIN_CONST_TRUE, false }, { "false", SHORTVER(5,39), &XS_builtin_false, &ck_builtin_const, BUILTIN_CONST_FALSE, false }, + { "inf", NO_BUNDLE, &XS_builtin_inf, &ck_builtin_const, BUILTIN_CONST_INF, true }, + { "nan", NO_BUNDLE, &XS_builtin_nan, &ck_builtin_const, BUILTIN_CONST_NAN, true }, /* unary functions */ { "is_bool", NO_BUNDLE, &XS_builtin_func1_scalar, &ck_builtin_func1, OP_IS_BOOL, true }, diff --git a/lib/builtin.pm b/lib/builtin.pm index 7bf8d6d67ee0f..6863a4aabbe47 100644 --- a/lib/builtin.pm +++ b/lib/builtin.pm @@ -1,4 +1,4 @@ -package builtin 0.012; +package builtin 0.013; use strict; use warnings; @@ -18,6 +18,7 @@ builtin - Perl pragma to import built-in utility functions use builtin qw( true false is_bool + inf nan weaken unweaken is_weak blessed refaddr reftype created_as_string created_as_number @@ -143,6 +144,22 @@ or any variable containing one of these results. This function used to be named C. A compatibility alias is provided currently but will be removed in a later version. +=head2 inf + + $num = inf; + +This function is currently B. + +Returns the numerical infinity value. + +=head2 nan + + $num = nan; + +This function is currently B. + +Returns the numerical not-a-number value. + =head2 weaken weaken($ref); diff --git a/lib/builtin.t b/lib/builtin.t index 391c4c72a0f47..532bf2902342d 100644 --- a/lib/builtin.t +++ b/lib/builtin.t @@ -51,6 +51,18 @@ package FetchStoreCounter { is(prototype(\&builtin::is_bool), '$', 'is_bool prototype'); } +# float constants +{ + use builtin qw( inf nan ); + + ok(inf, 'inf is true'); + ok(inf > 1E10, 'inf is bigger than 1E10'); + ok(inf == inf, 'inf is equal to inf'); + ok(inf == inf + 1, 'inf is equal to inf + 1'); + + ok(nan != nan, 'NaN is not equal to NaN'); +} + # weakrefs { use builtin qw( is_weak weaken unweaken );