From b2ca4c0381fcbfc68d1ee7e1133939d00a8801a3 Mon Sep 17 00:00:00 2001 From: Bob Nystrom Date: Tue, 17 Feb 2015 07:32:33 -0800 Subject: [PATCH] Allow zero or multiple imported names. --- src/wren_compiler.c | 37 +++++++++++-------- .../change_imported_value.wren | 4 +- test/module/cyclic_import/cyclic_import.wren | 2 +- .../implicitly_imports_core.wren | 3 +- .../implicitly_imports_core/module.wren | 2 - test/module/inside_block/inside_block.wren | 10 +++++ test/module/inside_block/module.wren | 3 ++ .../multiple_variables.wren | 7 +--- test/module/name_collision.wren | 2 + test/module/no_variable/module.wren | 2 + test/module/no_variable/no_variable.wren | 2 + 11 files changed, 44 insertions(+), 30 deletions(-) create mode 100644 test/module/inside_block/inside_block.wren create mode 100644 test/module/inside_block/module.wren create mode 100644 test/module/name_collision.wren create mode 100644 test/module/no_variable/module.wren create mode 100644 test/module/no_variable/no_variable.wren diff --git a/src/wren_compiler.c b/src/wren_compiler.c index 5ce5c449..a609ace2 100644 --- a/src/wren_compiler.c +++ b/src/wren_compiler.c @@ -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) diff --git a/test/module/change_imported_value/change_imported_value.wren b/test/module/change_imported_value/change_imported_value.wren index 8f8d1e01..c5163410 100644 --- a/test/module/change_imported_value/change_imported_value.wren +++ b/test/module/change_imported_value/change_imported_value.wren @@ -1,6 +1,4 @@ -// TODO: Use comma-separated list. -import "module" for Module -import "module" for Other +import "module" for Module, Other IO.print(Module) // expect: before diff --git a/test/module/cyclic_import/cyclic_import.wren b/test/module/cyclic_import/cyclic_import.wren index a880af49..1cb4de97 100644 --- a/test/module/cyclic_import/cyclic_import.wren +++ b/test/module/cyclic_import/cyclic_import.wren @@ -1,4 +1,4 @@ -import "a" for A +import "a" // Shared module should only run once: // expect: start a diff --git a/test/module/implicitly_imports_core/implicitly_imports_core.wren b/test/module/implicitly_imports_core/implicitly_imports_core.wren index e6c99572..1fef7723 100644 --- a/test/module/implicitly_imports_core/implicitly_imports_core.wren +++ b/test/module/implicitly_imports_core/implicitly_imports_core.wren @@ -1,5 +1,4 @@ -// TODO: Allow omitting "for" clause. -import "module" for Module +import "module" // expect: Bool // expect: Class // expect: Fiber diff --git a/test/module/implicitly_imports_core/module.wren b/test/module/implicitly_imports_core/module.wren index 934bb6c6..bd444960 100644 --- a/test/module/implicitly_imports_core/module.wren +++ b/test/module/implicitly_imports_core/module.wren @@ -1,6 +1,4 @@ // nontest -var Module = "from module" - IO.print(Bool) IO.print(Class) IO.print(Fiber) diff --git a/test/module/inside_block/inside_block.wren b/test/module/inside_block/inside_block.wren new file mode 100644 index 00000000..d15d27d9 --- /dev/null +++ b/test/module/inside_block/inside_block.wren @@ -0,0 +1,10 @@ +var Module = "outer" + +if (true) { + import "module" for Module + // expect: ran module + + IO.print(Module) // expect: from module +} + +IO.print(Module) // expect: outer diff --git a/test/module/inside_block/module.wren b/test/module/inside_block/module.wren new file mode 100644 index 00000000..cf2ce362 --- /dev/null +++ b/test/module/inside_block/module.wren @@ -0,0 +1,3 @@ +// nontest +var Module = "from module" +IO.print("ran module") diff --git a/test/module/multiple_variables/multiple_variables.wren b/test/module/multiple_variables/multiple_variables.wren index d99bb66d..7d007604 100644 --- a/test/module/multiple_variables/multiple_variables.wren +++ b/test/module/multiple_variables/multiple_variables.wren @@ -1,9 +1,4 @@ -// TODO: Comma-separated list. -import "module" for Module1 -import "module" for Module2 -import "module" for Module3 -import "module" for Module4 -import "module" for Module5 +import "module" for Module1, Module2, Module3, Module4, Module5 // Only execute module body once: // expect: ran module diff --git a/test/module/name_collision.wren b/test/module/name_collision.wren new file mode 100644 index 00000000..468c2448 --- /dev/null +++ b/test/module/name_collision.wren @@ -0,0 +1,2 @@ +var Collides +import "module" for Collides // expect error diff --git a/test/module/no_variable/module.wren b/test/module/no_variable/module.wren new file mode 100644 index 00000000..c1acca4a --- /dev/null +++ b/test/module/no_variable/module.wren @@ -0,0 +1,2 @@ +// nontest +IO.print("ran module") diff --git a/test/module/no_variable/no_variable.wren b/test/module/no_variable/no_variable.wren new file mode 100644 index 00000000..38b440d3 --- /dev/null +++ b/test/module/no_variable/no_variable.wren @@ -0,0 +1,2 @@ +import "module" +// expect: ran module