diff --git a/src/bytecode.rs b/src/bytecode.rs index aede69c..c87bc0a 100644 --- a/src/bytecode.rs +++ b/src/bytecode.rs @@ -50,7 +50,7 @@ pub enum NameScope { pub enum Instruction { Import { name: String, - symbol: Option, + symbols: Vec, }, ImportStar { name: String, @@ -330,7 +330,7 @@ impl Instruction { } match self { - Import { name, symbol } => w!(Import, name, format!("{:?}", symbol)), + Import { name, symbols } => w!(Import, name, format!("{:?}", symbols)), ImportStar { name } => w!(ImportStar, name), LoadName { name, scope } => w!(LoadName, name, format!("{:?}", scope)), StoreName { name, scope } => w!(StoreName, name, format!("{:?}", scope)), diff --git a/src/compile.rs b/src/compile.rs index 30510c2..dc83fad 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -250,29 +250,51 @@ impl Compiler { ast::Statement::Import { import_parts } => { for ast::SingleImport { module, - symbol, + symbols, alias, } in import_parts { - match symbol { - Some(name) if name == "*" => { - self.emit(Instruction::ImportStar { - name: module.clone(), - }); - } - _ => { + if let Some(alias) = alias { + self.emit(Instruction::Import { + name: module.clone(), + symbols: vec![], + }); + self.store_name(&alias); + } else { + if symbols.is_empty() { self.emit(Instruction::Import { name: module.clone(), - symbol: symbol.clone(), + symbols: vec![], }); - let name = match alias { - Some(alias) => alias.clone(), - None => match symbol { - Some(symbol) => symbol.clone(), - None => module.clone(), - }, - }; - self.store_name(&name); + self.store_name(&module.clone()); + } else { + let mut import_star = false; + let mut symbols_strings = vec![]; + let mut names = vec![]; + for ast::ImportSymbol { symbol, alias } in symbols { + if symbol == "*" { + import_star = true; + } + symbols_strings.push(symbol.to_string()); + names.insert( + 0, + match alias { + Some(alias) => alias, + None => symbol, + }, + ); + } + if import_star { + self.emit(Instruction::ImportStar { + name: module.clone(), + }); + } else { + self.emit(Instruction::Import { + name: module.clone(), + symbols: symbols_strings, + }); + names.iter().for_each(|name| self.store_name(&name)); + } } } } diff --git a/src/symboltable.rs b/src/symboltable.rs index 9687b0e..04e5d9e 100644 --- a/src/symboltable.rs +++ b/src/symboltable.rs @@ -300,14 +300,22 @@ impl SymbolTableBuilder { for part in import_parts { if let Some(alias) = &part.alias { // `import mymodule as myalias` - // `from mymodule import myimportname as myalias` self.register_name(alias, SymbolRole::Assigned)?; - } else if let Some(symbol) = &part.symbol { - // `from mymodule import myimport` - self.register_name(symbol, SymbolRole::Assigned)?; } else { - // `import module` - self.register_name(&part.module, SymbolRole::Assigned)?; + if part.symbols.is_empty() { + // `import module` + self.register_name(&part.module, SymbolRole::Assigned)?; + } else { + // `from mymodule import myimport` + for symbol in &part.symbols { + if let Some(alias) = &symbol.alias { + // `from mymodule import myimportname as myalias` + self.register_name(alias, SymbolRole::Assigned)?; + } else { + self.register_name(&symbol.symbol, SymbolRole::Assigned)?; + } + } + } } } }