Skip to content

Commit 26023c7

Browse files
authored
Merge pull request RustPython#99 from RustPython/objtyp
Alternative operator implementation based on typ instead of kind
2 parents 0f8ba73 + af84076 commit 26023c7

8 files changed

Lines changed: 349 additions & 223 deletions

File tree

tests/snippets/basic_types.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,20 @@
44
# print(True) # LOAD_NAME???
55
print(1)
66
# print(1L) # Long
7-
# print(1.1)
7+
print(1.1)
88
# ComplexType
99
print("abc")
1010
# print(u"abc")
1111
# Structural below
12-
# print((1, 2)) # Tuple can be any length, but fixed after declared
13-
# x = (1,2)
14-
# print(x[0]) # Tuple can be any length, but fixed after declared
15-
# print([1, 2, 3])
12+
print((1, 2)) # Tuple can be any length, but fixed after declared
13+
x = (1,2)
14+
print(x[0]) # Tuple can be any length, but fixed after declared
15+
print([1, 2, 3])
1616
# print({"first":1,"second":2})
17+
18+
19+
assert type(1 - 2) is int
20+
assert type(2 / 3) is float
21+
x = 1
22+
assert type(x) is int
23+
assert type(x - 1) is int

vm/src/objbool.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,27 @@ pub fn boolval(vm: &mut VirtualMachine, obj: PyObjectRef) -> Result<bool, PyObje
3434
pub fn init(context: &PyContext) {
3535
let ref bool_type = context.bool_type;
3636
bool_type.set_attr("__new__", context.new_rustfunc(bool_new));
37+
bool_type.set_attr("__str__", context.new_rustfunc(bool_str));
38+
}
39+
40+
// Retrieve inner int value:
41+
pub fn get_value(obj: &PyObjectRef) -> bool {
42+
if let PyObjectKind::Boolean { value } = &obj.borrow().kind {
43+
*value
44+
} else {
45+
panic!("Inner error getting inner boolean");
46+
}
47+
}
48+
49+
fn bool_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
50+
arg_check!(vm, args, required = [(obj, Some(vm.ctx.bool_type()))]);
51+
let v = get_value(obj);
52+
let s = if v {
53+
"True".to_string()
54+
} else {
55+
"True".to_string()
56+
};
57+
Ok(vm.new_str(s))
3758
}
3859

3960
fn bool_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/objfloat.rs

Lines changed: 59 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use super::objint;
12
use super::objtype;
23
use super::pyobject::{
3-
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, TypeProtocol,
4+
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
45
};
56
use super::vm::VirtualMachine;
67

@@ -11,16 +12,72 @@ fn str(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjec
1112
}
1213

1314
// Retrieve inner float value:
14-
fn get_value(obj: PyObjectRef) -> f64 {
15+
pub fn get_value(obj: PyObjectRef) -> f64 {
1516
if let PyObjectKind::Float { value } = &obj.borrow().kind {
1617
*value
1718
} else {
1819
panic!("Inner error getting float");
1920
}
2021
}
2122

23+
fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
24+
arg_check!(
25+
vm,
26+
args,
27+
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
28+
);
29+
30+
let v1 = get_value(i.clone());
31+
if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
32+
Ok(vm.ctx.new_float(v1 + get_value(i2.clone())))
33+
} else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
34+
Ok(vm.ctx.new_float(v1 + objint::get_value(i2.clone()) as f64))
35+
} else {
36+
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
37+
}
38+
}
39+
40+
fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
41+
arg_check!(
42+
vm,
43+
args,
44+
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
45+
);
46+
47+
let v1 = get_value(i.clone());
48+
if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
49+
Ok(vm.ctx.new_float(v1 - get_value(i2.clone())))
50+
} else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
51+
Ok(vm.ctx.new_float(v1 - objint::get_value(i2.clone()) as f64))
52+
} else {
53+
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
54+
}
55+
}
56+
57+
fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
58+
arg_check!(
59+
vm,
60+
args,
61+
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
62+
);
63+
64+
let v1 = get_value(i.clone());
65+
if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
66+
let result = v1.powf(get_value(i2.clone()));
67+
Ok(vm.ctx.new_float(result))
68+
} else if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
69+
let result = v1.powf(objint::get_value(i2.clone()) as f64);
70+
Ok(vm.ctx.new_float(result))
71+
} else {
72+
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
73+
}
74+
}
75+
2276
pub fn init(context: &PyContext) {
2377
let ref float_type = context.float_type;
78+
float_type.set_attr("__add__", context.new_rustfunc(float_add));
79+
float_type.set_attr("__pow__", context.new_rustfunc(float_pow));
2480
float_type.set_attr("__str__", context.new_rustfunc(str));
81+
float_type.set_attr("__sub__", context.new_rustfunc(float_sub));
2582
float_type.set_attr("__repr__", context.new_rustfunc(str));
2683
}

vm/src/objint.rs

Lines changed: 103 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
use super::objfloat;
12
use super::objtype;
23
use super::pyobject::{
3-
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, TypeProtocol,
4+
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
45
};
56
use super::vm::VirtualMachine;
67

@@ -11,16 +12,115 @@ fn str(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjec
1112
}
1213

1314
// Retrieve inner int value:
14-
fn get_value(obj: PyObjectRef) -> i32 {
15+
pub fn get_value(obj: PyObjectRef) -> i32 {
1516
if let PyObjectKind::Integer { value } = &obj.borrow().kind {
1617
*value
1718
} else {
1819
panic!("Inner error getting int");
1920
}
2021
}
2122

23+
fn int_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
24+
arg_check!(
25+
vm,
26+
args,
27+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
28+
);
29+
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
30+
Ok(vm.ctx.new_int(get_value(i.clone()) + get_value(i2.clone())))
31+
} else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
32+
Ok(vm
33+
.ctx
34+
.new_float(get_value(i.clone()) as f64 + objfloat::get_value(i2.clone())))
35+
} else {
36+
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", i, i2)))
37+
}
38+
}
39+
40+
fn int_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
41+
arg_check!(
42+
vm,
43+
args,
44+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
45+
);
46+
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
47+
Ok(vm.ctx.new_int(get_value(i.clone()) - get_value(i2.clone())))
48+
} else {
49+
Err(vm.new_type_error(format!("Cannot substract {:?} and {:?}", i, i2)))
50+
}
51+
}
52+
53+
fn int_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
54+
arg_check!(
55+
vm,
56+
args,
57+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
58+
);
59+
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
60+
Ok(vm.ctx.new_int(get_value(i.clone()) * get_value(i2.clone())))
61+
} else {
62+
Err(vm.new_type_error(format!("Cannot multiply {:?} and {:?}", i, i2)))
63+
}
64+
}
65+
66+
fn int_truediv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
67+
arg_check!(
68+
vm,
69+
args,
70+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
71+
);
72+
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
73+
Ok(vm
74+
.ctx
75+
.new_float(get_value(i.clone()) as f64 / get_value(i2.clone()) as f64))
76+
} else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
77+
Ok(vm
78+
.ctx
79+
.new_float(get_value(i.clone()) as f64 / objfloat::get_value(i2.clone())))
80+
} else {
81+
Err(vm.new_type_error(format!("Cannot multiply {:?} and {:?}", i, i2)))
82+
}
83+
}
84+
85+
fn int_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
86+
arg_check!(
87+
vm,
88+
args,
89+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
90+
);
91+
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
92+
Ok(vm.ctx.new_int(get_value(i.clone()) % get_value(i2.clone())))
93+
} else {
94+
Err(vm.new_type_error(format!("Cannot modulo {:?} and {:?}", i, i2)))
95+
}
96+
}
97+
98+
fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
99+
arg_check!(
100+
vm,
101+
args,
102+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
103+
);
104+
let v1 = get_value(i.clone());
105+
if objtype::isinstance(i2.clone(), vm.ctx.int_type()) {
106+
let v2 = get_value(i2.clone());
107+
Ok(vm.ctx.new_int(v1.pow(v2 as u32)))
108+
} else if objtype::isinstance(i2.clone(), vm.ctx.float_type()) {
109+
let v2 = objfloat::get_value(i2.clone());
110+
Ok(vm.ctx.new_float((v1 as f64).powf(v2)))
111+
} else {
112+
Err(vm.new_type_error(format!("Cannot modulo {:?} and {:?}", i, i2)))
113+
}
114+
}
115+
22116
pub fn init(context: &PyContext) {
23117
let ref int_type = context.int_type;
24-
int_type.set_attr("__str__", context.new_rustfunc(str));
118+
int_type.set_attr("__add__", context.new_rustfunc(int_add));
119+
int_type.set_attr("__mod__", context.new_rustfunc(int_mod));
120+
int_type.set_attr("__mul__", context.new_rustfunc(int_mul));
121+
int_type.set_attr("__pow__", context.new_rustfunc(int_pow));
25122
int_type.set_attr("__repr__", context.new_rustfunc(str));
123+
int_type.set_attr("__str__", context.new_rustfunc(str));
124+
int_type.set_attr("__sub__", context.new_rustfunc(int_sub));
125+
int_type.set_attr("__truediv__", context.new_rustfunc(int_truediv));
26126
}

vm/src/objlist.rs

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,53 @@ pub fn set_item(
2525
}
2626
}
2727

28+
fn get_elements(obj: PyObjectRef) -> Vec<PyObjectRef> {
29+
if let PyObjectKind::List { elements } = &obj.borrow().kind {
30+
elements.to_vec()
31+
} else {
32+
panic!("Cannot extract list elements from non-list");
33+
}
34+
}
35+
36+
fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
37+
arg_check!(
38+
vm,
39+
args,
40+
required = [(o, Some(vm.ctx.list_type())), (o2, None)]
41+
);
42+
43+
if objtype::isinstance(o2.clone(), vm.ctx.list_type()) {
44+
let e1 = get_elements(o.clone());
45+
let e2 = get_elements(o2.clone());
46+
let elements = e1.iter().chain(e2.iter()).map(|e| e.clone()).collect();
47+
Ok(vm.ctx.new_list(elements))
48+
} else {
49+
Err(vm.new_type_error(format!("Cannot add {:?} and {:?}", o, o2)))
50+
}
51+
}
52+
53+
/*
54+
* TODO:
55+
fn list_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
56+
arg_check!(
57+
vm,
58+
args,
59+
required = [(o, Some(vm.ctx.list_type()))]
60+
);
61+
62+
let
63+
PyObjectKind::List { ref elements } => format!(
64+
"[{}]",
65+
elements
66+
.iter()
67+
.map(|elem| elem.borrow().str())
68+
.collect::<Vec<_>>()
69+
.join(", ")
70+
),
71+
}
72+
}
73+
*/
74+
2875
pub fn append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
2976
trace!("list.append called with: {:?}", args);
3077
arg_check!(
@@ -78,7 +125,9 @@ fn reverse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
78125

79126
pub fn init(context: &PyContext) {
80127
let ref list_type = context.list_type;
128+
list_type.set_attr("__add__", context.new_rustfunc(list_add));
81129
list_type.set_attr("__len__", context.new_rustfunc(len));
130+
// list_type.set_attr("__str__", context.new_rustfunc(list_str));
82131
list_type.set_attr("append", context.new_rustfunc(append));
83132
list_type.set_attr("clear", context.new_rustfunc(clear));
84133
list_type.set_attr("reverse", context.new_rustfunc(reverse));

0 commit comments

Comments
 (0)