Skip to content

Commit 2f39478

Browse files
committed
Change print to use __str__ and add __str__ to object
1 parent 26023c7 commit 2f39478

8 files changed

Lines changed: 57 additions & 17 deletions

File tree

src/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use clap::{App, Arg};
1111
use rustpython_parser::parser;
1212
use rustpython_vm::compile;
1313
use rustpython_vm::VirtualMachine;
14+
use rustpython_vm::print_exception;
1415
use std::io;
1516
use std::io::prelude::*;
1617
use std::path::Path;
@@ -59,6 +60,7 @@ fn _run_string(source: &String, source_path: Option<String>) {
5960
Ok(_value) => {}
6061
Err(exc) => {
6162
// println!("X: {:?}", exc.get_attr("__traceback__"));
63+
print_exception(&mut vm, &exc);
6264
panic!("Exception: {:?}", exc);
6365
}
6466
}
@@ -93,7 +95,7 @@ fn shell_exec(vm: &mut VirtualMachine, source: &String, scope: PyObjectRef) -> b
9395
// Printed already.
9496
}
9597
Err(msg) => {
96-
println!("Error: {:?}", msg);
98+
print_exception(vm, &msg);
9799
}
98100
}
99101
}

vm/src/builtins.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::io::{self, Write};
55

66
use super::compile;
77
use super::objbool;
8+
use super::objstr;
89
use super::objtype;
910
use super::pyobject::{
1011
AttributeProtocol, DictProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind,
@@ -262,7 +263,11 @@ fn builtin_locals(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
262263
pub fn builtin_print(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
263264
trace!("print called with {:?}", args);
264265
for a in args.args {
265-
print!("{} ", a.borrow().str());
266+
let s = match vm.to_str(a) {
267+
Ok(v) => objstr::get_value(v),
268+
Err(err) => return Err(err),
269+
};
270+
print!("{} ", s);
266271
}
267272
println!();
268273
io::stdout().flush().unwrap();

vm/src/exceptions.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use super::pyobject::{
22
create_type, AttributeProtocol, PyContext, PyFuncArgs, PyObjectRef, PyResult,
33
};
4+
use super::objstr;
45
use super::vm::VirtualMachine;
56

67
fn exception_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -16,6 +17,13 @@ fn exception_init(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
1617
Ok(vm.get_none())
1718
}
1819

20+
pub fn print_exception(vm: &mut VirtualMachine, exc: &PyObjectRef) {
21+
match vm.to_str(exc.clone()) {
22+
Ok(txt) => println!("Error: {}", objstr::get_value(txt)),
23+
Err(err) => println!("Error during error {:?}", err),
24+
}
25+
}
26+
1927
#[derive(Debug)]
2028
pub struct ExceptionZoo {
2129
pub base_exception_type: PyObjectRef,

vm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,4 @@ mod vm;
3838

3939
// pub use self::pyobject::Executor;
4040
pub use self::vm::VirtualMachine;
41+
pub use self::exceptions::print_exception;

vm/src/objint.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::pyobject::{
55
};
66
use super::vm::VirtualMachine;
77

8-
fn str(vm: &mut VirtualMachine, args: PyFuncArgs) -> Result<PyObjectRef, PyObjectRef> {
8+
fn str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
99
arg_check!(vm, args, required = [(int, Some(vm.ctx.int_type()))]);
1010
let v = get_value(int.clone());
1111
Ok(vm.new_str(v.to_string()))

vm/src/objlist.rs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::objsequence::PySliceableSequence;
2+
use super::objstr;
23
use super::objtype;
34
use super::pyobject::{
45
AttributeProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
@@ -50,27 +51,25 @@ fn list_add(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5051
}
5152
}
5253

53-
/*
54-
* TODO:
5554
fn list_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5655
arg_check!(
5756
vm,
5857
args,
5958
required = [(o, Some(vm.ctx.list_type()))]
6059
);
6160

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-
),
61+
let elements = get_elements(o.clone());
62+
let mut str_parts = vec!();
63+
for elem in elements {
64+
match vm.to_str(elem) {
65+
Ok(s) => str_parts.push(objstr::get_value(s)),
66+
Err(err) => return Err(err),
67+
}
7168
}
69+
70+
let s = format!( "[{}]", str_parts.join(", "));
71+
Ok(vm.new_str(s))
7272
}
73-
*/
7473

7574
pub fn append(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
7675
trace!("list.append called with: {:?}", args);
@@ -127,7 +126,7 @@ pub fn init(context: &PyContext) {
127126
let ref list_type = context.list_type;
128127
list_type.set_attr("__add__", context.new_rustfunc(list_add));
129128
list_type.set_attr("__len__", context.new_rustfunc(len));
130-
// list_type.set_attr("__str__", context.new_rustfunc(list_str));
129+
list_type.set_attr("__str__", context.new_rustfunc(list_str));
131130
list_type.set_attr("append", context.new_rustfunc(append));
132131
list_type.set_attr("clear", context.new_rustfunc(clear));
133132
list_type.set_attr("reverse", context.new_rustfunc(reverse));

vm/src/objobject.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::objdict;
22
use super::objtype;
33
use super::pyobject::{
4-
AttributeProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult,
4+
AttributeProtocol, IdProtocol, PyContext, PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
55
};
66
use super::vm::VirtualMachine;
77

@@ -28,10 +28,18 @@ pub fn create_object(type_type: PyObjectRef, object_type: PyObjectRef, dict_type
2828
(*object_type.borrow_mut()).typ = Some(type_type.clone());
2929
}
3030

31+
fn obj_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
32+
arg_check!(vm, args, required = [(obj, Some(vm.ctx.object()))]);
33+
let type_name = objtype::get_type_name(&obj.typ());
34+
let address = obj.get_id();
35+
Ok(vm.new_str(format!("<{} object at 0x{:x}>", type_name, address)))
36+
}
37+
3138
pub fn init(context: &PyContext) {
3239
let ref object = context.object;
3340
object.set_attr("__new__", context.new_rustfunc(new_instance));
3441
object.set_attr("__dict__", context.new_member_descriptor(object_dict));
42+
object.set_attr("__str__", context.new_rustfunc(obj_str));
3543
}
3644

3745
fn object_dict(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {

vm/src/objtype.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ pub fn init(context: &PyContext) {
2424
type_type.set_attr("__new__", context.new_rustfunc(type_new));
2525
type_type.set_attr("__mro__", context.new_member_descriptor(type_mro));
2626
type_type.set_attr("__class__", context.new_member_descriptor(type_new));
27+
type_type.set_attr("__str__", context.new_rustfunc(type_str));
2728
}
2829

2930
fn type_mro(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
@@ -54,6 +55,14 @@ pub fn issubclass(typ: PyObjectRef, cls: PyObjectRef) -> bool {
5455
mro.into_iter().any(|c| c.is(&cls))
5556
}
5657

58+
pub fn get_type_name(typ: &PyObjectRef) -> String {
59+
if let PyObjectKind::Class { name, dict: _, mro: _ } = &typ.borrow().kind {
60+
name.clone()
61+
} else {
62+
panic!("Cannot get type_name of non-type type");
63+
}
64+
}
65+
5766
pub fn type_new(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
5867
debug!("type.__new__{:?}", args);
5968
if args.args.len() == 2 {
@@ -170,6 +179,14 @@ pub fn new(typ: PyObjectRef, name: &str, bases: Vec<PyObjectRef>, dict: PyObject
170179
))
171180
}
172181

182+
fn type_str(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
183+
// TODO: fix macro:
184+
// arg_check!(vm, args, required = [(obj, Some(vm.ctx.type_type()))]);
185+
let obj = args.args[0].clone();
186+
let type_name = get_type_name(&obj);
187+
Ok(vm.new_str(format!("<class '{}'>", type_name)))
188+
}
189+
173190
pub fn call(vm: &mut VirtualMachine, typ: PyObjectRef, args: PyFuncArgs) -> PyResult {
174191
let function = get_attribute(vm, typ, &String::from("__call__"))?;
175192
vm.invoke(function, args)

0 commit comments

Comments
 (0)