From 840bd5d448921a2f50b56dbb2141658c95c71fcd Mon Sep 17 00:00:00 2001 From: peefy Date: Tue, 10 Sep 2024 13:25:09 +0800 Subject: [PATCH] refactor: all runtime func args and kwargs Signed-off-by: peefy --- kclvm/Cargo.lock | 35 +++++ kclvm/runtime/Cargo.toml | 4 + kclvm/runtime/src/json/mod.rs | 27 ++-- kclvm/runtime/src/manifests/mod.rs | 2 +- kclvm/runtime/src/math/mod.rs | 145 +++++++++++------- kclvm/runtime/src/net/mod.rs | 139 +++++++++++------ kclvm/runtime/src/regex/mod.rs | 100 ++++++------ kclvm/runtime/src/stdlib/builtin_api.rs | 3 +- kclvm/runtime/src/units/mod.rs | 85 ++++++---- kclvm/runtime/src/value/val_args.rs | 20 +++ kclvm/runtime/src/value/val_as_val.rs | 9 ++ kclvm/runtime/src/yaml/mod.rs | 42 ++--- .../builtins/net/is_ip_2/stdout.golden | 2 +- 13 files changed, 399 insertions(+), 214 deletions(-) diff --git a/kclvm/Cargo.lock b/kclvm/Cargo.lock index f2d8e8fd1..af0f12015 100644 --- a/kclvm/Cargo.lock +++ b/kclvm/Cargo.lock @@ -778,6 +778,18 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" +[[package]] +name = "dns-lookup" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5766087c2235fec47fafa4cfecc81e494ee679d0fd4a59887ea0919bfb0e4fc" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "socket2", + "windows-sys 0.48.0", +] + [[package]] name = "either" version = "1.13.0" @@ -1286,6 +1298,17 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "hostname" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "windows", +] + [[package]] name = "http" version = "1.1.0" @@ -2075,11 +2098,13 @@ dependencies = [ "blake3", "bstr", "chrono", + "dns-lookup", "encoding", "fancy-regex", "generational-arena", "glob", "handlebars", + "hostname", "indexmap 1.9.3", "itertools", "kclvm_runtime_internal_macros", @@ -4812,6 +4837,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" diff --git a/kclvm/runtime/Cargo.toml b/kclvm/runtime/Cargo.toml index bf90ccf0e..c98093613 100644 --- a/kclvm/runtime/Cargo.toml +++ b/kclvm/runtime/Cargo.toml @@ -35,6 +35,10 @@ anyhow = "1" blake3 = "1.5.4" encoding = "0.2.33" +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +hostname = "0.4.0" +dns-lookup = "2.0.4" + [[bin]] name = "gen-api-spec" path = "scripts/gen-api-spec.rs" diff --git a/kclvm/runtime/src/json/mod.rs b/kclvm/runtime/src/json/mod.rs index e8933c493..24d9230c7 100644 --- a/kclvm/runtime/src/json/mod.rs +++ b/kclvm/runtime/src/json/mod.rs @@ -15,9 +15,9 @@ pub extern "C" fn kclvm_json_encode( let ctx = mut_ptr_as_ref(ctx); let kwargs = ptr_as_ref(kwargs); - if let Some(arg0) = args.arg_i(0) { + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("data")) { let s = ValueRef::str( - arg0.to_json_string_with_options(&kwargs_to_opts(kwargs)) + arg0.to_json_string_with_options(&args_to_opts(args, kwargs, 1)) .as_ref(), ); return s.into_raw(ctx); @@ -30,12 +30,13 @@ pub extern "C" fn kclvm_json_encode( pub extern "C" fn kclvm_json_decode( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(arg0) = args.arg_i(0) { + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("value")) { match ValueRef::from_json(ctx, arg0.as_str().as_ref()) { Ok(x) => return x.into_raw(ctx), Err(err) => panic!("{}", err), @@ -49,12 +50,13 @@ pub extern "C" fn kclvm_json_decode( pub extern "C" fn kclvm_json_validate( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(arg0) = args.arg_i(0) { + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("value")) { match ValueRef::from_json(ctx, arg0.as_str().as_ref()) { Ok(_) => return kclvm_value_True(ctx), Err(_) => return kclvm_value_False(ctx), @@ -77,7 +79,7 @@ pub extern "C" fn kclvm_json_dump_to_file( match (data, filename) { (Some(data), Some(filename)) => { let filename = filename.as_str(); - let json = data.to_json_string_with_options(&kwargs_to_opts(kwargs)); + let json = data.to_json_string_with_options(&args_to_opts(args, kwargs, 2)); std::fs::write(&filename, json) .unwrap_or_else(|e| panic!("Unable to write file '{}': {}", filename, e)); kclvm_value_Undefined(ctx) @@ -88,18 +90,19 @@ pub extern "C" fn kclvm_json_dump_to_file( } } -fn kwargs_to_opts(kwargs: &ValueRef) -> JsonEncodeOptions { +fn args_to_opts(args: &ValueRef, kwargs: &ValueRef, index: usize) -> JsonEncodeOptions { let mut opts = JsonEncodeOptions::default(); - if let Some(sort_keys) = kwargs.kwarg_bool("sort_keys", None) { + if let Some(sort_keys) = get_call_arg_bool(args, kwargs, index, Some("sort_keys")) { opts.sort_keys = sort_keys; } - if let Some(indent) = kwargs.kwarg_int("indent", None) { + if let Some(indent) = get_call_arg_int(args, kwargs, index + 1, Some("indent")) { opts.indent = indent; } - if let Some(ignore_private) = kwargs.kwarg_bool("ignore_private", None) { + if let Some(ignore_private) = get_call_arg_bool(args, kwargs, index + 2, Some("ignore_private")) + { opts.ignore_private = ignore_private; } - if let Some(ignore_none) = kwargs.kwarg_bool("ignore_none", None) { + if let Some(ignore_none) = get_call_arg_bool(args, kwargs, index + 3, Some("ignore_none")) { opts.ignore_none = ignore_none; } opts diff --git a/kclvm/runtime/src/manifests/mod.rs b/kclvm/runtime/src/manifests/mod.rs index 7b3c0c517..aabad1700 100644 --- a/kclvm/runtime/src/manifests/mod.rs +++ b/kclvm/runtime/src/manifests/mod.rs @@ -93,7 +93,7 @@ pub extern "C" fn kclvm_manifests_yaml_stream( None => YamlEncodeOptions::default(), }; - if let Some(value) = args.arg_i(0) { + if let Some(value) = get_call_arg(args, kwargs, 0, Some("values")) { self::yaml::encode_yaml_stream_to_manifests(ctx, &value, opts); } else { panic!("yaml_stream() missing 1 required positional argument: 'values'"); diff --git a/kclvm/runtime/src/math/mod.rs b/kclvm/runtime/src/math/mod.rs index ab0ba6b35..ec3913704 100644 --- a/kclvm/runtime/src/math/mod.rs +++ b/kclvm/runtime/src/math/mod.rs @@ -13,14 +13,15 @@ use crate::*; pub extern "C" fn kclvm_math_ceil( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Int(ctx, x); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Int(ctx, x.ceil() as i64); } @@ -32,7 +33,7 @@ pub extern "C" fn kclvm_math_ceil( pub extern "C" fn kclvm_math_factorial( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { fn factorial(num: i64) -> i64 { if num >= 21 { @@ -48,13 +49,14 @@ pub extern "C" fn kclvm_math_factorial( } let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { if x >= 0 { return kclvm_value_Int(ctx, factorial(x)); } } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { if x >= 0.0 && (x as i64 as f64) == x { return kclvm_value_Float(ctx, factorial(x as i64) as f64); } @@ -71,14 +73,15 @@ pub extern "C" fn kclvm_math_factorial( pub extern "C" fn kclvm_math_floor( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Int(ctx, x); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Float(ctx, x.floor()); } @@ -90,12 +93,13 @@ pub extern "C" fn kclvm_math_floor( pub extern "C" fn kclvm_math_gcd( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(a) = args.arg_i_int(0, None) { - if let Some(b) = args.arg_i_int(1, None) { + if let Some(a) = args.arg_i_int(0, None).or(kwargs.kwarg_int("a", None)) { + if let Some(b) = args.arg_i_int(1, None).or(kwargs.kwarg_int("b", None)) { return kclvm_value_Int(ctx, num_integer::gcd(a, b)); } } @@ -111,19 +115,21 @@ pub extern "C" fn kclvm_math_gcd( pub extern "C" fn kclvm_math_isfinite( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if args.arg_i_int_or_bool(0, None).is_some() { + if args + .arg_i_int(0, None) + .or(kwargs.kwarg_int("x", None)) + .is_some() + { return kclvm_value_Bool(ctx, true as i8); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Bool(ctx, x.is_finite() as i8); } - if args.arg_i_bool(0, None).is_some() { - return kclvm_value_Bool(ctx, true as i8); - } panic!("isfinite() takes exactly one argument (0 given)"); } @@ -133,14 +139,19 @@ pub extern "C" fn kclvm_math_isfinite( pub extern "C" fn kclvm_math_isinf( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if args.arg_i_int_or_bool(0, None).is_some() { + if args + .arg_i_int(0, None) + .or(kwargs.kwarg_int("x", None)) + .is_some() + { return kclvm_value_Bool(ctx, false as i8); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Bool(ctx, x.is_infinite() as i8); } if args.arg_i_bool(0, None).is_some() { @@ -155,14 +166,19 @@ pub extern "C" fn kclvm_math_isinf( pub extern "C" fn kclvm_math_isnan( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(_x) = args.arg_i_int_or_bool(0, None) { + if args + .arg_i_int(0, None) + .or(kwargs.kwarg_int("x", None)) + .is_some() + { return kclvm_value_Bool(ctx, false as i8); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Bool(ctx, x.is_nan() as i8); } @@ -174,16 +190,17 @@ pub extern "C" fn kclvm_math_isnan( pub extern "C" fn kclvm_math_modf( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); let ctx = mut_ptr_as_ref(ctx); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { let list = ValueRef::list_float(&[0.0, x as f64]); return list.into_raw(ctx); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { if !x.is_finite() { if x.is_infinite() { let list = ValueRef::list_float(&[0.0_f64.copysign(x), x]); @@ -205,14 +222,15 @@ pub extern "C" fn kclvm_math_modf( pub extern "C" fn kclvm_math_exp( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Float(ctx, (x as f64).exp()); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Float(ctx, x.exp()); } panic!("exp() takes exactly one argument (0 given)"); @@ -223,14 +241,15 @@ pub extern "C" fn kclvm_math_exp( pub extern "C" fn kclvm_math_expm1( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Float(ctx, (x as f64).exp_m1()); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Float(ctx, x.exp_m1()); } panic!("expm1() takes exactly one argument (0 given)"); @@ -241,17 +260,24 @@ pub extern "C" fn kclvm_math_expm1( pub extern "C" fn kclvm_math_log( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { - if let Some(base) = args.arg_i_float(1, Some(std::f64::consts::E)) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { + if let Some(base) = args + .arg_i_float(1, Some(std::f64::consts::E)) + .or_else(|| kwargs.kwarg_float("e", Some(std::f64::consts::E))) + { return kclvm_value_Int(ctx, (x as f64).log(base) as i64); } } - if let Some(x) = args.arg_i_float(0, None) { - if let Some(base) = args.arg_i_float(1, Some(std::f64::consts::E)) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { + if let Some(base) = args + .arg_i_float(1, Some(std::f64::consts::E)) + .or_else(|| kwargs.kwarg_float("e", Some(std::f64::consts::E))) + { return kclvm_value_Float(ctx, x.log(base)); } } @@ -263,14 +289,15 @@ pub extern "C" fn kclvm_math_log( pub extern "C" fn kclvm_math_log1p( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Float(ctx, ((x + 1) as f64).ln_1p()); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Float(ctx, (x + 1.0).ln_1p()); } panic!("log1p() takes exactly one argument (0 given)"); @@ -281,14 +308,15 @@ pub extern "C" fn kclvm_math_log1p( pub extern "C" fn kclvm_math_log2( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Int(ctx, (x as f64).log2() as i64); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Float(ctx, x.log2()); } panic!("log2() takes exactly one argument (0 given)"); @@ -299,14 +327,15 @@ pub extern "C" fn kclvm_math_log2( pub extern "C" fn kclvm_math_log10( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Float(ctx, (x as f64).log10()); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Float(ctx, x.log10()); } panic!("log10() takes exactly one argument (0 given)"); @@ -317,27 +346,28 @@ pub extern "C" fn kclvm_math_log10( pub extern "C" fn kclvm_math_pow( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { - if let Some(n) = args.arg_i_int_or_bool(1, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { + if let Some(n) = args.arg_i_int(1, None).or(kwargs.kwarg_int("n", None)) { if n < 0 { return kclvm_value_Float(ctx, (x as f64).powf(n as f64)); } else { return kclvm_value_Int(ctx, x.pow(n as u32)); } } - if let Some(n) = args.arg_i_float(1, None) { + if let Some(n) = args.arg_i_float(1, None).or(kwargs.kwarg_float("n", None)) { return kclvm_value_Float(ctx, (x as f64).powf(n)); } } - if let Some(x) = args.arg_i_float(0, None) { - if let Some(n) = args.arg_i_int_or_bool(1, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { + if let Some(n) = args.arg_i_int(1, None).or(kwargs.kwarg_int("n", None)) { return kclvm_value_Float(ctx, x.powi(n as i32)); } - if let Some(n) = args.arg_i_float(1, None) { + if let Some(n) = args.arg_i_float(1, None).or(kwargs.kwarg_float("n", None)) { return kclvm_value_Float(ctx, x.powf(n)); } } @@ -349,14 +379,15 @@ pub extern "C" fn kclvm_math_pow( pub extern "C" fn kclvm_math_sqrt( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(x) = args.arg_i_int_or_bool(0, None) { + if let Some(x) = args.arg_i_int(0, None).or(kwargs.kwarg_int("x", None)) { return kclvm_value_Float(ctx, (x as f64).sqrt()); } - if let Some(x) = args.arg_i_float(0, None) { + if let Some(x) = args.arg_i_float(0, None).or(kwargs.kwarg_float("x", None)) { return kclvm_value_Float(ctx, x.sqrt()); } panic!("sqrt() takes exactly one argument (0 given)"); diff --git a/kclvm/runtime/src/net/mod.rs b/kclvm/runtime/src/net/mod.rs index 17fb1355b..5446d1bab 100644 --- a/kclvm/runtime/src/net/mod.rs +++ b/kclvm/runtime/src/net/mod.rs @@ -13,12 +13,13 @@ use crate::*; pub extern "C" fn kclvm_net_split_host_port( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(string) = args.arg_i_str(0, None) { + if let Some(string) = get_call_arg_str(args, kwargs, 0, Some("ip_end_point")) { let mut list = ValueRef::list(None); for s in string.split(':') { list.list_append(&ValueRef::str(s)); @@ -36,17 +37,18 @@ pub extern "C" fn kclvm_net_split_host_port( pub extern "C" fn kclvm_net_join_host_port( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(host) = args.arg_i_str(0, None) { - if let Some(port) = args.arg_i_int(1, None) { + if let Some(host) = get_call_arg_str(args, kwargs, 0, Some("host")) { + if let Some(port) = args.arg_i_int(1, None).or(kwargs.kwarg_int("port", None)) { let s = format!("{host}:{port}"); return ValueRef::str(s.as_ref()).into_raw(ctx); } - if let Some(port) = args.arg_i_str(1, None) { + if let Some(port) = args.arg_i_str(1, None).or(kwargs.kwarg_str("port", None)) { let s = format!("{host}:{port}"); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -56,19 +58,52 @@ pub extern "C" fn kclvm_net_join_host_port( // fqdn(name: str = '') -> str +#[cfg(not(target_arch = "wasm32"))] #[no_mangle] #[runtime_fn] pub extern "C" fn kclvm_net_fqdn( - _ctx: *mut kclvm_context_t, + ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { + use std::net::ToSocketAddrs; + let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); - - if let Some(_name) = args.arg_i_str(0, Some("".to_string())) { - todo!("todo"); + let kwargs = ptr_as_ref(kwargs); + let name = get_call_arg_str(args, kwargs, 0, Some("name")).unwrap_or_default(); + let hostname = if name.is_empty() { + match hostname::get() { + Ok(name) => name.to_string_lossy().into_owned(), + Err(_) => return ValueRef::str("").into_raw(ctx), + } + } else { + name + }; + match (hostname.as_str(), 0).to_socket_addrs() { + Ok(mut addrs) => { + if let Some(addr) = addrs.next() { + match dns_lookup::lookup_addr(&addr.ip()) { + Ok(fqdn) => ValueRef::str(&fqdn), + Err(_) => ValueRef::str(&hostname), + } + } else { + ValueRef::str(&hostname) + } + } + Err(_) => ValueRef::str(&hostname), } - panic!("fqdn() missing 1 required positional argument: 'name'"); + .into_raw(ctx) +} + +#[cfg(target_arch = "wasm32")] +#[no_mangle] +#[runtime_fn] +pub extern "C" fn kclvm_net_fqdn( + _ctx: *mut kclvm_context_t, + _args: *const kclvm_value_ref_t, + _kwargs: *const kclvm_value_ref_t, +) -> *const kclvm_value_ref_t { + panic!("fqdn() do not support the WASM target"); } // parse_IP(ip) -> str @@ -114,11 +149,12 @@ pub extern "C" fn kclvm_net_to_IP16( pub extern "C" fn kclvm_net_IP_string( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { let s = format!("{addr}"); return ValueRef::str(s.as_ref()).into_raw(ctx); @@ -141,11 +177,12 @@ pub extern "C" fn kclvm_net_IP_string( pub extern "C" fn kclvm_net_is_IPv4( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(_addr) = Ipv4Addr::from_str(ip.as_ref()) { return kclvm_value_True(ctx); } @@ -166,11 +203,12 @@ pub extern "C" fn kclvm_net_is_IPv4( pub extern "C" fn kclvm_net_is_IP( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if Ipv4Addr::from_str(ip.as_ref()).is_ok() || Ipv6Addr::from_str(ip.as_ref()).is_ok() { kclvm_value_True(ctx) } else { @@ -188,11 +226,12 @@ pub extern "C" fn kclvm_net_is_IP( pub extern "C" fn kclvm_net_is_loopback_IP( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { let x = addr.is_loopback(); return kclvm_value_Bool(ctx, x as i8); @@ -215,11 +254,12 @@ pub extern "C" fn kclvm_net_is_loopback_IP( pub extern "C" fn kclvm_net_is_multicast_IP( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { let x = addr.is_multicast(); return kclvm_value_Bool(ctx, x as i8); @@ -242,23 +282,26 @@ pub extern "C" fn kclvm_net_is_multicast_IP( pub extern "C" fn kclvm_net_is_interface_local_multicast_IP( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); - - if let Some(ip) = args.arg_i_str(0, None) { + let kwargs = ptr_as_ref(kwargs); + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { - let is_site_local = false; // TODO - let x = is_site_local && addr.is_multicast(); + // For IPv4, interface-local multicast addresses are in the range 224.0.0.0/24 + let is_interface_local = + addr.octets()[0] == 224 && addr.octets()[1] == 0 && addr.octets()[2] == 0; + let x = is_interface_local && addr.is_multicast(); return kclvm_value_Bool(ctx, x as i8); } - if let Ok(_addr) = Ipv6Addr::from_str(ip.as_ref()) { - todo!("todo"); + if let Ok(addr) = Ipv6Addr::from_str(ip.as_ref()) { + // For IPv6, interface-local multicast addresses start with ff01::/16 + let is_interface_local = addr.segments()[0] == 0xff01; + let x = is_interface_local && addr.is_multicast(); + return kclvm_value_Bool(ctx, x as i8); } - - return kclvm_value_False(ctx); + return kclvm_value_Bool(ctx, 0); // False for invalid IP addresses } - panic!("is_interface_local_multicast_IP() missing 1 required positional argument: 'ip'"); } @@ -269,22 +312,26 @@ pub extern "C" fn kclvm_net_is_interface_local_multicast_IP( pub extern "C" fn kclvm_net_is_link_local_multicast_IP( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { - let x = addr.is_link_local() && addr.is_multicast(); + // For IPv4, link-local multicast addresses are in the range 224.0.0.0/24 + let is_link_local_multicast = + addr.octets()[0] == 224 && addr.octets()[1] == 0 && addr.octets()[2] == 0; + let x = is_link_local_multicast && addr.is_multicast(); return kclvm_value_Bool(ctx, x as i8); } if let Ok(addr) = Ipv6Addr::from_str(ip.as_ref()) { - let is_link_local = false; // TODO - let x = is_link_local && addr.is_multicast(); + // For IPv6, link-local multicast addresses start with ff02::/16 + let is_link_local_multicast = addr.segments()[0] == 0xff02; + let x = is_link_local_multicast && addr.is_multicast(); return kclvm_value_Bool(ctx, x as i8); } - - return kclvm_value_False(ctx); + return kclvm_value_Bool(ctx, 0); // False for invalid IP addresses } panic!("is_link_local_multicast_IP() missing 1 required positional argument: 'ip'"); @@ -300,9 +347,9 @@ pub extern "C" fn kclvm_net_is_link_local_unicast_IP( kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); - let _kwargs = ptr_as_ref(kwargs); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { let x = addr.is_link_local() && (!addr.is_multicast()); return kclvm_value_Bool(ctx, x as i8); @@ -329,11 +376,12 @@ pub const fn Ipv6Addr_is_unicast_link_local(_self: &Ipv6Addr) -> bool { pub extern "C" fn kclvm_net_is_global_unicast_IP( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { let x = Ipv4Addr_is_global(&addr) && (!addr.is_multicast()); return kclvm_value_Bool(ctx, x as i8); @@ -394,11 +442,12 @@ const fn Ipv4Addr_is_benchmarking(_self: &std::net::Ipv4Addr) -> bool { pub extern "C" fn kclvm_net_is_unspecified_IP( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(ip) = args.arg_i_str(0, None) { + if let Some(ip) = get_call_arg_str(args, kwargs, 0, Some("ip")) { if let Ok(addr) = Ipv4Addr::from_str(ip.as_ref()) { return kclvm_value_Bool(ctx, addr.is_unspecified() as i8); } diff --git a/kclvm/runtime/src/regex/mod.rs b/kclvm/runtime/src/regex/mod.rs index 6192bfaa4..5d5a4b996 100644 --- a/kclvm/runtime/src/regex/mod.rs +++ b/kclvm/runtime/src/regex/mod.rs @@ -11,12 +11,13 @@ use crate::*; pub extern "C" fn kclvm_regex_match( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(string) = args.arg_i_str(0, None) { - if let Some(pattern) = args.arg_i_str(1, None) { + if let Some(string) = get_call_arg_str(args, kwargs, 0, Some("string")) { + if let Some(pattern) = get_call_arg_str(args, kwargs, 1, Some("pattern")) { let re = fancy_regex::Regex::new(pattern.as_ref()).unwrap(); match re.is_match(string.as_ref()) { Ok(ok) => { @@ -41,20 +42,22 @@ pub extern "C" fn kclvm_regex_match( pub extern "C" fn kclvm_regex_replace( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *mut kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(string) = args.arg_i_str(0, None) { - if let Some(pattern) = args.arg_i_str(1, None) { - if let Some(replace) = args.arg_i_str(2, None) { - if let Some(count) = args.arg_i_int(3, Some(0)) { - let re = fancy_regex::Regex::new(pattern.as_ref()).unwrap(); - let s = re.replacen(string.as_ref(), count as usize, replace.as_ref() as &str); - return ValueRef::str(&s).into_raw(ctx); - } + if let Some(string) = get_call_arg_str(args, kwargs, 0, Some("string")) { + if let Some(pattern) = get_call_arg_str(args, kwargs, 1, Some("pattern")) { + if let Some(replace) = get_call_arg_str(args, kwargs, 2, Some("replace")) { + let count = get_call_arg_int(args, kwargs, 3, Some("count")).unwrap_or_else(|| 0); + let re = fancy_regex::Regex::new(pattern.as_ref()).unwrap(); + let s = re.replacen(string.as_ref(), count as usize, replace.as_ref() as &str); + return ValueRef::str(&s).into_raw(ctx); } + panic!("replace() missing the required positional argument: 'replace'"); } + panic!("replace() missing the required positional argument: 'pattern'"); } panic!("replace() missing 3 required positional arguments: 'string', 'pattern', and 'replace"); } @@ -66,17 +69,18 @@ pub extern "C" fn kclvm_regex_replace( pub extern "C" fn kclvm_regex_compile( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *mut kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(pattern) = args.arg_i_str(0, None) { + if let Some(pattern) = get_call_arg_str(args, kwargs, 0, Some("pattern")) { match fancy_regex::Regex::new(pattern.as_ref()) { Ok(_) => return kclvm_value_Bool(ctx, 1), _ => return kclvm_value_Bool(ctx, 0), } } - panic!("compile() missing 2 required positional arguments: 'string' and 'pattern'") + panic!("compile() missing the required positional argument: 'pattern'") } // findall(string: str, pattern: str) -> [str]: @@ -86,12 +90,13 @@ pub extern "C" fn kclvm_regex_compile( pub extern "C" fn kclvm_regex_findall( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *mut kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(string) = args.arg_i_str(0, None) { - if let Some(pattern) = args.arg_i_str(1, None) { + if let Some(string) = get_call_arg_str(args, kwargs, 0, Some("string")) { + if let Some(pattern) = get_call_arg_str(args, kwargs, 1, Some("pattern")) { let mut list = ValueRef::list(None); for x in fancy_regex::Regex::new(pattern.as_ref()) @@ -113,8 +118,8 @@ pub extern "C" fn kclvm_regex_findall( return list.into_raw(ctx); } + panic!("findall() missing the required positional argument: 'pattern'") } - panic!("findall() missing 2 required positional arguments: 'string' and 'pattern'") } @@ -125,12 +130,13 @@ pub extern "C" fn kclvm_regex_findall( pub extern "C" fn kclvm_regex_search( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *mut kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(string) = args.arg_i_str(0, None) { - if let Some(pattern) = args.arg_i_str(1, None) { + if let Some(string) = get_call_arg_str(args, kwargs, 0, Some("string")) { + if let Some(pattern) = get_call_arg_str(args, kwargs, 1, Some("pattern")) { let re = fancy_regex::Regex::new(pattern.as_ref()).unwrap(); if let Ok(Some(..)) = re.find(string.as_ref()) { @@ -138,6 +144,7 @@ pub extern "C" fn kclvm_regex_search( } return kclvm_value_Bool(ctx, 0); } + panic!("search() missing the required positional argument: 'pattern'"); } panic!("search() missing 2 required positional arguments: 'string' and 'pattern'"); } @@ -149,41 +156,42 @@ pub extern "C" fn kclvm_regex_search( pub extern "C" fn kclvm_regex_split( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *mut kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(string) = args.arg_i_str(0, None) { - if let Some(pattern) = args.arg_i_str(1, None) { - if let Some(maxsplit) = args.arg_i_int(2, Some(0)) { - let mut list = ValueRef::list(None); + if let Some(string) = get_call_arg_str(args, kwargs, 0, Some("string")) { + if let Some(pattern) = get_call_arg_str(args, kwargs, 1, Some("pattern")) { + let maxsplit = get_call_arg_int(args, kwargs, 2, Some("maxsplit")).unwrap_or_else(|| 0); + let mut list = ValueRef::list(None); - let re = fancy_regex::Regex::new(pattern.as_ref()).unwrap(); + let re = fancy_regex::Regex::new(pattern.as_ref()).unwrap(); - let mut fields: Vec = Vec::new(); - let mut current_pos = 0; - loop { - let capture = re - .captures_from_pos(string.as_ref(), current_pos) - .map_or(None, |c| c); - if let Some(Some(cap)) = capture.map(|c| c.get(0)) { - fields.push(string[current_pos..cap.start()].to_string()); - if maxsplit > 0 && fields.len() >= (maxsplit as usize) { - break; - } - current_pos = cap.end(); - } else { - fields.push(string[current_pos..].to_string()); + let mut fields: Vec = Vec::new(); + let mut current_pos = 0; + loop { + let capture = re + .captures_from_pos(string.as_ref(), current_pos) + .map_or(None, |c| c); + if let Some(Some(cap)) = capture.map(|c| c.get(0)) { + fields.push(string[current_pos..cap.start()].to_string()); + if maxsplit > 0 && fields.len() >= (maxsplit as usize) { break; } + current_pos = cap.end(); + } else { + fields.push(string[current_pos..].to_string()); + break; } + } - for s in fields { - list.list_append(&ValueRef::str(s.as_ref())); - } - return list.into_raw(ctx); + for s in fields { + list.list_append(&ValueRef::str(s.as_ref())); } + return list.into_raw(ctx); } + panic!("split() missing the required positional argument: 'pattern'"); } panic!("split() missing 2 required positional arguments: 'string' and 'pattern'"); } diff --git a/kclvm/runtime/src/stdlib/builtin_api.rs b/kclvm/runtime/src/stdlib/builtin_api.rs index d09bb9978..d7c4dae60 100644 --- a/kclvm/runtime/src/stdlib/builtin_api.rs +++ b/kclvm/runtime/src/stdlib/builtin_api.rs @@ -186,7 +186,8 @@ pub unsafe extern "C" fn kclvm_builtin_option( } let required = get_call_arg_bool(args, kwargs, 2, Some("required")).unwrap_or_default(); if required { - let name = args.arg_i_str(0, Some("?".to_string())).unwrap(); + let name = + get_call_arg_str(args, kwargs, 0, Some("key")).unwrap_or_else(|| "?".to_string()); panic!("option('{name}') must be initialized, try '-D {name}=?' argument"); } ValueRef::none().into_raw(ctx) diff --git a/kclvm/runtime/src/units/mod.rs b/kclvm/runtime/src/units/mod.rs index 2dc4091bc..b71115a4f 100644 --- a/kclvm/runtime/src/units/mod.rs +++ b/kclvm/runtime/src/units/mod.rs @@ -44,14 +44,18 @@ pub const INVALID_UNITS: [&str; 4] = ["ni", "ui", "mi", "ki"]; pub extern "C" fn kclvm_units_to_n( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - let num = args.arg_0().unwrap().convert_to_float(ctx).as_float(); - let s = to_unit(num, to_unit_suffix::n); - return ValueRef::str(s.as_ref()).into_raw(ctx); + if let Some(num) = get_call_arg(args, kwargs, 0, Some("num")) { + let num = num.convert_to_float(ctx).as_float(); + let s = to_unit(num, to_unit_suffix::n); + return ValueRef::str(s.as_ref()).into_raw(ctx); + } + panic!("to_n() missing 1 required positional argument: 'num'"); } // to_u(num: int) -> str @@ -61,14 +65,18 @@ pub extern "C" fn kclvm_units_to_n( pub extern "C" fn kclvm_units_to_u( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - let num = args.arg_0().unwrap().convert_to_float(ctx).as_float(); - let s = to_unit(num, to_unit_suffix::u); - return ValueRef::str(s.as_ref()).into_raw(ctx); + if let Some(num) = get_call_arg(args, kwargs, 0, Some("num")) { + let num = num.convert_to_float(ctx).as_float(); + let s = to_unit(num, to_unit_suffix::u); + return ValueRef::str(s.as_ref()).into_raw(ctx); + } + panic!("to_u() missing 1 required positional argument: 'num'"); } // to_m(num: int) -> str @@ -78,14 +86,18 @@ pub extern "C" fn kclvm_units_to_u( pub extern "C" fn kclvm_units_to_m( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - let num = args.arg_0().unwrap().convert_to_float(ctx).as_float(); - let s = to_unit(num, to_unit_suffix::m); - return ValueRef::str(s.as_ref()).into_raw(ctx); + if let Some(num) = get_call_arg(args, kwargs, 0, Some("num")) { + let num = num.convert_to_float(ctx).as_float(); + let s = to_unit(num, to_unit_suffix::m); + return ValueRef::str(s.as_ref()).into_raw(ctx); + } + panic!("to_m() missing 1 required positional argument: 'num'"); } // to_K(num: int) -> str @@ -95,12 +107,13 @@ pub extern "C" fn kclvm_units_to_m( pub extern "C" fn kclvm_units_to_K( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::K); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -118,9 +131,9 @@ pub extern "C" fn kclvm_units_to_M( ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); - let _kwargs = ptr_as_ref(kwargs); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::M); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -134,12 +147,13 @@ pub extern "C" fn kclvm_units_to_M( pub extern "C" fn kclvm_units_to_G( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::G); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -153,12 +167,13 @@ pub extern "C" fn kclvm_units_to_G( pub extern "C" fn kclvm_units_to_T( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::T); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -172,12 +187,13 @@ pub extern "C" fn kclvm_units_to_T( pub extern "C" fn kclvm_units_to_P( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::P); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -191,12 +207,13 @@ pub extern "C" fn kclvm_units_to_P( pub extern "C" fn kclvm_units_to_Ki( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::Ki); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -210,12 +227,13 @@ pub extern "C" fn kclvm_units_to_Ki( pub extern "C" fn kclvm_units_to_Mi( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::Mi); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -229,12 +247,13 @@ pub extern "C" fn kclvm_units_to_Mi( pub extern "C" fn kclvm_units_to_Gi( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::Gi); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -248,12 +267,13 @@ pub extern "C" fn kclvm_units_to_Gi( pub extern "C" fn kclvm_units_to_Ti( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::Ti); return ValueRef::str(s.as_ref()).into_raw(ctx); } @@ -267,12 +287,13 @@ pub extern "C" fn kclvm_units_to_Ti( pub extern "C" fn kclvm_units_to_Pi( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let ctx = mut_ptr_as_ref(ctx); let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); - if let Some(num) = args.arg_i_num(0, None) { + if let Some(num) = get_call_arg_num(args, kwargs, 0, Some("num")) { let s = to_unit(num, to_unit_suffix::Pi); return ValueRef::str(s.as_ref()).into_raw(ctx); } diff --git a/kclvm/runtime/src/value/val_args.rs b/kclvm/runtime/src/value/val_args.rs index d99fb9d29..c32810775 100644 --- a/kclvm/runtime/src/value/val_args.rs +++ b/kclvm/runtime/src/value/val_args.rs @@ -253,6 +253,26 @@ pub fn get_call_arg_bool( get_call_arg(args, kwargs, index, key).map(|v| v.as_bool()) } +#[inline] +pub fn get_call_arg_int( + args: &ValueRef, + kwargs: &ValueRef, + index: usize, + key: Option<&str>, +) -> Option { + get_call_arg(args, kwargs, index, key).map(|v| v.must_as_strict_int()) +} + +#[inline] +pub fn get_call_arg_num( + args: &ValueRef, + kwargs: &ValueRef, + index: usize, + key: Option<&str>, +) -> Option { + get_call_arg(args, kwargs, index, key).map(|v| v.as_num()) +} + #[cfg(test)] mod test_value_args { use crate::*; diff --git a/kclvm/runtime/src/value/val_as_val.rs b/kclvm/runtime/src/value/val_as_val.rs index f118822fa..7e79f566c 100644 --- a/kclvm/runtime/src/value/val_as_val.rs +++ b/kclvm/runtime/src/value/val_as_val.rs @@ -37,6 +37,15 @@ impl ValueRef { } } + #[inline] + pub fn as_num(&self) -> f64 { + match *self.rc.borrow() { + Value::float_value(v) => v, + Value::int_value(v) => v as f64, + _ => return 0.0, + } + } + #[inline] pub fn as_str(&self) -> String { match *self.rc.borrow() { diff --git a/kclvm/runtime/src/yaml/mod.rs b/kclvm/runtime/src/yaml/mod.rs index 10a818a3c..edcfdf0c2 100644 --- a/kclvm/runtime/src/yaml/mod.rs +++ b/kclvm/runtime/src/yaml/mod.rs @@ -15,9 +15,9 @@ pub extern "C" fn kclvm_yaml_encode( let args = ptr_as_ref(args); let kwargs = ptr_as_ref(kwargs); - if let Some(arg0) = args.arg_i(0) { + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("data")) { let s = ValueRef::str( - arg0.to_yaml_string_with_options(&kwargs_to_opts(kwargs)) + arg0.to_yaml_string_with_options(&args_to_opts(args, kwargs, 1)) .as_ref(), ); return s.into_raw(mut_ptr_as_ref(ctx)); @@ -36,8 +36,8 @@ pub extern "C" fn kclvm_yaml_encode_all( let args = ptr_as_ref(args); let kwargs = ptr_as_ref(kwargs); - if let Some(arg0) = args.arg_i(0) { - let opts = kwargs_to_opts(kwargs); + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("data")) { + let opts = args_to_opts(args, kwargs, 1); let results = arg0 .as_list_ref() .values @@ -56,12 +56,13 @@ pub extern "C" fn kclvm_yaml_encode_all( pub extern "C" fn kclvm_yaml_decode( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); - + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(arg0) = args.arg_i(0) { + + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("value")) { match ValueRef::from_yaml(ctx, arg0.as_str().as_ref()) { Ok(x) => return x.into_raw(ctx), Err(err) => panic!("{}", err), @@ -76,12 +77,13 @@ pub extern "C" fn kclvm_yaml_decode( pub extern "C" fn kclvm_yaml_decode_all( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); - + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(arg0) = args.arg_i(0) { + + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("value")) { match ValueRef::list_from_yaml_stream(ctx, arg0.as_str().as_ref()) { Ok(x) => return x.into_raw(ctx), Err(err) => panic!("{}", err), @@ -106,7 +108,7 @@ pub extern "C" fn kclvm_yaml_dump_to_file( (Some(data), Some(filename)) => { let filename = filename.as_str(); - let yaml = data.to_yaml_string_with_options(&kwargs_to_opts(kwargs)); + let yaml = data.to_yaml_string_with_options(&args_to_opts(args, kwargs, 2)); std::fs::write(&filename, yaml) .unwrap_or_else(|e| panic!("Unable to write file '{}': {}", filename, e)); kclvm_value_Undefined(ctx) @@ -133,7 +135,7 @@ pub extern "C" fn kclvm_yaml_dump_all_to_file( match (data, filename) { (Some(data), Some(filename)) => { let filename = filename.as_str(); - let opts = kwargs_to_opts(kwargs); + let opts = args_to_opts(args, kwargs, 2); let results = data .as_list_ref() .values @@ -158,12 +160,13 @@ pub extern "C" fn kclvm_yaml_dump_all_to_file( pub extern "C" fn kclvm_yaml_validate( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); - + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(arg0) = args.arg_i(0) { + + if let Some(arg0) = get_call_arg(args, kwargs, 0, Some("value")) { match ValueRef::from_yaml_stream(ctx, arg0.as_str().as_ref()) { Ok(_) => return kclvm_value_True(ctx), Err(_) => return kclvm_value_False(ctx), @@ -172,15 +175,16 @@ pub extern "C" fn kclvm_yaml_validate( panic!("validate() missing 1 required positional argument: 'value'") } -fn kwargs_to_opts(kwargs: &ValueRef) -> YamlEncodeOptions { +fn args_to_opts(args: &ValueRef, kwargs: &ValueRef, index: usize) -> YamlEncodeOptions { let mut opts = YamlEncodeOptions::default(); - if let Some(sort_keys) = kwargs.kwarg_bool("sort_keys", None) { + if let Some(sort_keys) = get_call_arg_bool(args, kwargs, index, Some("sort_keys")) { opts.sort_keys = sort_keys; } - if let Some(ignore_private) = kwargs.kwarg_bool("ignore_private", None) { + if let Some(ignore_private) = get_call_arg_bool(args, kwargs, index + 1, Some("ignore_private")) + { opts.ignore_private = ignore_private; } - if let Some(ignore_none) = kwargs.kwarg_bool("ignore_none", None) { + if let Some(ignore_none) = get_call_arg_bool(args, kwargs, index + 2, Some("ignore_none")) { opts.ignore_none = ignore_none; } opts diff --git a/test/grammar/builtins/net/is_ip_2/stdout.golden b/test/grammar/builtins/net/is_ip_2/stdout.golden index 03265e7b7..f36847e50 100644 --- a/test/grammar/builtins/net/is_ip_2/stdout.golden +++ b/test/grammar/builtins/net/is_ip_2/stdout.golden @@ -1,6 +1,6 @@ isip0: true isip1: true -isip2: false +isip2: true isip3: true isip4: true isip5: true \ No newline at end of file