Restore import into caller's namespace
This commit is contained in:
1 parent
8cc31f0f49
commit
aaf305868c
6 files changed
+959
-880
No files matched your search
@@ -368,12 +368,13 @@ block block_bind(block binder, block body, int bindflags) {
|
||||
return block_join(binder, body);
|
||||
}
|
||||
|
||||
block block_bind_library(block binder, block body, int bindflags, const char* libname) {
|
||||
block block_bind_library(block binder, block body, int bindflags, const char *libname) {
|
||||
bindflags |= OP_HAS_BINDING;
|
||||
int nrefs = 0;
|
||||
int matchlen = strlen(libname);
|
||||
char* matchname = jv_mem_alloc(matchlen+2+1);
|
||||
if (libname[0] != '\0') {
|
||||
int matchlen = (libname == NULL) ? 0 : strlen(libname);
|
||||
char *matchname = jv_mem_alloc(matchlen+2+1);
|
||||
matchname[0] = '\0';
|
||||
if (libname != NULL && libname[0] != '\0') {
|
||||
strcpy(matchname,libname);
|
||||
strcpy(matchname+matchlen, "::");
|
||||
matchlen += 2;
|
||||
@@ -502,7 +503,8 @@ block gen_import(const char* name, block metadata, const char* as, int is_data)
|
||||
meta = block_const(metadata);
|
||||
else
|
||||
meta = jv_object();
|
||||
meta = jv_object_set(meta, jv_string("as"), jv_string(as));
|
||||
if (as != NULL)
|
||||
meta = jv_object_set(meta, jv_string("as"), jv_string(as));
|
||||
meta = jv_object_set(meta, jv_string("is_data"), is_data ? jv_true() : jv_false());
|
||||
meta = jv_object_set(meta, jv_string("relpath"), jv_string(name));
|
||||
i->imm.constant = meta;
|
||||
|
||||
@@ -2753,6 +2753,14 @@ sections:
|
||||
the relative path string. The module's symbols are prefixed
|
||||
with "NAME::".
|
||||
|
||||
- title: "`import RelativePathString;`"
|
||||
body: |
|
||||
|
||||
Imports a module found at the given path relative to a
|
||||
directory in a search path. A ".jq" suffix will be added to
|
||||
the relative path string. The module's symbols are imported
|
||||
into the caller's namespace as if the module's content had
|
||||
been included directly.
|
||||
|
||||
- title: "`import RelativePathString as NAME <metadata>;`"
|
||||
body: |
|
||||
|
||||
@@ -198,6 +198,7 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block
|
||||
jv deps = block_take_imports(src_block);
|
||||
block bk = *src_block;
|
||||
int nerrors = 0;
|
||||
const char *as_str = NULL;
|
||||
|
||||
jv_array_foreach(deps, i, dep) {
|
||||
int is_data = jv_get_kind(jv_object_get(jv_copy(dep), jv_string("is_data"))) == JV_KIND_TRUE;
|
||||
@@ -208,7 +209,9 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block
|
||||
jv_free(v);
|
||||
jv relpath = validate_relpath(jv_object_get(jv_copy(dep), jv_string("relpath")));
|
||||
jv as = jv_object_get(jv_copy(dep), jv_string("as"));
|
||||
assert(jv_is_valid(as) && jv_get_kind(as) == JV_KIND_STRING);
|
||||
assert(!jv_is_valid(as) || jv_get_kind(as) == JV_KIND_STRING);
|
||||
if (jv_get_kind(as) == JV_KIND_STRING)
|
||||
as_str = jv_string_value(as);
|
||||
jv search = default_search(jq, jv_object_get(dep, jv_string("search")));
|
||||
// dep is now freed; do not reuse
|
||||
|
||||
@@ -233,14 +236,14 @@ static int process_dependencies(jq_state *jq, jv jq_origin, jv lib_origin, block
|
||||
if (state_idx < lib_state->ct) { // Found
|
||||
jv_free(resolved);
|
||||
// Bind the library to the program
|
||||
bk = block_bind_library(lib_state->defs[state_idx], bk, OP_IS_CALL_PSEUDO, jv_string_value(as));
|
||||
bk = block_bind_library(lib_state->defs[state_idx], bk, OP_IS_CALL_PSEUDO, as_str);
|
||||
} else { // Not found. Add it to the table before binding.
|
||||
block dep_def_block = gen_noop();
|
||||
nerrors += load_library(jq, resolved, is_data, raw, jv_string_value(as), &dep_def_block, lib_state);
|
||||
nerrors += load_library(jq, resolved, is_data, raw, as_str, &dep_def_block, lib_state);
|
||||
// resolved has been freed
|
||||
if (nerrors == 0) {
|
||||
// Bind the library to the program
|
||||
bk = block_bind_library(dep_def_block, bk, OP_IS_CALL_PSEUDO, jv_string_value(as));
|
||||
bk = block_bind_library(dep_def_block, bk, OP_IS_CALL_PSEUDO, as_str);
|
||||
}
|
||||
}
|
||||
jv_free(as);
|
||||
|
||||
@@ -487,6 +487,12 @@ Import:
|
||||
jv_free($4);
|
||||
jv_free(v);
|
||||
} |
|
||||
"import" String ';' {
|
||||
jv v = block_const($2);
|
||||
$$ = gen_import(jv_string_value(v), gen_noop(), NULL, 0);
|
||||
block_free($2);
|
||||
jv_free(v);
|
||||
} |
|
||||
"import" String "as" IDENT Exp ';' {
|
||||
if (!block_is_const($5)) {
|
||||
FAIL(@$, "Module metadata must be constant.");
|
||||
@@ -499,6 +505,17 @@ Import:
|
||||
block_free($2);
|
||||
jv_free($4);
|
||||
} |
|
||||
"import" String Exp ';' {
|
||||
if (!block_is_const($3)) {
|
||||
FAIL(@$, "Module metadata must be constant.");
|
||||
$$ = gen_noop();
|
||||
} else {
|
||||
jv v = block_const($2);
|
||||
$$ = gen_import(jv_string_value(v), $3, NULL, 0);
|
||||
jv_free(v);
|
||||
}
|
||||
block_free($2);
|
||||
} |
|
||||
"import" String "as" '$' IDENT Exp ';' {
|
||||
if (!block_is_const($6)) {
|
||||
FAIL(@$, "Module metadata must be constant.");
|
||||
|
||||
@@ -1117,6 +1117,10 @@ import "c" as foo; [foo::a, foo::c]
|
||||
null
|
||||
[0,"acmehbah"]
|
||||
|
||||
import "c"; [a, c]
|
||||
null
|
||||
[0,"acmehbah"]
|
||||
|
||||
modulemeta
|
||||
"c"
|
||||
{"whatever":null,"deps":[{"as":"foo","is_data":false,"relpath":"a"},{"search":"./","as":"d","is_data":false,"relpath":"d"},{"search":"./","as":"d2","is_data":false,"relpath":"d"},{"search":"./../lib/jq","as":"e","is_data":false,"relpath":"e"},{"search":"./../lib/jq","as":"f","is_data":false,"relpath":"f"},{"as":"d","is_data":true,"relpath":"data"}]}
|
||||
|
||||
Reference in new issue
Block a user