hare

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

import.ha (2118B)


      1 // SPDX-License-Identifier: MPL-2.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use fmt;
      5 use hare::ast;
      6 use io;
      7 use memio;
      8 
      9 // Unparses a [[hare::ast::import]].
     10 export fn import(
     11 	out: io::handle,
     12 	syn: *synfunc,
     13 	import: *ast::import,
     14 ) (size | io::error) = {
     15 	let n = 0z;
     16 	let ctx = context {
     17 		out = out,
     18 		stack = &stack {
     19 			cur = import,
     20 			...
     21 		},
     22 		...
     23 	};
     24 	n += syn(&ctx, "use", synkind::KEYWORD)?;
     25 	n += space(&ctx)?;
     26 	match (import.bindings) {
     27 	case void =>
     28 		n += _ident(&ctx, syn, import.ident, synkind::IDENT)?;
     29 	case let alias: ast::import_alias =>
     30 		n += syn(&ctx, alias, synkind::IMPORT_ALIAS)?;
     31 		n += space(&ctx)?;
     32 		n += syn(&ctx, "=", synkind::OPERATOR)?;
     33 		n += space(&ctx)?;
     34 		n += _ident(&ctx, syn, import.ident, synkind::IDENT)?;
     35 	case let objects: ast::import_members =>
     36 		n += _ident(&ctx, syn, import.ident, synkind::IDENT)?;
     37 		n += syn(&ctx, "::", synkind::IDENT)?;
     38 		n += syn(&ctx, "{", synkind::PUNCTUATION)?;
     39 		for (let i = 0z; i < len(objects); i += 1) {
     40 			n += syn(&ctx, objects[i], synkind::SECONDARY)?;
     41 			if (i + 1 < len(objects)) {
     42 				n += syn(&ctx, ",", synkind::PUNCTUATION)?;
     43 				n += space(&ctx)?;
     44 			};
     45 		};
     46 		n += syn(&ctx, "}", synkind::PUNCTUATION)?;
     47 	case ast::import_wildcard =>
     48 		n += _ident(&ctx, syn, import.ident, synkind::IDENT)?;
     49 		n += syn(&ctx, "::", synkind::IDENT)?;
     50 		n += syn(&ctx, "*", synkind::PUNCTUATION)?;
     51 	};
     52 	n += syn(&ctx, ";", synkind::PUNCTUATION)?;
     53 	return n;
     54 };
     55 
     56 @test fn import() void = {
     57 	let tests: [_](ast::import, str) = [
     58 		(ast::import {
     59 			ident = ["foo", "bar", "baz"],
     60 			bindings = void,
     61 			...
     62 		}, "use foo::bar::baz;"),
     63 		(ast::import {
     64 			ident = ["foo"],
     65 			bindings = "bar",
     66 			...
     67 		}, "use bar = foo;"),
     68 		(ast::import {
     69 			ident = ["foo"],
     70 			bindings = ["bar", "baz"],
     71 			...
     72 		},  "use foo::{bar, baz};"),
     73 		(ast::import {
     74 			ident = ["foo", "bar"],
     75 			bindings = ast::import_wildcard,
     76 			...
     77 		},  "use foo::bar::*;"),
     78 	];
     79 	for (let (ast_import, str_import) .. tests) {
     80 		let buf = memio::dynamic();
     81 		import(&buf, &syn_nowrap, &ast_import)!;
     82 		let s = memio::string(&buf)!;
     83 		assert(s == str_import);
     84 		free(s);
     85 	};
     86 };