view src/ast_scope.rs @ 68:c59ad5ccd8a6

Add ast.Try
author Bastien Orivel <eijebong@bananium.fr>
date Mon, 13 Jun 2016 03:03:13 +0200
parents 38b0d63697b1
children
line wrap: on
line source

use python_ast::{Module, stmt, expr, alias};

use std::collections::HashMap;

#[derive(Debug)]
struct BlockStatement {
    statement: stmt,
    block: Option<Block>
}

#[derive(Debug)]
struct Block {
    statements: Vec<BlockStatement>,
    bindings: Vec<String>
}

#[derive(Debug)]
pub struct Scoping {
    modules: HashMap<String, Block>
}

fn scope_expr(expr: expr, block: &mut Block) {
    println!("{:?}", expr);
}

fn scope_statement(statement: stmt, block: &mut Block) {
    let new_block = match statement.clone() {
        stmt::Assign(targets, value) => {
            //scope_expr(value, &mut block);
            for target in targets {
                match target {
                    expr::Name(name, ctx) => block.bindings.push(name),
                    _ => ()  // No new binding.
                }
            }
            None
        },
        stmt::FunctionDef(name, args, statements) => {
            block.bindings.push(name.clone());
            let mut function_block = Block{statements: vec!(), bindings: vec!()};
            for statement in statements {
                scope_statement(statement, &mut function_block);
            }
            Some(function_block)
        },
        stmt::ImportFrom(module, names, level) => {
            /*
            for alias in names {
                let asname = alias.asname;
                let name = alias.name;
                match asname {
                    Some(name) => block.bindings.push(name),
                    None => block.bindings.push(name)
                }
            }
            */
            None
        },
        _ => None
    };
    block.statements.push(BlockStatement{statement: statement, block: 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
}

/*
#[derive(Debug)]
struct NewBlockStatement {
    statement: stmt,
    block: Option<NewBlock>
}

#[derive(Debug)]
enum Binding {
    Bound,
    Free
}

#[derive(Debug)]
struct NewBlock {
    statements: Vec<NewBlockStatement>,
    bindings: Vec<String>,
    variables: HashMap<String, Binding>
}

#[derive(Debug)]
pub struct NewScoping {
    modules: HashMap<String, NewBlock>
}

fn check_expr(expr: expr, block: Block) {
    println!("{:?}", expr);
}

fn check_block(block: Block) -> NewBlock {
    let mut variables = HashMap::new();
    let mut statements = vec!();
    for blocked_statement in block.statements {
        let statement = match blocked_statement.statement {
            stmt::FunctionDef(name, args, body) => {
                // No need to recurse here, this will be in a new block.
                variables.insert(name.clone(), Binding::Bound);
                stmt::FunctionDef(name, args, body)
            },
            stmt::Assign(targets, value) => {
                for target in targets.clone() {
                    match target {
                        expr::Name(name) => {
                            variables.insert(name, Binding::Bound);
                        },
                        _ => panic!()
                    }
                }
                stmt::Assign(targets, value)
            },
            any => any
        };
        let new_block = match blocked_statement.block {
            Some(block) => Some(check_block(block)),
            None => None
        };
        statements.push(NewBlockStatement{statement: statement, block: new_block});
    }
    NewBlock{statements: statements, bindings: block.bindings, variables: variables}
}

#[allow(dead_code)]
pub fn check_scoping(scoping: Scoping) -> NewScoping {
    let mut modules = HashMap::new();
    for (name, block) in scoping.modules {
        modules.insert(name, check_block(block));
    }
    let mut new_scoping = NewScoping{modules: modules};
    new_scoping
}
*/