From edb1f9d37b83a1a1eaafe151723270d1e1bf222e Mon Sep 17 00:00:00 2001 From: underscorediscovery Date: Fri, 10 Jul 2020 20:59:39 -0700 Subject: [PATCH] allow import strings to use string interpolation Note that this has some major caveats around stuff like code completion being able to resolve modules at compile time, but I think the PR is interesting for others to see/discuss either way. --- src/vm/wren_compiler.c | 15 +++++++++++---- src/vm/wren_vm.c | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/vm/wren_compiler.c b/src/vm/wren_compiler.c index ee8eb78a..cd5c4caf 100644 --- a/src/vm/wren_compiler.c +++ b/src/vm/wren_compiler.c @@ -2721,6 +2721,7 @@ static int getByteCountForArguments(const uint8_t* bytecode, case CODE_FOREIGN_CONSTRUCT: case CODE_FOREIGN_CLASS: case CODE_END_MODULE: + case CODE_IMPORT_MODULE: return 0; case CODE_LOAD_LOCAL: @@ -2761,7 +2762,6 @@ static int getByteCountForArguments(const uint8_t* bytecode, case CODE_OR: case CODE_METHOD_INSTANCE: case CODE_METHOD_STATIC: - case CODE_IMPORT_MODULE: case CODE_IMPORT_VARIABLE: return 2; @@ -3343,11 +3343,18 @@ static void classDefinition(Compiler* compiler, bool isForeign) static void import(Compiler* compiler) { ignoreNewlines(compiler); - consume(compiler, TOKEN_STRING, "Expect a string after 'import'."); - int moduleConstant = addConstant(compiler, compiler->parser->previous.value); + if(match(compiler, TOKEN_STRING)) { + int constant = addConstant(compiler, compiler->parser->previous.value); + emitShortArg(compiler, CODE_CONSTANT, constant); + } else if(match(compiler, TOKEN_INTERPOLATION)) { + stringInterpolation(compiler, false); + } else { + error(compiler, "Expect a string after 'import'"); + } + // Load the module. - emitShortArg(compiler, CODE_IMPORT_MODULE, moduleConstant); + emitOp(compiler, CODE_IMPORT_MODULE); // Discard the unused result value from calling the module body's closure. emitOp(compiler, CODE_POP); diff --git a/src/vm/wren_vm.c b/src/vm/wren_vm.c index dbd111f7..189fd326 100644 --- a/src/vm/wren_vm.c +++ b/src/vm/wren_vm.c @@ -1281,7 +1281,7 @@ static WrenInterpretResult runInterpreter(WrenVM* vm, register ObjFiber* fiber) // value. It will be popped after this fiber is resumed. Store the // imported module's closure in the slot in case a GC happens when // invoking the closure. - PUSH(importModule(vm, fn->constants.data[READ_SHORT()])); + PUSH(importModule(vm, POP())); if (wrenHasError(fiber)) RUNTIME_ERROR(); // If we get a closure, call it to execute the module body.