Skip to content

Commit e6edf71

Browse files
committed
Improve symbol table processing.
1 parent dd9a4a1 commit e6edf71

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,
@@ -123,7 +125,7 @@ impl<O: OutputStream> Compiler<O> {
123125
fn new(optimize: u8) -> Self {
124126
Compiler {
125127
output_stack: Vec::new(),
126-
scope_stack: Vec::new(),
128+
symbol_table_stack: Vec::new(),
127129
nxt_label: 0,
128130
source_path: None,
129131
current_source_location: ast::Location::default(),
@@ -158,10 +160,10 @@ impl<O: OutputStream> Compiler<O> {
158160
fn compile_program(
159161
&mut self,
160162
program: &ast::Program,
161-
symbol_scope: SymbolScope,
163+
symbol_table: SymbolTable,
162164
) -> Result<(), CompileError> {
163165
let size_before = self.output_stack.len();
164-
self.scope_stack.push(symbol_scope);
166+
self.symbol_table_stack.push(symbol_table);
165167
self.compile_statements(&program.statements)?;
166168
assert_eq!(self.output_stack.len(), size_before);
167169

@@ -176,9 +178,9 @@ impl<O: OutputStream> Compiler<O> {
176178
fn compile_program_single(
177179
&mut self,
178180
program: &ast::Program,
179-
symbol_scope: SymbolScope,
181+
symbol_table: SymbolTable,
180182
) -> Result<(), CompileError> {
181-
self.scope_stack.push(symbol_scope);
183+
self.symbol_table_stack.push(symbol_table);
182184

183185
let mut emitted_return = false;
184186

@@ -215,9 +217,9 @@ impl<O: OutputStream> Compiler<O> {
215217
fn compile_statement_eval(
216218
&mut self,
217219
statements: &[ast::Statement],
218-
symbol_table: SymbolScope,
220+
symbol_table: SymbolTable,
219221
) -> Result<(), CompileError> {
220-
self.scope_stack.push(symbol_table);
222+
self.symbol_table_stack.push(symbol_table);
221223
for statement in statements {
222224
if let ast::StatementType::Expression { ref expression } = statement.node {
223225
self.compile_expression(expression)?;
@@ -241,12 +243,11 @@ impl<O: OutputStream> Compiler<O> {
241243

242244
fn scope_for_name(&self, name: &str) -> bytecode::NameScope {
243245
let symbol = self.lookup_name(name);
244-
if symbol.is_global {
245-
bytecode::NameScope::Global
246-
} else if symbol.is_nonlocal {
247-
bytecode::NameScope::NonLocal
248-
} else {
249-
bytecode::NameScope::Local
246+
match symbol.scope {
247+
SymbolScope::Global => bytecode::NameScope::Global,
248+
SymbolScope::Nonlocal => bytecode::NameScope::NonLocal,
249+
SymbolScope::Unknown => bytecode::NameScope::Local,
250+
SymbolScope::Local => bytecode::NameScope::Local,
250251
}
251252
}
252253

@@ -1897,22 +1898,27 @@ impl<O: OutputStream> Compiler<O> {
18971898

18981899
// Scope helpers:
18991900
fn enter_scope(&mut self) {
1900-
// println!("Enter scope {:?}", self.scope_stack);
1901+
// println!("Enter scope {:?}", self.symbol_table_stack);
19011902
// Enter first subscope!
1902-
let scope = self.scope_stack.last_mut().unwrap().sub_scopes.remove(0);
1903-
self.scope_stack.push(scope);
1903+
let table = self
1904+
.symbol_table_stack
1905+
.last_mut()
1906+
.unwrap()
1907+
.sub_tables
1908+
.remove(0);
1909+
self.symbol_table_stack.push(table);
19041910
}
19051911

19061912
fn leave_scope(&mut self) {
1907-
// println!("Leave scope {:?}", self.scope_stack);
1908-
let scope = self.scope_stack.pop().unwrap();
1909-
assert!(scope.sub_scopes.is_empty());
1913+
// println!("Leave scope {:?}", self.symbol_table_stack);
1914+
let table = self.symbol_table_stack.pop().unwrap();
1915+
assert!(table.sub_tables.is_empty());
19101916
}
19111917

19121918
fn lookup_name(&self, name: &str) -> &Symbol {
19131919
// println!("Looking up {:?}", name);
1914-
let scope = self.scope_stack.last().unwrap();
1915-
scope.lookup(name).expect(
1920+
let symbol_table = self.symbol_table_stack.last().unwrap();
1921+
symbol_table.lookup(name).expect(
19161922
"The symbol must be present in the symbol table, even when it is undefined in python.",
19171923
)
19181924
}

0 commit comments

Comments
 (0)