commit fa4ac1140043f747b7c179cfa9fd1388636bf3d7
parent 12dfb39fa74ede4502755d1b48319aa441d0547f
Author: Eyal Sawady <ecs@d2evs.net>
Date: Thu, 6 May 2021 03:44:23 -0400
hare::types: finish data structures and hashing
Signed-off-by: Eyal Sawady <ecs@d2evs.net>
Diffstat:
3 files changed, 118 insertions(+), 23 deletions(-)
diff --git a/hare/types/hash.ha b/hare/types/hash.ha
@@ -10,32 +10,37 @@ type storage = enum u8 {
FUNCTION, POINTER, SLICE, STRING, STRUCT, TAGGED, TUPLE, UNION,
};
+fn builtin_storage(b: builtin) u8 = switch (b) {
+ builtin::BOOL => storage::BOOL,
+ builtin::CHAR => storage::CHAR,
+ builtin::F32 => storage::F32,
+ builtin::F64 => storage::F64,
+ builtin::I16 => storage::I16,
+ builtin::I32 => storage::I32,
+ builtin::I64 => storage::I64,
+ builtin::I8 => storage::I8,
+ builtin::INT => storage::INT,
+ builtin::NULL => storage::NULL,
+ builtin::RUNE => storage::RUNE,
+ builtin::SIZE => storage::SIZE,
+ builtin::STR => storage::STRING,
+ builtin::U16 => storage::U16,
+ builtin::U32 => storage::U32,
+ builtin::U64 => storage::U64,
+ builtin::U8 => storage::U8,
+ builtin::UINT => storage::UINT,
+ builtin::UINTPTR => storage::UINTPTR,
+ builtin::VOID => storage::VOID,
+};
+
fn type_storage(t: *_type) u8 = match (t._type) {
alias => storage::ALIAS,
array => storage::ARRAY,
- t: builtin => switch (t) {
- builtin::BOOL => storage::BOOL,
- builtin::CHAR => storage::CHAR,
- builtin::F32 => storage::F32,
- builtin::F64 => storage::F64,
- builtin::I16 => storage::I16,
- builtin::I32 => storage::I32,
- builtin::I64 => storage::I64,
- builtin::I8 => storage::I8,
- builtin::INT => storage::INT,
- builtin::NULL => storage::NULL,
- builtin::RUNE => storage::RUNE,
- builtin::SIZE => storage::SIZE,
- builtin::STR => storage::STRING,
- builtin::U16 => storage::U16,
- builtin::U32 => storage::U32,
- builtin::U64 => storage::U64,
- builtin::U8 => storage::U8,
- builtin::UINT => storage::UINT,
- builtin::UINTPTR => storage::UINTPTR,
- builtin::VOID => storage::VOID,
- },
+ b: builtin => builtin_storage(b),
+ _enum => storage::ENUM,
+ func => storage::FUNCTION,
pointer => storage::POINTER,
+ slice => storage::SLICE,
st: _struct =>
if (st.kind == struct_union::STRUCT)
storage::STRUCT
@@ -82,10 +87,26 @@ export fn hash(t: *_type) u32 = {
write64(id, a.length);
},
builtin => void,
+ e: _enum => {
+ write8(id, builtin_storage(e.storage));
+ for (let i = 0z; i < len(e.values); i += 1) {
+ hash::write(id, strings::toutf8(e.values[i].0));
+ write64(id, e.values[i].1);
+ };
+ },
+ f: func => {
+ write32(id, hash(f.result));
+ write8(id, f.variadism: u8);
+ write8(id, f.flags: u8);
+ for (let i = 0z; i < len(f.params); i += 1) {
+ write32(id, hash(f.params[i]));
+ };
+ },
p: pointer => {
write8(id, p.flags);
write32(id, hash(p.referent));
},
+ s: slice => write32(id, hash(s)),
st: _struct => for (let i = 0z; i < len(st.fields); i += 1) {
const field = st.fields[i];
hash::write(id, strings::toutf8(field.name));
@@ -220,4 +241,34 @@ export fn hash(t: *_type) u32 = {
]: tagged,
};
assert(hash(&sample) == 3951208153);
+
+ let sample = _type {
+ flags = flags::NONE,
+ _type = _enum {
+ storage = builtin::INT,
+ values = [
+ ("FOO", 0),
+ ("BAR", 42),
+ ("BAZ", 69),
+ ],
+ },
+ };
+ assert(hash(&sample) == 1838699449);
+
+ let sample = _type {
+ flags = flags::NONE,
+ _type = func {
+ result = &_void,
+ variadism = variadism::C,
+ flags = func_flags::NORETURN,
+ params = [&_uint, &_int],
+ },
+ };
+ assert(hash(&sample) == 1706980510);
+
+ let sample = _type {
+ flags = flags::NONE,
+ _type = &_void: slice,
+ };
+ assert(hash(&sample) == 3143795781);
};
diff --git a/hare/types/store.ha b/hare/types/store.ha
@@ -361,7 +361,21 @@ fn type_finish(t: *_type) void = {
a: alias => ast::ident_free(a.id),
array => void,
builtin => void,
+ e: _enum => {
+ for (let i = 0z; i < len(e.values); i += 1) {
+ free(e.values[i].0);
+ };
+ free(e.values);
+ },
+ f: func => {
+ type_finish(f.result);
+ for (let i = 0z; i < len(f.params); i += 1) {
+ type_finish(f.params[i]);
+ };
+ free(f.params);
+ },
pointer => void,
+ s: slice => type_finish(s),
st: _struct => free(st.fields),
tu: tuple => free(tu),
ta: tagged => free(ta),
diff --git a/hare/types/types.ha b/hare/types/types.ha
@@ -21,6 +21,32 @@ export type builtin = enum u8 {
U16, U32, U64, U8, UINT, UINTPTR, VOID,
};
+// An enum type, e.g. enum { FOO = 0 }
+export type _enum = struct {
+ storage: builtin,
+ values: [](str, u64),
+};
+
+// Indicates the variadism of a [[func]]
+export type variadism = enum {
+ NONE,
+ C,
+ HARE,
+};
+
+// Indicats if a [[func]] has the @noreturn attribute
+export type func_flags = enum uint {
+ NORETURN = 1 << 0,
+};
+
+// A function type, e.g. fn(x: int, y: int) int
+export type func = struct {
+ result: const *_type,
+ variadism: variadism,
+ flags: func_flags,
+ params: []const *_type,
+};
+
// Flags which apply to a pointer type.
export type pointer_flags = enum u8 {
NONE = 0,
@@ -34,6 +60,9 @@ export type pointer = struct {
flags: pointer_flags,
};
+// []int
+export type slice = const *_type;
+
// Indicates if a [[_struct]] was declared as a struct or union type.
export type struct_union = enum {
STRUCT,
@@ -84,7 +113,8 @@ export def SIZE_UNDEFINED: size = -1: size;
// A Hare type.
export type _type = struct {
flags: flags,
- _type: (alias | array | builtin | pointer | _struct | tagged | tuple),
+ _type: (alias | array | builtin | _enum | func | pointer | slice |
+ _struct | tagged | tuple),
id: u32,
sz: size,
align: size,