commit 3c083f52bc45cf51e3bdf943585ac8ce412ec3d6
parent 9caae7b9fa389ea58025c9f55513b63e6661b2ea
Author: Armin Weigl <tb46305@gmail.com>
Date: Tue, 23 Feb 2021 17:21:26 +0100
Implement imports
Fixes hare#9
Diffstat:
4 files changed, 91 insertions(+), 10 deletions(-)
diff --git a/src/check.c b/src/check.c
@@ -2584,13 +2584,13 @@ load_import(struct ast_imports *import,
obj; obj = obj->next) {
scope_insert(scope, obj->otype, &obj->ident,
&obj->name, obj->type, obj->value);
- if (obj->ident.ns && obj->ident.ns->ns) {
+ if (obj->name.ns && obj->name.ns->ns) {
struct identifier ns = {
- .name = obj->ident.ns->name,
+ .name = obj->name.ns->name,
.ns = NULL
};
struct identifier name = {
- .name = obj->ident.name,
+ .name = obj->name.name,
.ns = &ns,
};
scope_insert(scope, obj->otype, &obj->ident,
@@ -2599,9 +2599,29 @@ load_import(struct ast_imports *import,
}
break;
case AST_IMPORT_ALIAS:
- assert(0); // TODO
+ for (struct scope_object *obj = mod->objects;
+ obj; obj = obj->next) {
+ struct identifier name = {
+ .name = obj->name.name,
+ .ns = import->alias,
+ };
+ scope_insert(scope, obj->otype, &obj->ident,
+ &name, obj->type, obj->value);
+ }
+ break;
case AST_IMPORT_MEMBERS:
- assert(0); // TODO
+ for (struct ast_imports *member = import->members;
+ member; member = member->next) {
+ struct identifier name = {
+ .name = member->ident.name,
+ .ns = &import->ident,
+ };
+ const struct scope_object *obj = scope_lookup(mod, &name);
+ name.ns = NULL;
+ scope_insert(scope, obj->otype, &obj->ident,
+ &name, obj->type, obj->value);
+ }
+ break;
}
}
diff --git a/src/parse.c b/src/parse.c
@@ -139,24 +139,74 @@ parse_identifier(struct lexer *lexer, struct identifier *ident, bool trailing)
}
static void
+parse_name_list(struct lexer *lexer, struct ast_imports *name)
+{
+ trenter(TR_PARSE, "name_list");
+ bool more = true;
+ struct ast_imports **next = &name->next;
+ while (more) {
+ struct token tok = {0};
+ want(lexer, T_NAME, &tok);
+ name->ident.name = strdup(tok.name);
+ token_finish(&tok);
+
+ switch (lex(lexer, &tok)) {
+ case T_COMMA:
+ switch (lex(lexer, &tok)) {
+ case T_RBRACE:
+ more = false;
+ break;
+ default:
+ unlex(lexer, &tok);
+ name = xcalloc(1, sizeof(struct ast_imports));
+ *next = name;
+ next = &name->next;
+ }
+ break;
+ case T_RBRACE:
+ more = false;
+ break;
+ default:
+ synassert(false, &tok, T_RBRACE, T_COMMA, T_EOF);
+ break;
+ }
+ }
+ trleave(TR_PARSE, NULL);
+}
+
+static void
parse_import(struct lexer *lexer, struct ast_imports *imports)
{
trenter(TR_PARSE, "import");
struct identifier ident = {0};
- parse_identifier(lexer, &ident, false);
+ bool trailing_colon = parse_identifier(lexer, &ident, true);
struct token tok = {0};
switch (lex(lexer, &tok)) {
case T_EQUAL:
- assert(0); // TODO
+ synassert(!trailing_colon, &tok, T_NAME, T_EOF);
+ imports->mode = AST_IMPORT_ALIAS;
+ imports->alias = xcalloc(1, sizeof(struct identifier));
+ *imports->alias = ident;
+ parse_identifier(lexer, &imports->ident, false);
+ want(lexer, T_SEMICOLON, &tok);
+ break;
case T_LBRACE:
- assert(0); // TODO
+ synassert(trailing_colon, &tok, T_DOUBLE_COLON, T_EOF);
+ imports->mode = AST_IMPORT_MEMBERS;
+ imports->ident = ident;
+ imports->members = xcalloc(1, sizeof(struct ast_imports));
+ parse_name_list(lexer, imports->members);
+ want(lexer, T_SEMICOLON, &tok);
+ break;
case T_SEMICOLON:
+ synassert(!trailing_colon, &tok, T_NAME, T_EOF);
imports->mode = AST_IMPORT_IDENTIFIER;
imports->ident = ident;
break;
default:
- synassert(false, &tok, T_EQUAL, T_LBRACE, T_SEMICOLON, T_EOF);
+ synassert(!trailing_colon, &tok, T_EQUAL, T_SEMICOLON, T_EOF);
+ synassert(trailing_colon, &tok, T_NAME, T_LBRACE, T_EOF);
break;
}
diff --git a/tests/24-imports.ha b/tests/24-imports.ha
@@ -0,0 +1,10 @@
+use rt;
+use test = rt;
+use rt::{malloc, free_};
+
+export fn main() void = {
+ assert(&rt::malloc == &test::malloc);
+ assert(&rt::malloc == &malloc);
+ assert(&rt::free_ == &test::free_);
+ assert(&rt::free_ == &free_);
+};
diff --git a/tests/configure b/tests/configure
@@ -26,7 +26,8 @@ tests() {
20-if \
21-tuples \
22-delete \
- 23-errors
+ 23-errors \
+ 24-imports
do
cat <<EOF
tests/$t: libhart.a tests/$t.ha