@@ -43,6 +43,16 @@ pub struct PyContext {
4343 pub int_type : PyObjectRef ,
4444}
4545
46+ /*
47+ * So a scope is a linked list of scopes.
48+ * When a name is looked up, it is check in its scope.
49+ */
50+ #[ derive( Debug ) ]
51+ pub struct Scope {
52+ pub locals : PyObjectRef , // Variables
53+ pub parent : Option < PyObjectRef > , // Parent scope
54+ }
55+
4656// Basic objects:
4757impl PyContext {
4858 pub fn new ( ) -> PyContext {
@@ -118,6 +128,7 @@ pub trait Executor {
118128 fn new_str ( & self , s : String ) -> PyObjectRef ;
119129 fn new_bool ( & self , b : bool ) -> PyObjectRef ;
120130 fn new_dict ( & self ) -> PyObjectRef ;
131+ fn new_scope ( & self , parent : Option < PyObjectRef > ) -> PyObjectRef ;
121132 fn new_exception ( & self , msg : String ) -> PyObjectRef ;
122133 fn get_none ( & self ) -> PyObjectRef ;
123134 fn get_type ( & self ) -> PyObjectRef ;
@@ -141,6 +152,33 @@ impl Default for PyObject {
141152 }
142153}
143154
155+ pub trait ParentProtocol {
156+ fn has_parent ( & self ) -> bool ;
157+ fn get_parent ( & self ) -> PyObjectRef ;
158+ }
159+
160+ impl ParentProtocol for PyObjectRef {
161+ fn has_parent ( & self ) -> bool {
162+ match self . borrow ( ) . kind {
163+ PyObjectKind :: Scope { ref scope } => match scope. parent {
164+ Some ( _) => true ,
165+ None => false ,
166+ } ,
167+ _ => panic ! ( "Only scopes have parent (not {:?}" , self ) ,
168+ }
169+ }
170+
171+ fn get_parent ( & self ) -> PyObjectRef {
172+ match self . borrow ( ) . kind {
173+ PyObjectKind :: Scope { ref scope } => match scope. parent {
174+ Some ( ref value) => value. clone ( ) ,
175+ None => panic ! ( "OMG" ) ,
176+ } ,
177+ _ => panic ! ( "TODO" ) ,
178+ }
179+ }
180+ }
181+
144182pub trait DictProtocol {
145183 fn contains_key ( & self , k : & String ) -> bool ;
146184 fn get_item ( & self , k : & String ) -> PyObjectRef ;
@@ -152,6 +190,7 @@ impl DictProtocol for PyObjectRef {
152190 match self . borrow ( ) . kind {
153191 PyObjectKind :: Dict { ref elements } => elements. contains_key ( k) ,
154192 PyObjectKind :: Module { ref name, ref dict } => dict. contains_key ( k) ,
193+ PyObjectKind :: Scope { ref scope } => scope. locals . contains_key ( k) ,
155194 _ => panic ! ( "TODO" ) ,
156195 }
157196 }
@@ -160,6 +199,7 @@ impl DictProtocol for PyObjectRef {
160199 match self . borrow ( ) . kind {
161200 PyObjectKind :: Dict { ref elements } => elements[ k] . clone ( ) ,
162201 PyObjectKind :: Module { ref name, ref dict } => dict. get_item ( k) ,
202+ PyObjectKind :: Scope { ref scope } => scope. locals . get_item ( k) ,
163203 _ => panic ! ( "TODO" ) ,
164204 }
165205 }
@@ -168,7 +208,12 @@ impl DictProtocol for PyObjectRef {
168208 match self . borrow_mut ( ) . kind {
169209 PyObjectKind :: Dict {
170210 elements : ref mut el,
171- } => el. insert ( k. to_string ( ) , v) ,
211+ } => {
212+ el. insert ( k. to_string ( ) , v) ;
213+ } ,
214+ PyObjectKind :: Scope { ref mut scope } => {
215+ scope. locals . set_item ( k, v) ;
216+ } ,
172217 _ => panic ! ( "TODO" ) ,
173218 } ;
174219 }
@@ -223,6 +268,9 @@ pub enum PyObjectKind {
223268 Function {
224269 code : PyObjectRef ,
225270 } ,
271+ Scope {
272+ scope : Scope ,
273+ } ,
226274 Module {
227275 name : String ,
228276 dict : PyObjectRef ,
@@ -253,6 +301,7 @@ impl fmt::Debug for PyObjectKind {
253301 & PyObjectKind :: Code { ref code } => write ! ( f, "code: {:?}" , code) ,
254302 & PyObjectKind :: Function { ref code } => write ! ( f, "function" ) ,
255303 & PyObjectKind :: Module { ref name, ref dict } => write ! ( f, "module" ) ,
304+ & PyObjectKind :: Scope { ref scope } => write ! ( f, "scope" ) ,
256305 & PyObjectKind :: None => write ! ( f, "None" ) ,
257306 & PyObjectKind :: Class { ref name } => write ! ( f, "class" ) ,
258307 & PyObjectKind :: RustFunction { ref function } => write ! ( f, "rust function" ) ,
0 commit comments