Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0.4.0] Import as #775

Merged
merged 5 commits into from Dec 3, 2020
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/site/modularity.markdown
Expand Up @@ -42,6 +42,17 @@ if (thirsty) {
}
</pre>

If you need to import a variable via a different name, you can use
ruby0x1 marked this conversation as resolved.
Show resolved Hide resolved
`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 it's value.
ruby0x1 marked this conversation as resolved.
Show resolved Hide resolved

<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
the `for` clause:

Expand Down
2 changes: 1 addition & 1 deletion doc/site/static/prism.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion doc/site/syntax.markdown
Expand Up @@ -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:

<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
</pre>

Expand Down
40 changes: 32 additions & 8 deletions src/vm/wren_compiler.c
Expand Up @@ -95,6 +95,7 @@ typedef enum
TOKEN_FOREIGN,
TOKEN_IF,
TOKEN_IMPORT,
TOKEN_AS,
TOKEN_IN,
TOKEN_IS,
TOKEN_NULL,
Expand Down Expand Up @@ -575,6 +576,7 @@ static Keyword keywords[] =
{"foreign", 7, TOKEN_FOREIGN},
{"if", 2, TOKEN_IF},
{"import", 6, TOKEN_IMPORT},
{"as", 2, TOKEN_AS},
{"in", 2, TOKEN_IN},
{"is", 2, TOKEN_IS},
{"null", 4, TOKEN_NULL},
Expand Down Expand Up @@ -2629,6 +2631,7 @@ GrammarRule rules[] =
/* TOKEN_FOREIGN */ UNUSED,
/* TOKEN_IF */ UNUSED,
/* TOKEN_IMPORT */ UNUSED,
/* TOKEN_AS */ UNUSED,
/* TOKEN_IN */ UNUSED,
/* TOKEN_IS */ INFIX_OPERATOR(PREC_IS, "is"),
/* TOKEN_NULL */ PREFIX(null),
Expand Down Expand Up @@ -3359,17 +3362,38 @@ static void import(Compiler* compiler)
do
{
ignoreNewlines(compiler);
int slot = declareNamedVariable(compiler);

// Define a string constant for the variable name.
int variableConstant = addConstant(compiler,
wrenNewStringLength(compiler->parser->vm,
compiler->parser->previous.start,
compiler->parser->previous.length));
consume(compiler, TOKEN_NAME, "Expect variable name.");

// 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.
emitShortArg(compiler, CODE_IMPORT_VARIABLE, variableConstant);
emitShortArg(compiler, CODE_IMPORT_VARIABLE, sourceVariableConstant);

// Store the result in the variable here.
defineVariable(compiler, slot);
} while (match(compiler, TOKEN_COMMA));
Expand Down
11 changes: 11 additions & 0 deletions test/language/module/import_as/import_as.wren
@@ -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
7 changes: 7 additions & 0 deletions test/language/module/import_as/module.wren
@@ -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"