Skip to content

Commit 1abe636

Browse files
committed
SymbolTable::varnames
1 parent c3967bf commit 1abe636

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

compiler/codegen/src/symboltable.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ pub struct SymbolTable {
4545
/// A list of sub-scopes in the order as found in the
4646
/// AST nodes.
4747
pub sub_tables: Vec<SymbolTable>,
48+
49+
/// Variable names in definition order (parameters first, then locals)
50+
pub varnames: Vec<String>,
4851
}
4952

5053
impl SymbolTable {
@@ -56,6 +59,7 @@ impl SymbolTable {
5659
is_nested,
5760
symbols: IndexMap::default(),
5861
sub_tables: vec![],
62+
varnames: Vec::new(),
5963
}
6064
}
6165

@@ -573,6 +577,8 @@ struct SymbolTableBuilder<'src> {
573577
tables: Vec<SymbolTable>,
574578
future_annotations: bool,
575579
source_code: SourceCode<'src>,
580+
// Current scope's varnames being collected (temporary storage)
581+
current_varnames: Vec<String>,
576582
}
577583

578584
/// Enum to indicate in what mode an expression
@@ -595,6 +601,7 @@ impl<'src> SymbolTableBuilder<'src> {
595601
tables: vec![],
596602
future_annotations: false,
597603
source_code,
604+
current_varnames: Vec::new(),
598605
};
599606
this.enter_scope("top", SymbolTableType::Module, 0);
600607
this
@@ -605,6 +612,8 @@ impl SymbolTableBuilder<'_> {
605612
fn finish(mut self) -> Result<SymbolTable, SymbolTableError> {
606613
assert_eq!(self.tables.len(), 1);
607614
let mut symbol_table = self.tables.pop().unwrap();
615+
// Save varnames for the top-level module scope
616+
symbol_table.varnames = self.current_varnames;
608617
analyze_symbol_table(&mut symbol_table)?;
609618
Ok(symbol_table)
610619
}
@@ -621,7 +630,9 @@ impl SymbolTableBuilder<'_> {
621630

622631
/// Pop symbol table and add to sub table of parent table.
623632
fn leave_scope(&mut self) {
624-
let table = self.tables.pop().unwrap();
633+
let mut table = self.tables.pop().unwrap();
634+
// Save the collected varnames to the symbol table
635+
table.varnames = std::mem::take(&mut self.current_varnames);
625636
self.tables.last_mut().unwrap().sub_tables.push(table);
626637
}
627638

@@ -1533,18 +1544,43 @@ impl SymbolTableBuilder<'_> {
15331544
}
15341545
SymbolUsage::Parameter => {
15351546
flags.insert(SymbolFlags::PARAMETER);
1547+
// Parameters are always added to varnames first
1548+
let name_str = symbol.name.clone();
1549+
if !self.current_varnames.contains(&name_str) {
1550+
self.current_varnames.push(name_str);
1551+
}
15361552
}
15371553
SymbolUsage::AnnotationParameter => {
15381554
flags.insert(SymbolFlags::PARAMETER | SymbolFlags::ANNOTATED);
1555+
// Annotated parameters are also added to varnames
1556+
let name_str = symbol.name.clone();
1557+
if !self.current_varnames.contains(&name_str) {
1558+
self.current_varnames.push(name_str);
1559+
}
15391560
}
15401561
SymbolUsage::AnnotationAssigned => {
15411562
flags.insert(SymbolFlags::ASSIGNED | SymbolFlags::ANNOTATED);
15421563
}
15431564
SymbolUsage::Assigned => {
15441565
flags.insert(SymbolFlags::ASSIGNED);
1566+
// Local variables (assigned) are added to varnames if they are local scope
1567+
// and not already in varnames
1568+
if symbol.scope == SymbolScope::Local {
1569+
let name_str = symbol.name.clone();
1570+
if !self.current_varnames.contains(&name_str) {
1571+
self.current_varnames.push(name_str);
1572+
}
1573+
}
15451574
}
15461575
SymbolUsage::AssignedNamedExprInComprehension => {
15471576
flags.insert(SymbolFlags::ASSIGNED | SymbolFlags::ASSIGNED_IN_COMPREHENSION);
1577+
// Named expressions in comprehensions might also be locals
1578+
if symbol.scope == SymbolScope::Local {
1579+
let name_str = symbol.name.clone();
1580+
if !self.current_varnames.contains(&name_str) {
1581+
self.current_varnames.push(name_str);
1582+
}
1583+
}
15481584
}
15491585
SymbolUsage::Global => {
15501586
symbol.scope = SymbolScope::GlobalExplicit;

0 commit comments

Comments
 (0)