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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }