Mercurial > python-compiler.rs
changeset 19:0cb53a31ac12
Implement ast.BoolOp, and improve its display.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Fri, 03 Jun 2016 00:55:24 +0100 |
parents | 51ef651266b1 |
children | ace12d6b9855 |
files | src/ast_convert.rs src/ast_dump.rs |
diffstat | 2 files changed, 54 insertions(+), 5 deletions(-) [+] |
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, operator, unaryop, arguments, arg, alias, comprehension}; +use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension}; use cpython::{Python, PyObject}; use cpython::ObjectProtocol; //for call method @@ -31,7 +31,17 @@ fn get_ctx(py: Python, object: PyObject) } } -fn parse_expr_vec(py: Python, ast: PyObject) -> Vec<String> { +fn parse_expr_vec(py: Python, list: PyObject) -> Vec<expr> { + let mut exprs = vec!(); + for item in list.iter(py).unwrap() { + let item = item.unwrap(); + let item = parse_expr(py, item); + exprs.push(item); + } + exprs +} + +fn parse_string_vec(py: Python, ast: PyObject) -> Vec<String> { let builtins_module = py.import("builtins").unwrap(); let isinstance = builtins_module.get(py, "isinstance").unwrap(); @@ -92,6 +102,30 @@ fn parse_unaryop(py: Python, ast: PyObje } } +fn parse_boolop(py: Python, ast: PyObject) -> boolop { + 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 and_type = ast_module.get(py, "And").unwrap(); + let or_type = ast_module.get(py, "Or").unwrap(); + + assert!(is_instance(&ast, &ast_type)); + + if is_instance(&ast, &and_type) { + boolop::And + } else if is_instance(&ast, &or_type) { + boolop::Or + } else { + unreachable!() + } +} + fn parse_cmpop(py: Python, ast: PyObject) -> cmpop { let builtins_module = py.import("builtins").unwrap(); let isinstance = builtins_module.get(py, "isinstance").unwrap(); @@ -228,6 +262,7 @@ fn parse_expr(py: Python, ast: PyObject) let ast_type = ast_module.get(py, "AST").unwrap(); let arg_type = ast_module.get(py, "arg").unwrap(); let unary_op_type = ast_module.get(py, "UnaryOp").unwrap(); + let bool_op_type = ast_module.get(py, "BoolOp").unwrap(); let bin_op_type = ast_module.get(py, "BinOp").unwrap(); let name_constant_type = ast_module.get(py, "NameConstant").unwrap(); let attribute_type = ast_module.get(py, "Attribute").unwrap(); @@ -289,6 +324,14 @@ fn parse_expr(py: Python, ast: PyObject) let operand = parse_expr(py, operand); expr::UnaryOp(op, Box::new(operand)) + } else if is_instance(&ast, &bool_op_type) { + let op = ast.getattr(py, "op").unwrap(); + let values = ast.getattr(py, "values").unwrap(); + + let op = parse_boolop(py, op); + let values = parse_expr_vec(py, values); + + expr::BoolOp(op, values) } else if is_instance(&ast, &bin_op_type) { let left = ast.getattr(py, "left").unwrap(); let op = ast.getattr(py, "op").unwrap();
--- a/src/ast_dump.rs +++ b/src/ast_dump.rs @@ -5,8 +5,8 @@ use std::iter; impl boolop { fn to_string(&self) -> &'static str { match *self { - boolop::And => "and", - boolop::Or => "or" + boolop::And => " and ", + boolop::Or => " or " } } } @@ -116,7 +116,13 @@ fn generators_to_string(generators: Vec< impl expr { fn to_string(&self) -> String { match self.clone() { - expr::BoolOp(op, values) => format!("{}({})", op.to_string(), args_to_string(values)), + expr::BoolOp(op, values) => { + let mut data = vec!(); + for value in values { + data.push(value.to_string()); + } + data.join(op.to_string()) + }, expr::BinOp(a, op, b) => format!("{} {} {}", a.to_string(), op.to_string(), b.to_string()), expr::UnaryOp(op, operand) => format!("{}{}", op.to_string(), operand.to_string()),