Implement import a, b, c from foo syntax
This brings stuff into the local scope, but it is a little funky with local scopes that are above the current level (in the same function or module). Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
@@ -795,6 +795,28 @@ impl StmtVisitor for Compiler<'_> {
|
||||
|
||||
let line = stmt_line_number(stmt);
|
||||
|
||||
// allocate names - local or global
|
||||
let nil_constant = self.insert_constant(Nil::create())?;
|
||||
for what in &stmt.what {
|
||||
if self.is_global_scope() {
|
||||
self.insert_global(&what.text)?;
|
||||
} else {
|
||||
self.emit((what.line, what.line), Op::PushConstant(nil_constant));
|
||||
self.insert_local(what.text.to_string())?;
|
||||
}
|
||||
}
|
||||
if stmt.what.is_empty() && stmt.module.kind == TokenKind::Name {
|
||||
if self.is_global_scope() {
|
||||
self.insert_global(&stmt.module.text)?;
|
||||
} else {
|
||||
self.emit(
|
||||
(stmt.module.line, stmt.module.line),
|
||||
Op::PushConstant(nil_constant),
|
||||
);
|
||||
self.insert_local(stmt.module.text.to_string())?;
|
||||
}
|
||||
}
|
||||
|
||||
// resolve filename and get full filepath
|
||||
let path = match stmt.module.kind {
|
||||
TokenKind::Name => self
|
||||
@@ -831,12 +853,12 @@ impl StmtVisitor for Compiler<'_> {
|
||||
};
|
||||
let module_constant = self.insert_constant(upcast_obj(module.clone()))?;
|
||||
|
||||
self.emit(stmt_line_number(stmt), Op::PushConstant(module_constant));
|
||||
// evaluate module
|
||||
self.emit(line, Op::PushConstant(module_constant));
|
||||
self.emit(line, Op::EvalModule);
|
||||
|
||||
if stmt.what.is_empty() {
|
||||
// evaluate the module, and then assign the resulting object to the module name as
|
||||
// appropriate
|
||||
self.emit(line, Op::EnterModule);
|
||||
// assign the resulting object to the module name as appropriate
|
||||
// only assign if it's a name, if it's a string we don't assign anything
|
||||
if stmt.module.kind == TokenKind::Name {
|
||||
self.emit_assign(line, &stmt.module.text)?;
|
||||
@@ -845,8 +867,16 @@ impl StmtVisitor for Compiler<'_> {
|
||||
}
|
||||
} else {
|
||||
// evaluate the module, and then assign all names that were imported as appropriate
|
||||
// TODO Compiler::visit_import_stmt - visit names from module
|
||||
todo!("import names from module")
|
||||
for what in stmt.what.iter() {
|
||||
self.emit(line, Op::Dup);
|
||||
let constant_id = self.insert_constant(Str::create(&what.text))?;
|
||||
self.emit(line, Op::GetAttr(constant_id));
|
||||
self.emit_assign(line, &what.text)?;
|
||||
}
|
||||
|
||||
// not importing the module name itself, so clean up the stack after we're done setting
|
||||
// names
|
||||
self.emit(line, Op::Pop);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user