Skip to content

Commit 6293117

Browse files
committed
Initial attempt at ast builtin module
1 parent ba78000 commit 6293117

File tree

3 files changed

+81
-0
lines changed

3 files changed

+81
-0
lines changed

tests/snippets/ast_snippet.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
2+
import ast
3+
4+
source = """
5+
def foo():
6+
print('bar')
7+
"""
8+
n = ast.parse(source)
9+
print(n)

vm/src/stdlib/ast.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Ast standard module
3+
*
4+
* This module makes use of the parser logic, and translates all ast nodes
5+
* into python ast.AST objects.
6+
*/
7+
8+
extern crate rustpython_parser;
9+
10+
use self::rustpython_parser::{ast, parser};
11+
use super::super::obj::{objdict, objfloat, objint, objlist, objstr, objtuple, objtype};
12+
use super::super::objbool;
13+
use super::super::pyobject::{
14+
DictProtocol, PyContext, PyFuncArgs, PyObjectKind, PyObjectRef, PyResult, TypeProtocol,
15+
};
16+
use super::super::VirtualMachine;
17+
18+
fn program_to_ast(ctx: &PyContext, program: &ast::Program) -> PyObjectRef {
19+
let mut body = vec![];
20+
for statement in &program.statements {
21+
body.push(statement_to_ast(ctx, statement));
22+
}
23+
// TODO: create Module node and set attributes:
24+
let ast_node = ctx.new_list(body);
25+
ast_node
26+
}
27+
28+
fn statement_to_ast(ctx: &PyContext, statement: &ast::LocatedStatement) -> PyObjectRef {
29+
match &statement.node {
30+
ast::Statement::FunctionDef { name, args, body } => {
31+
// TODO: create ast.FunctionDef object and set attributes
32+
// let node = ctx.new_object();
33+
let mut py_body = vec![];
34+
py_body.push(ctx.new_str(format!("{:?}", name)));
35+
// node.set_attr("name", new_str(name));
36+
for statement in body {
37+
py_body.push(statement_to_ast(ctx, statement));
38+
}
39+
40+
ctx.new_list(py_body)
41+
},
42+
_ => {
43+
ctx.new_str(format!("{:?}", statement))
44+
}
45+
}
46+
47+
// TODO: set lineno on object
48+
}
49+
50+
fn ast_parse(vm: &mut VirtualMachine, args: PyFuncArgs) -> PyResult {
51+
arg_check!(vm, args, required = [(source, Some(vm.ctx.str_type()))]);
52+
53+
let source_string = objstr::get_value(source);
54+
let internal_ast = match parser::parse_program(&source_string) {
55+
Ok(ast) => ast,
56+
Err(msg) => {
57+
return Err(vm.new_value_error(msg));
58+
}
59+
};
60+
61+
// source.clone();
62+
let ast_node = program_to_ast(&vm.ctx, &internal_ast);
63+
Ok(ast_node)
64+
}
65+
66+
pub fn mk_module(ctx: &PyContext) -> PyObjectRef {
67+
let ast_mod = ctx.new_module(&"ast".to_string(), ctx.new_scope(None));
68+
ast_mod.set_item("parse", ctx.new_rustfunc(ast_parse));
69+
ast_mod
70+
}

vm/src/stdlib/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
mod ast;
12
mod json;
23
use std::collections::HashMap;
34

@@ -8,5 +9,6 @@ pub type StdlibInitFunc = fn(&PyContext) -> PyObjectRef;
89
pub fn get_module_inits() -> HashMap<String, StdlibInitFunc> {
910
let mut modules = HashMap::new();
1011
modules.insert("json".to_string(), json::mk_module as StdlibInitFunc);
12+
modules.insert("ast".to_string(), ast::mk_module as StdlibInitFunc);
1113
modules
1214
}

0 commit comments

Comments
 (0)