Mercurial > python-compiler.rs
changeset 68:c59ad5ccd8a6
Add ast.Try
author | Bastien Orivel <eijebong@bananium.fr> |
---|---|
date | Mon, 13 Jun 2016 03:03:13 +0200 |
parents | 8ce78e2ba48c |
children | a73eaf42bea1 |
files | src/ast_convert.rs src/ast_dump.rs src/python_ast.rs tests/test_parse_files/test_try.py |
diffstat | 4 files changed, 83 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, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem}; +use python_ast::{Module, stmt, expr, expr_context, cmpop, boolop, operator, unaryop, arguments, arg, alias, comprehension, keyword, withitem, excepthandler}; use cpython::{Python, PyObject}; use cpython::ObjectProtocol; //for call method @@ -255,6 +255,18 @@ fn parse_operator(py: Python, ast: PyObj } } +fn parse_excepthandler(py: Python, ast: PyObject) -> excepthandler { + let type_ = ast.getattr(py, "type").unwrap(); + let name = ast.getattr(py, "name").unwrap(); + let body = ast.getattr(py, "body").unwrap(); + + let type_ = parse_optional_expr(py, type_); + let name = if name == py.None() { None } else { Some(get_str(py, name)) }; + let body = parse_list(py, body, parse_statement); + + excepthandler{type_: type_, name: name, body: body} +} + fn parse_optional_expr(py: Python, ast: PyObject) -> Option<expr> { if ast == py.None() { None @@ -531,6 +543,7 @@ fn parse_statement(py: Python, ast: PyOb let assert_type = ast_module.get(py, "Assert").unwrap(); let with_type = ast_module.get(py, "With").unwrap(); let raise_type = ast_module.get(py, "Raise").unwrap(); + let try_type = ast_module.get(py, "Try").unwrap(); assert!(is_instance(&ast, &ast_type)); @@ -695,6 +708,18 @@ fn parse_statement(py: Python, ast: PyOb let cause = parse_optional_expr(py, cause); stmt::Raise(exc, cause) + } else if is_instance(&ast, &try_type) { + let body = ast.getattr(py, "body").unwrap(); + let excepthandlers = ast.getattr(py, "handlers").unwrap(); + let orelse = ast.getattr(py, "orelse").unwrap(); + let finalbody = ast.getattr(py, "finalbody").unwrap(); + + let body = parse_list(py, body, parse_statement); + let excepthandlers = parse_list(py, excepthandlers, parse_excepthandler); + let orelse = parse_list(py, orelse, parse_statement); + let finalbody = parse_list(py, finalbody, parse_statement); + + stmt::Try(body, excepthandlers, orelse, finalbody) } else { println!("stmt {}", ast); panic!()
--- a/src/ast_dump.rs +++ b/src/ast_dump.rs @@ -1,4 +1,4 @@ -use python_ast::{Module, stmt, expr, boolop, operator, unaryop, cmpop, arguments, arg, keyword, comprehension, withitem}; +use python_ast::{Module, stmt, expr, boolop, operator, unaryop, cmpop, arguments, arg, keyword, comprehension, withitem, excepthandler}; use std::iter; @@ -117,6 +117,24 @@ impl to_string_able for comprehension { } } +impl excepthandler { + fn to_string(self, indent: usize) -> String { + let current_indent = make_indent(indent); + format!("{}except {}{}:\n{}", + current_indent, + match self.type_ { + None => String::new(), + Some(ref type_) => type_.to_string() + }, + match self.name { + None => String::new(), + Some(ref name) => format!(" as {}", name) + }, + statements_to_string(indent, self.body) + ) + } +} + impl to_string_able for expr { fn to_string(&self) -> String { match self.clone() { @@ -346,6 +364,30 @@ impl stmt { Some(ref cause) => format!(" from {}", cause.to_string()) } ) + }, + stmt::Try(body, excepthandlers, orelse, finalbody) => { + format!("{}try:\n{}\n{}{}\n{}", + current_indent, + statements_to_string(indent, body), + { + let mut excepthandlers_ = vec!(); + for excepthandler in excepthandlers { + let excepthandler = excepthandler.to_string(indent); + excepthandlers_.push(excepthandler); + } + excepthandlers_.join("\n") + }, + if !orelse.is_empty() { + format!("{}else:\n{}", current_indent, statements_to_string(indent, orelse)) + } else { + String::new() + }, + if !finalbody.is_empty() { + format!("{}finally:\n{}", current_indent, statements_to_string(indent, finalbody)) + } else { + String::new() + } + ) } } }
--- a/src/python_ast.rs +++ b/src/python_ast.rs @@ -51,7 +51,7 @@ pub enum stmt { Raise(Option<expr>, Option<expr>), // Try(stmt* body, excepthandler* handlers, stmt* orelse, stmt* finalbody) - //Try(Vec<stmt>, Vec<excepthandler>, Vec<stmt>, Vec<stmt>) + Try(Vec<stmt>, Vec<excepthandler>, Vec<stmt>, Vec<stmt>), // Assert(expr test, expr? msg) Assert(expr, Option<expr>), @@ -186,8 +186,10 @@ pub struct comprehension { } #[derive(Clone, Debug, PartialEq, Eq, Hash)] -pub enum excepthandler { - ExceptHandler(Option<expr>, Option<String>, Vec<stmt>) +pub struct excepthandler { + pub type_: Option<expr>, + pub name: Option<String>, + pub body: Vec<stmt>, } #[derive(Clone, Debug, PartialEq, Eq, Hash)]