hare

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

main.ha (3282B)


      1 // SPDX-License-Identifier: GPL-3.0
      2 // (c) Hare authors <https://harelang.org>
      3 
      4 use fmt;
      5 use hare::module;
      6 use hare::unparse;
      7 use io;
      8 use memio;
      9 use os;
     10 use path;
     11 use strings;
     12 
     13 export fn main() void = {
     14 	if (len(os::args) > 1 && os::args[1] == "-h") {
     15 		fmt::errorln("usage:", os::args[0], "[<tag>...]")!;
     16 		os::exit(0);
     17 	};
     18 
     19 	const ctx = module::context {
     20 		harepath = os::tryenv("HAREPATH", "."),
     21 		harecache = os::tryenv("HARECACHE", ".cache"),
     22 		tags = os::args[1..],
     23 	};
     24 	let mods: []module::module = [];
     25 	defer module::free_slice(mods);
     26 	module::gather(&ctx, &mods, ["rt"])!;
     27 	module::gather(&ctx, &mods, ["cmd", "hare"])!;
     28 
     29 	let ids: [](str, str) = [];
     30 	defer free(ids);
     31 	defer for (let i = 0z; i < len(ids); i += 1) {
     32 		free(ids[i].0);
     33 		free(ids[i].1);
     34 	};
     35 
     36 	let with_libc = false;
     37 	for (let i = 0z; i < len(ctx.tags); i += 1) {
     38 		if (ctx.tags[i] == "libc") {
     39 			with_libc = true;
     40 		};
     41 	};
     42 
     43 	let tds = memio::dynamic();
     44 	defer io::close(&tds)!;
     45 	let objs = memio::dynamic();
     46 	defer io::close(&objs)!;
     47 	for (let i = 0z; i < len(mods); i += 1) {
     48 		append(ids, (strings::join("_", mods[i].ns...),
     49 			unparse::identstr(mods[i].ns)));
     50 		fmt::fprintf(&tds, ` HARE_TD_{}=$(HARECACHE)/{}.td`,
     51 			ids[i].1, ids[i].0)!;
     52 		fmt::fprintf(&objs, ` $(HARECACHE)/{}.o`, ids[i].0)!;
     53 	};
     54 
     55 	let cwd = os::getcwd();
     56 	let buf = path::init(mods[0].srcs.sc[0])!;
     57 	fmt::println(`# generated by cmd/genbootstrap`)!;
     58 	fmt::println(`# DO NOT EDIT BY HAND. run 'make bootstrap' to update`)!;
     59 	fmt::printfln(`TDENV = env{}`, memio::string(&tds)!)!;
     60 	fmt::printfln(`RTSCRIPT = {}`, path::trimprefix(&buf, cwd)!)!;
     61 	fmt::printfln(`OBJS ={}`, memio::string(&objs)!)!;
     62 
     63 	let deps = memio::dynamic();
     64 	defer io::close(&deps)!;
     65 	let sources = memio::dynamic();
     66 	defer io::close(&sources)!;
     67 	for (let i = 0z; i < len(mods); i += 1) {
     68 		memio::reset(&deps);
     69 		for (let j = 0z; j < len(mods[i].deps); j += 1) {
     70 			fmt::fprintf(&deps, ` $(HARECACHE)/{}.td`,
     71 				ids[mods[i].deps[j].0].0)!;
     72 		};
     73 		memio::reset(&sources);
     74 		for (let j = 0z; j < len(mods[i].srcs.ha); j += 1) {
     75 			path::set(&buf, mods[i].srcs.ha[j])!;
     76 			fmt::fprint(&sources, "", path::trimprefix(&buf, cwd)!)!;
     77 		};
     78 
     79 		fmt::println()!;
     80 		fmt::printfln(`{}_ha ={}`, ids[i].0, memio::string(&sources)!)!;
     81 		fmt::printfln(`$(HARECACHE)/{}.ssa: $({}_ha){}`,
     82 			ids[i].0, ids[i].0, memio::string(&deps)!)!;
     83 		fmt::println("\t" `@mkdir -p -- "$(HARECACHE)"`)!;
     84 		fmt::println("\t" `@printf 'HAREC\t%s\n' "$@"`)!;
     85 		fmt::printfln("\t" `@$(TDENV) $(HAREC) $(HARECFLAGS) {}-o $@ -t $(HARECACHE)/{}.td.tmp {} {} $({}_ha)`,
     86 			if (i == len(mods) - 1 && with_libc) `-N "" ` else ``,
     87 			ids[i].0,
     88 			if (i == len(mods) - 1) `$(HARE_DEFINES)` else `-N`,
     89 			if (i == len(mods) - 1) `` else ids[i].1, ids[i].0)!;
     90 		if (len(mods[i].srcs.s) == 0) {
     91 			continue;
     92 		};
     93 
     94 		memio::reset(&sources);
     95 		for (let j = 0z; j < len(mods[i].srcs.s); j += 1) {
     96 			path::set(&buf, mods[i].srcs.s[j])!;
     97 			fmt::fprint(&sources, "", path::trimprefix(&buf, cwd)!)!;
     98 		};
     99 
    100 		fmt::println()!;
    101 		fmt::printfln(`{}_s = $(HARECACHE)/{}.s{}`,
    102 			ids[i].0, ids[i].0, memio::string(&sources)!)!;
    103 		fmt::printfln(`$(HARECACHE)/{}.o: $({}_s)`, ids[i].0, ids[i].0)!;
    104 		fmt::println("\t" `@printf 'AS\t%s\n' "$@"`)!;
    105 		fmt::printfln("\t" `@$(AS) $(ASFLAGS) -o $@ $({}_s)`, ids[i].0)!;
    106 	};
    107 };