Skip to content

Commit 5838183

Browse files
committed
Add BaseException class
1 parent f595553 commit 5838183

File tree

8 files changed

+90
-8
lines changed

8 files changed

+90
-8
lines changed

parser/src/ast.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,15 @@ pub enum Statement {
8383
body: Vec<LocatedStatement>,
8484
orelse: Option<Vec<LocatedStatement>>,
8585
},
86+
Raise {
87+
expression: Option<Expression>,
88+
},
89+
Try {
90+
body: Vec<LocatedStatement>,
91+
handlers: Vec<Expression>,
92+
orelse: Option<Vec<LocatedStatement>>,
93+
finalbody: Option<Vec<LocatedStatement>>,
94+
},
8695
ClassDef {
8796
name: String,
8897
body: Vec<LocatedStatement>,

parser/src/python.lalrpop

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,12 @@ FlowStatement: ast::LocatedStatement = {
123123
node: ast::Statement::Return { value: t},
124124
}
125125
},
126-
// raise
126+
<loc:@L> "raise" <t:Test?> => {
127+
ast::LocatedStatement {
128+
location: loc,
129+
node: ast::Statement::Raise { expression: t },
130+
}
131+
},
127132
// yield
128133
};
129134

@@ -552,6 +557,7 @@ extern {
552557
"not" => lexer::Tok::Not,
553558
"or" => lexer::Tok::Or,
554559
"pass" => lexer::Tok::Pass,
560+
"raise" => lexer::Tok::Raise,
555561
"return" => lexer::Tok::Return,
556562
"while" => lexer::Tok::While,
557563
"with" => lexer::Tok::With,

vm/src/builtins.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ pub fn make_module(ctx: &PyContext) -> PyObjectRef {
345345
dict.insert(String::from("tuple"), ctx.tuple_type.clone());
346346
dict.insert(String::from("type"), ctx.type_type.clone());
347347
dict.insert(String::from("object"), ctx.object.clone());
348+
dict.insert(String::from("BaseException"), ctx.base_exception_type.clone());
348349
let d2 = PyObject::new(PyObjectKind::Dict { elements: dict }, ctx.type_type.clone());
349350
let scope = PyObject::new(
350351
PyObjectKind::Scope {

vm/src/compile.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,20 @@ impl Compiler {
235235
self.set_label(end_label);
236236
self.emit(Instruction::PopBlock);
237237
}
238+
ast::Statement::Raise { expression } => {
239+
match expression {
240+
Some(value) => {
241+
self.compile_expression(value);
242+
self.emit(Instruction::Raise { argc: 1 });
243+
}
244+
None => {
245+
unimplemented!();
246+
}
247+
}
248+
}
249+
ast::Statement::Try {..} => {
250+
unimplemented!();
251+
}
238252
ast::Statement::FunctionDef { name, args, body } => {
239253
// Create bytecode for this function:
240254
self.code_object_stack.push(CodeObject::new(args.to_vec()));

vm/src/exceptions.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
use std::collections::HashMap;
3+
use super::pyobject::{PyFuncArgs, PyObject, PyObjectKind, PyObjectRef, PyResult};
4+
use super::vm::VirtualMachine;
5+
6+
fn init(vm: &mut VirtualMachine, _args: PyFuncArgs) -> PyResult {
7+
// TODO: Implement objint::str
8+
Ok(vm.new_str("todo".to_string()))
9+
}
10+
11+
pub fn create_base_exception_type(type_type: PyObjectRef, object_type: PyObjectRef) -> PyObjectRef {
12+
let mut dict = HashMap::new();
13+
dict.insert(
14+
"__init__".to_string(),
15+
PyObject::new(
16+
PyObjectKind::RustFunction { function: init },
17+
type_type.clone(),
18+
),
19+
);
20+
let typ = PyObject::new(
21+
PyObjectKind::Class {
22+
name: "BaseException".to_string(),
23+
dict: PyObject::new(PyObjectKind::Dict { elements: dict }, type_type.clone()),
24+
mro: vec![object_type],
25+
},
26+
type_type.clone(),
27+
);
28+
typ
29+
}
30+
31+
/*
32+
* TODO: create a whole exception hierarchy somehow?
33+
pub fn create_exception_zoo(context: &PyContext) {
34+
let base_exception_type = PyObjectKind::Class {
35+
name: String::from("Exception"),
36+
dict: context.new_dict(),
37+
mro: vec![object_type],
38+
}.into_ref();
39+
}
40+
*/

vm/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ mod builtins;
99
pub mod bytecode;
1010
pub mod compile;
1111
pub mod eval;
12+
mod exceptions;
1213
mod frame;
1314
mod import;
1415
mod objbool;

vm/src/pyobject.rs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::bytecode;
2+
use super::exceptions;
23
use super::objdict;
34
use super::objfunction;
45
use super::objint;
@@ -54,6 +55,7 @@ pub struct PyContext {
5455
pub bound_method_type: PyObjectRef,
5556
pub member_descriptor_type: PyObjectRef,
5657
pub object: PyObjectRef,
58+
pub base_exception_type: PyObjectRef,
5759
}
5860

5961
/*
@@ -95,21 +97,24 @@ impl PyContext {
9597
tuple_type: type_type.clone(),
9698
dict_type: dict_type.clone(),
9799
none: PyObject::new(PyObjectKind::None, type_type.clone()),
98-
object: object_type,
100+
object: object_type.clone(),
99101
function_type: function_type,
100102
bound_method_type: bound_method_type,
101103
member_descriptor_type: member_descriptor_type,
102-
type_type: type_type,
104+
type_type: type_type.clone(),
105+
base_exception_type: exceptions::create_base_exception_type(type_type.clone(), object_type.clone()),
103106
};
104107
objtype::init(&context);
105108
objlist::init(&context);
106109
objobject::init(&context);
107110
objdict::init(&context);
111+
// TODO: create exception hierarchy here?
112+
// exceptions::create_zoo(&context);
108113
context
109114
}
110115

111116
pub fn new_int(&self, i: i32) -> PyObjectRef {
112-
PyObject::new(PyObjectKind::Integer { value: i }, self.type_type.clone())
117+
PyObject::new(PyObjectKind::Integer { value: i }, self.int_type.clone())
113118
}
114119

115120
pub fn new_float(&self, i: f64) -> PyObjectRef {
@@ -127,7 +132,7 @@ impl PyContext {
127132
pub fn new_tuple(&self, elements: Vec<PyObjectRef>) -> PyObjectRef {
128133
PyObject::new(
129134
PyObjectKind::Tuple { elements: elements },
130-
self.type_type.clone(),
135+
self.tuple_type.clone(),
131136
)
132137
}
133138

vm/src/vm.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,14 @@ impl VirtualMachine {
227227
Some(Err(exception)) => {
228228
// unwind block stack on exception and find any handlers.
229229
match self.unwind_exception(exception) {
230-
None => {}
231-
Some(exception) => break Err(exception),
230+
None => {
231+
},
232+
Some(exception) => {
233+
let _traceback = self.get_attribute(exception.clone(), &"__traceback__".to_string());
234+
// TODO: append line number to traceback?
235+
// traceback.append();
236+
break Err(exception)
237+
},
232238
}
233239
}
234240
}
@@ -760,7 +766,7 @@ impl VirtualMachine {
760766
0 | 2 | 3 => panic!("Not implemented!"),
761767
_ => panic!("Invalid paramter for RAISE_VARARGS, must be between 0 to 3"),
762768
};
763-
error!("{:?}", exception);
769+
info!("Exception raised: {:?}", exception);
764770
Some(Err(exception))
765771
}
766772

0 commit comments

Comments
 (0)