hare

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

commit 147f3d5c907a04d6091d0a216ebf27d6d0e0299b
parent 2ac46dee05b1df152fa0a1a53e59ad45ff039c6f
Author: Alexey Yerin <yyp@disroot.org>
Date:   Thu, 14 Oct 2021 14:52:44 +0300

types: add strflag reflection helper

Signed-off-by: Alexey Yerin <yyp@disroot.org>

Diffstat:
Mtypes/util.ha | 55+++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 55 insertions(+), 0 deletions(-)

diff --git a/types/util.ha b/types/util.ha @@ -41,6 +41,61 @@ export fn strenum(ty: type, val: *void) str = { abort("enum has invalid value"); }; +// TODO: should we have a static version of that? + +// Returns the names of enabled flags of a bitfield enum at "val" formatted as +// '|' operation, or "0" when the value doesn't match any flags. The string +// must be freed by the caller. +export fn strflag(ty: type, val: *void) str = { + const ty = unwrap(ty); + const en = ty.repr as enumerated; + const value: u64 = switch (en.storage) { + case builtin::CHAR, builtin::I8, builtin::U8 => + yield *(val: *u8); + case builtin::I16, builtin::U16 => + yield *(val: *u16); + case builtin::I32, builtin::U32 => + yield *(val: *u32); + case builtin::I64, builtin::U64 => + yield *(val: *u64); + case builtin::INT, builtin::UINT => + yield switch (size(int)) { + case 4 => + yield *(val: *u32); + case 8 => + yield *(val: *u64); + case => abort(); + }; + case builtin::SIZE => + yield switch (size(size)) { + case 4 => + yield *(val: *u32); + case 8 => + yield *(val: *u64); + case => abort(); + }; + case => abort(); + }; + + let buf: []u8 = alloc([]); + + for (let i = 0z; i < len(en.values); i += 1) { + if (en.values[i].1.u & value != 0) { + if (i > 0) { + append(buf, '|': u8); + }; + const name = en.values[i].0; + append(buf, *(&name: *[]u8)...); + }; + }; + + if (len(buf) == 0) { + append(buf, '0': u8); + }; + + return *(&buf: *str); +}; + // Returns [[typeinfo]] for the provided type, unwrapping any aliases along the // way. export fn unwrap(in: type) const *typeinfo = {