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