Mercurial > python-compiler.rs
comparison src/python_dump.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 extern crate cpython; | |
2 | |
3 use std::iter; | |
4 | |
5 use cpython::{Python, PyObject}; | |
6 use cpython::ObjectProtocol; //for call method | |
7 | |
8 fn dump(py: Python, indent: usize, ast: PyObject) -> String { | |
9 let builtins_module = py.import("builtins").unwrap(); | |
10 let isinstance = builtins_module.get(py, "isinstance").unwrap(); | |
11 | |
12 let is_instance = |object: &PyObject, type_: &PyObject| { | |
13 return isinstance.call(py, (object, type_), None).unwrap().is_true(py).unwrap(); | |
14 }; | |
15 | |
16 let ast_module = py.import("ast").unwrap(); | |
17 let ast_type = ast_module.get(py, "AST").unwrap(); | |
18 let function_def_type = ast_module.get(py, "FunctionDef").unwrap(); | |
19 let arguments_type = ast_module.get(py, "arguments").unwrap(); | |
20 let arg_type = ast_module.get(py, "arg").unwrap(); | |
21 let assign_type = ast_module.get(py, "Assign").unwrap(); | |
22 let return_type = ast_module.get(py, "Return").unwrap(); | |
23 let bin_op_type = ast_module.get(py, "BinOp").unwrap(); | |
24 let name_constant_type = ast_module.get(py, "NameConstant").unwrap(); | |
25 let name_type = ast_module.get(py, "Name").unwrap(); | |
26 let num_type = ast_module.get(py, "Num").unwrap(); | |
27 let str_type = ast_module.get(py, "Str").unwrap(); | |
28 let add_type = ast_module.get(py, "Add").unwrap(); | |
29 let mult_type = ast_module.get(py, "Mult").unwrap(); | |
30 let eq_type = ast_module.get(py, "Eq").unwrap(); | |
31 let lt_type = ast_module.get(py, "Lt").unwrap(); | |
32 let if_type = ast_module.get(py, "If").unwrap(); | |
33 let compare_type = ast_module.get(py, "Compare").unwrap(); | |
34 let expr_type = ast_module.get(py, "Expr").unwrap(); | |
35 let call_type = ast_module.get(py, "Call").unwrap(); | |
36 let import_from_type = ast_module.get(py, "ImportFrom").unwrap(); | |
37 let alias_type = ast_module.get(py, "alias").unwrap(); | |
38 | |
39 assert!(is_instance(&ast, &ast_type)); | |
40 | |
41 /* | |
42 // TODO: implement Hash for PyObject. (trivial) | |
43 let map = { | |
44 let fields = ast.getattr(py, "_fields").unwrap(); | |
45 let mut map = HashMap::new(); | |
46 for field in fields.iter(py).unwrap() { | |
47 let field = field.unwrap(); | |
48 let value = ast.getattr(py, field).unwrap(); | |
49 map.insert(field, value); | |
50 } | |
51 map | |
52 }; | |
53 */ | |
54 | |
55 if is_instance(&ast, &function_def_type) { | |
56 let name = ast.getattr(py, "name").unwrap(); | |
57 let args = ast.getattr(py, "args").unwrap(); | |
58 let body = ast.getattr(py, "body").unwrap(); | |
59 let args = dump(py, indent, args); | |
60 let declaration = format!("def {}({}):", name, args); | |
61 let mut statements = vec!("".to_string()); | |
62 for statement in body.iter(py).unwrap() { | |
63 let statement = dump(py, indent + 1, statement.unwrap()); | |
64 statements.push(statement); | |
65 } | |
66 let indent: String = iter::repeat(" ").take(indent + 1).collect(); | |
67 let indent = format!("\n{}", indent); | |
68 let indent = indent.as_str(); | |
69 let body = statements.join(indent); | |
70 format!("{}{}", declaration, body) | |
71 } else if is_instance(&ast, &if_type) { | |
72 let test = ast.getattr(py, "test").unwrap(); | |
73 let body = ast.getattr(py, "body").unwrap(); | |
74 | |
75 let test = dump(py, indent, test); | |
76 | |
77 let declaration = format!("if {}:", test); | |
78 let mut statements = vec!("".to_string()); | |
79 for statement in body.iter(py).unwrap() { | |
80 let statement = dump(py, indent + 1, statement.unwrap()); | |
81 statements.push(statement); | |
82 } | |
83 let indent: String = iter::repeat(" ").take(indent + 1).collect(); | |
84 let indent = format!("\n{}", indent); | |
85 let indent = indent.as_str(); | |
86 let body = statements.join(indent); | |
87 format!("{}{}", declaration, body) | |
88 } else if is_instance(&ast, &arguments_type) { | |
89 let args_list = ast.getattr(py, "args").unwrap(); | |
90 let mut arguments = vec!(); | |
91 for arg in args_list.iter(py).unwrap() { | |
92 let arg = arg.unwrap(); | |
93 arguments.push(dump(py, indent, arg)); | |
94 } | |
95 format!("{}", arguments.join(", ")) | |
96 } else if is_instance(&ast, &arg_type) { | |
97 let arg = ast.getattr(py, "arg").unwrap(); | |
98 format!("{}", arg) | |
99 } else if is_instance(&ast, &compare_type) { | |
100 let left = ast.getattr(py, "left").unwrap(); | |
101 let ops = ast.getattr(py, "ops").unwrap(); | |
102 let comparators = ast.getattr(py, "comparators").unwrap(); | |
103 | |
104 let left = dump(py, indent, left); | |
105 let ops = ops.iter(py).unwrap(); | |
106 let comparators = comparators.iter(py).unwrap(); | |
107 | |
108 let mut comparisons = vec!(); | |
109 for (op, comparator) in ops.zip(comparators) { | |
110 let op = op.unwrap(); | |
111 let comparator = comparator.unwrap(); | |
112 | |
113 let op = dump(py, indent, op); | |
114 let comparator = dump(py, indent, comparator); | |
115 | |
116 comparisons.push(format!("{} {}", op, comparator)); | |
117 } | |
118 format!("{} {}", left, comparisons.join(" ")) | |
119 } else if is_instance(&ast, &assign_type) { | |
120 let targets = ast.getattr(py, "targets").unwrap(); | |
121 let value = ast.getattr(py, "value").unwrap(); | |
122 let mut cibles = vec!(); | |
123 for target in targets.iter(py).unwrap() { | |
124 let target = target.unwrap(); | |
125 let target = dump(py, indent, target); | |
126 cibles.push(target.to_string()); | |
127 } | |
128 let value = dump(py, indent, value); | |
129 format!("{} = {}", cibles.join(", "), value) | |
130 } else if is_instance(&ast, &return_type) { | |
131 let value = ast.getattr(py, "value").unwrap(); | |
132 let value = dump(py, indent, value); | |
133 format!("return {}", value) | |
134 } else if is_instance(&ast, &bin_op_type) { | |
135 let left = ast.getattr(py, "left").unwrap(); | |
136 let op = ast.getattr(py, "op").unwrap(); | |
137 let right = ast.getattr(py, "right").unwrap(); | |
138 | |
139 let left = dump(py, indent, left); | |
140 let op = dump(py, indent, op); | |
141 let right = dump(py, indent, right); | |
142 | |
143 format!("{} {} {}", left, op, right) | |
144 } else if is_instance(&ast, &name_type) { | |
145 let id = ast.getattr(py, "id").unwrap(); | |
146 format!("{}", id) | |
147 } else if is_instance(&ast, &name_constant_type) { | |
148 let value = ast.getattr(py, "value").unwrap(); | |
149 format!("{}", value) | |
150 } else if is_instance(&ast, &expr_type) { | |
151 let value = ast.getattr(py, "value").unwrap(); | |
152 let value = dump(py, indent, value); | |
153 format!("{}", value) | |
154 } else if is_instance(&ast, &call_type) { | |
155 let func = ast.getattr(py, "func").unwrap(); | |
156 let args = ast.getattr(py, "args").unwrap(); | |
157 //let keywords = ast.getattr(py, "keywords").unwrap(); | |
158 | |
159 let func = dump(py, indent, func); | |
160 | |
161 let mut arguments = vec!(); | |
162 for arg in args.iter(py).unwrap() { | |
163 let arg = arg.unwrap(); | |
164 arguments.push(dump(py, indent, arg)); | |
165 } | |
166 | |
167 format!("{}({})", func, arguments.join(", ")) | |
168 } else if is_instance(&ast, &import_from_type) { | |
169 let module = ast.getattr(py, "module").unwrap(); | |
170 let names = ast.getattr(py, "names").unwrap(); | |
171 //let level = ast.getattr(py, "level").unwrap(); | |
172 | |
173 let mut arguments = vec!(); | |
174 for name in names.iter(py).unwrap() { | |
175 let name = name.unwrap(); | |
176 arguments.push(dump(py, indent, name)); | |
177 } | |
178 | |
179 format!("from {} import {}", module, arguments.join(", ")) | |
180 } else if is_instance(&ast, &alias_type) { | |
181 let name = ast.getattr(py, "name").unwrap(); | |
182 let asname = ast.getattr(py, "asname").unwrap(); | |
183 | |
184 let name = { | |
185 let name = name.str(py).unwrap(); | |
186 let mut name = name.to_string(py).unwrap(); | |
187 name.to_mut().to_string() | |
188 }; | |
189 | |
190 let asname = { | |
191 let asname = asname.str(py).unwrap(); | |
192 let mut asname = asname.to_string(py).unwrap(); | |
193 asname.to_mut().to_string() | |
194 }; | |
195 | |
196 if asname == "None" { | |
197 format!("{}", name) | |
198 } else { | |
199 format!("{} as {}", name, asname) | |
200 } | |
201 } else if is_instance(&ast, &num_type) { | |
202 let n = ast.getattr(py, "n").unwrap(); | |
203 format!("{}", n) | |
204 } else if is_instance(&ast, &str_type) { | |
205 let s = ast.getattr(py, "s").unwrap(); | |
206 format!("\"{}\"", s) | |
207 } else if is_instance(&ast, &add_type) { | |
208 format!("+") | |
209 } else if is_instance(&ast, &mult_type) { | |
210 format!("*") | |
211 } else if is_instance(&ast, &eq_type) { | |
212 format!("==") | |
213 } else if is_instance(&ast, <_type) { | |
214 format!("<") | |
215 } else { | |
216 format!("unknown {}", ast) | |
217 } | |
218 } | |
219 | |
220 #[allow(dead_code)] | |
221 pub fn dump_module(module: &PyObject) { | |
222 let gil = Python::acquire_gil(); | |
223 let py = gil.python(); | |
224 | |
225 let builtins_module = py.import("builtins").unwrap(); | |
226 let isinstance = builtins_module.get(py, "isinstance").unwrap(); | |
227 | |
228 let ast_module = py.import("ast").unwrap(); | |
229 let module_type = ast_module.get(py, "Module").unwrap(); | |
230 | |
231 assert!(isinstance.call(py, (module, module_type), None).unwrap().is_true(py).unwrap()); | |
232 | |
233 let body = module.getattr(py, "body").unwrap(); | |
234 for statement in body.iter(py).unwrap() { | |
235 println!("{}", dump(py, 0, statement.unwrap())); | |
236 } | |
237 } |