1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use crate::eval::Env;
use crate::objects::{Eval, Object, Vtable};

pub fn vtable() -> Vtable {
    let vt = Vtable::new("Float");
    // FUNDAMENTAL
    vt.add_primitive_method_or_panic("addFloat:", float_add_float);
    vt.add_primitive_method_or_panic("divFloat:", float_div_float);
    vt.add_primitive_method_or_panic("equalFloat:", float_equal_float);
    vt.add_primitive_method_or_panic("greaterThanFloat:", float_greater_than_float);
    vt.add_primitive_method_or_panic("greaterThanOrEqualFloat:", float_greater_than_or_equal_float);
    vt.add_primitive_method_or_panic("lessThanFloat:", float_less_than_float);
    vt.add_primitive_method_or_panic("lessThanOrEqualFloat:", float_less_than_or_equal_float);
    vt.add_primitive_method_or_panic("mulFloat:", float_mul_float);
    vt.add_primitive_method_or_panic("prefix-", float_neg);
    vt.add_primitive_method_or_panic("subFloat:", float_sub_float);
    vt.add_primitive_method_or_panic("toString", float_to_string);
    vt.add_primitive_method_or_panic("asInteger", float_as_integer);
    vt.add_primitive_method_or_panic("sqrt", float_sqrt);
    vt
}

// FUNDAMENTAL METHODS

fn float_as_integer(receiver: &Object, _args: &[Object], env: &Env) -> Eval {
    Ok(env.foo.make_integer(receiver.float().round() as i64))
}

fn float_add_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = args[0].float() + receiver.float();
    Ok(env.foo.make_float(res))
}

fn float_div_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = args[0].float() / receiver.float();
    Ok(env.foo.make_float(res))
}

fn float_mul_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = args[0].float() * receiver.float();
    Ok(env.foo.make_float(res))
}

fn float_sub_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = args[0].float() - receiver.float();
    Ok(env.foo.make_float(res))
}

fn float_equal_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = receiver.float() == args[0].float();
    Ok(env.foo.make_boolean(res))
}

fn float_greater_than_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = receiver.float() > args[0].float();
    Ok(env.foo.make_boolean(res))
}

fn float_greater_than_or_equal_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = receiver.float() >= args[0].float();
    Ok(env.foo.make_boolean(res))
}

fn float_less_than_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = receiver.float() < args[0].float();
    Ok(env.foo.make_boolean(res))
}

fn float_less_than_or_equal_float(receiver: &Object, args: &[Object], env: &Env) -> Eval {
    let res = receiver.float() <= args[0].float();
    Ok(env.foo.make_boolean(res))
}

fn float_neg(receiver: &Object, _args: &[Object], env: &Env) -> Eval {
    Ok(env.foo.make_float(-receiver.float()))
}

fn float_to_string(receiver: &Object, _args: &[Object], env: &Env) -> Eval {
    Ok(env.foo.make_string(&receiver.float().to_string()))
}

fn float_sqrt(receiver: &Object, _args: &[Object], env: &Env) -> Eval {
    Ok(env.foo.make_float(receiver.float().sqrt()))
}