1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
// SPDX-License-Identifier: MPL-2.0
// (c) Hare authors <https://harelang.org>
use common::{token, ltok, nonterminal};
use vNEXT::ast;
use vNEXT::lex;
fn name_list(lexer: *lex::lexer) (ast::import_members | error) = {
let names: []str = [];
for (true) {
append(names, want(lexer, ltok::NAME)?.1 as str)!;
switch (want(lexer, ltok::COMMA, ltok::RBRACE)?.0) {
case ltok::COMMA =>
match (try(lexer, ltok::RBRACE)?) {
case void => void;
case =>
return names;
};
case ltok::RBRACE =>
return names;
case => abort(); // Unreachable
};
};
};
// Parses the import list for a sub-unit
export fn imports(lexer: *lex::lexer) ([]ast::import | error) = {
on(lexer, nonterminal::IMPORTS, null)?;
let imports: []ast::import = [];
for (true) {
const start = match (try(lexer, ltok::USE)?) {
case void => break;
case let tok: token =>
yield tok.2;
};
append(imports, ast::import {
bindings = void,
...
})!;
let import = &imports[len(imports) - 1];
import.start = start;
let (name, trailing) = ident_trailing(lexer)?;
import.ident = name;
switch (want(lexer, ltok::SEMICOLON, ltok::LBRACE,
ltok::EQUAL, ltok::TIMES)?.0) {
case ltok::SEMICOLON =>
synassert(lex::mkloc(lexer), !trailing,
"Unexpected trailing :: in ident")?;
case ltok::LBRACE =>
synassert(lex::mkloc(lexer), trailing,
"Expected trailing :: in ident")?;
import.bindings = name_list(lexer)?;
want(lexer, ltok::SEMICOLON)?;
case ltok::EQUAL =>
synassert(lex::mkloc(lexer),
len(name) == 1 && !trailing,
"Expected name, not ident")?;
import.bindings = name[0];
free(name);
import.ident = ident(lexer)?;
want(lexer, ltok::SEMICOLON)?;
case ltok::TIMES =>
synassert(lex::mkloc(lexer), trailing,
"Expected trailing :: in ident")?;
import.bindings = ast::import_wildcard;
want(lexer, ltok::SEMICOLON)?;
case => abort(); // Unreachable
};
import.end = lex::mkloc(lexer);
};
return imports;
};
|