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