Skip to content

Commit d438ddc

Browse files
authored
Merge pull request RustPython#144 from rmliddle/added_builtins
Added builtins
2 parents e561559 + e19c3c1 commit d438ddc

File tree

6 files changed

+126
-4
lines changed

6 files changed

+126
-4
lines changed

tests/snippets/builtin_abs.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
assert abs(-3) == 3
2+
assert abs(7) == 7
3+
assert abs(-3.21) == 3.21
4+
assert abs(6.25) == 6.25
5+

tests/snippets/builtin_divmod.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
assert divmod(11, 3) == (3, 2)
2+
assert divmod(8,11) == (0, 8)
3+
assert divmod(0.873, 0.252) == (3.0, 0.11699999999999999)

vm/src/builtins.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@ fn dir_object(vm: &mut VirtualMachine, obj: &PyObjectRef) -> PyObjectRef {
4545
vm.ctx.new_list(members_pystr)
4646
}
4747

48-
// builtin_abs
48+
fn builtin_abs(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
49+
arg_check!(vm, args, required = [(x, None)]);
50+
match vm.get_attribute(x.clone(), &"__abs__") {
51+
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![], vec![])),
52+
Err(..) => Err(vm.new_type_error("bad operand for abs".to_string())),
53+
}
54+
}
4955

5056
fn builtin_all(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5157
for item in args.args {
@@ -122,7 +128,14 @@ fn builtin_dir(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
122128
}
123129
}
124130

125-
// builtin_divmod
131+
fn builtin_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
132+
arg_check!(vm, args, required = [(x, None), (y, None)]);
133+
match vm.get_attribute(x.clone(), &"__divmod__") {
134+
Ok(attrib) => vm.invoke(attrib, PyFuncArgs::new(vec![y.clone()], vec![])),
135+
Err(..) => Err(vm.new_type_error("unsupported operand type(s) for divmod".to_string())),
136+
}
137+
}
138+
126139
// builtin_enumerate
127140

128141
fn builtin_eval(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -373,7 +386,6 @@ fn builtin_setattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
373386
// builtin_slice
374387
// builtin_sorted
375388
// builtin_staticmethod
376-
377389
// builtin_sum
378390
// builtin_super
379391
// builtin_vars
@@ -383,13 +395,15 @@ fn builtin_setattr(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
383395
pub fn make_module(ctx: &PyContext) -> PyObjectRef {
384396
// scope[String::from("print")] = print;
385397
let mut dict = HashMap::new();
398+
dict.insert(String::from("abs"), ctx.new_rustfunc(builtin_abs));
386399
dict.insert(String::from("all"), ctx.new_rustfunc(builtin_all));
387400
dict.insert(String::from("any"), ctx.new_rustfunc(builtin_any));
388401
dict.insert(String::from("bool"), ctx.bool_type());
389402
dict.insert(String::from("bytes"), ctx.bytes_type());
390403
dict.insert(String::from("chr"), ctx.new_rustfunc(builtin_chr));
391404
dict.insert(String::from("compile"), ctx.new_rustfunc(builtin_compile));
392405
dict.insert(String::from("dict"), ctx.dict_type());
406+
dict.insert(String::from("divmod"), ctx.new_rustfunc(builtin_divmod));
393407
dict.insert(String::from("dir"), ctx.new_rustfunc(builtin_dir));
394408
dict.insert(String::from("eval"), ctx.new_rustfunc(builtin_eval));
395409
dict.insert(String::from("float"), ctx.float_type());

vm/src/obj/objfloat.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ fn float_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6161
Ok(vm.ctx.new_bool(result))
6262
}
6363

64+
fn float_abs(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
65+
arg_check!(vm, args, required = [(i, Some(vm.ctx.float_type()))]);
66+
Ok(vm.ctx.new_float(get_value(i).abs()))
67+
}
68+
6469
fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
6570
arg_check!(
6671
vm,
@@ -78,13 +83,45 @@ fn float_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
7883
}
7984
}
8085

81-
fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
86+
fn float_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
8287
arg_check!(
8388
vm,
8489
args,
8590
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
8691
);
92+
let args = PyFuncArgs::new(vec![i.clone(), i2.clone()], vec![]);
93+
if objtype::isinstance(i2, vm.ctx.float_type()) || objtype::isinstance(i2, vm.ctx.int_type()) {
94+
let r1 = float_floordiv(vm, args.clone());
95+
let r2 = float_mod(vm, args.clone());
96+
Ok(vm.ctx.new_tuple(vec![r1.unwrap(), r2.unwrap()]))
97+
} else {
98+
Err(vm.new_type_error(format!("Cannot divmod power {:?} and {:?}", i, i2)))
99+
}
100+
}
101+
102+
fn float_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
103+
arg_check!(
104+
vm,
105+
args,
106+
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
107+
);
108+
if objtype::isinstance(i2, vm.ctx.float_type()) {
109+
Ok(vm.ctx.new_float((get_value(i) / get_value(i2)).floor()))
110+
} else if objtype::isinstance(i2, vm.ctx.int_type()) {
111+
Ok(vm
112+
.ctx
113+
.new_float((get_value(i) / objint::get_value(i2) as f64).floor()))
114+
} else {
115+
Err(vm.new_type_error(format!("Cannot floordiv {:?} and {:?}", i, i2)))
116+
}
117+
}
87118

119+
fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
120+
arg_check!(
121+
vm,
122+
args,
123+
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
124+
);
88125
let v1 = get_value(i);
89126
if objtype::isinstance(i2, vm.ctx.float_type()) {
90127
Ok(vm.ctx.new_float(v1 - get_value(i2)))
@@ -95,6 +132,23 @@ fn float_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
95132
}
96133
}
97134

135+
fn float_mod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
136+
arg_check!(
137+
vm,
138+
args,
139+
required = [(i, Some(vm.ctx.float_type())), (i2, None)]
140+
);
141+
if objtype::isinstance(i2, vm.ctx.float_type()) {
142+
Ok(vm.ctx.new_float(get_value(i) % get_value(i2)))
143+
} else if objtype::isinstance(i2, vm.ctx.int_type()) {
144+
Ok(vm
145+
.ctx
146+
.new_float(get_value(i) % objint::get_value(i2) as f64))
147+
} else {
148+
Err(vm.new_type_error(format!("Cannot mod {:?} and {:?}", i, i2)))
149+
}
150+
}
151+
98152
fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
99153
arg_check!(
100154
vm,
@@ -117,8 +171,12 @@ fn float_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
117171
pub fn init(context: &PyContext) {
118172
let ref float_type = context.float_type;
119173
float_type.set_attr("__eq__", context.new_rustfunc(float_eq));
174+
float_type.set_attr("__abs__", context.new_rustfunc(float_abs));
120175
float_type.set_attr("__add__", context.new_rustfunc(float_add));
176+
float_type.set_attr("__divmod__", context.new_rustfunc(float_divmod));
177+
float_type.set_attr("__floordiv__", context.new_rustfunc(float_floordiv));
121178
float_type.set_attr("__init__", context.new_rustfunc(float_init));
179+
float_type.set_attr("__mod__", context.new_rustfunc(float_mod));
122180
float_type.set_attr("__pow__", context.new_rustfunc(float_pow));
123181
float_type.set_attr("__sub__", context.new_rustfunc(float_sub));
124182
float_type.set_attr("__repr__", context.new_rustfunc(float_repr));

vm/src/obj/objint.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,11 @@ fn int_eq(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
9999
Ok(vm.ctx.new_bool(result))
100100
}
101101

102+
fn int_abs(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
103+
arg_check!(vm, args, required = [(i, Some(vm.ctx.int_type()))]);
104+
Ok(vm.ctx.new_int(get_value(i).abs()))
105+
}
106+
102107
fn int_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
103108
arg_check!(
104109
vm,
@@ -115,6 +120,19 @@ fn int_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
115120
}
116121
}
117122

123+
fn int_floordiv(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
124+
arg_check!(
125+
vm,
126+
args,
127+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
128+
);
129+
if objtype::isinstance(i2, vm.ctx.int_type()) {
130+
Ok(vm.ctx.new_int(get_value(i) / get_value(i2)))
131+
} else {
132+
Err(vm.new_type_error(format!("Cannot floordiv {:?} and {:?}", i, i2)))
133+
}
134+
}
135+
118136
fn int_sub(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
119137
arg_check!(
120138
vm,
@@ -139,6 +157,10 @@ fn int_mul(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
139157
);
140158
if objtype::isinstance(i2, vm.ctx.int_type()) {
141159
Ok(vm.ctx.new_int(get_value(i) * get_value(i2)))
160+
} else if objtype::isinstance(i2, vm.ctx.float_type()) {
161+
Ok(vm
162+
.ctx
163+
.new_float(get_value(i) as f64 * objfloat::get_value(i2)))
142164
} else {
143165
Err(vm.new_type_error(format!("Cannot multiply {:?} and {:?}", i, i2)))
144166
}
@@ -192,6 +214,22 @@ fn int_pow(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
192214
}
193215
}
194216

217+
fn int_divmod(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
218+
arg_check!(
219+
vm,
220+
args,
221+
required = [(i, Some(vm.ctx.int_type())), (i2, None)]
222+
);
223+
let args = PyFuncArgs::new(vec![i.clone(), i2.clone()], vec![]);
224+
if objtype::isinstance(i2, vm.ctx.int_type()) {
225+
let r1 = int_floordiv(vm, args.clone());
226+
let r2 = int_mod(vm, args.clone());
227+
Ok(vm.ctx.new_tuple(vec![r1.unwrap(), r2.unwrap()]))
228+
} else {
229+
Err(vm.new_type_error(format!("Cannot divmod power {:?} and {:?}", i, i2)))
230+
}
231+
}
232+
195233
fn int_xor(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
196234
arg_check!(
197235
vm,
@@ -240,8 +278,11 @@ fn int_and(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
240278
pub fn init(context: &PyContext) {
241279
let ref int_type = context.int_type;
242280
int_type.set_attr("__eq__", context.new_rustfunc(int_eq));
281+
int_type.set_attr("__abs__", context.new_rustfunc(int_abs));
243282
int_type.set_attr("__add__", context.new_rustfunc(int_add));
244283
int_type.set_attr("__and__", context.new_rustfunc(int_and));
284+
int_type.set_attr("__divmod__", context.new_rustfunc(int_divmod));
285+
int_type.set_attr("__floordiv__", context.new_rustfunc(int_floordiv));
245286
int_type.set_attr("__new__", context.new_rustfunc(int_new));
246287
int_type.set_attr("__mod__", context.new_rustfunc(int_mod));
247288
int_type.set_attr("__mul__", context.new_rustfunc(int_mul));

vm/src/vm.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@ impl VirtualMachine {
443443
// self.invoke('__neg__'
444444
match a.borrow().kind {
445445
PyObjectKind::Integer { value: ref value1 } => Ok(self.ctx.new_int(-*value1)),
446+
PyObjectKind::Float { value: ref value1 } => Ok(self.ctx.new_float(-*value1)),
446447
_ => panic!("Not impl {:?}", a),
447448
}
448449
}

0 commit comments

Comments
 (0)