Mercurial > python-compiler.rs
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, <_type) { BinOp::BinLt + } else if is_instance(&ast, >_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