Mercurial > python-compiler.rs
annotate src/ast_convert.rs @ 5:ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 31 May 2016 04:15:00 +0100 |
parents | f27a4aee9dfa |
children | 6f2bf13f4cb5 |
rev | line source |
---|---|
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
1 use python_ast::{Module, Statement, Expr, BinOp, UnaryOp}; |
0 | 2 |
3 use cpython::{Python, PyObject}; | |
4 use cpython::ObjectProtocol; //for call method | |
5 | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
6 fn get_str(py: Python, object: PyObject) -> String { |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
7 let pystring = object.str(py).unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
8 let mut string = pystring.to_string(py).unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
9 string.to_mut().to_string() |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
10 } |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
11 |
0 | 12 fn parse_expr_vec(py: Python, ast: PyObject) -> Vec<Expr> { |
13 let builtins_module = py.import("builtins").unwrap(); | |
14 let isinstance = builtins_module.get(py, "isinstance").unwrap(); | |
15 | |
16 let is_instance = |object: &PyObject, type_: &PyObject| { | |
17 return isinstance.call(py, (object, type_), None).unwrap().is_true(py).unwrap(); | |
18 }; | |
19 | |
20 let ast_module = py.import("ast").unwrap(); | |
21 let ast_type = ast_module.get(py, "AST").unwrap(); | |
22 let arguments_type = ast_module.get(py, "arguments").unwrap(); | |
23 | |
24 assert!(is_instance(&ast, &ast_type)); | |
25 | |
26 if is_instance(&ast, &arguments_type) { | |
27 let args = ast.getattr(py, "args").unwrap(); | |
28 let mut arguments = vec!(); | |
29 for arg in args.iter(py).unwrap() { | |
30 let arg = parse_expr(py, arg.unwrap()); | |
31 arguments.push(arg); | |
32 } | |
33 arguments | |
34 } else { | |
35 vec!(Expr::Error) | |
36 } | |
37 } | |
38 | |
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
39 fn parse_unaryop(py: Python, ast: PyObject) -> UnaryOp { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
40 let builtins_module = py.import("builtins").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
41 let isinstance = builtins_module.get(py, "isinstance").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
42 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
43 let is_instance = |object: &PyObject, type_: &PyObject| { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
44 return isinstance.call(py, (object, type_), None).unwrap().is_true(py).unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
45 }; |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
46 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
47 let ast_module = py.import("ast").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
48 let ast_type = ast_module.get(py, "AST").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
49 let uadd_type = ast_module.get(py, "UAdd").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
50 let usub_type = ast_module.get(py, "USub").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
51 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
52 assert!(is_instance(&ast, &ast_type)); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
53 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
54 if is_instance(&ast, &uadd_type) { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
55 UnaryOp::UAdd |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
56 } else if is_instance(&ast, &usub_type) { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
57 UnaryOp::USub |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
58 } else { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
59 println!("UnaryOp {}", ast); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
60 UnaryOp::Error |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
61 } |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
62 } |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
63 |
0 | 64 fn parse_binop(py: Python, ast: PyObject) -> BinOp { |
65 let builtins_module = py.import("builtins").unwrap(); | |
66 let isinstance = builtins_module.get(py, "isinstance").unwrap(); | |
67 | |
68 let is_instance = |object: &PyObject, type_: &PyObject| { | |
69 return isinstance.call(py, (object, type_), None).unwrap().is_true(py).unwrap(); | |
70 }; | |
71 | |
72 let ast_module = py.import("ast").unwrap(); | |
73 let ast_type = ast_module.get(py, "AST").unwrap(); | |
74 let add_type = ast_module.get(py, "Add").unwrap(); | |
75 let mult_type = ast_module.get(py, "Mult").unwrap(); | |
76 let eq_type = ast_module.get(py, "Eq").unwrap(); | |
77 let lt_type = ast_module.get(py, "Lt").unwrap(); | |
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
78 let sub_type = ast_module.get(py, "Sub").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
79 let div_type = ast_module.get(py, "Div").unwrap(); |
0 | 80 |
81 assert!(is_instance(&ast, &ast_type)); | |
82 | |
83 if is_instance(&ast, &add_type) { | |
84 BinOp::BinAdd | |
85 } else if is_instance(&ast, &mult_type) { | |
86 BinOp::BinMult | |
87 } else if is_instance(&ast, &eq_type) { | |
88 BinOp::BinEq | |
89 } else if is_instance(&ast, <_type) { | |
90 BinOp::BinLt | |
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
91 } else if is_instance(&ast, &sub_type) { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
92 BinOp::Sub |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
93 } else if is_instance(&ast, &div_type) { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
94 BinOp::Div |
0 | 95 } else { |
96 println!("BinOp {}", ast); | |
97 BinOp::Error | |
98 } | |
99 } | |
100 | |
101 fn parse_expr(py: Python, ast: PyObject) -> Expr { | |
102 let builtins_module = py.import("builtins").unwrap(); | |
103 let isinstance = builtins_module.get(py, "isinstance").unwrap(); | |
104 | |
105 let is_instance = |object: &PyObject, type_: &PyObject| { | |
106 return isinstance.call(py, (object, type_), None).unwrap().is_true(py).unwrap(); | |
107 }; | |
108 | |
109 let ast_module = py.import("ast").unwrap(); | |
110 let ast_type = ast_module.get(py, "AST").unwrap(); | |
111 let arg_type = ast_module.get(py, "arg").unwrap(); | |
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
112 let unary_op_type = ast_module.get(py, "UnaryOp").unwrap(); |
0 | 113 let bin_op_type = ast_module.get(py, "BinOp").unwrap(); |
114 let name_constant_type = ast_module.get(py, "NameConstant").unwrap(); | |
4
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
115 let attribute_type = ast_module.get(py, "Attribute").unwrap(); |
0 | 116 let name_type = ast_module.get(py, "Name").unwrap(); |
117 let num_type = ast_module.get(py, "Num").unwrap(); | |
118 let str_type = ast_module.get(py, "Str").unwrap(); | |
119 let compare_type = ast_module.get(py, "Compare").unwrap(); | |
120 let call_type = ast_module.get(py, "Call").unwrap(); | |
121 let alias_type = ast_module.get(py, "alias").unwrap(); | |
122 | |
123 assert!(is_instance(&ast, &ast_type)); | |
124 | |
125 if is_instance(&ast, &arg_type) { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
126 let arg = ast.getattr(py, "arg").unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
127 let arg = get_str(py, arg); |
0 | 128 Expr::Name(arg) |
4
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
129 } else if is_instance(&ast, &attribute_type) { |
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
130 let value = ast.getattr(py, "value").unwrap(); |
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
131 let attr = ast.getattr(py, "attr").unwrap(); |
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
132 |
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
133 let value = parse_expr(py, value); |
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
134 let attr = get_str(py, attr); |
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
135 |
f27a4aee9dfa
Add ast.Attribute.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
136 Expr::Attribute(Box::new(value), attr) |
0 | 137 } else if is_instance(&ast, &name_type) { |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
138 let id = ast.getattr(py, "id").unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
139 let id = get_str(py, id); |
0 | 140 Expr::Name(id) |
141 } else if is_instance(&ast, &name_constant_type) { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
142 let value = ast.getattr(py, "value").unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
143 let value = get_str(py, value); |
0 | 144 Expr::NameConstant(value) |
145 } else if is_instance(&ast, &num_type) { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
146 let n = ast.getattr(py, "n").unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
147 let n = get_str(py, n); |
0 | 148 Expr::Num(n) |
149 } else if is_instance(&ast, &str_type) { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
150 let s = ast.getattr(py, "s").unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
151 let s = get_str(py, s); |
0 | 152 Expr::Str(s) |
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
153 } else if is_instance(&ast, &unary_op_type) { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
154 let op = ast.getattr(py, "op").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
155 let operand = ast.getattr(py, "operand").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
156 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
157 let op = parse_unaryop(py, op); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
158 let operand = parse_expr(py, operand); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
159 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
160 Expr::UnaryOp(op, Box::new(operand)) |
0 | 161 } else if is_instance(&ast, &bin_op_type) { |
162 let left = ast.getattr(py, "left").unwrap(); | |
163 let op = ast.getattr(py, "op").unwrap(); | |
164 let right = ast.getattr(py, "right").unwrap(); | |
165 | |
166 let left = parse_expr(py, left); | |
167 let op = parse_binop(py, op); | |
168 let right = parse_expr(py, right); | |
169 | |
170 Expr::BinOp(Box::new(left), op, Box::new(right)) | |
171 } else if is_instance(&ast, &call_type) { | |
172 let func = ast.getattr(py, "func").unwrap(); | |
173 let args = ast.getattr(py, "args").unwrap(); | |
174 //let keywords = ast.getattr(py, "keywords").unwrap(); | |
175 | |
176 let func = parse_expr(py, func); | |
177 | |
178 let mut arguments = vec!(); | |
179 for arg in args.iter(py).unwrap() { | |
180 let arg = arg.unwrap(); | |
181 arguments.push(parse_expr(py, arg)); | |
182 } | |
183 | |
184 Expr::Call(Box::new(func), arguments) | |
185 } else if is_instance(&ast, &alias_type) { | |
186 let name = ast.getattr(py, "name").unwrap(); | |
187 let asname = ast.getattr(py, "asname").unwrap(); | |
188 | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
189 let name = get_str(py, name); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
190 let asname = if asname == py.None() { |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
191 None |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
192 } else { |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
193 Some(get_str(py, asname)) |
0 | 194 }; |
195 | |
196 Expr::Alias(name, asname) | |
197 } else if is_instance(&ast, &compare_type) { | |
198 let left = ast.getattr(py, "left").unwrap(); | |
199 let ops = ast.getattr(py, "ops").unwrap(); | |
200 let comparators = ast.getattr(py, "comparators").unwrap(); | |
201 | |
202 let left = parse_expr(py, left); | |
203 let ops = ops.iter(py).unwrap(); | |
204 let comparators = comparators.iter(py).unwrap(); | |
205 | |
206 let mut new_ops = vec!(); | |
207 for op in ops { | |
208 let op = op.unwrap(); | |
209 let op = parse_binop(py, op); | |
210 new_ops.push(op); | |
211 } | |
212 | |
213 let mut new_comparators = vec!(); | |
214 for comparator in comparators { | |
215 let comparator = comparator.unwrap(); | |
216 let comparator = parse_expr(py, comparator); | |
217 new_comparators.push(comparator); | |
218 } | |
219 | |
220 Expr::Compare(Box::new(left), new_ops, new_comparators) | |
221 } else { | |
222 println!("Expr {}", ast); | |
223 Expr::Error | |
224 } | |
225 } | |
226 | |
227 fn parse_statement(py: Python, ast: PyObject) -> Statement { | |
228 //Statement::FunctionDef(Expr::Name("function".to_string()), vec!(Expr::Name("a".to_string()), Expr::Name("b".to_string())), vec!()) | |
229 //Statement::If(Expr::BinOp(BinOp::BinEq, Box::new(Expr::Name("__name__".to_string())), Box::new(Expr::Str("__main__".to_string()))), vec!(Statement::Expr(Expr::Call(Box::new(Expr::Name("function".to_string())), vec!(Expr::Num(1), Expr::Num(2)))))) | |
230 | |
231 let builtins_module = py.import("builtins").unwrap(); | |
232 let isinstance = builtins_module.get(py, "isinstance").unwrap(); | |
233 | |
234 let is_instance = |object: &PyObject, type_: &PyObject| { | |
235 return isinstance.call(py, (object, type_), None).unwrap().is_true(py).unwrap(); | |
236 }; | |
237 | |
238 let ast_module = py.import("ast").unwrap(); | |
239 let ast_type = ast_module.get(py, "AST").unwrap(); | |
2
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
240 let class_def_type = ast_module.get(py, "ClassDef").unwrap(); |
0 | 241 let function_def_type = ast_module.get(py, "FunctionDef").unwrap(); |
242 let global_type = ast_module.get(py, "Global").unwrap(); | |
243 let assign_type = ast_module.get(py, "Assign").unwrap(); | |
244 let return_type = ast_module.get(py, "Return").unwrap(); | |
245 let import_from_type = ast_module.get(py, "ImportFrom").unwrap(); | |
246 let if_type = ast_module.get(py, "If").unwrap(); | |
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
247 let for_type = ast_module.get(py, "For").unwrap(); |
0 | 248 let expr_type = ast_module.get(py, "Expr").unwrap(); |
249 | |
250 assert!(is_instance(&ast, &ast_type)); | |
251 | |
252 /* | |
253 // TODO: implement Hash for PyObject. (trivial) | |
254 let map = { | |
255 let fields = ast.getattr(py, "_fields").unwrap(); | |
256 let mut map = HashMap::new(); | |
257 for field in fields.iter(py).unwrap() { | |
258 let field = field.unwrap(); | |
259 let value = ast.getattr(py, field).unwrap(); | |
260 map.insert(field, value); | |
261 } | |
262 map | |
263 }; | |
264 */ | |
265 | |
2
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
266 if is_instance(&ast, &class_def_type) { |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
267 let name = ast.getattr(py, "name").unwrap(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
268 let bases = ast.getattr(py, "bases").unwrap(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
269 //let keywords = ast.getattr(py, "keywords").unwrap(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
270 let body = ast.getattr(py, "body").unwrap(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
271 //let decorator_list = ast.getattr(py, "decorator_list").unwrap(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
272 |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
273 let name = get_str(py, name); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
274 |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
275 let mut nodes = vec!(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
276 for name_node in bases.iter(py).unwrap() { |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
277 let name_node = name_node.unwrap(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
278 let name_node = parse_expr(py, name_node); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
279 nodes.push(name_node); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
280 } |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
281 |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
282 let mut statements = vec!(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
283 for statement in body.iter(py).unwrap() { |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
284 let statement = statement.unwrap(); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
285 let statement = parse_statement(py, statement); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
286 statements.push(statement); |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
287 } |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
288 |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
289 Statement::ClassDef(name, nodes, statements) |
5fc7c2790d8c
Add class support.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
290 } else if is_instance(&ast, &function_def_type) { |
0 | 291 let name = ast.getattr(py, "name").unwrap(); |
292 let args = ast.getattr(py, "args").unwrap(); | |
293 let body = ast.getattr(py, "body").unwrap(); | |
294 | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
295 let name = get_str(py, name); |
0 | 296 let args = parse_expr_vec(py, args); |
297 /* | |
298 let mut arguments = vec!(); | |
299 for arg in args.iter(py).unwrap() { | |
300 let arg = parse_expr(py, arg.unwrap()); | |
301 arguments.push(arg); | |
302 } | |
303 */ | |
304 | |
305 let mut statements = vec!(); | |
306 for statement in body.iter(py).unwrap() { | |
307 let statement = parse_statement(py, statement.unwrap()); | |
308 statements.push(statement); | |
309 } | |
310 | |
3
326d7f2a94d4
Remove useless abstraction of function name as Expr.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
2
diff
changeset
|
311 Statement::FunctionDef(name, args, statements) |
0 | 312 } else if is_instance(&ast, &global_type) { |
313 let names = ast.getattr(py, "names").unwrap(); | |
314 | |
315 let mut globals = vec!(); | |
316 for name in names.iter(py).unwrap() { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
317 let name = name.unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
318 let name = get_str(py, name); |
0 | 319 globals.push(name); |
320 } | |
321 | |
322 Statement::Global(globals) | |
323 } else if is_instance(&ast, &if_type) { | |
324 let test = ast.getattr(py, "test").unwrap(); | |
325 let body = ast.getattr(py, "body").unwrap(); | |
326 let orelse = ast.getattr(py, "orelse").unwrap(); | |
327 | |
328 let test = parse_expr(py, test); | |
329 | |
330 let mut statements = vec!(); | |
331 for statement in body.iter(py).unwrap() { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
332 let statement = statement.unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
333 let statement = parse_statement(py, statement); |
0 | 334 statements.push(statement); |
335 } | |
336 | |
337 let mut orelse_ = vec!(); | |
338 for statement in orelse.iter(py).unwrap() { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
339 let statement = statement.unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
340 let statement = parse_statement(py, statement); |
0 | 341 orelse_.push(statement); |
342 } | |
343 | |
344 Statement::If(test, statements, orelse_) | |
5
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
345 } else if is_instance(&ast, &for_type) { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
346 let target = ast.getattr(py, "target").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
347 let iter = ast.getattr(py, "iter").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
348 let body = ast.getattr(py, "body").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
349 let orelse = ast.getattr(py, "orelse").unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
350 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
351 let target = parse_expr(py, target); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
352 let iter = parse_expr(py, iter); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
353 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
354 let mut statements = vec!(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
355 for statement in body.iter(py).unwrap() { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
356 let statement = statement.unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
357 let statement = parse_statement(py, statement); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
358 statements.push(statement); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
359 } |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
360 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
361 let mut orelse_ = vec!(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
362 for statement in orelse.iter(py).unwrap() { |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
363 let statement = statement.unwrap(); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
364 let statement = parse_statement(py, statement); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
365 orelse_.push(statement); |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
366 } |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
367 |
ddf372373a77
Add ast.For, ast.UnaryOp, and Sub and Div to ast.BinOp.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
4
diff
changeset
|
368 Statement::For(target, iter, statements, orelse_) |
0 | 369 } else if is_instance(&ast, &assign_type) { |
370 let targets = ast.getattr(py, "targets").unwrap(); | |
371 let value = ast.getattr(py, "value").unwrap(); | |
372 | |
373 let mut arguments = vec!(); | |
374 for target in targets.iter(py).unwrap() { | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
375 let target = target.unwrap(); |
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
376 let target = parse_expr(py, target); |
0 | 377 arguments.push(target); |
378 } | |
379 | |
380 let value = parse_expr(py, value); | |
381 | |
382 Statement::Assign(arguments, value) | |
383 } else if is_instance(&ast, &import_from_type) { | |
384 let module = ast.getattr(py, "module").unwrap(); | |
385 let names = ast.getattr(py, "names").unwrap(); | |
386 //let level = ast.getattr(py, "level").unwrap(); | |
387 | |
1
b90e49ab734b
Factorise conversion of Python str into Rust String.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
388 let module = get_str(py, module); |
0 | 389 |
390 let mut names_ = vec!(); | |
391 for alias in names.iter(py).unwrap() { | |
392 let alias = alias.unwrap(); | |
393 let alias = parse_expr(py, alias); | |
394 names_.push(alias); | |
395 } | |
396 | |
397 Statement::ImportFrom(module, names_) | |
398 } else if is_instance(&ast, &return_type) { | |
399 let value = ast.getattr(py, "value").unwrap(); | |
400 let value = parse_expr(py, value); | |
401 Statement::Return(value) | |
402 } else if is_instance(&ast, &expr_type) { | |
403 let value = ast.getattr(py, "value").unwrap(); | |
404 let value = parse_expr(py, value); | |
405 Statement::Expr(value) | |
406 } else { | |
407 println!("Statement {}", ast); | |
408 Statement::Error | |
409 } | |
410 } | |
411 | |
412 #[allow(dead_code)] | |
413 pub fn convert_ast(name: String, module: &PyObject) -> Module { | |
414 let gil = Python::acquire_gil(); | |
415 let py = gil.python(); | |
416 | |
417 let builtins_module = py.import("builtins").unwrap(); | |
418 let isinstance = builtins_module.get(py, "isinstance").unwrap(); | |
419 | |
420 let ast_module = py.import("ast").unwrap(); | |
421 let module_type = ast_module.get(py, "Module").unwrap(); | |
422 | |
423 assert!(isinstance.call(py, (module, module_type), None).unwrap().is_true(py).unwrap()); | |
424 | |
425 let body = module.getattr(py, "body").unwrap(); | |
426 let mut statements = vec!(); | |
427 for statement in body.iter(py).unwrap() { | |
428 let statement = parse_statement(py, statement.unwrap()); | |
429 statements.push(statement) | |
430 } | |
431 Module{name: name, statements: statements} | |
432 } |