Skip to main content

rl_lang/interpreter/stdlib/debug/
common.rs

1use 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}