changeset 6:6f2bf13f4cb5

Add ast.While and ast.Break.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 31 May 2016 04:22:35 +0100
parents ddf372373a77
children 680d15073f55
files src/ast_convert.rs src/ast_dump.rs src/ast_rewrite.rs src/ast_type.rs src/python_ast.rs
diffstat 5 files changed, 74 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/src/ast_convert.rs
+++ b/src/ast_convert.rs
@@ -75,6 +75,7 @@ fn parse_binop(py: Python, ast: PyObject
     let mult_type = ast_module.get(py, "Mult").unwrap();
     let eq_type = ast_module.get(py, "Eq").unwrap();
     let lt_type = ast_module.get(py, "Lt").unwrap();
+    let gt_type = ast_module.get(py, "Gt").unwrap();
     let sub_type = ast_module.get(py, "Sub").unwrap();
     let div_type = ast_module.get(py, "Div").unwrap();
 
@@ -88,6 +89,8 @@ fn parse_binop(py: Python, ast: PyObject
         BinOp::BinEq
     } else if is_instance(&ast, &lt_type) {
         BinOp::BinLt
+    } else if is_instance(&ast, &gt_type) {
+        BinOp::BinGt
     } else if is_instance(&ast, &sub_type) {
         BinOp::Sub
     } else if is_instance(&ast, &div_type) {
@@ -244,8 +247,10 @@ fn parse_statement(py: Python, ast: PyOb
     let return_type = ast_module.get(py, "Return").unwrap();
     let import_from_type = ast_module.get(py, "ImportFrom").unwrap();
     let if_type = ast_module.get(py, "If").unwrap();
+    let while_type = ast_module.get(py, "While").unwrap();
     let for_type = ast_module.get(py, "For").unwrap();
     let expr_type = ast_module.get(py, "Expr").unwrap();
+    let break_type = ast_module.get(py, "Break").unwrap();
 
     assert!(is_instance(&ast, &ast_type));
 
@@ -342,6 +347,28 @@ fn parse_statement(py: Python, ast: PyOb
         }
 
         Statement::If(test, statements, orelse_)
+    } else if is_instance(&ast, &while_type) {
+        let test = ast.getattr(py, "test").unwrap();
+        let body = ast.getattr(py, "body").unwrap();
+        let orelse = ast.getattr(py, "orelse").unwrap();
+
+        let test = parse_expr(py, test);
+
+        let mut statements = vec!();
+        for statement in body.iter(py).unwrap() {
+            let statement = statement.unwrap();
+            let statement = parse_statement(py, statement);
+            statements.push(statement);
+        }
+
+        let mut orelse_ = vec!();
+        for statement in orelse.iter(py).unwrap() {
+            let statement = statement.unwrap();
+            let statement = parse_statement(py, statement);
+            orelse_.push(statement);
+        }
+
+        Statement::While(test, statements, orelse_)
     } else if is_instance(&ast, &for_type) {
         let target = ast.getattr(py, "target").unwrap();
         let iter = ast.getattr(py, "iter").unwrap();
@@ -403,6 +430,8 @@ fn parse_statement(py: Python, ast: PyOb
         let value = ast.getattr(py, "value").unwrap();
         let value = parse_expr(py, value);
         Statement::Expr(value)
+    } else if is_instance(&ast, &break_type) {
+        Statement::Break
     } else {
         println!("Statement {}", ast);
         Statement::Error
--- a/src/ast_dump.rs
+++ b/src/ast_dump.rs
@@ -19,6 +19,7 @@ impl BinOp {
             BinOp::BinMult => "*",
             BinOp::BinEq => "==",
             BinOp::BinLt => "<",
+            BinOp::BinGt => ">",
             BinOp::Sub => "-",
             BinOp::Div => "/",
             BinOp::Error => "BinOp::Error"
@@ -126,6 +127,23 @@ impl Statement {
                     format!("{}\n{}else:\n{}", statements.join("\n"), make_indent(indent), orelse_.join("\n"))
                 }
             }),
+            Statement::While(test, body, orelse) => format!("{}while {}:\n{}", make_indent(indent), test.to_string(), {
+                let mut statements = vec!();
+                for arg in body {
+                    statements.push(arg.to_string(indent + 1));
+                }
+
+                let mut orelse_ = vec!();
+                for arg in orelse {
+                    orelse_.push(arg.to_string(indent + 1));
+                }
+
+                if orelse_.is_empty() {
+                    statements.join("\n")
+                } else {
+                    format!("{}\n{}else:\n{}", statements.join("\n"), make_indent(indent), orelse_.join("\n"))
+                }
+            }),
             Statement::For(target, iter, body, orelse) => format!("{}for {} in {}:\n{}", make_indent(indent), target.to_string(), iter.to_string(), {
                 let mut statements = vec!();
                 for arg in body {
@@ -160,6 +178,7 @@ impl Statement {
                 exprs.join(", ")
             }),
             Statement::Expr(expr) => format!("{}{}", make_indent(indent), expr.to_string()),
+            Statement::Break => format!("{}break", make_indent(indent)),
             Statement::Error => format!("{}Statement::Error", make_indent(indent))
         }
     }
--- a/src/ast_rewrite.rs
+++ b/src/ast_rewrite.rs
@@ -40,6 +40,15 @@ impl Visitor<()> for Rewrite {
                     self.visit_statement(statement);
                 }
             },
+            Statement::While(test, body, orelse) => {
+                self.visit_expr(test);
+                for statement in body {
+                    self.visit_statement(statement);
+                }
+                for statement in orelse {
+                    self.visit_statement(statement);
+                }
+            },
             Statement::For(target, iter, body, orelse) => {
                 self.visit_expr(target);
                 self.visit_expr(iter);
@@ -65,6 +74,7 @@ impl Visitor<()> for Rewrite {
             Statement::Expr(expr) => {
                 self.visit_expr(expr);
             },
+            Statement::Break => {},
             Statement::Error => {
                 println!("Statement::Error");
                 panic!()
--- a/src/ast_type.rs
+++ b/src/ast_type.rs
@@ -84,6 +84,16 @@ impl Visitor<Type> for Typing {
                 }
                 Type::Bottom
             },
+            Statement::While(test, body, orelse) => {
+                self.visit_expr(test);
+                for statement in body {
+                    self.visit_statement(statement);
+                }
+                for statement in orelse {
+                    self.visit_statement(statement);
+                }
+                Type::Bottom
+            },
             Statement::For(target, iter, body, orelse) => {
                 self.visit_expr(target);
                 self.visit_expr(iter);
@@ -126,6 +136,9 @@ impl Visitor<Type> for Typing {
             Statement::Expr(expr) => {
                 self.visit_expr(expr)
             },
+            Statement::Break => {
+                Type::Bottom
+            },
             Statement::Error => {
                 println!("Statement::Error");
                 panic!()
--- a/src/python_ast.rs
+++ b/src/python_ast.rs
@@ -11,10 +11,12 @@ pub enum Statement {
     Global(Vec<String>),
     If(Expr, Vec<Statement>, Vec<Statement>),
     For(Expr, Expr, Vec<Statement>, Vec<Statement>),
+    While(Expr, Vec<Statement>, Vec<Statement>),
     Assign(Vec<Expr>, Expr),
     Return(Expr),
     ImportFrom(String, Vec<Expr>),
     Expr(Expr),
+    Break,
     Error
 }
 
@@ -46,6 +48,7 @@ pub enum BinOp {
     BinMult,
     BinEq,
     BinLt,
+    BinGt,
     Sub,
     Div,
     Error