@@ 24,8 24,10 @@ use strings;
export type import = struct {
// location of the first token in import after the use keyword
location: lex::location,
- module: str,
+ name: str,
alias: str,
+ // borrows the alias if there is one, otherwise borrows the name
+ path: str,
// TODO: handle second and third (unqualified) types of imports.
};
@@ 33,8 35,9 @@ export type import = struct {
export fn imports_freeall(imports: []import) void = {
for (let i = 0z; i < len(imports); i += 1) {
// TODO: imports[i].location?
- free(imports[i].module);
+ free(imports[i].name);
free(imports[i].alias);
+ // DON'T free .path; it is a borrow
};
free(imports);
};
@@ 43,11 46,20 @@ export fn imports_freeall(imports: []import) void = {
// of the provided token.
fn badtoken(t: lex::token) lex::syntax = (t.2, lex::tokstr(t));
+// Returns a [[import]] constructed from the provided parameters.
+fn newimport(loc: lex::location, name: str, alias: str) import =
+ import {
+ location = loc,
+ name = name,
+ alias = alias,
+ path = if (alias == "") name else alias,
+ };
+
// Parses a single import statement from the provided [[hare::lex::lexer]].
// Precondition: the use keyword MUST have already been lexed.
-// Only allow an alias to be parsed if the alias parameter is empty.
+// An alias will only be lexed if recursive_alias is void.
// Returns an [[import]] on success, or [[hare::lex::error]] on failure.
-fn getimport(lexp: *lex::lexer, alias: str) (import | lex::error) = {
+fn getimport(lexp: *lex::lexer, recursive_alias: str) (import | lex::error) = {
// The first token has to be a name: either the beginning of
// an import-alias or the beginning of an identifier.
// See also §6.4 (Identifiers).
@@ 55,12 67,6 @@ fn getimport(lexp: *lex::lexer, alias: str) (import | lex::error) = {
if (first.0 != lex::ltok::NAME)
return badtoken(first);
- let import = import {
- location = first.2,
- module = "",
- alias = alias,
- };
-
let module_builder = strio::dynamic();
defer io::close(&module_builder)!;
@@ 68,11 74,14 @@ fn getimport(lexp: *lex::lexer, alias: str) (import | lex::error) = {
switch (second.0) {
case lex::ltok::SEMICOLON =>
// top-level (i.e. not a submodule) import
- import.module = strings::dup(lex::tokstr(first));
- return import;
+ return newimport(
+ first.2, // location
+ strings::dup(lex::tokstr(first)),
+ recursive_alias,
+ );
case lex::ltok::EQUAL =>
// Import alias
- if (alias == "") {
+ if (recursive_alias == "") {
return getimport(lexp,
strings::dup(lex::tokstr(first)));
};
@@ 117,8 126,11 @@ fn getimport(lexp: *lex::lexer, alias: str) (import | lex::error) = {
};
};
- import.module = strings::dup(strio::string(&module_builder));
- return import;
+ return newimport(
+ first.2,
+ strings::dup(strio::string(&module_builder)),
+ recursive_alias,
+ );
};
// Returns a slice of [[import]]s or a [[hare::lex::error]]. The slice must be
@@ 147,5 159,6 @@ export fn main() void = {
defer imports_freeall(imports);
for (let i = 0z; i < len(imports); i += 1)
- fmt::printfln("{} {}", imports[i].module, imports[i].alias)!;
+ fmt::printfln("{} (= {})",
+ imports[i].name, imports[i].path)!;
};