Merge branch 'master' into coolreader18/comptime-pycompilation

This commit is contained in:
coolreader18 2019-06-16 09:05:34 -05:00
commit 8e3fdd7b36
3 changed files with 51 additions and 22 deletions

View file

@ -50,7 +50,7 @@ pub enum NameScope {
pub enum Instruction { pub enum Instruction {
Import { Import {
name: String, name: String,
symbol: Option<String>, symbols: Vec<String>,
}, },
ImportStar { ImportStar {
name: String, name: String,
@ -330,7 +330,7 @@ impl Instruction {
} }
match self { match self {
Import { name, symbol } => w!(Import, name, format!("{:?}", symbol)), Import { name, symbols } => w!(Import, name, format!("{:?}", symbols)),
ImportStar { name } => w!(ImportStar, name), ImportStar { name } => w!(ImportStar, name),
LoadName { name, scope } => w!(LoadName, name, format!("{:?}", scope)), LoadName { name, scope } => w!(LoadName, name, format!("{:?}", scope)),
StoreName { name, scope } => w!(StoreName, name, format!("{:?}", scope)), StoreName { name, scope } => w!(StoreName, name, format!("{:?}", scope)),

View file

@ -250,29 +250,50 @@ impl Compiler {
ast::Statement::Import { import_parts } => { ast::Statement::Import { import_parts } => {
for ast::SingleImport { for ast::SingleImport {
module, module,
symbol, symbols,
alias, alias,
} in import_parts } in import_parts
{ {
match symbol { if let Some(alias) = alias {
Some(name) if name == "*" => { // import module as alias
self.emit(Instruction::Import {
name: module.clone(),
symbols: vec![],
});
self.store_name(&alias);
} else if symbols.is_empty() {
// import module
self.emit(Instruction::Import {
name: module.clone(),
symbols: vec![],
});
self.store_name(&module.clone());
} else {
let import_star = symbols
.iter()
.any(|import_symbol| import_symbol.symbol == "*");
if import_star {
// from module import *
self.emit(Instruction::ImportStar { self.emit(Instruction::ImportStar {
name: module.clone(), name: module.clone(),
}); });
} } else {
_ => { // from module import symbol
// from module import symbol as alias
let (names, symbols_strings): (Vec<String>, Vec<String>) = symbols
.iter()
.map(|ast::ImportSymbol { symbol, alias }| {
(
alias.clone().unwrap_or_else(|| symbol.to_string()),
symbol.to_string(),
)
})
.unzip();
self.emit(Instruction::Import { self.emit(Instruction::Import {
name: module.clone(), name: module.clone(),
symbol: symbol.clone(), symbols: symbols_strings,
}); });
let name = match alias { names.iter().rev().for_each(|name| self.store_name(&name));
Some(alias) => alias.clone(),
None => match symbol {
Some(symbol) => symbol.clone(),
None => module.clone(),
},
};
self.store_name(&name);
} }
} }
} }

View file

@ -300,14 +300,22 @@ impl SymbolTableBuilder {
for part in import_parts { for part in import_parts {
if let Some(alias) = &part.alias { if let Some(alias) = &part.alias {
// `import mymodule as myalias` // `import mymodule as myalias`
// `from mymodule import myimportname as myalias`
self.register_name(alias, SymbolRole::Assigned)?; self.register_name(alias, SymbolRole::Assigned)?;
} else if let Some(symbol) = &part.symbol {
// `from mymodule import myimport`
self.register_name(symbol, SymbolRole::Assigned)?;
} else { } else {
if part.symbols.is_empty() {
// `import module` // `import module`
self.register_name(&part.module, SymbolRole::Assigned)?; 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)?;
}
}
}
} }
} }
} }