[0.4.0] Import as (#775)

* Add import "..." for Variable as OtherName
This commit is contained in:
ruby
2020-12-03 09:34:36 -08:00
committed by GitHub
parent 6bd2f810e2
commit 3e0f71b742
6 changed files with 63 additions and 10 deletions

View File

@ -42,6 +42,17 @@ if (thirsty) {
} }
</pre> </pre>
If you need to import a variable under a different name, you can use
`import "..." for Name as OtherName`. This looks up the top-level variable
`Name` in *that* module, but declares a variable called `OtherName` in *this* module
with its value.
<pre class="snippet">
import "liquids" for Water //Water is now taken
import "beverages" for Coffee, Water as H2O, Tea
// var water = H2O.new()
</pre>
If you want to load a module, but not bind any variables from it, you can omit If you want to load a module, but not bind any variables from it, you can omit
the `for` clause: the `for` clause:

File diff suppressed because one or more lines are too long

View File

@ -43,7 +43,7 @@ One way to get a quick feel for a language's style is to see what words it
reserves. Here's what Wren has: reserves. Here's what Wren has:
<pre class="snippet"> <pre class="snippet">
break class construct else false for foreign if import as break class construct else false for foreign if import
in is null return static super this true var while in is null return static super this true var while
</pre> </pre>

View File

@ -96,6 +96,7 @@ typedef enum
TOKEN_FOREIGN, TOKEN_FOREIGN,
TOKEN_IF, TOKEN_IF,
TOKEN_IMPORT, TOKEN_IMPORT,
TOKEN_AS,
TOKEN_IN, TOKEN_IN,
TOKEN_IS, TOKEN_IS,
TOKEN_NULL, TOKEN_NULL,
@ -577,6 +578,7 @@ static Keyword keywords[] =
{"foreign", 7, TOKEN_FOREIGN}, {"foreign", 7, TOKEN_FOREIGN},
{"if", 2, TOKEN_IF}, {"if", 2, TOKEN_IF},
{"import", 6, TOKEN_IMPORT}, {"import", 6, TOKEN_IMPORT},
{"as", 2, TOKEN_AS},
{"in", 2, TOKEN_IN}, {"in", 2, TOKEN_IN},
{"is", 2, TOKEN_IS}, {"is", 2, TOKEN_IS},
{"null", 4, TOKEN_NULL}, {"null", 4, TOKEN_NULL},
@ -2632,6 +2634,7 @@ GrammarRule rules[] =
/* TOKEN_FOREIGN */ UNUSED, /* TOKEN_FOREIGN */ UNUSED,
/* TOKEN_IF */ UNUSED, /* TOKEN_IF */ UNUSED,
/* TOKEN_IMPORT */ UNUSED, /* TOKEN_IMPORT */ UNUSED,
/* TOKEN_AS */ UNUSED,
/* TOKEN_IN */ UNUSED, /* TOKEN_IN */ UNUSED,
/* TOKEN_IS */ INFIX_OPERATOR(PREC_IS, "is"), /* TOKEN_IS */ INFIX_OPERATOR(PREC_IS, "is"),
/* TOKEN_NULL */ PREFIX(null), /* TOKEN_NULL */ PREFIX(null),
@ -3378,17 +3381,38 @@ static void import(Compiler* compiler)
do do
{ {
ignoreNewlines(compiler); ignoreNewlines(compiler);
int slot = declareNamedVariable(compiler);
// Define a string constant for the variable name. consume(compiler, TOKEN_NAME, "Expect variable name.");
int variableConstant = addConstant(compiler,
wrenNewStringLength(compiler->parser->vm,
compiler->parser->previous.start,
compiler->parser->previous.length));
// We need to hold onto the source variable,
// in order to reference it in the import later
Token sourceVariableToken = compiler->parser->previous;
// Define a string constant for the original variable name.
int sourceVariableConstant = addConstant(compiler,
wrenNewStringLength(compiler->parser->vm,
sourceVariableToken.start,
sourceVariableToken.length));
// Store the symbol we care about for the variable
int slot = -1;
if(match(compiler, TOKEN_AS))
{
//import "module" for Source as Dest
//Use 'Dest' as the name by declaring a new variable for it.
//This parses a name after the 'as' and defines it.
slot = declareNamedVariable(compiler);
}
else
{
//import "module" for Source
//Uses 'Source' as the name directly
slot = declareVariable(compiler, &sourceVariableToken);
}
// Load the variable from the other module. // Load the variable from the other module.
emitShortArg(compiler, CODE_IMPORT_VARIABLE, variableConstant); emitShortArg(compiler, CODE_IMPORT_VARIABLE, sourceVariableConstant);
// Store the result in the variable here. // Store the result in the variable here.
defineVariable(compiler, slot); defineVariable(compiler, slot);
} while (match(compiler, TOKEN_COMMA)); } while (match(compiler, TOKEN_COMMA));

View File

@ -0,0 +1,11 @@
var Module = "from here"
var ValueC = "value C"
import "./module" for ValueA, Module as Another, ValueB // expect: ran module
import "./module" for ValueC as OtherC
System.print(Module) // expect: from here
System.print(Another) // expect: from module
System.print(ValueA) // expect: module A
System.print(ValueB) // expect: module B
System.print(ValueC) // expect: value C
System.print(OtherC) // expect: module C

View File

@ -0,0 +1,7 @@
// nontest
var Module = "from module"
System.print("ran module")
var ValueA = "module A"
var ValueB = "module B"
var ValueC = "module C"