From c25faea558de25dc3de8a6de99affb608aaa7e09 Mon Sep 17 00:00:00 2001 From: Igor Sysoev Date: Mon, 25 Apr 2016 19:30:27 +0300 Subject: [PATCH] parseFloat() function. --- njs/njs_builtin.c | 2 ++ njs/njs_generator.c | 1 + njs/njs_lexer_keyword.c | 1 + njs/njs_number.c | 20 +++++++++++++++++++- njs/njs_number.h | 2 ++ njs/njs_parser.c | 1 + njs/njs_parser.h | 1 + njs/njs_string.c | 14 ++++++++------ njs/njs_string.h | 2 +- njs/njs_vm.c | 4 ++-- njs/njs_vm.h | 3 ++- njs/test/njs_unit_test.c | 3 +++ 12 files changed, 43 insertions(+), 11 deletions(-) diff --git a/njs/njs_builtin.c b/njs/njs_builtin.c index 895deb2b..c53a0047 100644 --- a/njs/njs_builtin.c +++ b/njs/njs_builtin.c @@ -84,6 +84,7 @@ njs_builtin_objects_create(njs_vm_t *vm) NULL, NULL, NULL, + NULL, }; static const njs_function_init_t native_functions[] = { @@ -94,6 +95,7 @@ njs_builtin_objects_create(njs_vm_t *vm) { njs_number_is_finite, { NJS_SKIP_ARG, NJS_NUMBER_ARG } }, { njs_number_parse_int, { NJS_SKIP_ARG, NJS_STRING_ARG, NJS_INTEGER_ARG } }, + { njs_number_parse_float, { NJS_SKIP_ARG, NJS_STRING_ARG } }, }; static const njs_object_prop_t null_proto_property = { diff --git a/njs/njs_generator.c b/njs/njs_generator.c index 5deb1ded..eb18e45b 100644 --- a/njs/njs_generator.c +++ b/njs/njs_generator.c @@ -298,6 +298,7 @@ njs_generator(njs_vm_t *vm, njs_parser_t *parser, njs_parser_node_t *node) case NJS_TOKEN_IS_NAN: case NJS_TOKEN_IS_FINITE: case NJS_TOKEN_PARSE_INT: + case NJS_TOKEN_PARSE_FLOAT: return njs_generate_builtin_object(vm, parser, node); case NJS_TOKEN_FUNCTION: diff --git a/njs/njs_lexer_keyword.c b/njs/njs_lexer_keyword.c index 53d84cd8..0a3a6228 100644 --- a/njs/njs_lexer_keyword.c +++ b/njs/njs_lexer_keyword.c @@ -92,6 +92,7 @@ static const njs_keyword_t njs_keywords[] = { { nxt_string("isNaN"), NJS_TOKEN_IS_NAN, 0 }, { nxt_string("isFinite"), NJS_TOKEN_IS_FINITE, 0 }, { nxt_string("parseInt"), NJS_TOKEN_PARSE_INT, 0 }, + { nxt_string("parseFloat"), NJS_TOKEN_PARSE_FLOAT, 0 }, /* Reserved words. */ diff --git a/njs/njs_number.c b/njs/njs_number.c index 5fa81452..51b0785c 100644 --- a/njs/njs_number.c +++ b/njs/njs_number.c @@ -36,7 +36,7 @@ njs_value_to_number(njs_value_t *value) } if (njs_is_string(value)) { - return njs_string_to_number(value); + return njs_string_to_number(value, 1); } if (njs_is_array(value)) { @@ -549,3 +549,21 @@ done: return NXT_OK; } + + +njs_ret_t +njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, + njs_index_t unused) +{ + double num; + + num = NJS_NAN; + + if (nargs > 1) { + num = njs_string_to_number(&args[1], 0); + } + + njs_number_set(&vm->retval, num); + + return NXT_OK; +} diff --git a/njs/njs_number.h b/njs/njs_number.h index 4fa27804..c63ff05c 100644 --- a/njs/njs_number.h +++ b/njs/njs_number.h @@ -37,6 +37,8 @@ njs_ret_t njs_number_is_finite(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); njs_ret_t njs_number_parse_int(njs_vm_t *vm, njs_value_t *args, nxt_uint_t nargs, njs_index_t unused); +njs_ret_t njs_number_parse_float(njs_vm_t *vm, njs_value_t *args, + nxt_uint_t nargs, njs_index_t unused); extern const njs_object_init_t njs_number_constructor_init; diff --git a/njs/njs_parser.c b/njs/njs_parser.c index 575c2e6a..cadfc3ce 100644 --- a/njs/njs_parser.c +++ b/njs/njs_parser.c @@ -1648,6 +1648,7 @@ njs_parser_terminal(njs_vm_t *vm, njs_parser_t *parser, njs_token_t token) case NJS_TOKEN_IS_NAN: case NJS_TOKEN_IS_FINITE: case NJS_TOKEN_PARSE_INT: + case NJS_TOKEN_PARSE_FLOAT: return njs_parser_builtin_function(vm, parser, node); default: diff --git a/njs/njs_parser.h b/njs/njs_parser.h index 3d35f096..f8d4ca98 100644 --- a/njs/njs_parser.h +++ b/njs/njs_parser.h @@ -179,6 +179,7 @@ typedef enum { NJS_TOKEN_IS_NAN, NJS_TOKEN_IS_FINITE, NJS_TOKEN_PARSE_INT, + NJS_TOKEN_PARSE_FLOAT, NJS_TOKEN_RESERVED, } njs_token_t; diff --git a/njs/njs_string.c b/njs/njs_string.c index d5bc353c..2f979b8d 100644 --- a/njs/njs_string.c +++ b/njs/njs_string.c @@ -1678,7 +1678,7 @@ njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, double -njs_string_to_number(njs_value_t *value) +njs_string_to_number(njs_value_t *value, nxt_bool_t exact) { double num; size_t size; @@ -1737,12 +1737,14 @@ njs_string_to_number(njs_value_t *value) p += infinity; } - while (p < end) { - if (*p != ' ' && *p != '\t') { - return NJS_NAN; - } + if (exact) { + while (p < end) { + if (*p != ' ' && *p != '\t') { + return NJS_NAN; + } - p++; + p++; + } } return minus ? -num : num; diff --git a/njs/njs_string.h b/njs/njs_string.h index d4d398a2..e651c705 100644 --- a/njs/njs_string.h +++ b/njs/njs_string.h @@ -103,7 +103,7 @@ nxt_noinline uint32_t njs_string_index(njs_string_prop_t *string, uint32_t offset); njs_ret_t njs_primitive_value_to_string(njs_vm_t *vm, njs_value_t *dst, const njs_value_t *src); -double njs_string_to_number(njs_value_t *value); +double njs_string_to_number(njs_value_t *value, nxt_bool_t exact); njs_index_t njs_value_index(njs_vm_t *vm, njs_parser_t *parser, const njs_value_t *src); diff --git a/njs/njs_vm.c b/njs/njs_vm.c index 046ce692..c2729036 100644 --- a/njs/njs_vm.c +++ b/njs/njs_vm.c @@ -2915,7 +2915,7 @@ njs_vmcode_number_primitive(njs_vm_t *vm, njs_value_t *invld, njs_value_t *narg) num = NJS_NAN; if (njs_is_string(value)) { - num = njs_string_to_number(value); + num = njs_string_to_number(value, 1); } njs_number_set(value, num); @@ -2968,7 +2968,7 @@ njs_vmcode_number_argument(njs_vm_t *vm, njs_value_t *invld1, num = NJS_NAN; if (njs_is_string(value)) { - num = njs_string_to_number(value); + num = njs_string_to_number(value, 1); } njs_number_set(value, num); diff --git a/njs/njs_vm.h b/njs/njs_vm.h index 9e9fb69c..00748208 100644 --- a/njs/njs_vm.h +++ b/njs/njs_vm.h @@ -705,7 +705,8 @@ enum njs_function_e { NJS_FUNCTION_IS_NAN = 2, NJS_FUNCTION_IS_FINITE = 3, NJS_FUNCTION_PARSE_INT = 4, -#define NJS_FUNCTION_MAX (NJS_FUNCTION_PARSE_INT + 1) + NJS_FUNCTION_PARSE_FLOAT = 5, +#define NJS_FUNCTION_MAX (NJS_FUNCTION_PARSE_FLOAT + 1) }; diff --git a/njs/test/njs_unit_test.c b/njs/test/njs_unit_test.c index f4b8b66a..59f80c51 100644 --- a/njs/test/njs_unit_test.c +++ b/njs/test/njs_unit_test.c @@ -4449,6 +4449,9 @@ static njs_unit_test_t njs_test[] = { nxt_string("parseInt('njscript', 36)"), nxt_string("1845449130881") }, + { nxt_string("parseFloat('12345abc')"), + nxt_string("12345") }, + /* External interface. */ { nxt_string("function f(req) { return req.uri }"), -- 2.47.3