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
+}