Skip to content

Commit 51885f2

Browse files
committed
Added more ast to pyast transformations
1 parent f914b48 commit 51885f2

File tree

1 file changed

+197
-15
lines changed

1 file changed

+197
-15
lines changed

vm/src/stdlib/ast.rs

Lines changed: 197 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ use super::super::pyobject::{
1414
};
1515
use super::super::VirtualMachine;
1616

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+
1733
fn program_to_ast(ctx: &PyContext, program: &ast::Program) -> PyObjectRef {
1834
let mut body = vec![];
1935
for statement in &program.statements {
@@ -27,33 +43,166 @@ fn program_to_ast(ctx: &PyContext, program: &ast::Program) -> PyObjectRef {
2743
ast_node
2844
}
2945

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+
3062
fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObjectRef {
3163
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+
}
3279
ast::Statement::FunctionDef {
3380
name,
3481
args: _,
3582
body,
3683
} => {
37-
// TODO: create ast.FunctionDef object:
38-
let node = ctx.new_object();
84+
let node = create_node(ctx, "FunctionDef");
3985

4086
// Set name:
4187
node.set_attr("name", ctx.new_str(name.to_string()));
4288

4389
// 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);
48197

49-
node.set_attr("body", ctx.new_list(py_body));
50198
node
51199
}
52200
ast::Statement::Expression { expression } => {
201+
let node = create_node(ctx, "Expr");
202+
53203
let value = expression_to_ast(ctx, expression);
54-
// TODO: create proper class:
55-
let node = ctx.new_object();
56204
node.set_attr("value", value);
205+
57206
node
58207
}
59208
x => {
@@ -71,8 +220,7 @@ fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObj
71220
fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectRef {
72221
let node = match &expression {
73222
ast::Expression::Call { function, args } => {
74-
// TODO: create ast.Call instance
75-
let node = ctx.new_object();
223+
let node = create_node(ctx, "Call");
76224

77225
let py_func_ast = expression_to_ast(ctx, function);
78226
node.set_attr("func", py_func_ast);
@@ -86,15 +234,45 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
86234

87235
node
88236
}
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+
}
89266
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:
92270
let py_name = ctx.new_str(name.clone());
93271
node.set_attr("id", py_name);
94272
node
95273
}
96274
ast::Expression::String { value } => {
97-
let node = ctx.new_object();
275+
let node = create_node(ctx, "Str");
98276
node.set_attr("s", ctx.new_str(value.clone()));
99277
node
100278
}
@@ -103,7 +281,10 @@ fn expression_to_ast(ctx: &PyContext, expression: &ast::Expression) -> PyObjectR
103281
}
104282
};
105283

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+
107288
node
108289
}
109290

@@ -130,6 +311,7 @@ pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
130311
"Module",
131312
ctx.new_class(&"_ast.Module".to_string(), ctx.object()),
132313
);
314+
133315
// TODO: maybe we can use some clever macro to generate this?
134316
ast_mod.set_item(
135317
"FunctionDef",

0 commit comments

Comments
 (0)