rl_lang/interpreter/stdlib/debug/
common.rs1use crate::{
2 interpreter::{
3 evaluator::Evaluator,
4 stdlib::common::{verr, vok, vs},
5 values::Value,
6 },
7 utils::{errors::Error, span::Span},
8};
9
10pub fn as_f64(value: &Value) -> Option<f64> {
11 match value {
12 Value::Integer(i) => Some(*i as f64),
13 Value::Float(f) => Some(*f),
14 Value::Byte(b) => Some(*b as f64),
15 _ => None,
16 }
17}
18
19pub fn assert_eq_message(
20 a: &Value,
21 b: &Value,
22 custom: Option<&Value>,
23 name: &str,
24 expected_equal: bool,
25) -> Value {
26 let op = if expected_equal { "!=" } else { "==" };
27 let default_msg = format!(
28 "{} failed: left `{}` ({}) {} right `{}` ({})",
29 name,
30 a,
31 a.type_name(),
32 op,
33 b,
34 b.type_name()
35 );
36
37 match custom {
38 Some(Value::String(s)) => vok!(vs!(format!("{}: {}", s, default_msg))),
39 Some(other) => verr!(vs!(format!(
40 "{}() expects a string message, got {}",
41 name,
42 other.type_name()
43 ))),
44 None => vok!(vs!(default_msg)),
45 }
46}
47
48pub fn assert_cmp(
49 eval: &mut Evaluator,
50 args: Vec<Value>,
51 span: Span,
52 name: &str,
53 op: fn(f64, f64) -> bool,
54) -> Result<Value, Error> {
55 if args.len() < 2 || args.len() > 3 {
56 return Err(eval.err(
57 format!("{}() expects 2 or 3 arguments, got {}", name, args.len()),
58 span,
59 ));
60 }
61
62 let (a, b) = (&args[0], &args[1]);
63 let (fa, fb) = match (as_f64(a), as_f64(b)) {
64 (Some(fa), Some(fb)) => (fa, fb),
65 _ => {
66 return Err(eval.err(
67 format!(
68 "{}: expects numeric arguments, got {} and {}",
69 name,
70 a.type_name(),
71 b.type_name()
72 ),
73 span,
74 ));
75 }
76 };
77
78 if !op(fa, fb) {
79 let default_msg = format!("{} failed: `{}` vs `{}`", name, a, b);
80 let message = match args.get(2) {
81 Some(Value::String(s)) => format!("{}: {}", s, default_msg),
82 Some(other) => {
83 return Err(eval.err(
84 format!(
85 "{}: expects a string message, got {}",
86 name,
87 other.type_name()
88 ),
89 span,
90 ));
91 }
92 None => default_msg,
93 };
94 return Err(eval.err(message, span));
95 }
96
97 Ok(Value::Null)
98}