Skip to content

Commit 49ed782

Browse files
Merge pull request RustPython#1245 from RustPython/symbol-context
Improve symbol table processing.
2 parents 11cbf55 + e6edf71 commit 49ed782

File tree

4 files changed

+319
-193
lines changed

4 files changed

+319
-193
lines changed

compiler/src/compile.rs

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
use crate::error::{CompileError, CompileErrorType};
99
use crate::output_stream::{CodeObjectStream, OutputStream};
1010
use crate::peephole::PeepholeOptimizer;
11-
use crate::symboltable::{make_symbol_table, statements_to_symbol_table, Symbol, SymbolScope};
11+
use crate::symboltable::{
12+
make_symbol_table, statements_to_symbol_table, Symbol, SymbolScope, SymbolTable,
13+
};
1214
use num_complex::Complex64;
1315
use rustpython_bytecode::bytecode::{self, CallType, CodeObject, Instruction, Varargs};
1416
use rustpython_parser::{ast, parser};
@@ -18,7 +20,7 @@ type BasicOutputStream = PeepholeOptimizer<CodeObjectStream>;
1820
/// Main structure holding the state of compilation.
1921
struct Compiler<O: OutputStream = BasicOutputStream> {
2022
output_stack: Vec<O>,
21-
scope_stack: Vec<SymbolScope>,
23+
symbol_table_stack: Vec<SymbolTable>,
2224
nxt_label: usize,
2325
source_path: Option<String>,
2426
current_source_location: ast::Location,
@@ -147,7 +149,7 @@ impl<O: OutputStream> Compiler<O> {
147149
fn new(optimize: u8) -> Self {
148150
Compiler {
149151
output_stack: Vec::new(),
150-
scope_stack: Vec::new(),
152+
symbol_table_stack: Vec::new(),
151153
nxt_label: 0,
152154
source_path: None,
153155
current_source_location: ast::Location::default(),
@@ -182,10 +184,10 @@ impl<O: OutputStream> Compiler<O> {
182184
fn compile_program(
183185
&mut self,
184186
program: &ast::Program,
185-
symbol_scope: SymbolScope,
187+
symbol_table: SymbolTable,
186188
) -> Result<(), CompileError> {
187189
let size_before = self.output_stack.len();
188-
self.scope_stack.push(symbol_scope);
190+
self.symbol_table_stack.push(symbol_table);
189191
self.compile_statements(&program.statements)?;
190192
assert_eq!(self.output_stack.len(), size_before);
191193

@@ -200,9 +202,9 @@ impl<O: OutputStream> Compiler<O> {
200202
fn compile_program_single(
201203
&mut self,
202204
program: &ast::Program,
203-
symbol_scope: SymbolScope,
205+
symbol_table: SymbolTable,
204206
) -> Result<(), CompileError> {
205-
self.scope_stack.push(symbol_scope);
207+
self.symbol_table_stack.push(symbol_table);
206208

207209
let mut emitted_return = false;
208210

@@ -239,9 +241,9 @@ impl<O: OutputStream> Compiler<O> {
239241
fn compile_statement_eval(
240242
&mut self,
241243
statements: &[ast::Statement],
242-
symbol_table: SymbolScope,
244+
symbol_table: SymbolTable,
243245
) -> Result<(), CompileError> {
244-
self.scope_stack.push(symbol_table);
246+
self.symbol_table_stack.push(symbol_table);
245247
for statement in statements {
246248
if let ast::StatementType::Expression { ref expression } = statement.node {
247249
self.compile_expression(expression)?;
@@ -265,12 +267,11 @@ impl<O: OutputStream> Compiler<O> {
265267

266268
fn scope_for_name(&self, name: &str) -> bytecode::NameScope {
267269
let symbol = self.lookup_name(name);
268-
if symbol.is_global {
269-
bytecode::NameScope::Global
270-
} else if symbol.is_nonlocal {
271-
bytecode::NameScope::NonLocal
272-
} else {
273-
bytecode::NameScope::Local
270+
match symbol.scope {
271+
SymbolScope::Global => bytecode::NameScope::Global,
272+
SymbolScope::Nonlocal => bytecode::NameScope::NonLocal,
273+
SymbolScope::Unknown => bytecode::NameScope::Local,
274+
SymbolScope::Local => bytecode::NameScope::Local,
274275
}
275276
}
276277

@@ -1921,22 +1922,27 @@ impl<O: OutputStream> Compiler<O> {
19211922

19221923
// Scope helpers:
19231924
fn enter_scope(&mut self) {
1924-
// println!("Enter scope {:?}", self.scope_stack);
1925+
// println!("Enter scope {:?}", self.symbol_table_stack);
19251926
// Enter first subscope!
1926-
let scope = self.scope_stack.last_mut().unwrap().sub_scopes.remove(0);
1927-
self.scope_stack.push(scope);
1927+
let table = self
1928+
.symbol_table_stack
1929+
.last_mut()
1930+
.unwrap()
1931+
.sub_tables
1932+
.remove(0);
1933+
self.symbol_table_stack.push(table);
19281934
}
19291935

19301936
fn leave_scope(&mut self) {
1931-
// println!("Leave scope {:?}", self.scope_stack);
1932-
let scope = self.scope_stack.pop().unwrap();
1933-
assert!(scope.sub_scopes.is_empty());
1937+
// println!("Leave scope {:?}", self.symbol_table_stack);
1938+
let table = self.symbol_table_stack.pop().unwrap();
1939+
assert!(table.sub_tables.is_empty());
19341940
}
19351941

19361942
fn lookup_name(&self, name: &str) -> &Symbol {
19371943
// println!("Looking up {:?}", name);
1938-
let scope = self.scope_stack.last().unwrap();
1939-
scope.lookup(name).expect(
1944+
let symbol_table = self.symbol_table_stack.last().unwrap();
1945+
symbol_table.lookup(name).expect(
19401946
"The symbol must be present in the symbol table, even when it is undefined in python.",
19411947
)
19421948
}

0 commit comments

Comments
 (0)