changeset 2:5fc7c2790d8c

Add class support.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 31 May 2016 02:31:55 +0100
parents b90e49ab734b
children 326d7f2a94d4
files example/class.py src/ast_convert.rs src/ast_dump.rs src/ast_type.rs src/python_ast.rs
diffstat 5 files changed, 50 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/example/class.py
@@ -0,0 +1,7 @@
+class A:
+    def a(self):
+        print('a')
+
+class B(A):
+    def b(self):
+        print('b')
--- a/src/ast_convert.rs
+++ b/src/ast_convert.rs
@@ -188,6 +188,7 @@ fn parse_statement(py: Python, ast: PyOb
 
     let ast_module = py.import("ast").unwrap();
     let ast_type = ast_module.get(py, "AST").unwrap();
+    let class_def_type = ast_module.get(py, "ClassDef").unwrap();
     let function_def_type = ast_module.get(py, "FunctionDef").unwrap();
     let global_type = ast_module.get(py, "Global").unwrap();
     let assign_type = ast_module.get(py, "Assign").unwrap();
@@ -212,7 +213,31 @@ fn parse_statement(py: Python, ast: PyOb
     };
     */
 
-    if is_instance(&ast, &function_def_type) {
+    if is_instance(&ast, &class_def_type) {
+        let name = ast.getattr(py, "name").unwrap();
+        let bases = ast.getattr(py, "bases").unwrap();
+        //let keywords = ast.getattr(py, "keywords").unwrap();
+        let body = ast.getattr(py, "body").unwrap();
+        //let decorator_list = ast.getattr(py, "decorator_list").unwrap();
+
+        let name = get_str(py, name);
+
+        let mut nodes = vec!();
+        for name_node in bases.iter(py).unwrap() {
+            let name_node = name_node.unwrap();
+            let name_node = parse_expr(py, name_node);
+            nodes.push(name_node);
+        }
+
+        let mut statements = vec!();
+        for statement in body.iter(py).unwrap() {
+            let statement = statement.unwrap();
+            let statement = parse_statement(py, statement);
+            statements.push(statement);
+        }
+
+        Statement::ClassDef(name, nodes, statements)
+    } else if is_instance(&ast, &function_def_type) {
         let name = ast.getattr(py, "name").unwrap();
         let args = ast.getattr(py, "args").unwrap();
         let body = ast.getattr(py, "body").unwrap();
--- a/src/ast_dump.rs
+++ b/src/ast_dump.rs
@@ -68,6 +68,19 @@ fn make_indent(indent: usize) -> String 
 impl Statement {
     fn to_string(&self, indent: usize) -> String {
         match self.clone() {
+            Statement::ClassDef(name, classes, body) => format!("{}def {}({}):\n{}", make_indent(indent), name, {
+                let mut bases = vec!();
+                for class in classes {
+                    bases.push(class.to_string());
+                }
+                bases.join(", ")
+            }, {
+                let mut statements = vec!();
+                for statement in body {
+                    statements.push(statement.to_string(indent + 1));
+                }
+                statements.join("\n")
+            }),
             Statement::FunctionDef(Expr::Name(name), arguments, body) => format!("{}def {}({}):\n{}", make_indent(indent), name, {
                 let mut args = vec!();
                 for arg in arguments {
--- a/src/ast_type.rs
+++ b/src/ast_type.rs
@@ -41,6 +41,9 @@ impl Visitor<Type> for Typing {
 
     fn visit_statement(&mut self, statement: Statement) -> Type {
         match statement {
+            Statement::ClassDef(name, classes, body) => {
+                Type::Bottom
+            },
             Statement::FunctionDef(Expr::Name(name), arguments, body) => {
                 let mut env = self.environment.pop().unwrap();
                 self.environment.push(env.clone());
--- a/src/python_ast.rs
+++ b/src/python_ast.rs
@@ -6,6 +6,7 @@ pub struct Module {
 
 #[derive(Clone, Debug)]
 pub enum Statement {
+    ClassDef(String, Vec<Expr>, Vec<Statement>),
     FunctionDef(Expr, Vec<Expr>, Vec<Statement>),
     Global(Vec<String>),
     If(Expr, Vec<Statement>, Vec<Statement>),