Mercurial > python-compiler.rs
annotate src/ast_scope.rs @ 12:0e96c5bc401d
Remove the need for a Box in BlockStatement.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 02 Jun 2016 03:14:01 +0100 |
parents | 5c169d5807b5 |
children | 38b0d63697b1 |
rev | line source |
---|---|
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
1 use python_ast::{Module, Statement, Expr}; |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
2 |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
3 use std::collections::HashMap; |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
4 |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
5 #[derive(Debug)] |
12
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
6 struct BlockStatement { |
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
7 statement: Statement, |
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
8 block: Option<Block> |
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
9 } |
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
10 |
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
11 #[derive(Debug)] |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
12 struct Block { |
12
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
13 statements: Vec<BlockStatement>, |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
14 bindings: Vec<String> |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
15 } |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
16 |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
17 #[derive(Debug)] |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
18 pub struct Scoping { |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
19 modules: HashMap<String, Block> |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
20 } |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
21 |
10
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
22 fn scope_expr(expr: Expr, block: &mut Block) { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
23 println!("{:?}", expr); |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
24 } |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
25 |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
26 fn scope_statement(statement: Statement, block: &mut Block) { |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
27 let new_block = match statement.clone() { |
10
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
28 Statement::Assign(targets, value) => { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
29 //scope_expr(value, &mut block); |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
30 for target in targets { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
31 match target { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
32 Expr::Name(name) => block.bindings.push(name), |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
33 _ => () // No new binding. |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
34 } |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
35 } |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
36 None |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
37 }, |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
38 Statement::FunctionDef(name, args, statements) => { |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
39 block.bindings.push(name.clone()); |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
40 let mut function_block = Block{statements: vec!(), bindings: args.clone()}; |
10
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
41 for statement in statements { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
42 scope_statement(statement, &mut function_block); |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
43 } |
12
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
44 Some(function_block) |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
45 }, |
10
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
46 Statement::ImportFrom(module, names) => { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
47 for name in names { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
48 let name = match name { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
49 Expr::Alias(name, asname) => (name, asname), |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
50 _ => panic!() |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
51 }; |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
52 let nameas = name.1; |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
53 let name = name.0; |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
54 match nameas { |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
55 Some(name) => block.bindings.push(name), |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
56 None => block.bindings.push(name) |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
57 } |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
58 } |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
59 None |
3bf4903d1d2c
Add Assign and ImportFrom bindings.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
9
diff
changeset
|
60 }, |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
61 _ => None |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
62 }; |
12
0e96c5bc401d
Remove the need for a Box in BlockStatement.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
11
diff
changeset
|
63 block.statements.push(BlockStatement{statement: statement, block: new_block}); |
9
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
64 } |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
65 |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
66 #[allow(dead_code)] |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
67 pub fn scope_ast(modules: Vec<Module>) -> Scoping { |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
68 let mut scoping = Scoping{modules: HashMap::new()}; |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
69 for module in modules { |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
70 let mut block = Block{statements: vec!(), bindings: vec!()}; |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
71 for statement in module.statements { |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
72 scope_statement(statement, &mut block); |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
73 } |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
74 scoping.modules.insert(module.name, block); |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
75 } |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
76 scoping |
fa7e285f88e7
Add a scoping pass, associating each module/statement with a block.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff
changeset
|
77 } |