From 3895bbf85698ab3e9f739fc74957415a8788a559 Mon Sep 17 00:00:00 2001 From: Stephen Dolan Date: Mon, 10 Sep 2012 17:08:13 +0100 Subject: [PATCH] String -> number conversions with "tonumber". --- c/builtin.c | 25 +++++++++++++++++++++++++ c/testdata | 4 ++++ 2 files changed, 29 insertions(+) diff --git a/c/builtin.c b/c/builtin.c index b65bb09b..7943675d 100644 --- a/c/builtin.c +++ b/c/builtin.c @@ -100,6 +100,30 @@ static void f_divide(jv input[], jv output[]) { } } +static void f_tonumber(jv input[], jv output[]) { + if (jv_get_kind(input[0]) == JV_KIND_NUMBER) { + output[0] = input[0]; + } else if (jv_get_kind(input[0]) == JV_KIND_STRING) { + jv parsed = jv_parse(jv_string_value(input[0])); + if (!jv_is_valid(parsed)) { + jv_free(input[0]); + output[0] = parsed; + } else if (jv_get_kind(parsed) != JV_KIND_NUMBER) { + output[0] = jv_invalid_with_msg(jv_string_fmt("'%s' is not a number", + jv_string_value(input[0]))); + jv_free(input[0]); + } else { + jv_free(input[0]); + output[0] = parsed; + } + } else { + output[0] = jv_invalid_with_msg(jv_string_fmt("Cannot parse %s as a number", + jv_kind_name(jv_get_kind(input[0])))); + jv_free(input[0]); + return; + } +} + struct cfunction function_list[] = { {f_true, "true", CALL_BUILTIN_1_1}, {f_false, "false", CALL_BUILTIN_1_1}, @@ -108,5 +132,6 @@ struct cfunction function_list[] = { {f_minus, "_minus", CALL_BUILTIN_3_1}, {f_multiply, "_multiply", CALL_BUILTIN_3_1}, {f_divide, "_divide", CALL_BUILTIN_3_1}, + {f_tonumber, "tonumber", CALL_BUILTIN_1_1}, }; struct symbol_table builtins = {function_list, sizeof(function_list)/sizeof(function_list[0])}; diff --git a/c/testdata b/c/testdata index eb9f0c5f..45140242 100644 --- a/c/testdata +++ b/c/testdata @@ -183,6 +183,10 @@ null null 10 +1 + tonumber + ("10" | tonumber) +4 +15 + # # User-defined functions # Oh god.