diff src/ast_convert.rs @ 82:2d906d1cb940

Add ast.Subscript.
author Bastien Orivel <eijebong@bananium.fr>
date Mon, 13 Jun 2016 21:32:43 +0200
parents dc82a0d8f144
children e59cd5754268
line wrap: on
line diff
--- a/src/ast_convert.rs
+++ b/src/ast_convert.rs
@@ -1,4 +1,4 @@
-use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem, excepthandler};
+use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem, excepthandler, slice};
 
 use cpython::{Python, PyObject};
 use cpython::ObjectProtocol; //for call method
@@ -267,6 +267,46 @@ fn parse_excepthandler(py: Python, ast: 
     excepthandler{type_: type_, name: name, body: body}
 }
 
+fn parse_slice(py: Python, ast: PyObject) -> slice {
+    let builtins_module = py.import("builtins").unwrap();
+    let isinstance = builtins_module.get(py, "isinstance").unwrap();
+
+    let is_instance = |object: &PyObject, type_: &PyObject| {
+        return isinstance.call(py, (object, type_), None).unwrap().is_true(py).unwrap();
+    };
+
+    let ast_module = py.import("ast").unwrap();
+    let ast_type = ast_module.get(py, "AST").unwrap();
+    let index_type = ast_module.get(py, "Index").unwrap();
+    let slice_type = ast_module.get(py, "Slice").unwrap();
+    let ext_slice_type = ast_module.get(py, "ExtSlice").unwrap();
+
+    assert!(is_instance(&ast, &ast_type));
+
+    if is_instance(&ast, &index_type) {
+        let value = ast.getattr(py, "value").unwrap();
+        let value = parse_expr(py, value);
+
+        slice::Index(value)
+    } else if is_instance(&ast, &slice_type) {
+        let lower = ast.getattr(py, "lower").unwrap();
+        let upper = ast.getattr(py, "upper").unwrap();
+        let step = ast.getattr(py, "step").unwrap();
+
+        let lower = parse_optional_expr(py, lower);
+        let upper = parse_optional_expr(py, upper);
+        let step = parse_optional_expr(py, step);
+        slice::Slice(lower, upper, step)
+    } else if is_instance(&ast, &ext_slice_type) {
+        let dims = ast.getattr(py, "dims").unwrap();
+        let dims = parse_list(py, dims, parse_slice);
+
+        slice::ExtSlice(dims)
+    } else {
+        unreachable!()
+    }
+}
+
 fn parse_optional_expr(py: Python, ast: PyObject) -> Option<expr> {
     if ast == py.None() {
         None
@@ -310,6 +350,7 @@ fn parse_expr(py: Python, ast: PyObject)
     let lambda_type = ast_module.get(py, "Lambda").unwrap();
     let ifexp_type = ast_module.get(py, "IfExp").unwrap();
     let dict_type = ast_module.get(py, "Dict").unwrap();
+    let subscript_type = ast_module.get(py, "Subscript").unwrap();
 
     assert!(is_instance(&ast, &ast_type));
 
@@ -473,6 +514,15 @@ fn parse_expr(py: Python, ast: PyObject)
         let values = parse_list(py, values, parse_expr);
 
         expr::Dict(keys, values)
+    } else if is_instance(&ast, &subscript_type) {
+        let value = ast.getattr(py, "value").unwrap();
+        let slice = ast.getattr(py, "slice").unwrap();
+        let ctx = get_ctx(py, ast);
+
+        let value = parse_expr(py, value);
+        let slice = parse_slice(py, slice);
+
+        expr::Subscript(Box::new(value), Box::new(slice), ctx)
     } else {
         println!("expr {}", ast);
         unreachable!()