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
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
use executor::ExecutorImpl;
use value::{Value, ValueContext};
use errors::VMError;

pub fn exec_add(executor: &mut ExecutorImpl, left: Value, right: Value) -> Value {
    match left {
        Value::Object(_) => {
            executor.invoke(left, Value::Null, Some("__add__"), &[right]);
            executor.get_current_frame().pop_exec()
        },
        Value::Int(v) => {
            Value::Float(
                (v as f64) + ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        Value::Float(v) => {
            Value::Float(
                v + ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        _ => panic!(VMError::from("Invalid operation"))
    }
}

pub fn exec_sub(executor: &mut ExecutorImpl, left: Value, right: Value) -> Value {
    match left {
        Value::Object(_) => {
            executor.invoke(left, Value::Null, Some("__sub__"), &[right]);
            executor.get_current_frame().pop_exec()
        },
        Value::Int(v) => {
            Value::Float(
                (v as f64) - ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        Value::Float(v) => {
            Value::Float(
                v - ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        _ => panic!(VMError::from("Invalid operation"))
    }
}

pub fn exec_mul(executor: &mut ExecutorImpl, left: Value, right: Value) -> Value {
    match left {
        Value::Object(_) => {
            executor.invoke(left, Value::Null, Some("__mul__"), &[right]);
            executor.get_current_frame().pop_exec()
        },
        Value::Int(v) => {
            Value::Float(
                (v as f64) * ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        Value::Float(v) => {
            Value::Float(
                v * ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        _ => panic!(VMError::from("Invalid operation"))
    }
}

pub fn exec_div(executor: &mut ExecutorImpl, left: Value, right: Value) -> Value {
    match left {
        Value::Object(_) => {
            executor.invoke(left, Value::Null, Some("__div__"), &[right]);
            executor.get_current_frame().pop_exec()
        },
        Value::Int(v) => {
            Value::Float(
                (v as f64) / ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        Value::Float(v) => {
            Value::Float(
                v / ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        _ => panic!(VMError::from("Invalid operation"))
    }
}

pub fn exec_mod(executor: &mut ExecutorImpl, left: Value, right: Value) -> Value {
    match left {
        Value::Object(_) => {
            executor.invoke(left, Value::Null, Some("__mod__"), &[right]);
            executor.get_current_frame().pop_exec()
        },
        Value::Int(v) => {
            Value::Float(
                (v as f64) % ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        Value::Float(v) => {
            Value::Float(
                v % ValueContext::new(&right, executor.get_object_pool()).to_f64()
            )
        },
        _ => panic!(VMError::from("Invalid operation"))
    }
}

pub fn exec_pow(executor: &mut ExecutorImpl, left: Value, right: Value) -> Value {
    match left {
        Value::Object(_) => {
            executor.invoke(left, Value::Null, Some("__pow__"), &[right]);
            executor.get_current_frame().pop_exec()
        },
        Value::Int(v) => {
            Value::Float(
                (v as f64).powf(ValueContext::new(&right, executor.get_object_pool()).to_f64())
            )
        },
        Value::Float(v) => {
            Value::Float(
                v.powf(ValueContext::new(&right, executor.get_object_pool()).to_f64())
            )
        },
        _ => panic!(VMError::from("Invalid operation"))
    }
}