@@ -14,6 +14,22 @@ use super::super::pyobject::{
14
14
} ;
15
15
use super :: super :: VirtualMachine ;
16
16
17
+ /*
18
+ * Idea: maybe we can create a sort of struct with some helper functions?
19
+ struct AstToPyAst {
20
+ ctx: &PyContext,
21
+ }
22
+
23
+ impl AstToPyAst {
24
+ fn new(ctx: &PyContext) -> Self {
25
+ AstToPyAst {
26
+ ctx: ctx,
27
+ }
28
+ }
29
+
30
+ }
31
+ */
32
+
17
33
fn program_to_ast ( ctx : & PyContext , program : & ast:: Program ) -> PyObjectRef {
18
34
let mut body = vec ! [ ] ;
19
35
for statement in & program. statements {
@@ -27,33 +43,166 @@ fn program_to_ast(ctx: &PyContext, program: &ast::Program) -> PyObjectRef {
27
43
ast_node
28
44
}
29
45
46
+ // Create a node class instance
47
+ fn create_node ( ctx : & PyContext , name : & str ) -> PyObjectRef {
48
+ // TODO: instantiate a class of type given by name
49
+ // TODO: lookup in the current module?
50
+ let node = ctx. new_object ( ) ;
51
+ node
52
+ }
53
+
54
+ fn statements_to_ast ( ctx : & PyContext , statements : & Vec < ast:: LocatedStatement > ) -> PyObjectRef {
55
+ let mut py_statements = vec ! [ ] ;
56
+ for statement in statements {
57
+ py_statements. push ( statement_to_ast ( ctx, statement) ) ;
58
+ }
59
+ ctx. new_list ( py_statements)
60
+ }
61
+
30
62
fn statement_to_ast ( ctx : & PyContext , statement : & ast:: LocatedStatement ) -> PyObjectRef {
31
63
let node = match & statement. node {
64
+ ast:: Statement :: ClassDef {
65
+ name,
66
+ body,
67
+ args : _,
68
+ } => {
69
+ let node = create_node ( ctx, "ClassDef" ) ;
70
+
71
+ // Set name:
72
+ node. set_attr ( "name" , ctx. new_str ( name. to_string ( ) ) ) ;
73
+
74
+ // Set body:
75
+ let py_body = statements_to_ast ( ctx, body) ;
76
+ node. set_attr ( "body" , py_body) ;
77
+ node
78
+ }
32
79
ast:: Statement :: FunctionDef {
33
80
name,
34
81
args : _,
35
82
body,
36
83
} => {
37
- // TODO: create ast.FunctionDef object:
38
- let node = ctx. new_object ( ) ;
84
+ let node = create_node ( ctx, "FunctionDef" ) ;
39
85
40
86
// Set name:
41
87
node. set_attr ( "name" , ctx. new_str ( name. to_string ( ) ) ) ;
42
88
43
89
// Set body:
44
- let mut py_body = vec ! [ ] ;
45
- for statement in body {
46
- py_body. push ( statement_to_ast ( ctx, statement) ) ;
47
- }
90
+ let py_body = statements_to_ast ( ctx, body) ;
91
+ node. set_attr ( "body" , py_body) ;
92
+ node
93
+ }
94
+ ast:: Statement :: Continue => {
95
+ let node = create_node ( ctx, "Continue" ) ;
96
+ node
97
+ }
98
+ ast:: Statement :: Break => {
99
+ let node = create_node ( ctx, "Break" ) ;
100
+ node
101
+ }
102
+ ast:: Statement :: Pass => {
103
+ let node = create_node ( ctx, "Pass" ) ;
104
+ node
105
+ }
106
+ ast:: Statement :: Delete { targets } => {
107
+ let node = create_node ( ctx, "Delete" ) ;
108
+
109
+ let py_targets = ctx. new_tuple (
110
+ targets
111
+ . into_iter ( )
112
+ . map ( |v| expression_to_ast ( ctx, v) )
113
+ . collect ( ) ,
114
+ ) ;
115
+ node. set_attr ( "targets" , py_targets) ;
116
+
117
+ node
118
+ }
119
+ ast:: Statement :: Return { value } => {
120
+ let node = create_node ( ctx, "Return" ) ;
121
+
122
+ let py_value = if let Some ( value) = value {
123
+ ctx. new_tuple (
124
+ value
125
+ . into_iter ( )
126
+ . map ( |v| expression_to_ast ( ctx, v) )
127
+ . collect ( ) ,
128
+ )
129
+ } else {
130
+ ctx. none ( )
131
+ } ;
132
+ node. set_attr ( "value" , py_value) ;
133
+
134
+ node
135
+ }
136
+ ast:: Statement :: If { test, body, orelse } => {
137
+ let node = create_node ( ctx, "If" ) ;
138
+
139
+ let py_test = expression_to_ast ( ctx, test) ;
140
+ node. set_attr ( "test" , py_test) ;
141
+
142
+ let py_body = statements_to_ast ( ctx, body) ;
143
+ node. set_attr ( "body" , py_body) ;
144
+
145
+ let py_orelse = if let Some ( orelse) = orelse {
146
+ statements_to_ast ( ctx, orelse)
147
+ } else {
148
+ ctx. none ( )
149
+ } ;
150
+ node. set_attr ( "orelse" , py_orelse) ;
151
+
152
+ node
153
+ }
154
+ ast:: Statement :: For {
155
+ target,
156
+ iter,
157
+ body,
158
+ orelse,
159
+ } => {
160
+ let node = create_node ( ctx, "For" ) ;
161
+
162
+ /*
163
+ let py_target = expression_to_ast(ctx, target);
164
+ node.set_attr("target", py_target);
165
+
166
+ let py_iter = expression_to_ast(ctx, iter);
167
+ node.set_attr("iter", py_iter);
168
+ */
169
+
170
+ let py_body = statements_to_ast ( ctx, body) ;
171
+ node. set_attr ( "body" , py_body) ;
172
+
173
+ let py_orelse = if let Some ( orelse) = orelse {
174
+ statements_to_ast ( ctx, orelse)
175
+ } else {
176
+ ctx. none ( )
177
+ } ;
178
+ node. set_attr ( "orelse" , py_orelse) ;
179
+
180
+ node
181
+ }
182
+ ast:: Statement :: While { test, body, orelse } => {
183
+ let node = create_node ( ctx, "While" ) ;
184
+
185
+ let py_test = expression_to_ast ( ctx, test) ;
186
+ node. set_attr ( "test" , py_test) ;
187
+
188
+ let py_body = statements_to_ast ( ctx, body) ;
189
+ node. set_attr ( "body" , py_body) ;
190
+
191
+ let py_orelse = if let Some ( orelse) = orelse {
192
+ statements_to_ast ( ctx, orelse)
193
+ } else {
194
+ ctx. none ( )
195
+ } ;
196
+ node. set_attr ( "orelse" , py_orelse) ;
48
197
49
- node. set_attr ( "body" , ctx. new_list ( py_body) ) ;
50
198
node
51
199
}
52
200
ast:: Statement :: Expression { expression } => {
201
+ let node = create_node ( ctx, "Expr" ) ;
202
+
53
203
let value = expression_to_ast ( ctx, expression) ;
54
- // TODO: create proper class:
55
- let node = ctx. new_object ( ) ;
56
204
node. set_attr ( "value" , value) ;
205
+
57
206
node
58
207
}
59
208
x => {
@@ -71,8 +220,7 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
71
220
fn expression_to_ast ( ctx : & PyContext , expression : & ast:: Expression ) -> PyObjectRef {
72
221
let node = match & expression {
73
222
ast:: Expression :: Call { function, args } => {
74
- // TODO: create ast.Call instance
75
- let node = ctx. new_object ( ) ;
223
+ let node = create_node ( ctx, "Call" ) ;
76
224
77
225
let py_func_ast = expression_to_ast ( ctx, function) ;
78
226
node. set_attr ( "func" , py_func_ast) ;
@@ -86,15 +234,45 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
86
234
87
235
node
88
236
}
237
+ ast:: Expression :: Binop { a, op, b } => {
238
+ let node = create_node ( ctx, "BinOp" ) ;
239
+
240
+ let py_a = expression_to_ast ( ctx, a) ;
241
+ node. set_attr ( "left" , py_a) ;
242
+
243
+ // Operator:
244
+ let str_op = match op {
245
+ ast:: Operator :: Add => "Add" ,
246
+ ast:: Operator :: Sub => "Sub" ,
247
+ ast:: Operator :: Mult => "Mult" ,
248
+ ast:: Operator :: MatMult => "MatMult" ,
249
+ ast:: Operator :: Div => "Div" ,
250
+ ast:: Operator :: Mod => "Mod" ,
251
+ ast:: Operator :: Pow => "Pow" ,
252
+ ast:: Operator :: LShift => "LShift" ,
253
+ ast:: Operator :: RShift => "RShift" ,
254
+ ast:: Operator :: BitOr => "BitOr" ,
255
+ ast:: Operator :: BitXor => "BitXor" ,
256
+ ast:: Operator :: BitAnd => "BitAnd" ,
257
+ ast:: Operator :: FloorDiv => "FloorDiv" ,
258
+ } ;
259
+ let py_op = ctx. new_str ( str_op. to_string ( ) ) ;
260
+ node. set_attr ( "op" , py_op) ;
261
+
262
+ let py_b = expression_to_ast ( ctx, b) ;
263
+ node. set_attr ( "right" , py_b) ;
264
+ node
265
+ }
89
266
ast:: Expression :: Identifier { name } => {
90
- // TODO: create ast.Identifier instance
91
- let node = ctx. new_object ( ) ;
267
+ let node = create_node ( ctx, "Identifier" ) ;
268
+
269
+ // Id:
92
270
let py_name = ctx. new_str ( name. clone ( ) ) ;
93
271
node. set_attr ( "id" , py_name) ;
94
272
node
95
273
}
96
274
ast:: Expression :: String { value } => {
97
- let node = ctx . new_object ( ) ;
275
+ let node = create_node ( ctx , "Str" ) ;
98
276
node. set_attr ( "s" , ctx. new_str ( value. clone ( ) ) ) ;
99
277
node
100
278
}
@@ -103,7 +281,10 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
103
281
}
104
282
} ;
105
283
106
- // TODO: set lineno on object
284
+ // TODO: retrieve correct lineno:
285
+ let lineno = ctx. new_int ( 1 ) ;
286
+ node. set_attr ( "lineno" , lineno) ;
287
+
107
288
node
108
289
}
109
290
@@ -130,6 +311,7 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
130
311
"Module" ,
131
312
ctx. new_class ( & "_ast.Module" . to_string ( ) , ctx. object ( ) ) ,
132
313
) ;
314
+
133
315
// TODO: maybe we can use some clever macro to generate this?
134
316
ast_mod. set_item (
135
317
"FunctionDef" ,
0 commit comments