hare

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

commit 7814b66ddfe6e8a5c23e1f308e759cdae25cb563
parent c9386573e9e3d247c938ae16a2da7aa7802be395
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sat,  9 Dec 2023 21:37:43 -0500

os: add arch type and functions

os::machine now returns the platform-specific architecture name, without
conversion (e.g. amd64 isn't converted to x86_64 on FreeBSD).
os::architecture is added, which returns an enum (os::arch) of all
currently supported target architectures. os::arch_name converts an
os::arch to a string.

This is a breaking change: code which expects portable names from
os::machine should switch to os::arch and os::arch_name.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mcmd/hare/build.ha | 5+++--
Mcmd/hare/deps.ha | 2+-
Mcmd/hare/util.ha | 6+++---
Mcmd/hare/version.ha | 3++-
Mcmd/haredoc/main.ha | 2+-
Mcmd/haredoc/util.ha | 4++--
Mos/+freebsd/platform_environ.ha | 23+++++++++++++++--------
Mos/+linux/platform_environ.ha | 16+++++++++++++++-
Mos/+openbsd/platform_environ.ha | 23++++++++++++++---------
Mos/environ.ha | 20++++++++++++++++++++
10 files changed, 76 insertions(+), 28 deletions(-)

diff --git a/cmd/hare/build.ha b/cmd/hare/build.ha @@ -21,13 +21,14 @@ use strings; use unix::tty; fn build(name: str, cmd: *getopt::command) (void | error) = { - let arch = get_arch(os::machine())?; + let arch = os::arch_name(os::architecture()); + let arch = get_arch(arch)!; let output = ""; let ctx = build::context { ctx = module::context { harepath = harepath(), harecache = harecache(), - tags = default_tags()?, + tags = default_tags(), }, goal = build::stage::BIN, jobs = match (os::cpucount()) { diff --git a/cmd/hare/deps.ha b/cmd/hare/deps.ha @@ -25,7 +25,7 @@ type link = struct { }; fn deps(name: str, cmd: *getopt::command) (void | error) = { - let tags = default_tags()?; + let tags = default_tags(); defer strings::freeall(tags); let build_dir: str = ""; diff --git a/cmd/hare/util.ha b/cmd/hare/util.ha @@ -44,9 +44,9 @@ fn harecache() str = { }; // result must be freed with strings::freeall -fn default_tags() ([]str | error) = { - let arch = get_arch(os::machine())?; +fn default_tags() []str = { + let arch = os::arch_name(os::architecture()); let platform = ascii::strlower(os::sysname()); - let tags: []str = alloc([strings::dup(arch.name), platform]); + let tags: []str = alloc([strings::dup(arch), platform]); return tags; }; diff --git a/cmd/hare/version.ha b/cmd/hare/version.ha @@ -24,7 +24,8 @@ fn version(name: str, cmd: *getopt::command) (void | error) = { return; }; - let build_arch = get_arch(os::machine())?; + let build_arch = os::arch_name(os::architecture()); + let build_arch = get_arch(build_arch)!; let build_platform = ascii::strlower(os::sysname()); fmt::printfln("build tags:\n\t+{}\n\t+{}\nHAREPATH{}:", diff --git a/cmd/haredoc/main.ha b/cmd/haredoc/main.ha @@ -58,7 +58,7 @@ fn doc(name: str, cmd: *getopt::command) (void | error) = { let html = false; let template = true; let show_undocumented = false; - let tags: []str = default_tags()?; + let tags: []str = default_tags(); defer strings::freeall(tags); for (let i = 0z; i < len(cmd.opts); i += 1) { diff --git a/cmd/haredoc/util.ha b/cmd/haredoc/util.ha @@ -46,8 +46,8 @@ fn harecache() str = { }; // result must be freed with strings::freeall -fn default_tags() ([]str | error) = { - let arch = os::machine(); +fn default_tags() []str = { + let arch = os::arch_name(os::architecture()); let platform = ascii::strlower(os::sysname()); let tags: []str = alloc([strings::dup(arch), platform]); return tags; diff --git a/os/+freebsd/platform_environ.ha b/os/+freebsd/platform_environ.ha @@ -79,18 +79,25 @@ export fn version() const str = { return strings::fromutf8(buf[..(sz - 1)])!; }; -// Returns the host CPU architecture +// Returns the host CPU architecture, in a platform-specific format. See +// [[architecture]] for a more portable wrapper. export fn machine() const str = { - static let buf: [512]u8 = [0...]; + static let buf: [32]u8 = [0...]; let sz: size = len(buf); rt::sysctlbyname("hw.machine", &buf, &sz, null, 0)!; - const mach = strings::fromutf8(buf[..(sz - 1)])!; - // Translate to Hare names - switch (mach) { + return strings::fromutf8(buf[..sz - 1])!; +}; + +// Returns the host CPU architecture. +export fn architecture() arch = { + switch (machine()) { + case "aarch64" => + return arch::AARCH64; + case "riscv64" => + return arch::RISCV64; case "amd64" => - return "x86_64"; - case => - return mach; + return arch::X86_64; + case => abort(); // unreachable }; }; diff --git a/os/+linux/platform_environ.ha b/os/+linux/platform_environ.ha @@ -87,7 +87,8 @@ export fn version() const str = { return c::tostr(&uts.version: *const c::char)!; }; -// Returns the host CPU architecture +// Returns the host CPU architecture, in a platform-specific format. See +// [[architecture]] for a more portable wrapper. export fn machine() const str = { if (!uts_valid) { rt::uname(&uts) as void; @@ -96,6 +97,19 @@ export fn machine() const str = { return c::tostr(&uts.machine: *const c::char)!; }; +// Returns the host CPU architecture. +export fn architecture() arch = { + switch (machine()) { + case "aarch64" => + return arch::AARCH64; + case "riscv64" => + return arch::RISCV64; + case "x86_64" => + return arch::X86_64; + case => abort(); // unreachable + }; +}; + // Returns the number of usable CPUs. export fn cpucount() (size | errors::error) = { let set = rt::cpu_set { ... }; diff --git a/os/+openbsd/platform_environ.ha b/os/+openbsd/platform_environ.ha @@ -69,7 +69,8 @@ export fn version() const str = { return strings::fromutf8(buf[..(buf_sz -1)])!; }; -// Returns the host CPU architecture +// Returns the host CPU architecture, in a platform-specific format. See +// [[architecture]] for a more portable wrapper. export fn machine() const str = { let name: [2]int = [rt::CTL_HW, rt::HW_MACHINE]; @@ -78,15 +79,19 @@ export fn machine() const str = { rt::sysctl(name, len(name): uint, &buf, &buf_sz, null, 0)!; - const mach = strings::fromutf8(buf[..(buf_sz - 1)])!; - // Translate to Hare names - switch (mach) { - case "amd64" => - return "x86_64"; + return strings::fromutf8(buf[..(buf_sz - 1)])!; +}; + +// Returns the host CPU architecture. +export fn architecture() arch = { + switch (machine()) { case "arm64" => - return "aarch64"; - case => - return mach; + return arch::AARCH64; + case "riscv64" => + return arch::RISCV64; + case "amd64" => + return arch::X86_64; + case => abort(); // unreachable }; }; diff --git a/os/environ.ha b/os/environ.ha @@ -4,6 +4,26 @@ use errors; use strings; +// All currently supported target architectures. This enum will be extended +// whenever support for a new architecture is added. +export type arch = enum { + AARCH64, + RISCV64, + X86_64, +}; + +// Returns a portable string for an [[arch]]. +export fn arch_name(arch: arch) const str = { + switch (arch) { + case arch::AARCH64 => + return "aarch64"; + case arch::RISCV64 => + return "riscv64"; + case arch::X86_64 => + return "x86_64"; + }; +}; + let envp: []str = []; @fini fn envp() void = strings::freeall(envp);