commit 1895c2ffed0b42545f2dbb22e7c6a43a0de44b29
parent 42a8bb0a2fd9e966004e8bf9a34eec48cbca3f1f
Author: Drew DeVault <sir@cmpwn.com>
Date: Thu, 29 Apr 2021 10:36:29 -0400
hare::types: flesh out API design for type store
Signed-off-by: Drew DeVault <sir@cmpwn.com>
Diffstat:
1 file changed, 41 insertions(+), 4 deletions(-)
diff --git a/hare/types/store.ha b/hare/types/store.ha
@@ -1,20 +1,53 @@
+use errors;
use hare::ast;
export def BUCKETS: size = 65535;
+// A function which evaluates an [[ast::expr]], providing either a size result
+// or an error.
+export type resolver = fn(
+ rstate: *void,
+ store: *typestore,
+ expr: const *ast::expr,
+) (size | errors::opaque);
+
// A type store. Holds singletons for types in a hash map.
export type typestore = struct {
map: [BUCKETS][]struct {
hash: u32,
_type: _type,
},
+ resolve: *resolver,
+ rstate: *void,
+};
+
+// Initializes a new type store. Optionally, provide a function which
+// type-checks and evaluates an [[ast::expr]].
+export fn store(resolver: *resolver, rstate: *void) *typestore = {
+ return alloc(typestore {
+ resolve = resolver,
+ rstate = rstate,
+ ...
+ });
};
-// Initializes a new type store.
-export fn store() *typestore = alloc(typestore { ... });
+// Returned from [[lookup]] when we are unable to resolve this type, but it does
+// not necessarily have an error. This occurs when a type includes an unknown
+// forward reference.
+export type deferred = void;
+
+// A resolver function was not provided to [[store]], but was required to look
+// up this type.
+export type noresolver = void!;
+
+// All possible errors for [[lookup]].
+export type error = (noresolver | errors::opaque)!;
// Retrieves a [[_type]] for a given [[ast::_type]].
-export fn lookup(store: *typestore, t: *ast::_type) const *_type = {
+export fn lookup(
+ store: *typestore,
+ t: *ast::_type,
+) (const *_type | deferred | error) = {
const t = fromast(t);
const h = hash(&t);
let bucket = &store.map[h % BUCKETS];
@@ -48,5 +81,9 @@ fn fromast(atype: *ast::_type) _type = {
};
fn type_finish(t: *_type) void = {
- void; // TODO
+ match (t._type) {
+ a: alias => ast::ident_free(a),
+ builtin => void,
+ * => abort(), // TODO
+ };
};