Merge pull request #1153 from RustPython/ast-module

Add initial draft of symtable module.
This commit is contained in:
Windel Bouwman 2019-07-20 09:07:05 +02:00 committed by GitHub
commit 9c9eadbd9e
3 changed files with 22 additions and 16 deletions

View file

@ -8,6 +8,7 @@ license = "MIT"
edition = "2018" edition = "2018"
[dependencies] [dependencies]
indexmap = "1.0"
rustpython-bytecode = { path = "../bytecode", version = "0.1.0" } rustpython-bytecode = { path = "../bytecode", version = "0.1.0" }
rustpython-parser = { path = "../parser", version = "0.1.0" } rustpython-parser = { path = "../parser", version = "0.1.0" }
num-complex = { version = "0.2", features = ["serde"] } num-complex = { version = "0.2", features = ["serde"] }

View file

@ -8,4 +8,4 @@ extern crate log;
pub mod compile; pub mod compile;
pub mod error; pub mod error;
mod symboltable; pub mod symboltable;

View file

@ -8,12 +8,12 @@ Inspirational file: https://github.com/python/cpython/blob/master/Python/symtabl
*/ */
use crate::error::{CompileError, CompileErrorType}; use crate::error::{CompileError, CompileErrorType};
use indexmap::map::IndexMap;
use rustpython_parser::ast; use rustpython_parser::ast;
use rustpython_parser::location::Location; use rustpython_parser::location::Location;
use std::collections::HashMap;
pub fn make_symbol_table(program: &ast::Program) -> Result<SymbolScope, SymbolTableError> { pub fn make_symbol_table(program: &ast::Program) -> Result<SymbolScope, SymbolTableError> {
let mut builder = SymbolTableBuilder::new(); let mut builder: SymbolTableBuilder = Default::default();
builder.enter_scope(); builder.enter_scope();
builder.scan_program(program)?; builder.scan_program(program)?;
assert_eq!(builder.scopes.len(), 1); assert_eq!(builder.scopes.len(), 1);
@ -26,7 +26,7 @@ pub fn make_symbol_table(program: &ast::Program) -> Result<SymbolScope, SymbolTa
pub fn statements_to_symbol_table( pub fn statements_to_symbol_table(
statements: &[ast::LocatedStatement], statements: &[ast::LocatedStatement],
) -> Result<SymbolScope, SymbolTableError> { ) -> Result<SymbolScope, SymbolTableError> {
let mut builder = SymbolTableBuilder::new(); let mut builder: SymbolTableBuilder = Default::default();
builder.enter_scope(); builder.enter_scope();
builder.scan_statements(statements)?; builder.scan_statements(statements)?;
assert_eq!(builder.scopes.len(), 1); assert_eq!(builder.scopes.len(), 1);
@ -36,7 +36,7 @@ pub fn statements_to_symbol_table(
Ok(symbol_table) Ok(symbol_table)
} }
#[derive(Debug)] #[derive(Debug, Clone)]
pub enum SymbolRole { pub enum SymbolRole {
Global, Global,
Nonlocal, Nonlocal,
@ -45,9 +45,10 @@ pub enum SymbolRole {
} }
/// Captures all symbols in the current scope, and has a list of subscopes in this scope. /// Captures all symbols in the current scope, and has a list of subscopes in this scope.
#[derive(Clone)]
pub struct SymbolScope { pub struct SymbolScope {
/// A set of symbols present on this scope level. /// A set of symbols present on this scope level.
pub symbols: HashMap<String, SymbolRole>, pub symbols: IndexMap<String, SymbolRole>,
/// A list of subscopes in the order as found in the /// A list of subscopes in the order as found in the
/// AST nodes. /// AST nodes.
@ -72,18 +73,20 @@ impl From<SymbolTableError> for CompileError {
type SymbolTableResult = Result<(), SymbolTableError>; type SymbolTableResult = Result<(), SymbolTableError>;
impl SymbolScope { impl SymbolScope {
pub fn new() -> Self {
SymbolScope {
symbols: HashMap::new(),
sub_scopes: vec![],
}
}
pub fn lookup(&self, name: &str) -> Option<&SymbolRole> { pub fn lookup(&self, name: &str) -> Option<&SymbolRole> {
self.symbols.get(name) self.symbols.get(name)
} }
} }
impl Default for SymbolScope {
fn default() -> Self {
SymbolScope {
symbols: Default::default(),
sub_scopes: Default::default(),
}
}
}
impl std::fmt::Debug for SymbolScope { impl std::fmt::Debug for SymbolScope {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!( write!(
@ -152,13 +155,15 @@ pub struct SymbolTableBuilder {
pub scopes: Vec<SymbolScope>, pub scopes: Vec<SymbolScope>,
} }
impl SymbolTableBuilder { impl Default for SymbolTableBuilder {
pub fn new() -> Self { fn default() -> Self {
SymbolTableBuilder { scopes: vec![] } SymbolTableBuilder { scopes: vec![] }
} }
}
impl SymbolTableBuilder {
pub fn enter_scope(&mut self) { pub fn enter_scope(&mut self) {
let scope = SymbolScope::new(); let scope = Default::default();
self.scopes.push(scope); self.scopes.push(scope);
} }