Skip to content

Commit 406c2e2

Browse files
committed
Add modules, better globals support, and call stack.
1 parent c353aad commit 406c2e2

File tree

7 files changed

+229
-106
lines changed

7 files changed

+229
-106
lines changed

src/lib.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ mod marshal;
22
mod objects;
33
mod processor;
44
mod sandbox;
5-
mod stack;
5+
mod varstack;
66
mod primitives;
77

88
use std::fmt;
99
use std::io;
10-
use processor::{PyResult, Processor};
10+
use std::collections::HashMap;
11+
pub use processor::{PyResult, Processor};
1112

1213
pub use sandbox::{EnvProxy, RealEnvProxy, MockEnvProxy};
1314

@@ -37,7 +38,7 @@ pub fn run_file<R: io::Read, EP: sandbox::EnvProxy>(reader: &mut R, envproxy: EP
3738
let mut store = objects::ObjectStore::new();
3839
let primitive_objects = objects::PrimitiveObjects::new(&mut store);
3940
let module = try!(marshal::read_object(reader, &mut store, &primitive_objects).map_err(InterpreterError::Unmarshal));
40-
let mut processor = Processor { envproxy: envproxy, store: store, primitive_functions: primitives::get_default_primitives(), primitive_objects: primitive_objects };
41+
let mut processor = Processor { envproxy: envproxy, store: store, primitive_functions: primitives::get_default_primitives(), primitive_objects: primitive_objects, modules: HashMap::new(), };
4142
let result = processor.run_code_object(module);
4243
Ok((processor, result))
4344
}

src/objects/mod.rs

+33-4
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,11 @@ pub enum ObjectContent {
4848
Set(Vec<ObjectRef>),
4949
FrozenSet(Vec<ObjectRef>),
5050
Bytes(Vec<u8>),
51-
Function(ObjectRef),
51+
Function(String, ObjectRef), // module, code
5252
PrimitiveNamespace, // __primitives__
5353
PrimitiveFunction(String),
5454
Class(Option<ObjectRef>),
55+
Module,
5556
OtherObject,
5657
}
5758

@@ -114,10 +115,10 @@ impl ObjectRef {
114115
ObjectContent::Code(_) => "<code object>".to_string(),
115116
ObjectContent::Set(ref l) => format!("set({})", ObjectRef::repr_vec(l, store)),
116117
ObjectContent::FrozenSet(ref l) => format!("frozenset({})", ObjectRef::repr_vec(l, store)),
117-
ObjectContent::Function(_) => {
118+
ObjectContent::Function(ref module, ref _code) => {
118119
match obj.name {
119-
None => "<anonymous function>".to_string(),
120-
Some(ref s) => format!("<function {}>", s),
120+
None => format!("<anonymous function in module {}>", module),
121+
Some(ref s) => format!("<function {} in module {}>", s, module),
121122
}
122123
},
123124
ObjectContent::PrimitiveNamespace => "__primitives__".to_string(),
@@ -128,9 +129,25 @@ impl ObjectRef {
128129
Some(ref s) => format!("<class {}>", s),
129130
}
130131
},
132+
ObjectContent::Module => {
133+
match obj.name {
134+
None => "<anonymous module>".to_string(),
135+
Some(ref s) => format!("<module {}", s),
136+
}
137+
},
131138
ObjectContent::OtherObject => format!("<{} instance>", obj.class.repr(store)),
132139
}
133140
}
141+
142+
pub fn module(&self, store: &ObjectStore) -> String {
143+
let func = store.deref(self);
144+
let ref name = func.name;
145+
match func.content {
146+
ObjectContent::Function(ref module_name, ref _code) => module_name.clone(),
147+
ObjectContent::Module => name.clone().unwrap(),
148+
_ => panic!(format!("Not a function/module: {:?}", func)),
149+
}
150+
}
134151
}
135152

136153

@@ -203,6 +220,8 @@ pub struct PrimitiveObjects {
203220
pub baseexception: ObjectRef,
204221
pub runtimeerror: ObjectRef,
205222

223+
pub module: ObjectRef,
224+
206225
pub names_map: HashMap<String, ObjectRef>,
207226
}
208227

@@ -236,6 +255,8 @@ impl PrimitiveObjects {
236255
let baseexception = store.allocate(Object::new_class("BaseException".to_string(), None, type_ref.clone(), vec![obj_ref.clone()]));
237256
let runtimeerror = store.allocate(Object::new_class("RuntimeError".to_string(), None, type_ref.clone(), vec![baseexception.clone()]));
238257

258+
let module = store.allocate(Object::new_class("module".to_string(), None, type_ref.clone(), vec![obj_ref.clone()]));
259+
239260
let mut map = HashMap::new();
240261
map.insert("object".to_string(), obj_ref.clone());
241262
map.insert("tuple".to_string(), type_ref.clone());
@@ -255,6 +276,7 @@ impl PrimitiveObjects {
255276
map.insert("code".to_string(), code_type.clone());
256277
map.insert("BaseException".to_string(), baseexception.clone());
257278
map.insert("RuntimeError".to_string(), runtimeerror.clone());
279+
map.insert("module".to_string(), module.clone());
258280

259281
PrimitiveObjects {
260282
object: obj_ref, type_: type_ref,
@@ -265,6 +287,7 @@ impl PrimitiveObjects {
265287
bytes_type: bytes_type, str_type: str_type,
266288
function_type: function_type, code_type: code_type,
267289
baseexception: baseexception, runtimeerror: runtimeerror,
290+
module: module,
268291
names_map: map,
269292
}
270293
}
@@ -293,4 +316,10 @@ impl PrimitiveObjects {
293316
pub fn new_code(&self, c: Code) -> Object {
294317
Object::new_instance(None, self.code_type.clone(), ObjectContent::Code(Box::new(c)))
295318
}
319+
pub fn new_function(&self, name: String, module_name: String, code: ObjectRef) -> Object {
320+
Object::new_instance(Some(name), self.function_type.clone(), ObjectContent::Function(module_name, code))
321+
}
322+
pub fn new_module(&self, name: String) -> Object {
323+
Object::new_instance(Some(name), self.module.clone(), ObjectContent::Module)
324+
}
296325
}

src/primitives/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn build_class<EP: EnvProxy>(processor: &mut Processor<EP>, args: Vec<ObjectRef>
5757
let mut args_iter = args.into_iter();
5858
parse_first_arguments!("__primitives__.build_class", processor.store, args, args_iter,
5959
"func" "a function": {
60-
ObjectContent::Function(ref code_arg) => {
60+
ObjectContent::Function(_, ref code_arg) => {
6161
code = code_arg.clone();
6262
},
6363
},

src/processor/frame.rs

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
use std::collections::HashMap;
2+
use std::rc::Rc;
3+
use std::cell::RefCell;
4+
use super::super::varstack::{VarStack, VectorVarStack};
5+
use super::super::objects::{ObjectRef, ObjectStore, ObjectContent};
6+
7+
#[derive(Debug)]
8+
pub enum Block {
9+
Loop(usize, usize), // begin, end
10+
TryExcept(usize, usize), // begin, end
11+
}
12+
13+
#[derive(Debug)]
14+
pub struct Frame {
15+
pub object: ObjectRef,
16+
pub var_stack: VectorVarStack<ObjectRef>,
17+
pub block_stack: Vec<Block>,
18+
pub locals: Rc<RefCell<HashMap<String, ObjectRef>>>,
19+
}
20+
21+
impl Frame {
22+
pub fn new(object: ObjectRef, locals: Rc<RefCell<HashMap<String, ObjectRef>>>) -> Frame {
23+
Frame {
24+
object: object,
25+
var_stack: VectorVarStack::new(),
26+
block_stack: Vec::new(),
27+
locals: locals,
28+
}
29+
}
30+
}
31+

0 commit comments

Comments
 (0)