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