using in importation statements

This commit is contained in:
gingerBill
2017-12-17 11:17:54 +00:00
parent 1b6a14ac39
commit 0d665c637f
2 changed files with 108 additions and 31 deletions
+62 -6
View File
@@ -2642,6 +2642,8 @@ void check_add_import_decl(Checker *c, AstNodeImportDecl *id) {
ptr_set_add(&parent_scope->imported, scope); ptr_set_add(&parent_scope->imported, scope);
} }
if (id->using_in_list.count == 0) {
String import_name = path_to_entity_name(id->import_name.string, id->fullpath); String import_name = path_to_entity_name(id->import_name.string, id->fullpath);
if (is_blank_ident(import_name)) { if (is_blank_ident(import_name)) {
if (id->is_using) { if (id->is_using) {
@@ -2658,20 +2660,31 @@ void check_add_import_decl(Checker *c, AstNodeImportDecl *id) {
add_entity(c, parent_scope, nullptr, e); add_entity(c, parent_scope, nullptr, e);
} }
}
if (id->is_using) { if (id->is_using) {
if (parent_scope->is_global) { if (parent_scope->is_global) {
error(id->import_name, "#shared_global_scope imports cannot use using"); error(id->import_name, "#shared_global_scope imports cannot use using");
return; return;
} }
// NOTE(bill): Add imported entities to this file's scope
for_array(elem_index, scope->elements.entries) {
Entity *e = scope->elements.entries[elem_index].value;
if (e->scope == parent_scope) continue;
if (e->token.string == "get_proc_address") { // NOTE(bill): Add imported entities to this file's scope
// gb_printf_err("%.*s %.*s get_proc_address\n", LIT(scope->file->fullpath), LIT(parent_scope->file->fullpath)); if (id->using_in_list.count > 0) {
for_array(list_index, id->using_in_list) {
AstNode *node = id->using_in_list[list_index];
ast_node(ident, Ident, node);
String name = ident->token.string;
Entity *e = scope_lookup_entity(scope, name);
if (e == nullptr) {
if (is_blank_ident(name)) {
error(node, "'_' cannot be used as a value");
} else {
error(node, "Undeclared name in this importation: '%.*s'", LIT(name));
} }
continue;
}
if (e->scope == parent_scope) continue;
bool implicit_is_found = ptr_set_exists(&scope->implicit, e); bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
if (is_entity_exported(e) && !implicit_is_found) { if (is_entity_exported(e) && !implicit_is_found) {
@@ -2679,6 +2692,23 @@ void check_add_import_decl(Checker *c, AstNodeImportDecl *id) {
// if (prev) gb_printf_err("%.*s\n", LIT(prev->token.string)); // if (prev) gb_printf_err("%.*s\n", LIT(prev->token.string));
bool ok = add_entity(c, parent_scope, e->identifier, e); bool ok = add_entity(c, parent_scope, e->identifier, e);
if (ok) ptr_set_add(&parent_scope->implicit, e); if (ok) ptr_set_add(&parent_scope->implicit, e);
} else {
error(node, "'%.*s' is exported from this scope", LIT(name));
continue;
}
}
} else {
for_array(elem_index, scope->elements.entries) {
Entity *e = scope->elements.entries[elem_index].value;
if (e->scope == parent_scope) continue;
bool implicit_is_found = ptr_set_exists(&scope->implicit, e);
if (is_entity_exported(e) && !implicit_is_found) {
Entity *prev = scope_lookup_entity(parent_scope, e->token.string);
// if (prev) gb_printf_err("%.*s\n", LIT(prev->token.string));
bool ok = add_entity(c, parent_scope, e->identifier, e);
if (ok) ptr_set_add(&parent_scope->implicit, e);
}
} }
} }
} }
@@ -2722,6 +2752,31 @@ void check_add_export_decl(Checker *c, AstNodeExportDecl *ed) {
ptr_set_add(&parent_scope->imported, scope); ptr_set_add(&parent_scope->imported, scope);
} }
if (ed->using_in_list.count > 0) {
for_array(list_index, ed->using_in_list) {
AstNode *node = ed->using_in_list[list_index];
ast_node(ident, Ident, node);
String name = ident->token.string;
Entity *e = scope_lookup_entity(scope, name);
if (e == nullptr) {
if (is_blank_ident(name)) {
error(node, "'_' cannot be used as a value");
} else {
error(node, "Undeclared name in this importation: '%.*s'", LIT(name));
}
continue;
}
if (e->scope == parent_scope) continue;
if (is_entity_exported(e)) {
add_entity(c, parent_scope, e->identifier, e);
} else {
error(node, "'%.*s' is exported from this scope", LIT(name));
continue;
}
}
} else {
// NOTE(bill): Add imported entities to this file's scope // NOTE(bill): Add imported entities to this file's scope
for_array(elem_index, scope->elements.entries) { for_array(elem_index, scope->elements.entries) {
Entity *e = scope->elements.entries[elem_index].value; Entity *e = scope->elements.entries[elem_index].value;
@@ -2731,6 +2786,7 @@ void check_add_export_decl(Checker *c, AstNodeExportDecl *ed) {
add_entity(c, parent_scope, e->identifier, e); add_entity(c, parent_scope, e->identifier, e);
} }
} }
}
ptr_set_add(&c->checked_files, scope->file); ptr_set_add(&c->checked_files, scope->file);
scope->has_been_imported = true; scope->has_been_imported = true;
+21
View File
@@ -362,6 +362,7 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
Token import_name; \ Token import_name; \
bool is_using; \ bool is_using; \
bool been_handled; \ bool been_handled; \
Array<AstNode *> using_in_list; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
@@ -371,6 +372,7 @@ AST_NODE_KIND(_DeclBegin, "", i32) \
Token relpath; \ Token relpath; \
String fullpath; \ String fullpath; \
bool been_handled; \ bool been_handled; \
Array<AstNode *> using_in_list; \
CommentGroup docs; \ CommentGroup docs; \
CommentGroup comment; \ CommentGroup comment; \
}) \ }) \
@@ -4518,6 +4520,25 @@ AstNode *parse_stmt(AstFile *f) {
return ast_bad_stmt(f, token, f->curr_token); return ast_bad_stmt(f, token, f->curr_token);
} }
if (f->curr_token.kind == Token_in) {
Token in_token = expect_token(f, Token_in);
if (f->curr_token.kind == Token_import) {
AstNode *import_decl = parse_import_decl(f, true);
if (import_decl->kind == AstNode_ImportDecl) {
import_decl->ImportDecl.using_in_list = list;
}
return import_decl;
} else if (f->curr_token.kind == Token_export) {
AstNode *export_decl = parse_export_decl(f);
if (export_decl->kind == AstNode_ExportDecl) {
export_decl->ExportDecl.using_in_list = list;
}
return export_decl;
}
syntax_error(token, "Illegal use of 'using' statement");
return ast_bad_stmt(f, token, f->curr_token);
}
if (f->curr_token.kind != Token_Colon) { if (f->curr_token.kind != Token_Colon) {
expect_semicolon(f, list[list.count-1]); expect_semicolon(f, list[list.count-1]);
return ast_using_stmt(f, token, list); return ast_using_stmt(f, token, list);