hare

[hare] The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

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 };