File: import.ha

package info (click to toggle)
hare-update 0.26.0.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,044 kB
  • sloc: makefile: 37; sh: 14
file content (74 lines) | stat: -rw-r--r-- 1,977 bytes parent folder | download
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;
};