Mercurial > python-compiler.rs
comparison 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 |
comparison
equal
deleted
inserted
replaced
8:94ff501bf336 | 9:fa7e285f88e7 |
---|---|
1 use python_ast::{Module, Statement, Expr}; | |
2 | |
3 use std::collections::HashMap; | |
4 | |
5 /* | |
6 trait Visitor<T> { | |
7 fn visit(&mut self, modules: Vec<Module>) -> Vec<T>; | |
8 fn visit_module(&mut self, block: &mut Block, module: Module) -> T; | |
9 fn visit_statement(&mut self, block: &mut Block, statement: Statement) -> Option<Box<T>>; | |
10 fn visit_expr(&mut self, block: &mut Block, expr: Expr) -> (); | |
11 } | |
12 */ | |
13 | |
14 #[derive(Debug)] | |
15 struct Block { | |
16 statements: Vec<(Statement, Option<Box<Block>>)>, | |
17 bindings: Vec<String> | |
18 } | |
19 | |
20 #[derive(Debug)] | |
21 pub struct Scoping { | |
22 modules: HashMap<String, Block> | |
23 } | |
24 | |
25 /* | |
26 impl Visitor<Block> for Scoping { | |
27 fn visit(&mut self, modules: Vec<Module>) -> Vec<Block> { | |
28 println!("Scoping all modules."); | |
29 let mut blocks = vec!(); | |
30 for module in modules { | |
31 let mut block = Block{statements: vec!(), bindings: vec!()}; | |
32 let block = self.visit_module(&mut block, module); | |
33 blocks.push(block); | |
34 } | |
35 blocks | |
36 } | |
37 | |
38 fn visit_module(&mut self, block: &mut Block, module: Module) -> Block { | |
39 println!("Scoping module {}.", module.name); | |
40 for statement in module.statements { | |
41 self.visit_statement(block, statement); | |
42 } | |
43 println!("Module block: {:?}", block); | |
44 } | |
45 | |
46 fn visit_statement(&mut self, block: &mut Block, statement: Statement) -> Option<Box<Block>> { | |
47 match statement { | |
48 //Statement::ClassDef(a, b, c) => println!("{:?} {:?} {:?}", a, b, c), | |
49 Statement::FunctionDef(name, args, statements) => { | |
50 block.bindings.push(name.clone()); | |
51 //block.statements.insert(module.name, block); | |
52 println!("{:?} {:?}", name, args); | |
53 let mut function_block = Block{statements: vec!(), bindings: vec!()}; | |
54 for statement in statements { | |
55 let option = self.visit_statement(block, statement); | |
56 function_block.statements.push((statement, option)); | |
57 } | |
58 Some(Box::new(function_block)) | |
59 }, | |
60 Statement::For(target, iter, statements, orelse) => { | |
61 println!("for"); | |
62 for statement in statements { | |
63 let option = self.visit_statement(block, statement); | |
64 } | |
65 block.statements.push(name.clone()); | |
66 Some(Box::new()) | |
67 }, | |
68 Statement::Assign(lhs, rhs) => { | |
69 for target in lhs.clone() { | |
70 match target.clone() { | |
71 Expr::Name(name) => block.bindings.push(name), | |
72 _ => panic!() | |
73 } | |
74 self.visit_expr(block, target); | |
75 } | |
76 println!("assign {:?} {:?}", lhs, rhs); | |
77 Some() | |
78 }, | |
79 _ => { | |
80 println!("something"); | |
81 None | |
82 } | |
83 } | |
84 } | |
85 | |
86 fn visit_expr(&mut self, block: &mut Block, expr: Expr) -> () { | |
87 } | |
88 } | |
89 */ | |
90 | |
91 /* | |
92 #[allow(dead_code)] | |
93 pub fn scope_ast(ast: Module) -> Scoping { | |
94 let mut modules = HashMap::new(); | |
95 let mut scoping = Scoping{modules: modules}; | |
96 scoping.visit(vec!(ast)); | |
97 scoping | |
98 } | |
99 */ | |
100 | |
101 fn scope_statement(statement: Statement, block: &mut Block) { | |
102 let new_block = match statement.clone() { | |
103 Statement::FunctionDef(name, args, statements) => { | |
104 block.bindings.push(name.clone()); | |
105 let mut function_block = Block{statements: vec!(), bindings: args.clone()}; | |
106 for other_statement in statements { | |
107 scope_statement(other_statement, &mut function_block); | |
108 } | |
109 Some(Box::new(function_block)) | |
110 }, | |
111 _ => None | |
112 }; | |
113 block.statements.push((statement, new_block)); | |
114 } | |
115 | |
116 #[allow(dead_code)] | |
117 pub fn scope_ast(modules: Vec<Module>) -> Scoping { | |
118 let mut scoping = Scoping{modules: HashMap::new()}; | |
119 for module in modules { | |
120 let mut block = Block{statements: vec!(), bindings: vec!()}; | |
121 for statement in module.statements { | |
122 scope_statement(statement, &mut block); | |
123 } | |
124 scoping.modules.insert(module.name, block); | |
125 } | |
126 scoping | |
127 } |