feat: allow zero or multiple imported names in import statement

Make the `for` clause in import statements optional, and support comma-separated lists of imported names when present. This removes the previous restriction of exactly one imported variable per import statement.

- Refactor `import()` in compiler to handle optional `for` clause with loop over comma-separated names
- Update existing tests to use comma-separated imports and omit `for` clause where appropriate
- Add new tests: `inside_block`, `name_collision`, `no_variable`
This commit is contained in:
Bob Nystrom
2015-02-17 15:32:33 +00:00
parent d96fc0a381
commit 0d3eae5269
11 changed files with 44 additions and 30 deletions
+21 -16
View File
@@ -2903,29 +2903,34 @@ static void import(Compiler* compiler)
consume(compiler, TOKEN_STRING, "Expect a string after 'import'.");
int moduleConstant = stringConstant(compiler);
consume(compiler, TOKEN_FOR, "Expect 'for' after module string.");
consume(compiler, TOKEN_NAME, "Expect name of variable to import.");
int slot = declareVariable(compiler);
// TODO: Allow multiple variables.
// Also define a string constant for the variable name.
int variableConstant = addConstant(compiler,
wrenNewString(compiler->parser->vm,
compiler->parser->previous.start, compiler->parser->previous.length));
// Load the module.
emitShortArg(compiler, CODE_LOAD_MODULE, moduleConstant);
// Discard the unused result value from calling the module's fiber.
emit(compiler, CODE_POP);
// Load the variable from the other module.
emitShortArg(compiler, CODE_IMPORT_VARIABLE, moduleConstant);
emitShort(compiler, variableConstant);
// The for clause is optional.
if (!match(compiler, TOKEN_FOR)) return;
// Store the result in the variable here.
defineVariable(compiler, slot);
// Compile the comma-separated list of variables to import.
do
{
consume(compiler, TOKEN_NAME, "Expect name of variable to import.");
int slot = declareVariable(compiler);
// Define a string constant for the variable name.
int variableConstant = addConstant(compiler,
wrenNewString(compiler->parser->vm,
compiler->parser->previous.start,
compiler->parser->previous.length));
// Load the variable from the other module.
emitShortArg(compiler, CODE_IMPORT_VARIABLE, moduleConstant);
emitShort(compiler, variableConstant);
// Store the result in the variable here.
defineVariable(compiler, slot);
} while (match(compiler, TOKEN_COMMA));
}
static void variableDefinition(Compiler* compiler)