Mercurial > python-compiler.rs
diff src/ast_scope.rs @ 9:fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Wed, 01 Jun 2016 22:17:28 +0100 |
parents | |
children | 3bf4903d1d2c |
line wrap: on
line diff
new file mode 100644 --- /dev/null +++ b/src/ast_scope.rs @@ -0,0 +1,127 @@ +use python_ast::{Module, Statement, Expr}; + +use std::collections::HashMap; + +/* +trait Visitor<T> { + fn visit(&mut self, modules: Vec<Module>) -> Vec<T>; + fn visit_module(&mut self, block: &mut Block, module: Module) -> T; + fn visit_statement(&mut self, block: &mut Block, statement: Statement) -> Option<Box<T>>; + fn visit_expr(&mut self, block: &mut Block, expr: Expr) -> (); +} +*/ + +#[derive(Debug)] +struct Block { + statements: Vec<(Statement, Option<Box<Block>>)>, + bindings: Vec<String> +} + +#[derive(Debug)] +pub struct Scoping { + modules: HashMap<String, Block> +} + +/* +impl Visitor<Block> for Scoping { + fn visit(&mut self, modules: Vec<Module>) -> Vec<Block> { + println!("Scoping all modules."); + let mut blocks = vec!(); + for module in modules { + let mut block = Block{statements: vec!(), bindings: vec!()}; + let block = self.visit_module(&mut block, module); + blocks.push(block); + } + blocks + } + + fn visit_module(&mut self, block: &mut Block, module: Module) -> Block { + println!("Scoping module {}.", module.name); + for statement in module.statements { + self.visit_statement(block, statement); + } + println!("Module block: {:?}", block); + } + + fn visit_statement(&mut self, block: &mut Block, statement: Statement) -> Option<Box<Block>> { + match statement { + //Statement::ClassDef(a, b, c) => println!("{:?} {:?} {:?}", a, b, c), + Statement::FunctionDef(name, args, statements) => { + block.bindings.push(name.clone()); + //block.statements.insert(module.name, block); + println!("{:?} {:?}", name, args); + let mut function_block = Block{statements: vec!(), bindings: vec!()}; + for statement in statements { + let option = self.visit_statement(block, statement); + function_block.statements.push((statement, option)); + } + Some(Box::new(function_block)) + }, + Statement::For(target, iter, statements, orelse) => { + println!("for"); + for statement in statements { + let option = self.visit_statement(block, statement); + } + block.statements.push(name.clone()); + Some(Box::new()) + }, + Statement::Assign(lhs, rhs) => { + for target in lhs.clone() { + match target.clone() { + Expr::Name(name) => block.bindings.push(name), + _ => panic!() + } + self.visit_expr(block, target); + } + println!("assign {:?} {:?}", lhs, rhs); + Some() + }, + _ => { + println!("something"); + None + } + } + } + + fn visit_expr(&mut self, block: &mut Block, expr: Expr) -> () { + } +} +*/ + +/* +#[allow(dead_code)] +pub fn scope_ast(ast: Module) -> Scoping { + let mut modules = HashMap::new(); + let mut scoping = Scoping{modules: modules}; + scoping.visit(vec!(ast)); + scoping +} +*/ + +fn scope_statement(statement: Statement, block: &mut Block) { + let new_block = match statement.clone() { + Statement::FunctionDef(name, args, statements) => { + block.bindings.push(name.clone()); + let mut function_block = Block{statements: vec!(), bindings: args.clone()}; + for other_statement in statements { + scope_statement(other_statement, &mut function_block); + } + Some(Box::new(function_block)) + }, + _ => None + }; + block.statements.push((statement, new_block)); +} + +#[allow(dead_code)] +pub fn scope_ast(modules: Vec<Module>) -> Scoping { + let mut scoping = Scoping{modules: HashMap::new()}; + for module in modules { + let mut block = Block{statements: vec!(), bindings: vec!()}; + for statement in module.statements { + scope_statement(statement, &mut block); + } + scoping.modules.insert(module.name, block); + } + scoping +}