diff --git a/samples/helloworld.ks b/samples/helloworld.ks index 2acc79b..b334adf 100644 --- a/samples/helloworld.ks +++ b/samples/helloworld.ks @@ -2,8 +2,4 @@ //mod D:\code\rs\key-native\target\debug\key_native.dll> m //mod D:\code\rs\key-lang\samples\testmod.ks> m; -log('{//start - 8A03D5af 90 - / ok - 3223 423 2 -}') \ No newline at end of file +log(2.76543.to_fixed(3)) \ No newline at end of file diff --git a/src/primitive/float.rs b/src/primitive/float.rs new file mode 100644 index 0000000..40fded6 --- /dev/null +++ b/src/primitive/float.rs @@ -0,0 +1,133 @@ +use crate::{ + intern::{Interned,intern}, + runtime::calc::CalcRef, + native::NativeFn +}; +use super::litr::Litr; + +fn to_f(v:&Litr)-> f64 { + match v { + Litr::Uint(n)=> *n as _, + Litr::Int(n)=> *n as _, + Litr::Float(n)=> *n, + _=> 0.0 + } +} +pub fn method(n:f64, name:Interned, args:Vec)-> Litr { + macro_rules! get_arg0 {($deal:ident)=> { + args.get(0).map_or(0.0, |n|$deal(n)) + }} + match name.vec() { + // exponential 指数 + b"log"=> Litr::Float(n.log(get_arg0!(to_f))), + b"log2"=> Litr::Float(n.log2()), + b"log10"=> Litr::Float(n.log10()), + b"ln"=> Litr::Float(n.ln()), + b"log1p"=> Litr::Float(n.ln_1p()), + b"exp"=> Litr::Float(n.exp()), + b"exp2"=> Litr::Float(n.exp2()), + b"expm1"=> Litr::Float(n.exp_m1()), + b"hypot"=> Litr::Float(n.hypot(get_arg0!(to_f))), + + // triangles 三角函数 + b"acos"=> Litr::Float(n.acos()), + b"acosh"=> Litr::Float(n.acosh()), + b"asin"=> Litr::Float(n.asin()), + b"asinh"=> Litr::Float(n.asinh()), + b"atan"=> Litr::Float(n.atan()), + b"atan2"=> Litr::Float(n.atan2(get_arg0!(to_f))), + b"atanh"=> Litr::Float(n.atanh()), + b"cos"=> Litr::Float(n.cos()), + b"cosh"=> Litr::Float(n.cosh()), + b"sin"=> Litr::Float(n.sin()), + b"sinh"=> Litr::Float(n.sinh()), + b"tan"=> Litr::Float(n.tan()), + b"tanh"=> Litr::Float(n.tanh()), + b"sincos"=> Litr::List(vec![Litr::Float(n.sin()), Litr::Float(n.cos())]), + + // rounding 四舍五入 + b"ceil"=> Litr::Int(n.ceil() as _), + b"floor"=> Litr::Float(n.floor()), + b"round"=> Litr::Float(n.round()), + b"trunc"=> Litr::Int(n.trunc() as _), + b"fract"=> Litr::Float(n.fract()), + + // power 次幂 + b"pow"=> Litr::Float( + args.get(0).map_or(0.0, |val|match &**val { + Litr::Uint(r)=> n.powi(*r as _), + Litr::Int(r)=> n.powi(*r as _), + Litr::Float(r)=> n.powf(*r), + _=> 1.0 + })), + b"sqrt"=> Litr::Float(n.sqrt()), + b"cbrt"=> Litr::Float(n.cbrt()), + b"recip"=> Litr::Float(n.recip()), + + // compare 比较 + b"max"=> Litr::Float(n.max(get_arg0!(to_f))), + b"min"=> Litr::Float(n.min(get_arg0!(to_f))), + b"clamp"=> Litr::Float({ + assert!(args.len()>=2, "float.clamp需要2个Float作为参数"); + let [mut min,mut max] = [to_f(args.get(0).unwrap()), to_f(args.get(1).unwrap())]; + if min > max { + std::mem::swap(&mut min, &mut max); + } + n.clamp(min,max) + }), + + // sign 符号 注意0和-0的符号不一样 + b"abs"=> Litr::Float(n.abs()), + b"copy_sign"=> Litr::Float(n.copysign(get_arg0!(to_f))), + b"is_pos"=> Litr::Bool(n.is_sign_positive()), + + // Pi 圆周 + b"deg"=> Litr::Float(n.to_degrees()), + b"rad"=> Litr::Float(n.to_radians()), + + // memory 内存 + b"as_buf"=> Litr::Buf(n.to_ne_bytes().to_vec()), + b"rev"=> Litr::Float({ + let mut b = n.to_ne_bytes(); + b.reverse(); + // SAFETY: 这十分unsafe, 不过在考虑字节序时这会很便利 + unsafe{std::mem::transmute(b)} + }), + b"is_nan"=> Litr::Bool(n.is_nan()), + b"is_infinite"=> Litr::Bool(n.is_infinite()), + + // string 字符 + b"to_str"=> Litr::Str(n.to_string()), + b"to_fixed"=> Litr::Str({ + match args.get(0) { + Some(fix_to)=> { + let mut s = n.to_string(); + + let fix_to = 2 + match &**fix_to { + Litr::Int(n)=> *n as _, + Litr::Uint(n)=> *n as _, + _=> 0 + }; + let trunc_len = n.trunc().to_string().len(); + let len = trunc_len - 1 + fix_to; + + if len>=s.len() { + s.push_str(&"0".repeat(len - s.len())); + }else { + s.truncate(len); + } + s + } + None=> n.to_string() + } + }), + + _=> panic!("{}上没有{}方法","Float",name) + } +} + +// - statics - +pub fn statics()-> Vec<(Interned, NativeFn)> { + vec![ + ] +} \ No newline at end of file diff --git a/src/primitive/int.rs b/src/primitive/int.rs index 1d43449..b70f721 100644 --- a/src/primitive/int.rs +++ b/src/primitive/int.rs @@ -45,7 +45,7 @@ pub fn method_int(n:isize, name:Interned, args:Vec)-> Litr { b"to_hex"=> Litr::Str(format!("{:X}", n)), b"min"=> Litr::Int(n.min(get_arg0!(to_isize))), b"max"=> Litr::Int(n.max(get_arg0!(to_isize))), - _=> panic!("{}上没有{}方法","int",name) + _=> panic!("{}上没有{}方法","Int",name) } } @@ -71,7 +71,7 @@ pub fn method_uint(n:usize, name:Interned, args:Vec)-> Litr { b"to_hex"=> Litr::Str(format!("{:X}", n)), b"min"=> Litr::Uint(n.min(get_arg0!(to_usize))), b"max"=> Litr::Uint(n.max(get_arg0!(to_usize))), - _=> panic!("{}上没有{}方法","int",name) + _=> panic!("{}上没有{}方法","Uint",name) } } @@ -96,3 +96,25 @@ fn s_parse_int(args:Vec, _cx:Scope)-> Litr { } Litr::Int(0) } + +// - statics uint - +pub fn statics_uint()-> Vec<(Interned, NativeFn)> { + vec![ + (intern(b"parse"), s_parse_uint), + (intern(b"max"), |_,_|Litr::Uint(usize::MAX)), + (intern(b"min"), |_,_|Litr::Uint(usize::MIN)) + ] +} + +/// 根据传入的进制解析字符串 +fn s_parse_uint(args:Vec, _cx:Scope)-> Litr { + let radix = args.get(1).map_or(10, |n|to_u32(&**n)); + if let Some(s) = args.get(0) { + return match &**s { + Litr::Str(s)=> Litr::Uint(usize::from_str_radix(s, radix) + .unwrap_or_else(|_|panic!("Uint::parse: 数字'{}'解析失败",s))), + n=> Litr::Uint(to_usize(n)) + } + } + Litr::Uint(0) +} diff --git a/src/primitive/mod.rs b/src/primitive/mod.rs index 7d2b2fb..d2005a2 100644 --- a/src/primitive/mod.rs +++ b/src/primitive/mod.rs @@ -9,6 +9,7 @@ pub mod kstd; pub mod buf; pub mod list; pub mod int; +pub mod float; pub mod sym; pub mod obj; pub mod iter; @@ -68,13 +69,15 @@ pub fn classes()-> Vec<(Interned, Class)> {unsafe { if let Some(cls) = &mut CLASSES { cls.iter_mut().map(|(name, f)|(*name, Class::Native(f))).collect() }else { - let buf_c = new_static_class(b"Buf", buf::statics()); - let list_c = new_static_class(b"List", list::statics()); - let obj_c = new_static_class(b"Obj", obj::statics()); - let int_c = new_static_class(b"Int", int::statics_int()); - let sym_c = new_static_class(b"Sym", sym::statics()); - let func_c = new_static_class(b"Func", func::statics()); - CLASSES = Some(vec![buf_c, list_c, obj_c, int_c, sym_c, func_c]); + CLASSES = Some(vec![ + new_static_class(b"Buf", buf::statics()), + new_static_class(b"List", list::statics()), + new_static_class(b"Obj", obj::statics()), + new_static_class(b"Int", int::statics_int()), + new_static_class(b"Uint", int::statics_uint()), + new_static_class(b"Sym", sym::statics()), + new_static_class(b"Func", func::statics()), + ]); classes() } }} diff --git a/src/runtime/calc.rs b/src/runtime/calc.rs index 942711c..3c3bc5d 100644 --- a/src/runtime/calc.rs +++ b/src/runtime/calc.rs @@ -490,15 +490,6 @@ fn binary(mut this: Scope, left:&Box, right:&Box, op:&Box<[u8]>)-> L _=> panic!($pan) } }}; - ($pan:literal $op:tt $n:tt)=> {{ - if match &*right { - Int(r) => *r == 0, - Uint(r) => *r == 0, - Float(r) => *r == 0.0, - _=> false - } {panic!("除数必须非0")} - impl_num!($pan $op) - }}; } /// 二元运算中无符号数的戏份 @@ -571,8 +562,9 @@ fn binary(mut this: Scope, left:&Box, right:&Box, op:&Box<[u8]>)-> L }, b"-" => impl_num!("相减类型不同" -), b"*" => impl_num!("相乘类型不同" *), - b"%" => impl_num!("求余类型不同" % 0), - b"/" => impl_num!("相除类型不同" / 0), + // 本应该判断非0的,还是让rust帮我报错吧 + b"%" => impl_num!("求余类型不同" %), + b"/" => impl_num!("相除类型不同" /), // unsigned b"<<" => impl_unsigned!("左移需要左值无符号" <<), diff --git a/src/runtime/call.rs b/src/runtime/call.rs index 8856459..a5f1ac8 100644 --- a/src/runtime/call.rs +++ b/src/runtime/call.rs @@ -46,6 +46,7 @@ impl Scope { Litr::List(v)=> primitive::list::method(v, self, name, args), Litr::Obj(o)=> primitive::obj::method(o, self, name, args), Litr::Int(n)=> primitive::int::method_int(*n, name, args), + Litr::Float(n)=> primitive::float::method(*n, name, args), Litr::Inst(inst)=> { let cannot_access_private = unsafe {(*inst.cls).module} != self.exports; let cls = unsafe {&*inst.cls};